From f8d3cbdd59f0aff5fe2dee80b39a4f829fd3f052 Mon Sep 17 00:00:00 2001 From: Sergey Antropoff Date: Sat, 18 Jul 2026 04:42:11 +0300 Subject: [PATCH] Initial commit: VMware vSphere API simulator scaffold. Add the FastAPI app, PostgreSQL migrations, Docker/Helm packaging, API contracts, docs, client examples, and the unit/integration/compatibility test suite for local client and tooling labs without a real vCenter. --- .dockerignore | 10 + .env.example | 33 + .gitignore | 80 + Dockerfile | 58 + LICENSE | 13 + Makefile | 256 + README.md | 228 + README.ru.md | 229 + app/__init__.py | 1 + app/api/__init__.py | 1 + app/api/errors.py | 51 + app/api/middleware.py | 42 + app/api/openapi.py | 138 + app/api/registry.py | 375 + app/compatibility.py | 311 + app/config.py | 63 + app/contracts/__init__.py | 1 + app/contracts/cli.py | 87 + app/contracts/diff.py | 224 + app/contracts/examples.py | 76 + app/contracts/importer.py | 110 + app/contracts/model.py | 134 + app/contracts/normalize.py | 168 + app/contracts/runtime.py | 210 + app/contracts/source.py | 154 + app/contracts/store.py | 48 + app/db/__init__.py | 1 + app/db/migrate_cli.py | 16 + app/db/migrations.py | 70 + app/db/migrations/001_initial.sql | 60 + .../migrations/002_identity_realms_tokens.sql | 16 + app/db/migrations/003_durable_tasks.sql | 32 + app/db/migrations/004_domain_model.sql | 204 + app/db/migrations/005_token_lifecycle.sql | 6 + app/db/migrations/006_group_acl.sql | 9 + app/db/migrations/007_realm_config.sql | 17 + app/db/migrations/008_tfa_openid.sql | 23 + app/db/migrations/009_vsphere.sql | 30 + app/db/migrations/010_vsphere_platform.sql | 87 + app/db/migrations/011_vsphere_api_state.sql | 12 + .../migrations/012_vsphere_transfer_nfc.sql | 30 + app/db/migrations/013_vsphere_pc_state.sql | 19 + app/db/pool.py | 88 + app/db/primitives.py | 94 + app/db/repositories/__init__.py | 1 + app/db/repositories/resources.py | 97 + app/dependencies.py | 14 + app/evidence_gen.py | 171 + app/handlers/__init__.py | 1 + app/handlers/access.py | 747 + app/handlers/access_auth.py | 381 + app/handlers/acme.py | 223 + app/handlers/backup.py | 236 + app/handlers/ceph.py | 759 + app/handlers/cluster.py | 217 + app/handlers/cluster_config.py | 204 + app/handlers/cluster_extra.py | 688 + app/handlers/common.py | 145 + app/handlers/core.py | 162 + app/handlers/firewall.py | 526 + app/handlers/ha.py | 350 + app/handlers/legacy_aliases.py | 59 + app/handlers/lxc.py | 574 + app/handlers/lxc_extra.py | 152 + app/handlers/mapping.py | 99 + app/handlers/nodes.py | 421 + app/handlers/nodes_extra.py | 972 + app/handlers/notifications.py | 276 + app/handlers/pools.py | 134 + app/handlers/qemu.py | 865 + app/handlers/qemu_extra.py | 445 + app/handlers/sdn.py | 1027 + app/handlers/storage.py | 576 + app/lifespan.py | 63 + app/logging.py | 40 + app/main.py | 136 + app/observability/__init__.py | 1 + app/observability/health.py | 37 + app/security/__init__.py | 1 + app/security/acl.py | 92 + app/security/auth.py | 136 + app/simulation/__init__.py | 1 + app/simulation/clock.py | 61 + app/simulation/demo_cluster.py | 370 + app/simulation/scenarios.py | 49 + app/simulation/seed.py | 863 + app/simulation/seed_cli.py | 44 + app/simulation/transitions.py | 67 + app/surface_probe.py | 282 + app/tasks/__init__.py | 1 + app/tasks/backup.py | 86 + app/tasks/lxc.py | 245 + app/tasks/qemu.py | 328 + app/tasks/repository.py | 197 + app/tasks/upid.py | 75 + app/tasks/worker.py | 99 + app/vsphere/__init__.py | 1 + app/vsphere/contracts/__init__.py | 1 + app/vsphere/contracts/catalog.py | 304 + app/vsphere/contracts/compatibility.py | 148 + app/vsphere/contracts/matrix.py | 244 + app/vsphere/domain/__init__.py | 1 + app/vsphere/domain/api_state.py | 763 + app/vsphere/domain/appliance.py | 164 + app/vsphere/domain/content.py | 632 + app/vsphere/domain/inventory_ops.py | 225 + app/vsphere/domain/platform_surface.py | 434 + app/vsphere/domain/tagging.py | 321 + app/vsphere/domain/tasks.py | 103 + app/vsphere/domain/vm_ops.py | 511 + app/vsphere/errors.py | 107 + app/vsphere/inventory.py | 190 + app/vsphere/profiles.py | 468 + app/vsphere/rest/__init__.py | 46 + app/vsphere/rest/appliance_ext.py | 123 + app/vsphere/rest/content_rest.py | 191 + app/vsphere/rest/coverage.py | 222 + app/vsphere/rest/inventory_ext.py | 213 + app/vsphere/rest/legacy.py | 223 + app/vsphere/rest/mappers.py | 122 + app/vsphere/rest/nfc_rest.py | 80 + app/vsphere/rest/platform_rest.py | 531 + app/vsphere/rest/router.py | 450 + app/vsphere/rest/stub_surface.py | 349 + app/vsphere/rest/tagging_rest.py | 140 + app/vsphere/rest/tasks.py | 47 + app/vsphere/rest/universe.json | 7282 ++ app/vsphere/rest/version_gate.py | 29 + app/vsphere/rest/vm_ext.py | 227 + app/vsphere/security/__init__.py | 1 + app/vsphere/security/authz.py | 179 + app/vsphere/security/session.py | 154 + app/vsphere/seed.py | 199 + app/vsphere/soap/__init__.py | 5 + app/vsphere/soap/pbm.py | 92 + app/vsphere/soap/property_collector.py | 1639 + app/vsphere/soap/router.py | 1255 + app/web/__init__.py | 0 app/web/assets.py | 21 + app/web/compatibility_catalog.py | 77 + app/web/console.html | 342 + app/web/contract_catalog.py | 358 + app/web/index.html | 7014 ++ app/web/routes.py | 340 + app/web/static/vmware-favicon.png | Bin 0 -> 2423 bytes app/web/static/vmware-mark.png | Bin 0 -> 8477 bytes app/web/static/vmware-mark.svg | 14 + .../manifest.json | 1 + .../raw.js | 51901 +++++++++++ .../snapshot.json | 1 + .../manifest.json | 1 + .../raw.js | 45726 ++++++++++ .../snapshot.json | 1 + contracts/README.md | 21 + contracts/README.ru.md | 22 + .../manifest.json | 1 + .../raw.js | 71325 ++++++++++++++++ .../snapshot.json | 1 + .../manifest.json | 1 + .../raw.js | 59148 +++++++++++++ .../snapshot.json | 1 + contracts/vsphere/7.0.0/manifest.json | 167 + contracts/vsphere/7.0.3/manifest.json | 397 + contracts/vsphere/8.0.0/manifest.json | 527 + contracts/vsphere/8.0.2/manifest.json | 5397 ++ contracts/vsphere/README.md | 9 + contracts/vsphere/README.ru.md | 9 + .../vsphere/broadcom-9.1-operations-index.txt | 3783 + docker-compose.release.yml | 132 + docker-compose.yml | 171 + docker/gateway/vmware-ports.conf | 60 + docker/tls/server.crt | 17 + docker/tls/server.key | 28 + docs/README.md | 31 + docs/api-coverage.md | 135 + docs/api-surface.md | 87 + docs/api-versions.md | 77 + docs/architecture.md | 76 + docs/authentication.md | 102 + docs/clients.md | 83 + docs/compatibility-0.1.0.md | 86 + docs/compatibility.md | 74 + docs/configuration.md | 96 + docs/domains/README.md | 42 + docs/domains/appliance.md | 35 + docs/domains/authz.md | 52 + docs/domains/content-library.md | 38 + docs/domains/inventory.md | 46 + docs/domains/networking.md | 35 + docs/domains/session.md | 31 + docs/domains/soap.md | 68 + docs/domains/storage.md | 37 + docs/domains/tagging.md | 31 + docs/domains/tasks.md | 37 + docs/domains/vm.md | 50 + docs/examples/ansible.md | 23 + docs/examples/go.md | 21 + docs/examples/java.md | 22 + docs/examples/overview.md | 53 + docs/examples/perl.md | 20 + docs/examples/pulumi.md | 31 + docs/examples/python-requests.md | 33 + docs/examples/terraform.md | 32 + docs/examples/troubleshooting-clients.md | 15 + docs/faq.md | 57 + docs/getting-started.md | 175 + docs/images/vmware-logo-reference.png | Bin 0 -> 101111 bytes docs/images/web-ui-dark.png | Bin 0 -> 54717 bytes docs/images/web-ui-light.png | Bin 0 -> 53630 bytes docs/kubernetes.md | 162 + docs/observability.md | 45 + docs/operations.md | 148 + docs/ports.md | 49 + docs/ru/README.md | 32 + docs/ru/api-coverage.md | 167 + docs/ru/api-surface.md | 91 + docs/ru/api-versions.md | 77 + docs/ru/architecture.md | 77 + docs/ru/authentication.md | 101 + docs/ru/clients.md | 88 + docs/ru/compatibility-0.1.0.md | 87 + docs/ru/compatibility.md | 79 + docs/ru/configuration.md | 96 + docs/ru/domains/README.md | 43 + docs/ru/domains/appliance.md | 35 + docs/ru/domains/authz.md | 51 + docs/ru/domains/content-library.md | 38 + docs/ru/domains/inventory.md | 46 + docs/ru/domains/networking.md | 35 + docs/ru/domains/session.md | 32 + docs/ru/domains/soap.md | 68 + docs/ru/domains/storage.md | 37 + docs/ru/domains/tagging.md | 33 + docs/ru/domains/tasks.md | 38 + docs/ru/domains/vm.md | 50 + docs/ru/examples/ansible.md | 23 + docs/ru/examples/go.md | 21 + docs/ru/examples/java.md | 22 + docs/ru/examples/overview.md | 53 + docs/ru/examples/perl.md | 20 + docs/ru/examples/pulumi.md | 32 + docs/ru/examples/python-requests.md | 33 + docs/ru/examples/terraform.md | 32 + docs/ru/examples/troubleshooting-clients.md | 15 + docs/ru/faq.md | 57 + docs/ru/getting-started.md | 176 + docs/ru/kubernetes.md | 166 + docs/ru/observability.md | 47 + docs/ru/operations.md | 151 + docs/ru/ports.md | 50 + docs/ru/security.md | 57 + docs/ru/seed-profiles.md | 76 + docs/ru/troubleshooting.md | 75 + docs/ru/web-ui.md | 68 + docs/security.md | 54 + docs/seed-profiles.md | 70 + docs/troubleshooting.md | 71 + docs/web-ui.md | 64 + evidence/pve-6.4-15.json | 12607 +++ evidence/pve-7.4-16.json | 13507 +++ evidence/pve-8.4.5.json | 15132 ++++ evidence/pve-9.2.3-0.1.0.json | 223 + evidence/pve-9.2.3.json | 16971 ++++ evidence/vsphere-7.0.0.json | 81 + evidence/vsphere-7.0.3.json | 82 + evidence/vsphere-8.0.0.json | 82 + evidence/vsphere-8.0.2.json | 83 + examples/README.md | 49 + examples/README.ru.md | 49 + examples/ansible/inventory.ini | 2 + examples/ansible/vsphere_playbook.yml | 123 + examples/go/go.mod | 3 + examples/go/main.go | 121 + examples/java/Cookbook.java | 170 + examples/perl/cookbook.pl | 84 + examples/perl/cpanfile | 3 + examples/pulumi/Pulumi.yaml | 3 + examples/pulumi/__main__.py | 69 + examples/pulumi/requirements.txt | 2 + examples/python/requests_cookbook.py | 106 + examples/python/requirements.txt | 1 + examples/python/vsphere_lifecycle.py | 128 + examples/python/vsphere_rest_smoke.py | 58 + examples/python/vsphere_soap_smoke.py | 73 + .../terraform/vsphere/.terraform.lock.hcl | 22 + examples/terraform/vsphere/main.tf | 69 + examples/terraform/vsphere/variables.tf | 50 + helm/vmware-api-simulator/.helmignore | 7 + helm/vmware-api-simulator/Chart.yaml | 16 + helm/vmware-api-simulator/README.md | 42 + helm/vmware-api-simulator/README.ru.md | 42 + helm/vmware-api-simulator/templates/NOTES.txt | 35 + .../templates/_helpers.tpl | 121 + .../templates/clusterissuer.yaml | 42 + .../templates/deployment.yaml | 152 + .../templates/ingress.yaml | 46 + .../templates/migrate-job.yaml | 50 + .../templates/postgresql-service.yaml | 19 + .../templates/postgresql-statefulset.yaml | 71 + .../templates/secret.yaml | 12 + .../templates/seed-job.yaml | 56 + .../templates/service.yaml | 15 + .../templates/serviceaccount.yaml | 13 + .../values-ingress-example.yaml | 54 + helm/vmware-api-simulator/values.yaml | 180 + pulumi-tests/Makefile | 48 + pulumi-tests/README.md | 84 + pulumi-tests/README.ru.md | 78 + pulumi-tests/docker-compose.yml | 168 + pulumi-tests/docker/Dockerfile.pulumi-runner | 22 + pulumi-tests/fixtures/config.env.example | 12 + pulumi-tests/lib/__init__.py | 0 pulumi-tests/lib/assert_nonempty.py | 32 + pulumi-tests/lib/rest_crud.py | 361 + pulumi-tests/lib/rest_matrix.py | 497 + pulumi-tests/lib/soap_ops.py | 648 + pulumi-tests/programs/folders/Pulumi.yaml | 6 + pulumi-tests/programs/folders/__main__.py | 40 + .../programs/folders/requirements.txt | 2 + pulumi-tests/programs/inventory/Pulumi.yaml | 3 + pulumi-tests/programs/inventory/__main__.py | 81 + .../programs/inventory/requirements.txt | 2 + pulumi-tests/programs/tags/Pulumi.yaml | 3 + pulumi-tests/programs/tags/__main__.py | 45 + pulumi-tests/programs/tags/requirements.txt | 2 + .../vm_lifecycle/Pulumi.dbg-vm-fix.yaml | 1 + .../vm_lifecycle/Pulumi.dbg-vm-fix2.yaml | 1 + .../vm_lifecycle/Pulumi.dbg-vm-fix3.yaml | 1 + .../vm_lifecycle/Pulumi.dbg-vm-fix4.yaml | 1 + .../vm_lifecycle/Pulumi.dbg-vm-fix5.yaml | 1 + .../vm_lifecycle/Pulumi.dbg-vm-fix6.yaml | 1 + .../vm_lifecycle/Pulumi.dbg-vm-fix7.yaml | 1 + .../vm_lifecycle/Pulumi.dbg-vm-fix8.yaml | 1 + .../vm_lifecycle/Pulumi.dbg-vm-fix9.yaml | 1 + .../vm_lifecycle/Pulumi.dbg-vm-hang.yaml | 1 + .../programs/vm_lifecycle/Pulumi.yaml | 3 + .../programs/vm_lifecycle/__main__.py | 71 + .../programs/vm_lifecycle/requirements.txt | 2 + pulumi-tests/report_html.py | 213 + pulumi-tests/reports/.gitkeep | 0 pulumi-tests/reports/pulumi-report.html | 199 + pulumi-tests/reports/pulumi-summary.json | 42 + pulumi-tests/run_suite.py | 398 + pyproject.toml | 84 + scripts/generate_vsphere_universe.py | 253 + scripts/probe_api_surface.py | 11 + scripts/run_client_cookbooks.py | 380 + scripts/run_vsphere_full_green.sh | 34 + scripts/vsphere_full_matrix_probe.py | 439 + scripts/vsphere_nonempty_probe.py | 163 + scripts/vsphere_real_data_spotcheck.py | 102 + scripts/vsphere_surface_probe.py | 170 + scripts/write_vsphere_bundles.py | 17 + scripts/write_vsphere_evidence.py | 30 + tests/__init__.py | 1 + tests/compatibility/__init__.py | 1 + tests/compatibility/test_api_surface_probe.py | 38 + tests/compatibility/test_group_smoke.py | 283 + tests/compatibility/test_proxmoxer.py | 195 + tests/compatibility/test_verified_surface.py | 73 + tests/compatibility/test_vsphere_pyvmomi.py | 44 + .../api-viewer/pve-9.2.3-version.json | 48 + .../pve-9.2.3-version.provenance.json | 12 + tests/integration/__init__.py | 1 + tests/integration/test_migrations.py | 130 + tests/integration/test_tasks.py | 81 + tests/integration/test_vsphere_api.py | 168 + .../test_vsphere_api_surface_data.py | 86 + tests/integration/test_vsphere_full_api.py | 450 + .../test_vsphere_soap_create_vm.py | 135 + tests/integration/test_vsphere_soap_depth.py | 165 + tests/unit/test_access_auth_handlers.py | 277 + tests/unit/test_access_handlers.py | 247 + tests/unit/test_acl.py | 61 + tests/unit/test_api_auth_boundary.py | 106 + tests/unit/test_api_viewer_fixture.py | 25 + tests/unit/test_auth.py | 68 + tests/unit/test_ceph_handlers.py | 140 + tests/unit/test_clock.py | 28 + tests/unit/test_cluster_meta_handlers.py | 141 + tests/unit/test_compatibility.py | 156 + tests/unit/test_compatibility_catalog.py | 125 + tests/unit/test_compatible_io.py | 113 + tests/unit/test_contract_catalog.py | 109 + tests/unit/test_contract_cli.py | 54 + tests/unit/test_contract_diff.py | 87 + tests/unit/test_contract_importer.py | 107 + tests/unit/test_contract_model.py | 94 + tests/unit/test_contract_runtime.py | 97 + tests/unit/test_contract_source.py | 67 + tests/unit/test_core_handlers.py | 204 + tests/unit/test_db_primitives.py | 59 + tests/unit/test_dynamic_routes.py | 101 + tests/unit/test_extended_handlers.py | 180 + tests/unit/test_firewall_handlers.py | 83 + tests/unit/test_gap_plan_handlers.py | 288 + tests/unit/test_gap_remaining_handlers.py | 163 + tests/unit/test_health.py | 87 + tests/unit/test_logging.py | 17 + tests/unit/test_lxc_handlers.py | 155 + tests/unit/test_migrations.py | 56 + tests/unit/test_node_ops_handlers.py | 128 + tests/unit/test_notifications_handlers.py | 87 + tests/unit/test_openapi.py | 37 + tests/unit/test_property_collector.py | 131 + tests/unit/test_qemu_handlers.py | 364 + tests/unit/test_qemu_task.py | 284 + tests/unit/test_schema_examples.py | 25 + tests/unit/test_sdn_handlers.py | 128 + tests/unit/test_seed.py | 127 + tests/unit/test_task_worker.py | 100 + tests/unit/test_transitions.py | 50 + tests/unit/test_upid.py | 71 + tests/unit/test_vsphere_catalog.py | 48 + tests/unit/test_vsphere_compatibility.py | 27 + tests/unit/test_vsphere_contract_apply.py | 57 + tests/unit/test_vsphere_mappers.py | 39 + tests/unit/test_vsphere_matrix.py | 69 + tests/unit/test_vsphere_profiles.py | 52 + tests/unit/test_vsphere_universe.py | 51 + tests/unit/test_web_assets.py | 44 + tests/unit/test_web_console.py | 119 + 422 files changed, 361335 insertions(+) create mode 100644 .dockerignore create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 README.ru.md create mode 100644 app/__init__.py create mode 100644 app/api/__init__.py create mode 100644 app/api/errors.py create mode 100644 app/api/middleware.py create mode 100644 app/api/openapi.py create mode 100644 app/api/registry.py create mode 100644 app/compatibility.py create mode 100644 app/config.py create mode 100644 app/contracts/__init__.py create mode 100644 app/contracts/cli.py create mode 100644 app/contracts/diff.py create mode 100644 app/contracts/examples.py create mode 100644 app/contracts/importer.py create mode 100644 app/contracts/model.py create mode 100644 app/contracts/normalize.py create mode 100644 app/contracts/runtime.py create mode 100644 app/contracts/source.py create mode 100644 app/contracts/store.py create mode 100644 app/db/__init__.py create mode 100644 app/db/migrate_cli.py create mode 100644 app/db/migrations.py create mode 100644 app/db/migrations/001_initial.sql create mode 100644 app/db/migrations/002_identity_realms_tokens.sql create mode 100644 app/db/migrations/003_durable_tasks.sql create mode 100644 app/db/migrations/004_domain_model.sql create mode 100644 app/db/migrations/005_token_lifecycle.sql create mode 100644 app/db/migrations/006_group_acl.sql create mode 100644 app/db/migrations/007_realm_config.sql create mode 100644 app/db/migrations/008_tfa_openid.sql create mode 100644 app/db/migrations/009_vsphere.sql create mode 100644 app/db/migrations/010_vsphere_platform.sql create mode 100644 app/db/migrations/011_vsphere_api_state.sql create mode 100644 app/db/migrations/012_vsphere_transfer_nfc.sql create mode 100644 app/db/migrations/013_vsphere_pc_state.sql create mode 100644 app/db/pool.py create mode 100644 app/db/primitives.py create mode 100644 app/db/repositories/__init__.py create mode 100644 app/db/repositories/resources.py create mode 100644 app/dependencies.py create mode 100644 app/evidence_gen.py create mode 100644 app/handlers/__init__.py create mode 100644 app/handlers/access.py create mode 100644 app/handlers/access_auth.py create mode 100644 app/handlers/acme.py create mode 100644 app/handlers/backup.py create mode 100644 app/handlers/ceph.py create mode 100644 app/handlers/cluster.py create mode 100644 app/handlers/cluster_config.py create mode 100644 app/handlers/cluster_extra.py create mode 100644 app/handlers/common.py create mode 100644 app/handlers/core.py create mode 100644 app/handlers/firewall.py create mode 100644 app/handlers/ha.py create mode 100644 app/handlers/legacy_aliases.py create mode 100644 app/handlers/lxc.py create mode 100644 app/handlers/lxc_extra.py create mode 100644 app/handlers/mapping.py create mode 100644 app/handlers/nodes.py create mode 100644 app/handlers/nodes_extra.py create mode 100644 app/handlers/notifications.py create mode 100644 app/handlers/pools.py create mode 100644 app/handlers/qemu.py create mode 100644 app/handlers/qemu_extra.py create mode 100644 app/handlers/sdn.py create mode 100644 app/handlers/storage.py create mode 100644 app/lifespan.py create mode 100644 app/logging.py create mode 100644 app/main.py create mode 100644 app/observability/__init__.py create mode 100644 app/observability/health.py create mode 100644 app/security/__init__.py create mode 100644 app/security/acl.py create mode 100644 app/security/auth.py create mode 100644 app/simulation/__init__.py create mode 100644 app/simulation/clock.py create mode 100644 app/simulation/demo_cluster.py create mode 100644 app/simulation/scenarios.py create mode 100644 app/simulation/seed.py create mode 100644 app/simulation/seed_cli.py create mode 100644 app/simulation/transitions.py create mode 100644 app/surface_probe.py create mode 100644 app/tasks/__init__.py create mode 100644 app/tasks/backup.py create mode 100644 app/tasks/lxc.py create mode 100644 app/tasks/qemu.py create mode 100644 app/tasks/repository.py create mode 100644 app/tasks/upid.py create mode 100644 app/tasks/worker.py create mode 100644 app/vsphere/__init__.py create mode 100644 app/vsphere/contracts/__init__.py create mode 100644 app/vsphere/contracts/catalog.py create mode 100644 app/vsphere/contracts/compatibility.py create mode 100644 app/vsphere/contracts/matrix.py create mode 100644 app/vsphere/domain/__init__.py create mode 100644 app/vsphere/domain/api_state.py create mode 100644 app/vsphere/domain/appliance.py create mode 100644 app/vsphere/domain/content.py create mode 100644 app/vsphere/domain/inventory_ops.py create mode 100644 app/vsphere/domain/platform_surface.py create mode 100644 app/vsphere/domain/tagging.py create mode 100644 app/vsphere/domain/tasks.py create mode 100644 app/vsphere/domain/vm_ops.py create mode 100644 app/vsphere/errors.py create mode 100644 app/vsphere/inventory.py create mode 100644 app/vsphere/profiles.py create mode 100644 app/vsphere/rest/__init__.py create mode 100644 app/vsphere/rest/appliance_ext.py create mode 100644 app/vsphere/rest/content_rest.py create mode 100644 app/vsphere/rest/coverage.py create mode 100644 app/vsphere/rest/inventory_ext.py create mode 100644 app/vsphere/rest/legacy.py create mode 100644 app/vsphere/rest/mappers.py create mode 100644 app/vsphere/rest/nfc_rest.py create mode 100644 app/vsphere/rest/platform_rest.py create mode 100644 app/vsphere/rest/router.py create mode 100644 app/vsphere/rest/stub_surface.py create mode 100644 app/vsphere/rest/tagging_rest.py create mode 100644 app/vsphere/rest/tasks.py create mode 100644 app/vsphere/rest/universe.json create mode 100644 app/vsphere/rest/version_gate.py create mode 100644 app/vsphere/rest/vm_ext.py create mode 100644 app/vsphere/security/__init__.py create mode 100644 app/vsphere/security/authz.py create mode 100644 app/vsphere/security/session.py create mode 100644 app/vsphere/seed.py create mode 100644 app/vsphere/soap/__init__.py create mode 100644 app/vsphere/soap/pbm.py create mode 100644 app/vsphere/soap/property_collector.py create mode 100644 app/vsphere/soap/router.py create mode 100644 app/web/__init__.py create mode 100644 app/web/assets.py create mode 100644 app/web/compatibility_catalog.py create mode 100644 app/web/console.html create mode 100644 app/web/contract_catalog.py create mode 100644 app/web/index.html create mode 100644 app/web/routes.py create mode 100644 app/web/static/vmware-favicon.png create mode 100644 app/web/static/vmware-mark.png create mode 100644 app/web/static/vmware-mark.svg create mode 100644 contracts/2cf632fa6ea4939ca9cb7998ade688150db25b0684600f53ac0ca95730f1d99f/manifest.json create mode 100644 contracts/2cf632fa6ea4939ca9cb7998ade688150db25b0684600f53ac0ca95730f1d99f/raw.js create mode 100644 contracts/2cf632fa6ea4939ca9cb7998ade688150db25b0684600f53ac0ca95730f1d99f/snapshot.json create mode 100644 contracts/96cd7121e75cdb3efd58f79ca988f6b235a2f28e6f7eae276ae243f65d8a6724/manifest.json create mode 100644 contracts/96cd7121e75cdb3efd58f79ca988f6b235a2f28e6f7eae276ae243f65d8a6724/raw.js create mode 100644 contracts/96cd7121e75cdb3efd58f79ca988f6b235a2f28e6f7eae276ae243f65d8a6724/snapshot.json create mode 100644 contracts/README.md create mode 100644 contracts/README.ru.md create mode 100644 contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/manifest.json create mode 100644 contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/raw.js create mode 100644 contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/snapshot.json create mode 100644 contracts/fce6db0a784b3a9b447895895fc6ff4b4437c2dce82e5f3db99227af217726fa/manifest.json create mode 100644 contracts/fce6db0a784b3a9b447895895fc6ff4b4437c2dce82e5f3db99227af217726fa/raw.js create mode 100644 contracts/fce6db0a784b3a9b447895895fc6ff4b4437c2dce82e5f3db99227af217726fa/snapshot.json create mode 100644 contracts/vsphere/7.0.0/manifest.json create mode 100644 contracts/vsphere/7.0.3/manifest.json create mode 100644 contracts/vsphere/8.0.0/manifest.json create mode 100644 contracts/vsphere/8.0.2/manifest.json create mode 100644 contracts/vsphere/README.md create mode 100644 contracts/vsphere/README.ru.md create mode 100644 contracts/vsphere/broadcom-9.1-operations-index.txt create mode 100644 docker-compose.release.yml create mode 100644 docker-compose.yml create mode 100644 docker/gateway/vmware-ports.conf create mode 100644 docker/tls/server.crt create mode 100644 docker/tls/server.key create mode 100644 docs/README.md create mode 100644 docs/api-coverage.md create mode 100644 docs/api-surface.md create mode 100644 docs/api-versions.md create mode 100644 docs/architecture.md create mode 100644 docs/authentication.md create mode 100644 docs/clients.md create mode 100644 docs/compatibility-0.1.0.md create mode 100644 docs/compatibility.md create mode 100644 docs/configuration.md create mode 100644 docs/domains/README.md create mode 100644 docs/domains/appliance.md create mode 100644 docs/domains/authz.md create mode 100644 docs/domains/content-library.md create mode 100644 docs/domains/inventory.md create mode 100644 docs/domains/networking.md create mode 100644 docs/domains/session.md create mode 100644 docs/domains/soap.md create mode 100644 docs/domains/storage.md create mode 100644 docs/domains/tagging.md create mode 100644 docs/domains/tasks.md create mode 100644 docs/domains/vm.md create mode 100644 docs/examples/ansible.md create mode 100644 docs/examples/go.md create mode 100644 docs/examples/java.md create mode 100644 docs/examples/overview.md create mode 100644 docs/examples/perl.md create mode 100644 docs/examples/pulumi.md create mode 100644 docs/examples/python-requests.md create mode 100644 docs/examples/terraform.md create mode 100644 docs/examples/troubleshooting-clients.md create mode 100644 docs/faq.md create mode 100644 docs/getting-started.md create mode 100644 docs/images/vmware-logo-reference.png create mode 100644 docs/images/web-ui-dark.png create mode 100644 docs/images/web-ui-light.png create mode 100644 docs/kubernetes.md create mode 100644 docs/observability.md create mode 100644 docs/operations.md create mode 100644 docs/ports.md create mode 100644 docs/ru/README.md create mode 100644 docs/ru/api-coverage.md create mode 100644 docs/ru/api-surface.md create mode 100644 docs/ru/api-versions.md create mode 100644 docs/ru/architecture.md create mode 100644 docs/ru/authentication.md create mode 100644 docs/ru/clients.md create mode 100644 docs/ru/compatibility-0.1.0.md create mode 100644 docs/ru/compatibility.md create mode 100644 docs/ru/configuration.md create mode 100644 docs/ru/domains/README.md create mode 100644 docs/ru/domains/appliance.md create mode 100644 docs/ru/domains/authz.md create mode 100644 docs/ru/domains/content-library.md create mode 100644 docs/ru/domains/inventory.md create mode 100644 docs/ru/domains/networking.md create mode 100644 docs/ru/domains/session.md create mode 100644 docs/ru/domains/soap.md create mode 100644 docs/ru/domains/storage.md create mode 100644 docs/ru/domains/tagging.md create mode 100644 docs/ru/domains/tasks.md create mode 100644 docs/ru/domains/vm.md create mode 100644 docs/ru/examples/ansible.md create mode 100644 docs/ru/examples/go.md create mode 100644 docs/ru/examples/java.md create mode 100644 docs/ru/examples/overview.md create mode 100644 docs/ru/examples/perl.md create mode 100644 docs/ru/examples/pulumi.md create mode 100644 docs/ru/examples/python-requests.md create mode 100644 docs/ru/examples/terraform.md create mode 100644 docs/ru/examples/troubleshooting-clients.md create mode 100644 docs/ru/faq.md create mode 100644 docs/ru/getting-started.md create mode 100644 docs/ru/kubernetes.md create mode 100644 docs/ru/observability.md create mode 100644 docs/ru/operations.md create mode 100644 docs/ru/ports.md create mode 100644 docs/ru/security.md create mode 100644 docs/ru/seed-profiles.md create mode 100644 docs/ru/troubleshooting.md create mode 100644 docs/ru/web-ui.md create mode 100644 docs/security.md create mode 100644 docs/seed-profiles.md create mode 100644 docs/troubleshooting.md create mode 100644 docs/web-ui.md create mode 100644 evidence/pve-6.4-15.json create mode 100644 evidence/pve-7.4-16.json create mode 100644 evidence/pve-8.4.5.json create mode 100644 evidence/pve-9.2.3-0.1.0.json create mode 100644 evidence/pve-9.2.3.json create mode 100644 evidence/vsphere-7.0.0.json create mode 100644 evidence/vsphere-7.0.3.json create mode 100644 evidence/vsphere-8.0.0.json create mode 100644 evidence/vsphere-8.0.2.json create mode 100644 examples/README.md create mode 100644 examples/README.ru.md create mode 100644 examples/ansible/inventory.ini create mode 100644 examples/ansible/vsphere_playbook.yml create mode 100644 examples/go/go.mod create mode 100644 examples/go/main.go create mode 100644 examples/java/Cookbook.java create mode 100644 examples/perl/cookbook.pl create mode 100644 examples/perl/cpanfile create mode 100644 examples/pulumi/Pulumi.yaml create mode 100644 examples/pulumi/__main__.py create mode 100644 examples/pulumi/requirements.txt create mode 100644 examples/python/requests_cookbook.py create mode 100644 examples/python/requirements.txt create mode 100644 examples/python/vsphere_lifecycle.py create mode 100644 examples/python/vsphere_rest_smoke.py create mode 100644 examples/python/vsphere_soap_smoke.py create mode 100644 examples/terraform/vsphere/.terraform.lock.hcl create mode 100644 examples/terraform/vsphere/main.tf create mode 100644 examples/terraform/vsphere/variables.tf create mode 100644 helm/vmware-api-simulator/.helmignore create mode 100644 helm/vmware-api-simulator/Chart.yaml create mode 100644 helm/vmware-api-simulator/README.md create mode 100644 helm/vmware-api-simulator/README.ru.md create mode 100644 helm/vmware-api-simulator/templates/NOTES.txt create mode 100644 helm/vmware-api-simulator/templates/_helpers.tpl create mode 100644 helm/vmware-api-simulator/templates/clusterissuer.yaml create mode 100644 helm/vmware-api-simulator/templates/deployment.yaml create mode 100644 helm/vmware-api-simulator/templates/ingress.yaml create mode 100644 helm/vmware-api-simulator/templates/migrate-job.yaml create mode 100644 helm/vmware-api-simulator/templates/postgresql-service.yaml create mode 100644 helm/vmware-api-simulator/templates/postgresql-statefulset.yaml create mode 100644 helm/vmware-api-simulator/templates/secret.yaml create mode 100644 helm/vmware-api-simulator/templates/seed-job.yaml create mode 100644 helm/vmware-api-simulator/templates/service.yaml create mode 100644 helm/vmware-api-simulator/templates/serviceaccount.yaml create mode 100644 helm/vmware-api-simulator/values-ingress-example.yaml create mode 100644 helm/vmware-api-simulator/values.yaml create mode 100644 pulumi-tests/Makefile create mode 100644 pulumi-tests/README.md create mode 100644 pulumi-tests/README.ru.md create mode 100644 pulumi-tests/docker-compose.yml create mode 100644 pulumi-tests/docker/Dockerfile.pulumi-runner create mode 100644 pulumi-tests/fixtures/config.env.example create mode 100644 pulumi-tests/lib/__init__.py create mode 100644 pulumi-tests/lib/assert_nonempty.py create mode 100644 pulumi-tests/lib/rest_crud.py create mode 100644 pulumi-tests/lib/rest_matrix.py create mode 100644 pulumi-tests/lib/soap_ops.py create mode 100644 pulumi-tests/programs/folders/Pulumi.yaml create mode 100644 pulumi-tests/programs/folders/__main__.py create mode 100644 pulumi-tests/programs/folders/requirements.txt create mode 100644 pulumi-tests/programs/inventory/Pulumi.yaml create mode 100644 pulumi-tests/programs/inventory/__main__.py create mode 100644 pulumi-tests/programs/inventory/requirements.txt create mode 100644 pulumi-tests/programs/tags/Pulumi.yaml create mode 100644 pulumi-tests/programs/tags/__main__.py create mode 100644 pulumi-tests/programs/tags/requirements.txt create mode 100644 pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix.yaml create mode 100644 pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix2.yaml create mode 100644 pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix3.yaml create mode 100644 pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix4.yaml create mode 100644 pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix5.yaml create mode 100644 pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix6.yaml create mode 100644 pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix7.yaml create mode 100644 pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix8.yaml create mode 100644 pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix9.yaml create mode 100644 pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-hang.yaml create mode 100644 pulumi-tests/programs/vm_lifecycle/Pulumi.yaml create mode 100644 pulumi-tests/programs/vm_lifecycle/__main__.py create mode 100644 pulumi-tests/programs/vm_lifecycle/requirements.txt create mode 100644 pulumi-tests/report_html.py create mode 100644 pulumi-tests/reports/.gitkeep create mode 100644 pulumi-tests/reports/pulumi-report.html create mode 100644 pulumi-tests/reports/pulumi-summary.json create mode 100644 pulumi-tests/run_suite.py create mode 100644 pyproject.toml create mode 100644 scripts/generate_vsphere_universe.py create mode 100644 scripts/probe_api_surface.py create mode 100644 scripts/run_client_cookbooks.py create mode 100755 scripts/run_vsphere_full_green.sh create mode 100644 scripts/vsphere_full_matrix_probe.py create mode 100644 scripts/vsphere_nonempty_probe.py create mode 100644 scripts/vsphere_real_data_spotcheck.py create mode 100644 scripts/vsphere_surface_probe.py create mode 100644 scripts/write_vsphere_bundles.py create mode 100644 scripts/write_vsphere_evidence.py create mode 100644 tests/__init__.py create mode 100644 tests/compatibility/__init__.py create mode 100644 tests/compatibility/test_api_surface_probe.py create mode 100644 tests/compatibility/test_group_smoke.py create mode 100644 tests/compatibility/test_proxmoxer.py create mode 100644 tests/compatibility/test_verified_surface.py create mode 100644 tests/compatibility/test_vsphere_pyvmomi.py create mode 100644 tests/fixtures/api-viewer/pve-9.2.3-version.json create mode 100644 tests/fixtures/api-viewer/pve-9.2.3-version.provenance.json create mode 100644 tests/integration/__init__.py create mode 100644 tests/integration/test_migrations.py create mode 100644 tests/integration/test_tasks.py create mode 100644 tests/integration/test_vsphere_api.py create mode 100644 tests/integration/test_vsphere_api_surface_data.py create mode 100644 tests/integration/test_vsphere_full_api.py create mode 100644 tests/integration/test_vsphere_soap_create_vm.py create mode 100644 tests/integration/test_vsphere_soap_depth.py create mode 100644 tests/unit/test_access_auth_handlers.py create mode 100644 tests/unit/test_access_handlers.py create mode 100644 tests/unit/test_acl.py create mode 100644 tests/unit/test_api_auth_boundary.py create mode 100644 tests/unit/test_api_viewer_fixture.py create mode 100644 tests/unit/test_auth.py create mode 100644 tests/unit/test_ceph_handlers.py create mode 100644 tests/unit/test_clock.py create mode 100644 tests/unit/test_cluster_meta_handlers.py create mode 100644 tests/unit/test_compatibility.py create mode 100644 tests/unit/test_compatibility_catalog.py create mode 100644 tests/unit/test_compatible_io.py create mode 100644 tests/unit/test_contract_catalog.py create mode 100644 tests/unit/test_contract_cli.py create mode 100644 tests/unit/test_contract_diff.py create mode 100644 tests/unit/test_contract_importer.py create mode 100644 tests/unit/test_contract_model.py create mode 100644 tests/unit/test_contract_runtime.py create mode 100644 tests/unit/test_contract_source.py create mode 100644 tests/unit/test_core_handlers.py create mode 100644 tests/unit/test_db_primitives.py create mode 100644 tests/unit/test_dynamic_routes.py create mode 100644 tests/unit/test_extended_handlers.py create mode 100644 tests/unit/test_firewall_handlers.py create mode 100644 tests/unit/test_gap_plan_handlers.py create mode 100644 tests/unit/test_gap_remaining_handlers.py create mode 100644 tests/unit/test_health.py create mode 100644 tests/unit/test_logging.py create mode 100644 tests/unit/test_lxc_handlers.py create mode 100644 tests/unit/test_migrations.py create mode 100644 tests/unit/test_node_ops_handlers.py create mode 100644 tests/unit/test_notifications_handlers.py create mode 100644 tests/unit/test_openapi.py create mode 100644 tests/unit/test_property_collector.py create mode 100644 tests/unit/test_qemu_handlers.py create mode 100644 tests/unit/test_qemu_task.py create mode 100644 tests/unit/test_schema_examples.py create mode 100644 tests/unit/test_sdn_handlers.py create mode 100644 tests/unit/test_seed.py create mode 100644 tests/unit/test_task_worker.py create mode 100644 tests/unit/test_transitions.py create mode 100644 tests/unit/test_upid.py create mode 100644 tests/unit/test_vsphere_catalog.py create mode 100644 tests/unit/test_vsphere_compatibility.py create mode 100644 tests/unit/test_vsphere_contract_apply.py create mode 100644 tests/unit/test_vsphere_mappers.py create mode 100644 tests/unit/test_vsphere_matrix.py create mode 100644 tests/unit/test_vsphere_profiles.py create mode 100644 tests/unit/test_vsphere_universe.py create mode 100644 tests/unit/test_web_assets.py create mode 100644 tests/unit/test_web_console.py diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..67fc009 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +.git +.venv +__pycache__ +.mypy_cache +.pytest_cache +.ruff_cache +.env +htmlcov +docs + diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..c39b014 --- /dev/null +++ b/.env.example @@ -0,0 +1,33 @@ +APP_HOST=0.0.0.0 +# Internal uvicorn port (not published). Public vCenter HTTPS is on api-gateway :443. +APP_PORT=8080 +DATABASE_URL=postgresql://vmware:vmware@postgres:5432/vmware_simulator +TEST_DATABASE_URL=postgresql://vmware:vmware@postgres:5432/vmware_simulator +DB_POOL_MIN_SIZE=1 +DB_POOL_MAX_SIZE=10 +DB_CONNECT_TIMEOUT_SECONDS=10 +DB_COMMAND_TIMEOUT_SECONDS=30 +LOG_LEVEL=INFO +REQUEST_ID_HEADER=X-Request-ID +VSPHERE_RELEASE=8.0 U2 +# Native vSphere /api + /sdk is the default plane. +ENABLE_PVE_STUB=false +# vSphere synthetic inventory (default large ≈ 10 hosts / 1000 VMs) +SEED_VSPHERE_PROFILE=large +SEED_VSPHERE_LARGE_HOSTS=10 +SEED_VSPHERE_LARGE_VMS=1000 +# Optional Proxmox stub plane (only when ENABLE_PVE_STUB=true): +# CONTRACT_SNAPSHOT=/app/contracts/pve-9.2.3.json +# COMPATIBILITY_EVIDENCE=/app/evidence/pve-9.2.3.json +CONTRACT_FALLBACK=error +CATALOG_ARTIFACT_URL_6=stub://vmware/vsphere-7.0/api-contract +CATALOG_ARTIFACT_URL_7=stub://vmware/vsphere-7.0u3/api-contract +CATALOG_ARTIFACT_URL_8=stub://vmware/vsphere-8.0/api-contract +CATALOG_ARTIFACT_URL_9=stub://vmware/vsphere-8.0u2/api-contract +TICKET_SIGNING_KEY=development-only-signing-key-change-me +TASK_WORKER_CONCURRENCY=2 +TASK_LEASE_SECONDS=30 +SIMULATION_SEED=42 +SIMULATION_TIME_SCALE=10 +SIMULATOR_ADMIN_ENABLED=false +SIMULATOR_ADMIN_TOKEN=replace-with-a-long-random-secret diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f5413f7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,80 @@ +# Hidden directories (.cursor/, .pytest_cache/, .mypy_cache/, .ruff_cache/, …) +.*/ +# Keep GitHub Actions / repo metadata trackable despite the rule above. +!.github/ +!.github/** + +# macOS +.DS_Store +.AppleDouble +.LSOverride +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +.AppleDB +.AppleDesktop +.apdisk +Network Trash Folder +Temporary Items + +# Environment / secrets (keep .env.example tracked) +.env +.env.local +.env.*.local + +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +*.egg +*.egg-info/ +.eggs/ +dist/ +build/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.manifest +*.spec +pip-log.txt +pip-delete-this-directory.txt +.venv/ +venv/ +ENV/ +env/ + +# Test / coverage leftovers (directories also covered by .*/) +.coverage +.coverage.* +coverage.xml +htmlcov/ +.cache +nosetests.xml +pytestdebug.log +hypothesis/ + +# Editors / IDE leftovers outside .* +*.swp +*.swo +*~ +*.sublime-project +*.sublime-workspace + +# Docker / local runtime +*.log +docker-compose.override.yml + +# Terraform local state (never commit) +*.tfstate +*.tfstate.* +.terraform/ + +# Lab probe output (regenerated by scripts/probe_api_surface.py) +evidence/_api_surface_probe.json diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f6580a9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,58 @@ +# syntax=docker/dockerfile:1.7 +FROM python:3.13-slim AS builder + +ENV PIP_DISABLE_PIP_VERSION_CHECK=1 \ + PIP_NO_CACHE_DIR=1 \ + VIRTUAL_ENV=/opt/venv +RUN python -m venv "$VIRTUAL_ENV" +ENV PATH="$VIRTUAL_ENV/bin:$PATH" +WORKDIR /build +COPY pyproject.toml README.md ./ +COPY app ./app +RUN pip install --upgrade "pip>=25.1,<26" && pip install . + +FROM python:3.13-slim AS runtime + +ARG APP_VERSION=0.1.0 +LABEL org.opencontainers.image.title="vmware-api-simulator" \ + org.opencontainers.image.version="$APP_VERSION" \ + org.opencontainers.image.source="https://github.com/inecs/vmware-api-simulator" +ENV PATH="/opt/venv/bin:$PATH" \ + PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + APP_HOST=0.0.0.0 \ + APP_PORT=8080 +RUN groupadd --system --gid 10001 simulator \ + && useradd --system --uid 10001 --gid simulator --home-dir /app --no-create-home simulator +COPY --from=builder /opt/venv /opt/venv +COPY contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/snapshot.json /app/contracts/pve-9.2.3.json +# Optional legacy PVE stub plane only (ENABLE_PVE_STUB=true). Native vSphere +# contracts live under contracts/vsphere/ and app/vsphere/. +COPY evidence/ /app/evidence/ +WORKDIR /app +USER 10001:10001 +# Internal listen only — public vCenter HTTPS is on api-gateway. +EXPOSE 8080 +HEALTHCHECK --interval=10s --timeout=3s --start-period=10s --retries=3 \ + CMD ["python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/health/live', timeout=2)"] +ENTRYPOINT ["uvicorn", "app.main:app"] +CMD ["--host", "0.0.0.0", "--port", "8080"] + +FROM python:3.13-slim AS dev + +ENV PIP_DISABLE_PIP_VERSION_CHECK=1 \ + PIP_NO_CACHE_DIR=1 \ + VIRTUAL_ENV=/opt/venv \ + PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 +RUN python -m venv "$VIRTUAL_ENV" +ENV PATH="$VIRTUAL_ENV/bin:$PATH" +WORKDIR /workspace +COPY pyproject.toml README.md ./ +COPY app ./app +COPY tests ./tests +COPY contracts ./contracts +COPY evidence ./evidence +RUN pip install --upgrade "pip>=25.1,<26" && pip install -e '.[dev]' +ENTRYPOINT [] +CMD ["bash"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bb2e765 --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright 2026 vmware-api-simulator contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2f332d7 --- /dev/null +++ b/Makefile @@ -0,0 +1,256 @@ +COMPOSE ?= docker compose +SERVICE_DEV := dev +SERVICE_SIM := simulator +PYTEST_OFFLINE := -m "not integration and not compatibility and not pve_stub" + +# Docker Hub release image (runtime target only — not the local bind-mount "dev" image). +DOCKERHUB_USER ?= inecs +IMAGE_NAME ?= vmware-api-simulator +VERSION ?= $(shell sed -n 's/^version = "\(.*\)"/\1/p' pyproject.toml) +DOCKER_IMAGE ?= $(DOCKERHUB_USER)/$(IMAGE_NAME) +PUSH_LATEST ?= 1 + +COMPOSE_RELEASE ?= $(COMPOSE) -f docker-compose.release.yml +HELM_CHART ?= ./helm/vmware-api-simulator + +.PHONY: help install format lint typecheck test test-unit test-integration test-contract test-compatibility test-surface evidence coverage run dev up down restart logs docker-build docker-up docker-down docker-logs docker-restart db-up db-down db-migrate db-reset api-import api-diff seed clean ci ci-all shell release release-build release-up release-down release-seed helm-deps helm-template \ + pulumi-tests pulumi-tests-smoke test-pulumi-smoke test-pulumi test-smoke-all test-all clean-test-resources + +help: ## Show available commands + @awk 'BEGIN {FS = ":.*## "}; /^[a-zA-Z0-9_-]+:.*## / {printf "%-22s %s\n", $$1, $$2}' $(MAKEFILE_LIST) + +install: ## Build runtime and development images + @test -f .env || cp .env.example .env + $(COMPOSE) build simulator $(SERVICE_DEV) + +format: ## Format Python sources + $(COMPOSE) run --rm --no-deps $(SERVICE_DEV) ruff format . + +lint: ## Run Ruff lint checks + $(COMPOSE) run --rm --no-deps $(SERVICE_DEV) ruff check . + +typecheck: ## Run strict mypy checks + $(COMPOSE) run --rm --no-deps $(SERVICE_DEV) mypy + +test: ## Run offline unit and contract tests + $(COMPOSE) run --rm --no-deps $(SERVICE_DEV) pytest $(PYTEST_OFFLINE) + +test-unit: ## Run unit tests + $(COMPOSE) run --rm --no-deps $(SERVICE_DEV) pytest tests/unit + +test-integration: ## Run tests that require PostgreSQL + @test -f .env || cp .env.example .env + $(COMPOSE) up -d postgres + $(COMPOSE) run --rm $(SERVICE_DEV) pytest -m integration + +test-contract: ## Run offline API contract tests + $(COMPOSE) run --rm --no-deps $(SERVICE_DEV) pytest -m contract + +test-compatibility: ## Run client smoke flow against the Compose stack + @test -f .env || cp .env.example .env + $(COMPOSE) up -d --build --wait + $(COMPOSE) run --rm --entrypoint python $(SERVICE_SIM) -m app.simulation.seed_cli + $(COMPOSE) run --rm $(SERVICE_DEV) pytest -m compatibility + +test-surface: ## Probe every declared method on majors 6-9 (0x501 / 0xexception) + @test -f .env || cp .env.example .env + $(COMPOSE) up -d postgres + $(COMPOSE) run --rm $(SERVICE_DEV) pytest tests/compatibility/test_api_surface_probe.py -q + +vsphere-surface: ## Probe native vSphere REST coverage registry against running gateway + @test -f .env || cp .env.example .env + $(COMPOSE) up -d --wait + # From the tools container, hit the simulator service (not host-mapped :443). + $(COMPOSE) run --rm --no-deps -e VSPHERE_BASE=http://simulator:8080 $(SERVICE_DEV) \ + python scripts/vsphere_surface_probe.py + +vsphere-matrix: ## Full REST matrix: all verbs × majors 6–9 (no 5xx) + @test -f .env || cp .env.example .env + $(COMPOSE) up -d --wait + $(COMPOSE) run --rm --no-deps -e VSPHERE_BASE=http://simulator:8080 $(SERVICE_DEV) \ + python scripts/vsphere_full_matrix_probe.py + +vsphere-universe: ## Regenerate Broadcom Automation API universe.json from operations index + $(COMPOSE) run --rm --no-deps $(SERVICE_DEV) python scripts/generate_vsphere_universe.py + +vsphere-bundles: ## Regenerate stub OpenAPI matrices + evidence ledgers + $(COMPOSE) run --rm --no-deps $(SERVICE_DEV) python scripts/write_vsphere_bundles.py + $(COMPOSE) run --rm --no-deps $(SERVICE_DEV) python scripts/write_vsphere_evidence.py + +test-vsphere: ## Native vSphere unit + integration + surface + majors matrix + @test -f .env || cp .env.example .env + $(COMPOSE) up -d --wait + $(COMPOSE) run --rm --no-deps $(SERVICE_DEV) pytest \ + tests/unit/test_vsphere_profiles.py \ + tests/unit/test_vsphere_catalog.py \ + tests/unit/test_vsphere_matrix.py \ + tests/unit/test_vsphere_compatibility.py \ + tests/unit/test_vsphere_universe.py \ + tests/unit/test_vsphere_mappers.py \ + tests/unit/test_property_collector.py \ + tests/unit/test_web_assets.py \ + tests/unit/test_web_console.py \ + tests/integration/test_vsphere_api.py \ + tests/integration/test_vsphere_api_surface_data.py \ + tests/integration/test_vsphere_soap_depth.py \ + tests/integration/test_vsphere_soap_create_vm.py \ + tests/integration/test_vsphere_full_api.py -q + $(COMPOSE) run --rm --no-deps -e VSPHERE_BASE=http://simulator:8080 $(SERVICE_DEV) \ + python scripts/vsphere_surface_probe.py + $(COMPOSE) run --rm --no-deps -e VSPHERE_BASE=http://simulator:8080 $(SERVICE_DEV) \ + python scripts/vsphere_full_matrix_probe.py + $(COMPOSE) run --rm --no-deps -e VSPHERE_BASE=http://simulator:8080 $(SERVICE_DEV) \ + python scripts/vsphere_real_data_spotcheck.py + $(COMPOSE) run --rm --no-deps -e VSPHERE_BASE=http://simulator:8080 $(SERVICE_DEV) \ + python scripts/vsphere_nonempty_probe.py + $(COMPOSE) run --rm --no-deps -e VSPHERE_BASE=http://simulator:8080 $(SERVICE_DEV) \ + python scripts/run_client_cookbooks.py + +client-cookbooks: ## Python/Ansible/Terraform/Pulumi-style cookbooks against gateway or simulator + @test -f .env || cp .env.example .env + $(COMPOSE) up -d --wait + $(COMPOSE) run --rm --entrypoint python $(SERVICE_SIM) -m app.simulation.seed_cli + $(COMPOSE) run --rm --no-deps -e VSPHERE_BASE=http://simulator:8080 $(SERVICE_DEV) \ + python scripts/run_client_cookbooks.py + +# Hybrid pulumi-tests suite (pulumi-vsphere + REST matrix + CRUD + SOAP) +pulumi-tests: ## Run full hybrid suite (provider + REST×6-9 + CRUD + SOAP) + @$(MAKE) -C pulumi-tests test-pulumi + +pulumi-tests-smoke: ## PU-INV + one-major REST smoke (no VM/tags/CRUD/SOAP) + @$(MAKE) -C pulumi-tests test-pulumi-smoke + +test-pulumi-smoke test-pulumi test-smoke-all test-all clean-test-resources: ## Aliases → pulumi-tests/ + @$(MAKE) -C pulumi-tests $@ + +evidence: ## Regenerate per-major verified surface evidence ledgers + $(COMPOSE) run --rm --no-deps $(SERVICE_DEV) python -m app.evidence_gen + +coverage: ## Run offline tests with coverage enforcement + $(COMPOSE) run --rm --no-deps $(SERVICE_DEV) pytest $(PYTEST_OFFLINE) --cov=app --cov-report=term-missing --cov-report=xml + +run: ## Run the application in the foreground + @test -f .env || cp .env.example .env + $(COMPOSE) up --build + +up: ## Start PostgreSQL, simulator, and TLS gateway + @test -f .env || cp .env.example .env + $(COMPOSE) up -d --build --wait + +down: ## Stop local services + $(COMPOSE) down + +restart: ## Rebuild and restart the stack + @test -f .env || cp .env.example .env + $(COMPOSE) up -d --build --force-recreate --wait + +logs: ## Follow logs from all services + $(COMPOSE) logs -f + +dev: ## Run the application with auto-reload in Docker + @test -f .env || cp .env.example .env + $(COMPOSE) up -d postgres migrate + $(COMPOSE) up simulator + +docker-build: ## Build runtime and development images + $(MAKE) install + +docker-up: up ## Alias for up + +docker-restart: ## Rebuild and recreate simulator and TLS gateway only + $(COMPOSE) up -d --build --force-recreate simulator api-gateway + +docker-down: down ## Alias for down + +docker-logs: ## Follow simulator logs only + $(COMPOSE) logs -f simulator + +db-up: ## Start PostgreSQL only + @test -f .env || cp .env.example .env + $(COMPOSE) up -d postgres + +db-down: ## Stop PostgreSQL + $(COMPOSE) stop postgres + +db-migrate: ## Apply database migrations + @test -f .env || cp .env.example .env + $(COMPOSE) run --rm migrate + +db-reset: ## Recreate the local database volume + $(COMPOSE) down -v + $(COMPOSE) up -d postgres + $(COMPOSE) run --rm migrate + +api-import: ## Import an API snapshot + $(COMPOSE) run --rm --no-deps $(SERVICE_DEV) vmware-api-contract import $(ARGS) + +api-diff: ## Compare API snapshots + $(COMPOSE) run --rm --no-deps $(SERVICE_DEV) vmware-api-contract diff $(ARGS) + +seed: ## Seed simulation data (vSphere; PROFILE= / VSPHERE_PROFILE=small|large|demo-cluster) + @test -f .env || cp .env.example .env + SEED_PROFILE="$${PROFILE:-small}" \ + SEED_VSPHERE_PROFILE="$${VSPHERE_PROFILE:-$${PROFILE:-large}}" \ + SEED_VSPHERE_LARGE_VMS="$${VSPHERE_VMS:-1000}" \ + SEED_VSPHERE_LARGE_HOSTS="$${VSPHERE_HOSTS:-10}" \ + $(COMPOSE) run --rm --entrypoint python $(SERVICE_SIM) -m app.simulation.seed_cli + +shell: ## Open an interactive shell in the development container + $(COMPOSE) run --rm --no-deps $(SERVICE_DEV) bash + +clean: ## Remove generated local artifacts + rm -rf .coverage coverage.xml htmlcov .mypy_cache .pytest_cache .ruff_cache + +ci: ## Offline quality gate + full API surface probe (Postgres) + $(COMPOSE) run --rm --no-deps $(SERVICE_DEV) sh -c '\ + ruff format --check . && \ + ruff check . && \ + mypy && \ + pytest $(PYTEST_OFFLINE) --cov=app --cov-report=term-missing --cov-report=xml' + $(MAKE) test-surface + +ci-all: ## Full CI: offline + surface + remaining integration + client compatibility + $(MAKE) ci + $(MAKE) test-integration + $(MAKE) test-compatibility + +release-build: ## Build the runtime image tagged for Docker Hub (no push) + @test -n "$(VERSION)" || (echo "VERSION is empty; set VERSION=... or version in pyproject.toml" >&2; exit 1) + @echo "Building $(DOCKER_IMAGE):$(VERSION) (target=runtime)" + docker build \ + --target runtime \ + --build-arg APP_VERSION=$(VERSION) \ + -t $(DOCKER_IMAGE):$(VERSION) \ + $(if $(filter 1 true yes,$(PUSH_LATEST)),-t $(DOCKER_IMAGE):latest,) \ + . + +release: release-build ## Build and push the runtime image to Docker Hub + @echo "Pushing $(DOCKER_IMAGE):$(VERSION)" + @docker push $(DOCKER_IMAGE):$(VERSION) + @if [ "$(PUSH_LATEST)" = "1" ] || [ "$(PUSH_LATEST)" = "true" ] || [ "$(PUSH_LATEST)" = "yes" ]; then \ + echo "Pushing $(DOCKER_IMAGE):latest"; \ + docker push $(DOCKER_IMAGE):latest; \ + fi + @echo "Released $(DOCKER_IMAGE):$(VERSION)$(if $(filter 1 true yes,$(PUSH_LATEST)), and $(DOCKER_IMAGE):latest,)" + +release-up: ## Pull and start the published Hub stack (docker-compose.release.yml) + IMAGE_TAG="$${IMAGE_TAG:-$(VERSION)}" DOCKER_IMAGE="$(DOCKER_IMAGE)" $(COMPOSE_RELEASE) pull + IMAGE_TAG="$${IMAGE_TAG:-$(VERSION)}" DOCKER_IMAGE="$(DOCKER_IMAGE)" $(COMPOSE_RELEASE) up -d --wait + +release-down: ## Stop the published Hub stack + $(COMPOSE_RELEASE) down + +release-seed: ## Seed the published Hub stack (PROFILE=small by default) + SEED_PROFILE="$${PROFILE:-small}" \ + SEED_VSPHERE_PROFILE="$${VSPHERE_PROFILE:-$${PROFILE:-small}}" \ + IMAGE_TAG="$${IMAGE_TAG:-$(VERSION)}" DOCKER_IMAGE="$(DOCKER_IMAGE)" \ + $(COMPOSE_RELEASE) run --rm --entrypoint python simulator -m app.simulation.seed_cli + +helm-deps: ## No-op placeholder (chart has no OCI dependencies) + @echo "Chart $(HELM_CHART) vendors PostgreSQL templates; no helm dependency update required." + +helm-template: ## Render Helm manifests locally (requires helm) + helm template vmware-sim $(HELM_CHART) \ + -f $(HELM_CHART)/values-ingress-example.yaml \ + --set certManager.email=docs@example.com \ + --set secret.ticketSigningKey=docs-only-signing-key diff --git a/README.md b/README.md new file mode 100644 index 0000000..1741248 --- /dev/null +++ b/README.md @@ -0,0 +1,228 @@ +**Language / Язык:** [English](README.md) | [Русский](README.ru.md) + +# vmware-api-simulator + +Stateful asynchronous [VMware vSphere](https://www.vmware.com/products/vsphere.html) +API simulator for testing API clients and infrastructure tooling without a real +ESXi/vCenter cluster. + +The simulator is backed by PostgreSQL and exposes native vCenter surfaces: +**REST** Automation API (`/api`, legacy `/rest`) and **SOAP** VIM/PBM (`/sdk`). +Semantic handlers persist inventory, sessions, tasks, tags, content libraries, +and permissions; power/clone/relocate/snapshot operations run as durable CIS +tasks with real task ids. + +## Verified API coverage + +Coverage is tracked against the public +[vSphere Automation API operations index](https://developer.broadcom.com/xapis/vsphere-automation-api/latest/operation-index/) +(~1037 unique verb+path routes in the simulator registry). + +**Two layers (read this before the table):** + +| Layer | Share (major 9) | Meaning | +|---|---:|---| +| Core deep handlers | ~104 routes (~10%) | Inventory, VM lifecycle, tasks, tagging, content library, appliance, authz — real PostgreSQL semantics | +| DB-backed stub surface | remaining registry (~90%) | Seeded non-empty JSON for the rest of the Broadcom route table (lab stand-ins, not production parity) | + +| Catalog major | vSphere label | Catalog floor / universe | Floor coverage | +|---|---|---:|---:| +| 6 | 7.0 | 31 / 1077 | 2.9% | +| 7 | 7.0 U3 | 77 / 1077 | 7.2% | +| 8 | 8.0 | 103 / 1077 | 9.6% | +| 9 | 8.0 U2 (Automation 9.1 surface) | **1077 / 1077** | **100% route registry** | + +At major 9 the **full route registry** is served (no known path 501s): deep +handlers plus stubs. Hot-swap (`POST /ui/api/contract/apply?major=N`) only +changes the **catalog** major used by the Web UI / evidence reports. See +[Compatibility](docs/compatibility.md), [compatibility 0.1.0](docs/compatibility-0.1.0.md), +and [API coverage](docs/api-coverage.md). + +> This is measurable route-registry and handler coverage for a laboratory +> simulator — not a claim that every vSphere edge case or ESXi-hardware +> behavior is reproduced identically to production vCenter. + +## Quick start (published image) + +Image: [`inecs/vmware-api-simulator`](https://hub.docker.com/r/inecs/vmware-api-simulator) + +Requires a git checkout of this repository (Compose mounts +`docker/gateway/` and `docker/tls/` next to the compose file). + +### Docker Compose + +```bash +docker compose -f docker-compose.release.yml up -d --wait +# seed runs automatically; re-run manually if you wiped the DB: +# docker compose -f docker-compose.release.yml run --rm --entrypoint python \ +# simulator -m app.simulation.seed_cli + +curl -sk https://localhost/health/ready +SID=$(curl -sk -u 'administrator@vsphere.local:VMware1!' -X POST \ + https://localhost/api/session | tr -d '"') +curl -sk -H "vmware-api-session-id: $SID" https://localhost/api/vcenter/vm +``` + +Or: `make release-up` (seed is part of the release stack) + +### Helm (Kubernetes + Ingress + Let's Encrypt) + +```bash +helm upgrade --install vmware-sim ./helm/vmware-api-simulator \ + -n vmware-sim --create-namespace \ + -f ./helm/vmware-api-simulator/values-ingress-example.yaml \ + --set certManager.email=you@example.com \ + --set ingress.hosts[0].host=vmware-sim.example.com \ + --set ingress.tls[0].hosts[0]=vmware-sim.example.com \ + --set secret.ticketSigningKey="$(openssl rand -hex 32)" +``` + +Requires an Ingress controller and cert-manager. Details: +[Kubernetes / Helm](docs/kubernetes.md). + +- Lab UI + REST (Compose gateway): [https://localhost/](https://localhost/) +- FastAPI schema docs: [https://localhost/docs](https://localhost/docs) +- Default seeded admin: `administrator@vsphere.local` / `VMware1!` + +## Quick start (development checkout) + +Build and run the bind-mounted development stack from this repository: + +```bash +make install +make up +make seed PROFILE=small + +curl -sk https://localhost/health/ready +curl -sk https://localhost/api/appliance/system/version +``` + +- HTTPS gateway (primary vCenter entry): `https://localhost` +- HTTP lab face: `http://localhost` +- PostgreSQL (localhost only): `5434` +- Internal FastAPI process (not published to the host): `8080` +- The checked-in `docker/tls/server.key` is a **lab-only** localhost cert; do + not reuse it outside local Compose. +- FastAPI schema docs: [https://localhost/docs](https://localhost/docs) + +### Web UI + +Interactive console with light/dark themes, endpoint catalog for vSphere +majors 6–9, request/response editing, and runtime contract hot-swap. More +detail: [Web UI](docs/web-ui.md). + +![Web UI light theme](docs/images/web-ui-light.png) + +![Web UI dark theme](docs/images/web-ui-dark.png) + +## Credentials (seed) + +Password `VMware1!` for all seeded principals: + +| User | Role | +|---|---| +| `administrator@vsphere.local` | Administrator | +| `readonly@vsphere.local` | ReadOnly | +| `operator@vsphere.local` | VirtualMachinePowerUser | +| `vmadmin@vsphere.local` | VirtualMachineAdministrator | + +## Documentation + +Documentation is bilingual. Use the **Language / Язык** switcher at the top of +each page, or open the Russian root [README.ru.md](README.ru.md). Index: +[docs/README.md](docs/README.md) · [docs/ru/README.md](docs/ru/README.md). + +| Guide | Description | +|---|---| +| [Getting started](docs/getting-started.md) | First successful lab session | +| [Configuration](docs/configuration.md) | Environment variables and Compose | +| [Authentication](docs/authentication.md) | Sessions, `vmware-api-session-id`, privileges | +| [API versions](docs/api-versions.md) | Catalog majors 6–9 and hot-swap | +| [API surface](docs/api-surface.md) | REST/SOAP routing, coverage registry, stubs | +| [API coverage](docs/api-coverage.md) | Broadcom universe vs implemented surface | +| [Clients & examples](docs/clients.md) | Python, Go, Java, Perl, Ansible, Terraform, Pulumi | +| [Seed profiles](docs/seed-profiles.md) | Deterministic inventory fixtures | +| [Domains](docs/domains/README.md) | Session, inventory, VM, storage, networking, tagging, SOAP, tasks, … | +| [Web UI](docs/web-ui.md) | Interactive console and catalogs | +| [Operations](docs/operations.md) | Reseed, migrate, release, upgrade | +| [Kubernetes / Helm](docs/kubernetes.md) | Hub image + Ingress + Let's Encrypt | +| [Security](docs/security.md) | Lab threat model and credentials | +| [Observability](docs/observability.md) | Health endpoints and logging | +| [Ports](docs/ports.md) | Published host ports and internal services | +| [Troubleshooting](docs/troubleshooting.md) | Common failure modes | +| [FAQ](docs/faq.md) | Short answers | +| [Architecture](docs/architecture.md) | Component boundaries | +| [Compatibility](docs/compatibility.md) | Evidence model and release matrix | + +Runnable cookbooks live under [`examples/`](examples/README.md). The +[`pulumi-vsphere`](https://www.pulumi.com/registry/packages/vsphere/) lab suite +(nonempty output checks, HTML report) lives under +[`pulumi-tests/`](pulumi-tests/README.md) — run with `make pulumi-tests`. + +## Python (requests) against the HTTPS gateway + +```python +import requests + +requests.packages.urllib3.disable_warnings() +session = requests.post( + "https://localhost/api/session", + auth=("administrator@vsphere.local", "VMware1!"), + verify=False, # local self-signed development certificate only +) +headers = {"vmware-api-session-id": session.json()} +vms = requests.get("https://localhost/api/vcenter/vm", headers=headers, verify=False) +print(vms.json()) +``` + +SOAP / VIM clients (pyvmomi, govmomi, `hashicorp/vsphere` Terraform provider, +Pulumi) point at `https://localhost/sdk` with the same credentials. + +## Common Make targets + +```bash +make up / make down / make logs / make dev +make seed # large vSphere seed (10 hosts / 1000 VMs) +VSPHERE_PROFILE=small make seed # compact inventory (3 hosts / 5 VMs) +make test # unit + contract (offline) +make test-vsphere # native vSphere unit + integration + surface + matrix +make vsphere-surface # probe REST coverage registry against the running gateway +make vsphere-matrix # full REST matrix: all verbs × majors 6-9 (no 5xx) +make evidence # regenerate evidence/vsphere-*.json ledgers +make db-migrate +make shell +make ci # ruff + mypy + offline pytest + surface probe +make release # build + push runtime image to Docker Hub +make release-up # pull/start docker-compose.release.yml +make release-seed PROFILE=small +``` + +Docker Hub release (requires `docker login` as the Hub owner; see +[Operations](docs/operations.md)): + +```bash +make release # inecs/vmware-api-simulator: + :latest +make release VERSION=0.2.0 # override tag +make release-build # build/tag only, no push +make release-up && make release-seed # run the published stack locally +``` + +## What this is not + +- Not a hypervisor: no ESXi/KVM execution on bare metal or nested hosts. +- Not a drop-in multi-tenant production vCenter replacement. +- No Supervisor/Tanzu control plane, no NSX Manager, no deep vSAN, no + SAML/OIDC federation, no VECS certificate store — lab-shaped stand-ins + exist for some of these (seeded, non-binary-compatible data). HttpNfcLease + / content-library transfer **handshakes** are implemented on `/nfc` and + related REST/SOAP paths, but not production-binary-compatible NFC uploads; + see [docs/api-coverage.md](docs/api-coverage.md). +- Remote IdP / LDAP / live NSX / live ACME directories are simulated locally; + they do not call real external systems. +- An optional legacy Proxmox VE stub plane exists behind `ENABLE_PVE_STUB` + (**off** by default) from a shared platform lineage; it is not the primary + surface of this project. + +## License + +Apache-2.0 — see [LICENSE](LICENSE). diff --git a/README.ru.md b/README.ru.md new file mode 100644 index 0000000..bfaaa7e --- /dev/null +++ b/README.ru.md @@ -0,0 +1,229 @@ +**Language / Язык:** [English](README.md) | [Русский](README.ru.md) + +# vmware-api-simulator + +Stateful-асинхронный симулятор API [VMware vSphere](https://www.vmware.com/products/vsphere.html) +для тестирования API-клиентов и инфраструктурных инструментов без реального +кластера ESXi/vCenter. + +Симулятор работает на PostgreSQL и предоставляет нативные поверхности vCenter: +**REST** Automation API (`/api`, legacy `/rest`) и **SOAP** VIM/PBM (`/sdk`). +Семантические обработчики сохраняют инвентарь, сессии, задачи, теги, content library +и права доступа; операции power/clone/relocate/snapshot выполняются как устойчивые +CIS-задачи с реальными id задач. + +## Проверенное покрытие API + +Покрытие отслеживается относительно публичного +[vSphere Automation API operations index](https://developer.broadcom.com/xapis/vsphere-automation-api/latest/operation-index/) +(~1037 уникальных маршрутов verb+path в registry симулятора). + +**Два слоя (прочитайте до таблицы):** + +| Слой | Доля (major 9) | Смысл | +|---|---:|---| +| Core deep handlers | ~104 маршрута (~10%) | Инвентарь, lifecycle ВМ, tasks, tagging, content library, appliance, authz — реальная семантика в PostgreSQL | +| DB-backed stub surface | остальной registry (~90%) | Засеянный non-empty JSON по остальной таблице Broadcom (lab stand-in, не production parity) | + +| Catalog major | Метка vSphere | Catalog floor / universe | Floor coverage | +|---|---|---:|---:| +| 6 | 7.0 | 31 / 1077 | 2.9% | +| 7 | 7.0 U3 | 77 / 1077 | 7.2% | +| 8 | 8.0 | 103 / 1077 | 9.6% | +| 9 | 8.0 U2 (Automation 9.1 surface) | **1077 / 1077** | **100% route registry** | + +На major 9 обслуживается **полный route registry** (нет известных path 501): +deep handlers плюс stubs. Hot-swap (`POST /ui/api/contract/apply?major=N`) +меняет только **catalog** major для Web UI / evidence-отчётов. См. +[Совместимость](docs/ru/compatibility.md), +[compatibility 0.1.0](docs/ru/compatibility-0.1.0.md) и +[Покрытие API](docs/ru/api-coverage.md). + +> Это измеримое покрытие route-registry и обработчиков лабораторного симулятора — +> не утверждение, что каждый краевой случай vSphere или поведение ESXi-железа +> воспроизводится идентично продакшен-vCenter. + +## Быстрый старт (опубликованный образ) + +Образ: [`inecs/vmware-api-simulator`](https://hub.docker.com/r/inecs/vmware-api-simulator) + +Нужен git checkout этого репозитория (Compose монтирует `docker/gateway/` и +`docker/tls/` рядом с compose-файлом). + +### Docker Compose + +```bash +docker compose -f docker-compose.release.yml up -d --wait +# seed выполняется автоматически; при очистке БД: +# docker compose -f docker-compose.release.yml run --rm --entrypoint python \ +# simulator -m app.simulation.seed_cli + +curl -sk https://localhost/health/ready +SID=$(curl -sk -u 'administrator@vsphere.local:VMware1!' -X POST \ + https://localhost/api/session | tr -d '"') +curl -sk -H "vmware-api-session-id: $SID" https://localhost/api/vcenter/vm +``` + +Или: `make release-up` (seed входит в release-стек) + +### Helm (Kubernetes + Ingress + Let's Encrypt) + +```bash +helm upgrade --install vmware-sim ./helm/vmware-api-simulator \ + -n vmware-sim --create-namespace \ + -f ./helm/vmware-api-simulator/values-ingress-example.yaml \ + --set certManager.email=you@example.com \ + --set ingress.hosts[0].host=vmware-sim.example.com \ + --set ingress.tls[0].hosts[0]=vmware-sim.example.com \ + --set secret.ticketSigningKey="$(openssl rand -hex 32)" +``` + +Нужны Ingress-контроллер и cert-manager. Подробности: +[Kubernetes / Helm](docs/ru/kubernetes.md). + +- Lab UI + REST (Compose gateway): [https://localhost/](https://localhost/) +- Схема FastAPI: [https://localhost/docs](https://localhost/docs) +- Админ по умолчанию после seed: `administrator@vsphere.local` / `VMware1!` + +## Быстрый старт (разработка из репозитория) + +Сборка и запуск development-стека с bind-mount из этого репозитория: + +```bash +make install +make up +make seed PROFILE=small + +curl -sk https://localhost/health/ready +curl -sk https://localhost/api/appliance/system/version +``` + +- HTTPS gateway (основная точка входа vCenter): `https://localhost` +- HTTP lab face: `http://localhost` +- PostgreSQL (только localhost): `5434` +- Внутренний процесс FastAPI (не публикуется на хост): `8080` +- Вшитый `docker/tls/server.key` — **только для лаборатории** localhost-сертификат; + не используйте его вне локального Compose. +- Схема FastAPI: [https://localhost/docs](https://localhost/docs) + +### Web UI + +Интерактивная консоль со светлой/тёмной темой, каталог эндпоинтов для vSphere +majors 6–9, редактирование request/response и runtime contract hot-swap. Подробнее: +[Web UI](docs/ru/web-ui.md). + +![Web UI light theme](docs/images/web-ui-light.png) + +![Web UI dark theme](docs/images/web-ui-dark.png) + +## Учётные данные (seed) + +Пароль `VMware1!` для всех засеянных principals: + +| User | Role | +|---|---| +| `administrator@vsphere.local` | Administrator | +| `readonly@vsphere.local` | ReadOnly | +| `operator@vsphere.local` | VirtualMachinePowerUser | +| `vmadmin@vsphere.local` | VirtualMachineAdministrator | + +## Документация + +Документация двуязычная. Используйте переключатель **Language / Язык** в начале +каждой страницы или откройте русский корень [README.ru.md](README.ru.md). Индекс: +[docs/README.md](docs/README.md) · [docs/ru/README.md](docs/ru/README.md). + +| Руководство | Описание | +|---|---| +| [Быстрый старт](docs/ru/getting-started.md) | Первая успешная лабораторная сессия | +| [Конфигурация](docs/ru/configuration.md) | Переменные окружения и Compose | +| [Аутентификация](docs/ru/authentication.md) | Сессии, `vmware-api-session-id`, привилегии | +| [Версии API](docs/ru/api-versions.md) | Catalog majors 6–9 и hot-swap | +| [Поверхность API](docs/ru/api-surface.md) | Маршрутизация REST/SOAP, coverage registry, stubs | +| [Покрытие API](docs/ru/api-coverage.md) | Broadcom universe vs реализованная поверхность | +| [Клиенты и примеры](docs/ru/clients.md) | Python, Go, Java, Perl, Ansible, Terraform, Pulumi | +| [Профили seed](docs/ru/seed-profiles.md) | Детерминированные фикстуры инвентаря | +| [Домены](docs/ru/domains/README.md) | Session, inventory, VM, storage, networking, tagging, SOAP, tasks, … | +| [Web UI](docs/ru/web-ui.md) | Интерактивная консоль и каталоги | +| [Эксплуатация](docs/ru/operations.md) | Reseed, migrate, release, upgrade | +| [Kubernetes / Helm](docs/ru/kubernetes.md) | Образ Hub + Ingress + Let's Encrypt | +| [Безопасность](docs/ru/security.md) | Модель угроз лаборатории и учётные данные | +| [Наблюдаемость](docs/ru/observability.md) | Эндпоинты health и логирование | +| [Порты](docs/ru/ports.md) | Опубликованные порты хоста и внутренние сервисы | +| [Устранение неполадок](docs/ru/troubleshooting.md) | Типичные сбои | +| [FAQ](docs/ru/faq.md) | Краткие ответы | +| [Архитектура](docs/ru/architecture.md) | Границы компонентов | +| [Совместимость](docs/ru/compatibility.md) | Модель evidence и матрица релизов | + +Исполняемые cookbook'и находятся в [`examples/`](examples/README.ru.md). Lab-набор +на официальном [`pulumi-vsphere`](https://www.pulumi.com/registry/packages/vsphere/) +(проверки непустых export'ов, HTML-отчёт) — в +[`pulumi-tests/`](pulumi-tests/README.ru.md); запуск: `make pulumi-tests`. + +## Python (requests) через HTTPS gateway + +```python +import requests + +requests.packages.urllib3.disable_warnings() +session = requests.post( + "https://localhost/api/session", + auth=("administrator@vsphere.local", "VMware1!"), + verify=False, # local self-signed development certificate only +) +headers = {"vmware-api-session-id": session.json()} +vms = requests.get("https://localhost/api/vcenter/vm", headers=headers, verify=False) +print(vms.json()) +``` + +SOAP / VIM клиенты (pyvmomi, govmomi, Terraform provider `hashicorp/vsphere`, +Pulumi) указывают на `https://localhost/sdk` с теми же учётными данными. + +## Основные Make-цели + +```bash +make up / make down / make logs / make dev +make seed # large vSphere seed (10 hosts / 1000 VMs) +VSPHERE_PROFILE=small make seed # compact inventory (3 hosts / 5 VMs) +make test # unit + contract (offline) +make test-vsphere # native vSphere unit + integration + surface + matrix +make vsphere-surface # probe REST coverage registry against the running gateway +make vsphere-matrix # full REST matrix: all verbs × majors 6-9 (no 5xx) +make evidence # regenerate evidence/vsphere-*.json ledgers +make db-migrate +make shell +make ci # ruff + mypy + offline pytest + surface probe +make release # build + push runtime image to Docker Hub +make release-up # pull/start docker-compose.release.yml +make release-seed PROFILE=small +``` + +Docker Hub release (нужен `docker login` как владелец Hub; см. +[Эксплуатация](docs/ru/operations.md)): + +```bash +make release # inecs/vmware-api-simulator: + :latest +make release VERSION=0.2.0 # override tag +make release-build # build/tag only, no push +make release-up && make release-seed # run the published stack locally +``` + +## Чем это не является + +- Не гипервизор: нет выполнения ESXi/KVM на bare metal или nested hosts. +- Не drop-in multi-tenant production vCenter replacement. +- Нет Supervisor/Tanzu control plane, NSX Manager, deep vSAN, SAML/OIDC federation, + VECS certificate store — для некоторых из них есть lab-shaped stand-ins + (засеянные, non-binary-compatible данные). Handshake HttpNfcLease / + content-library transfer реализован на `/nfc` и связанных REST/SOAP-путях, + но не production-binary-compatible NFC uploads; см. + [docs/ru/api-coverage.md](docs/ru/api-coverage.md). +- Удалённые IdP / LDAP / live NSX / live ACME directories симулируются локально; + они не обращаются к реальным внешним системам. +- Опциональная legacy Proxmox VE stub-плоскость доступна за `ENABLE_PVE_STUB` + (**выключена** по умолчанию) из общей platform lineage; это не основная + поверхность проекта. + +## Лицензия + +Apache-2.0 — см. [LICENSE](LICENSE). diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..76fb20a --- /dev/null +++ b/app/__init__.py @@ -0,0 +1 @@ +"""Proxmox API simulator application package.""" diff --git a/app/api/__init__.py b/app/api/__init__.py new file mode 100644 index 0000000..95abe0d --- /dev/null +++ b/app/api/__init__.py @@ -0,0 +1 @@ +"""HTTP adapters.""" diff --git a/app/api/errors.py b/app/api/errors.py new file mode 100644 index 0000000..5d6933a --- /dev/null +++ b/app/api/errors.py @@ -0,0 +1,51 @@ +"""Base external error representation.""" + +from __future__ import annotations + +import logging +from typing import Any + +from fastapi import Request +from fastapi.responses import JSONResponse + +logger = logging.getLogger(__name__) + + +class ApiError(Exception): + """A safe error intended for the Proxmox-compatible boundary.""" + + def __init__( + self, status_code: int, message: str, errors: dict[str, str] | None = None + ) -> None: + super().__init__(message) + self.status_code = status_code + self.message = message + self.errors = errors + + +class ContractValidationError(ApiError): + def __init__(self, errors: dict[str, str]) -> None: + super().__init__(400, "parameter verification failed", errors) + + +async def api_error_handler(_request: Request, exc: Exception) -> JSONResponse: + if not isinstance(exc, ApiError): + raise TypeError("api_error_handler received an incompatible exception") + body: dict[str, Any] = {"data": None, "message": exc.message} + if exc.errors is not None: + body["errors"] = exc.errors + return JSONResponse(status_code=exc.status_code, content=body) + + +async def unhandled_exception_handler(request: Request, exc: Exception) -> JSONResponse: + """Log internal failures and return a stable non-FastAPI error envelope.""" + + logger.exception( + "unhandled request error", + extra={"request_id": getattr(request.state, "request_id", None), "path": request.url.path}, + ) + body: dict[str, Any] = { + "data": None, + "errors": {"internal": "internal server error"}, + } + return JSONResponse(status_code=500, content=body) diff --git a/app/api/middleware.py b/app/api/middleware.py new file mode 100644 index 0000000..d0e0c22 --- /dev/null +++ b/app/api/middleware.py @@ -0,0 +1,42 @@ +"""Request correlation and access logging middleware.""" + +from __future__ import annotations + +import logging +import time +import uuid +from collections.abc import Awaitable, Callable + +from fastapi import Request, Response +from starlette.middleware.base import BaseHTTPMiddleware + +logger = logging.getLogger(__name__) + +RequestHandler = Callable[[Request], Awaitable[Response]] + + +class RequestContextMiddleware(BaseHTTPMiddleware): + """Attach a bounded request ID and log one structured completion event.""" + + def __init__(self, app: object, header_name: str) -> None: + super().__init__(app) # type: ignore[arg-type] + self._header_name = header_name + + async def dispatch(self, request: Request, call_next: RequestHandler) -> Response: + supplied = request.headers.get(self._header_name, "") + request_id = supplied if 0 < len(supplied) <= 128 else str(uuid.uuid4()) + request.state.request_id = request_id + started = time.monotonic() + response = await call_next(request) + response.headers[self._header_name] = request_id + logger.info( + "request completed", + extra={ + "request_id": request_id, + "method": request.method, + "path": request.url.path, + "status": response.status_code, + "duration_ms": round((time.monotonic() - started) * 1000, 3), + }, + ) + return response diff --git a/app/api/openapi.py b/app/api/openapi.py new file mode 100644 index 0000000..2269773 --- /dev/null +++ b/app/api/openapi.py @@ -0,0 +1,138 @@ +"""OpenAPI tag resolution for contract-driven routes.""" + +from __future__ import annotations + +_NODE_SECTION_LABELS: dict[str, str] = { + "qemu": "QEMU", + "lxc": "LXC", + "ceph": "Ceph", + "storage": "Storage", + "sdn": "SDN", + "firewall": "Firewall", + "apt": "APT", + "certificates": "Certificates", + "scan": "Scan", + "network": "Network", + "services": "Services", + "capabilities": "Capabilities", + "hardware": "Hardware", + "replication": "Replication", + "tasks": "Tasks", + "subscription": "Subscription", + "vzdump": "Backup", + "disks": "Disks", + "config": "Config", + "dns": "DNS", + "hosts": "Hosts", + "status": "Status", + "time": "Time", + "aplinfo": "Appliance", +} + +_CLUSTER_SECTION_LABELS: dict[str, str] = { + "sdn": "SDN", + "firewall": "Firewall", + "notifications": "Notifications", + "ha": "HA", + "mapping": "Mapping", + "acme": "ACME", + "config": "Config", + "ceph": "Ceph", + "jobs": "Jobs", + "metrics": "Metrics", + "qemu": "QEMU", + "backup": "Backup", + "bulk-action": "Bulk Action", + "replication": "Replication", + "backup-info": "Backup Info", + "options": "Options", + "log": "Log", + "nextid": "Next ID", + "resources": "Resources", + "status": "Status", + "tasks": "Tasks", +} + +_VSPHERE_TAG_DESCRIPTIONS: dict[str, str] = { + "vSphere REST": "vSphere Automation REST inventory and lifecycle APIs.", + "vSphere REST surface": "Additional vSphere REST surface stubs.", + "vSphere SOAP": "vSphere Web Services (SOAP) SDK endpoints.", + "vSphere PBM": "Storage Policy Based Management (PBM) SOAP endpoints.", + "vSphere Platform": "Appliance, CIS session, and platform helpers.", + "vSphere Tagging": "CIS tagging categories and tags.", + "vSphere Content": "Content library stubs.", + "vSphere NFC": "NFC file transfer stubs.", + "vSphere Tasks": "vSphere task polling helpers.", + "vSphere VM Ext": "Extended VM operations beyond the core REST surface.", + "vSphere Inventory Ext": "Extended inventory and folder helpers.", + "vSphere Appliance": "vCenter appliance management stubs.", + "vSphere Legacy REST": "Legacy vSphere REST compatibility stubs.", +} + + +def contract_openapi_tag(path: str) -> str: + """Map a semantic contract path to a Swagger UI category.""" + + parts = [part for part in path.strip("/").split("/") if part] + if not parts or parts == ["version"]: + return "Core" + root = parts[0] + if root == "access": + return "Access" + if root == "nodes": + if len(parts) >= 3 and parts[1] == "{node}": + section = parts[2] + label = _NODE_SECTION_LABELS.get(section, section.replace("-", " ").title()) + return f"Nodes · {label}" + return "Nodes" + if root == "cluster": + if len(parts) >= 2: + section = parts[1] + label = _CLUSTER_SECTION_LABELS.get(section, section.replace("-", " ").title()) + return f"Cluster · {label}" + return "Cluster" + if root == "storage": + return "Storage" + if root == "pools": + return "Pools" + return root.replace("-", " ").title() + + +def contract_openapi_tags(path: str, renderer: str) -> list[str]: + """Return OpenAPI tags for a contract route, including the API renderer.""" + + renderer_label = "API2 JSON" if renderer == "json" else "API2 ExtJS" + return [contract_openapi_tag(path), renderer_label] + + +def _pve_openapi_tag_descriptions() -> dict[str, str]: + descriptions: dict[str, str] = { + "Core": "Version and global simulator metadata.", + "Access": "Authentication, users, groups, roles, ACLs, and API tokens.", + "Nodes": "Node inventory and node-level endpoints without a resource section.", + "Storage": "Cluster-wide and node storage definitions and content.", + "Pools": "Resource pools and membership.", + "API2 JSON": "Proxmox `/api2/json` renderer routes.", + "API2 ExtJS": "Proxmox `/api2/extjs` renderer routes.", + } + for label in _NODE_SECTION_LABELS.values(): + descriptions.setdefault(f"Nodes · {label}", f"Node-level {label} API.") + for label in _CLUSTER_SECTION_LABELS.values(): + descriptions.setdefault(f"Cluster · {label}", f"Cluster-level {label} API.") + return descriptions + + +def openapi_tag_metadata(*, include_pve: bool = False) -> list[dict[str, str]]: + """Descriptions shown in Swagger UI for each tag group. + + Proxmox `/api2/*` tag groups are omitted unless ``include_pve`` is true, + so the default vSphere plane does not show empty legacy sections in `/docs`. + """ + + descriptions: dict[str, str] = { + "Simulator": "Health checks, compatibility reports, and the web console.", + **_VSPHERE_TAG_DESCRIPTIONS, + } + if include_pve: + descriptions.update(_pve_openapi_tag_descriptions()) + return [{"name": name, "description": text} for name, text in sorted(descriptions.items())] diff --git a/app/api/registry.py b/app/api/registry.py new file mode 100644 index 0000000..862f0a6 --- /dev/null +++ b/app/api/registry.py @@ -0,0 +1,375 @@ +"""Contract-driven dynamic route and semantic handler registry.""" + +from __future__ import annotations + +import re +from collections.abc import Awaitable, Callable +from dataclasses import dataclass, field +from enum import Enum +from pathlib import Path +from typing import Any, Literal, cast +from urllib.parse import parse_qsl + +from fastapi import FastAPI, Request +from fastapi.responses import JSONResponse + +from app.api.errors import ApiError, ContractValidationError +from app.api.openapi import contract_openapi_tags +from app.config import Settings +from app.contracts.examples import schema_example +from app.contracts.model import Method, Schema, Snapshot +from app.db.pool import AsyncpgDatabase +from app.security.acl import AclEntry, CapabilityRequirement, authorize, requirement_from_contract +from app.security.auth import parse_api_token, verify_csrf, verify_secret, verify_ticket + +Handler = Callable[[Request, dict[str, Any]], Awaitable[Any]] +FallbackMode = Literal["error", "schema-default", "fixture"] + + +class RouteCollisionError(ValueError): + pass + + +@dataclass(slots=True) +class HandlerRegistry: + _handlers: dict[tuple[str, str], Handler] = field(default_factory=dict) + + def register(self, path: str, verb: str, handler: Handler) -> None: + key = (path, verb.upper()) + if key in self._handlers: + raise RouteCollisionError(f"duplicate semantic handler: {verb} {path}") + self._handlers[key] = handler + + def get(self, path: str, verb: str) -> Handler | None: + return self._handlers.get((path, verb.upper())) + + def keys(self) -> frozenset[tuple[str, str]]: + return frozenset(self._handlers) + + +def register_contract_routes( + app: FastAPI, + snapshot: Snapshot, + handlers: HandlerRegistry, + fallback: FallbackMode = "error", + *, + existing: set[tuple[str, str, str]] | None = None, + require_handler: bool = False, + allow_existing: bool = False, +) -> set[tuple[str, str, str]]: + """Register `/api2/{json,extjs}` routes for a contract snapshot. + + When ``allow_existing`` is true, path/verb pairs already present in + ``existing`` are skipped (used to merge older majors onto a primary contract). + When ``require_handler`` is true, only methods with a registered semantic + handler are added — used for legacy-path aliases. + """ + + seen = existing if existing is not None else set() + for contract_path in snapshot.paths: + for contract_method in contract_path.methods: + if require_handler and handlers.get(contract_path.path, contract_method.verb) is None: + continue + for renderer in ("json", "extjs"): + route = f"/api2/{renderer}{contract_path.path}" + key = (route, contract_method.verb, renderer) + if key in seen: + if allow_existing: + continue + raise RouteCollisionError( + f"duplicate contract route: {contract_method.verb} {route}" + ) + seen.add(key) + implemented = handlers.get(contract_path.path, contract_method.verb) is not None + endpoint = _endpoint( + contract_path.path, + contract_method, + renderer, + handlers, + fallback, + ) + app.add_api_route( + route, + endpoint, + methods=[contract_method.verb], + name=f"contract:{renderer}:{contract_method.verb}:{contract_path.path}", + tags=cast( + list[str | Enum], contract_openapi_tags(contract_path.path, renderer) + ), + openapi_extra={ + "x-proxmox-method-checksum": contract_method.checksum, + "x-proxmox-implementation": "implemented" if implemented else "unsupported", + }, + ) + return seen + + +def register_legacy_handler_routes( + app: FastAPI, + handlers: HandlerRegistry, + store_root: Path, + fallback: FallbackMode = "error", + *, + primary_version: str | None = None, + existing: set[tuple[str, str, str]] | None = None, +) -> set[tuple[str, str, str]]: + """Expose handler-backed paths declared only in older cached contracts.""" + + seen = existing if existing is not None else set() + if not store_root.is_dir(): + return seen + for revision_dir in sorted(store_root.iterdir()): + snapshot_path = revision_dir / "snapshot.json" + if not snapshot_path.is_file(): + continue + snapshot = Snapshot.model_validate_json(snapshot_path.read_bytes()) + if primary_version and snapshot.source_version == primary_version: + continue + seen = register_contract_routes( + app, + snapshot, + handlers, + fallback, + existing=seen, + require_handler=True, + allow_existing=True, + ) + return seen + + +def _endpoint( + semantic_path: str, + method: Method, + renderer: str, + handlers: HandlerRegistry, + fallback: FallbackMode, +) -> Callable[[Request], Awaitable[JSONResponse]]: + async def dispatch(request: Request) -> JSONResponse: + inputs = await _parse_inputs(request, method) + await _authenticate(request, semantic_path, method, inputs) + handler = handlers.get(semantic_path, method.verb) + if handler is not None: + data = await handler(request, inputs) + elif fallback == "schema-default": + data = schema_example(method.returns) + elif fallback == "fixture" and "fixture" in method.extra: + data = method.extra["fixture"] + else: + return JSONResponse( + status_code=501, + content={"data": None, "errors": "handler pending for this contract method"}, + ) + content = {"data": data, "success": True} if renderer == "extjs" else {"data": data} + response = JSONResponse(content) + if semantic_path == "/access/ticket" and isinstance(data, dict): + ticket = data.get("ticket") + if isinstance(ticket, str): + response.set_cookie( + "PVEAuthCookie", ticket, httponly=True, samesite="strict", path="/" + ) + return response + + return dispatch + + +async def _authenticate( + request: Request, semantic_path: str, method: Method, inputs: dict[str, Any] +) -> None: + if semantic_path in {"/version", "/access/ticket"}: + return + authorization = request.headers.get("Authorization", "") + token_privileges: frozenset[str] | None = None + principal: str + if authorization.startswith("PVEAPIToken="): + database = cast(AsyncpgDatabase, request.app.state.database) + try: + parsed_token = parse_api_token(authorization) + except ValueError as error: + raise ApiError(401, "authentication failure") from error + row = await database.pool.fetchrow( + """SELECT p.name, t.secret_hash, t.privileges, t.privilege_separation + FROM api_tokens t JOIN principals p ON p.id=t.principal_id + WHERE p.name=$1 AND t.token_id=$2 + AND (t.expires_at IS NULL OR t.expires_at > now())""", + parsed_token.principal, + parsed_token.token_id, + ) + if row is None or not verify_secret(parsed_token.secret, str(row["secret_hash"])): + raise ApiError(401, "authentication failure") + principal = str(row["name"]) + token_privileges = ( + frozenset(str(item) for item in row["privileges"]) + if bool(row["privilege_separation"]) + else None + ) + else: + ticket = request.cookies.get("PVEAuthCookie") + if ticket is None: + raise ApiError(401, "authentication required") + settings = cast(Settings, request.app.state.settings) + key = settings.ticket_signing_key.get_secret_value().encode() + try: + claims = verify_ticket(ticket, key) + except ValueError as error: + raise ApiError(401, "authentication failure") from error + principal = claims.principal + if request.method not in {"GET", "HEAD", "OPTIONS"}: + csrf_value = request.headers.get("CSRFPreventionToken", "") + if not verify_csrf(ticket, csrf_value, key): + raise ApiError(403, "invalid CSRF prevention token") + request.state.principal = principal + if principal == "root@pam" and token_privileges is None: + return + database = cast(AsyncpgDatabase, request.app.state.database) + await _authorize(database, principal, token_privileges, semantic_path, method, inputs) + + +async def _authorize( + database: AsyncpgDatabase, + principal: str, + token_privileges: frozenset[str] | None, + semantic_path: str, + method: Method, + inputs: dict[str, Any], +) -> None: + values = cast(dict[str, Any], inputs["values"]) + requirement = requirement_from_contract( + method.permissions, {name: str(value) for name, value in values.items()} + ) + if requirement is None and semantic_path == "/nodes/{node}/qemu" and method.verb == "POST": + requirement = CapabilityRequirement(f"/vms/{values['vmid']}", frozenset({"VM.Allocate"})) + if requirement is None and semantic_path == "/nodes/{node}/lxc" and method.verb == "POST": + requirement = CapabilityRequirement(f"/vms/{values['vmid']}", frozenset({"VM.Allocate"})) + if requirement is None: + return + rows = await database.pool.fetch( + """SELECT a.path, a.propagate, r.privileges + FROM acl_entries a JOIN roles r ON r.name=a.role_name + JOIN principals p ON p.id=a.principal_id WHERE p.name=$1 + UNION ALL + SELECT a.path, a.propagate, r.privileges + FROM group_acl_entries a JOIN roles r ON r.name=a.role_name + JOIN identity_group_members m ON m.group_id=a.group_id + JOIN principals p ON p.id=m.principal_id WHERE p.name=$1""", + principal, + ) + entries = tuple( + AclEntry( + principal, + str(row["path"]), + frozenset(str(item) for item in row["privileges"]), + bool(row["propagate"]), + ) + for row in rows + ) + if not authorize( + principal, + requirement.path, + requirement.privileges, + entries, + token_privileges=token_privileges, + require_all=requirement.require_all, + ): + raise ApiError(403, "permission check failed") + + +async def _parse_inputs(request: Request, method: Method) -> dict[str, Any]: + supplied: dict[str, Any] = dict(request.query_params) + supplied.update(request.path_params) + if request.method not in {"GET", "DELETE"}: + content_type = request.headers.get("content-type", "").split(";", 1)[0].strip() + if content_type == "application/json": + try: + body = await request.json() + except ValueError as exc: + raise ContractValidationError({"body": "invalid JSON"}) from exc + if not isinstance(body, dict): + raise ContractValidationError({"body": "expected an object"}) + supplied.update(body) + elif content_type == "application/x-www-form-urlencoded": + supplied.update(dict(parse_qsl((await request.body()).decode()))) + + definitions = {parameter.name: parameter.definition for parameter in method.parameters} + indexed = { + re.compile("^" + re.escape(name).replace(r"\[n\]", r"\d+") + "$"): definition + for name, definition in definitions.items() + if "[n]" in name + } + errors: dict[str, str] = {} + parsed: dict[str, Any] = {} + for name, definition in definitions.items(): + if "[n]" in name: + continue + if name not in supplied: + if definition.optional: + if definition.default is not None: + parsed[name] = definition.default + continue + errors[name] = "property is missing and it is not optional" + continue + try: + parsed[name] = _coerce(supplied[name], definition) + except (TypeError, ValueError) as exc: + errors[name] = str(exc) + indexed_names: set[str] = set() + for name in supplied.keys() - definitions.keys(): + indexed_definition = next( + (candidate for pattern, candidate in indexed.items() if pattern.fullmatch(name)), None + ) + if indexed_definition is not None: + indexed_names.add(name) + try: + parsed[name] = _coerce(supplied[name], indexed_definition) + except (TypeError, ValueError) as exc: + errors[name] = str(exc) + for name in supplied.keys() - definitions.keys() - indexed_names: + if name not in request.path_params: + errors[name] = "property is not defined in schema" + if errors: + raise ContractValidationError(dict(sorted(errors.items()))) + # Path params are always available to handlers even when omitted from the + # method property schema (common for Proxmox nested resources). + for name, value in request.path_params.items(): + parsed.setdefault(name, value) + return { + "values": parsed, + "path": dict(request.path_params), + "provided": tuple(sorted(supplied)), + } + + +def _coerce(value: Any, schema: Schema) -> Any: + if schema.type == "integer": + parsed: Any = int(value) + elif schema.type == "number": + parsed = float(value) + elif schema.type == "boolean": + if isinstance(value, bool): + parsed = value + elif str(value).lower() in {"1", "true", "yes", "on"}: + parsed = True + elif str(value).lower() in {"0", "false", "no", "off"}: + parsed = False + else: + raise ValueError("expected a boolean") + elif schema.type == "string" or schema.type is None: + parsed = str(value) + else: + parsed = value + if schema.enum and parsed not in schema.enum: + raise ValueError("value is not in the allowed enumeration") + if isinstance(parsed, int | float): + if schema.minimum is not None and parsed < schema.minimum: + raise ValueError(f"value must be at least {schema.minimum}") + if schema.maximum is not None and parsed > schema.maximum: + raise ValueError(f"value must be at most {schema.maximum}") + if isinstance(parsed, str): + if schema.min_length is not None and len(parsed) < schema.min_length: + raise ValueError(f"value is shorter than {schema.min_length}") + if schema.max_length is not None and len(parsed) > schema.max_length: + raise ValueError(f"value is longer than {schema.max_length}") + return parsed + + +def _schema_default(schema: Schema) -> Any: + return schema_example(schema) diff --git a/app/compatibility.py b/app/compatibility.py new file mode 100644 index 0000000..60a285e --- /dev/null +++ b/app/compatibility.py @@ -0,0 +1,311 @@ +"""Evidence-based compatibility accounting and reporting.""" + +from __future__ import annotations + +import json +from collections.abc import Mapping +from dataclasses import dataclass +from enum import StrEnum +from html import escape +from pathlib import Path +from types import MappingProxyType + +from pydantic import BaseModel, ConfigDict, field_validator, model_validator + +from app.contracts.model import Snapshot + +MethodKey = tuple[str, str] + + +class CompatibilityDimension(StrEnum): + ROUTE_METHOD = "route_method" + INPUT_PARAMETERS = "input_parameters" + PARAMETER_REQUIREDNESS = "parameter_requiredness" + TYPES_CONSTRAINTS = "types_constraints" + HTTP_STATUS = "http_status" + JSON_STRUCTURE = "json_structure" + RESPONSE_FIELD_TYPES = "response_field_types" + RESPONSE_REQUIRED_FIELDS = "response_required_fields" + HEADERS_COOKIES = "headers_cookies" + STATE_SEMANTICS = "state_semantics" + LONG_TASK_BEHAVIOR = "long_task_behavior" + ERRORS_PROHIBITIONS = "errors_prohibitions" + PERMISSIONS = "permissions" + + +EMPTY_DIMENSION_EVIDENCE: Mapping[CompatibilityDimension, frozenset[MethodKey]] = MappingProxyType( + {dimension: frozenset() for dimension in CompatibilityDimension} +) + + +class MethodEvidence(BaseModel): + model_config = ConfigDict(frozen=True, extra="forbid") + + path: str + verb: str + dimensions: tuple[CompatibilityDimension, ...] + sources: tuple[str, ...] + observed: bool = True + verified: bool = True + + @field_validator("sources") + @classmethod + def require_sources(cls, value: tuple[str, ...]) -> tuple[str, ...]: + if not value: + raise ValueError("evidence record requires at least one source") + return value + + @field_validator("verb") + @classmethod + def normalize_verb(cls, value: str) -> str: + return value.upper() + + +class EvidenceManifest(BaseModel): + model_config = ConfigDict(frozen=True, extra="forbid") + + format_version: int = 1 + profile: str + source_version: str + records: tuple[MethodEvidence, ...] + + @model_validator(mode="after") + def reject_duplicate_methods(self) -> EvidenceManifest: + keys = [(record.path, record.verb) for record in self.records] + if len(keys) != len(set(keys)): + raise ValueError("evidence manifest contains duplicate methods") + return self + + def dimension_map(self) -> Mapping[CompatibilityDimension, frozenset[MethodKey]]: + evidence: dict[CompatibilityDimension, set[MethodKey]] = { + dimension: set() for dimension in CompatibilityDimension + } + for record in self.records: + key = (record.path, record.verb.upper()) + for dimension in record.dimensions: + evidence[dimension].add(key) + return MappingProxyType( + {dimension: frozenset(methods) for dimension, methods in evidence.items()} + ) + + def observed_methods(self) -> frozenset[MethodKey]: + return frozenset( + (record.path, record.verb.upper()) for record in self.records if record.observed + ) + + def verified_methods(self) -> frozenset[MethodKey]: + return frozenset( + (record.path, record.verb.upper()) for record in self.records if record.verified + ) + + +def load_evidence_manifest(path: Path) -> EvidenceManifest: + return EvidenceManifest.model_validate_json(path.read_bytes()) + + +def evidence_dir(settings: object | None = None) -> Path: + """Directory that holds per-version ``pve-{version}.json`` ledgers.""" + + evidence = getattr(settings, "compatibility_evidence", None) if settings is not None else None + if isinstance(evidence, Path) and evidence.name: + return evidence.resolve().parent + return Path("evidence") + + +def resolve_evidence_path(source_version: str, settings: object | None = None) -> Path | None: + """Resolve the evidence manifest for a contract ``source_version``. + + Preference order: + 1. ``evidence/pve-{source_version}.json`` next to the configured evidence file + (or ``./evidence`` when unset) + 2. ``settings.compatibility_evidence`` when its embedded ``source_version`` matches + """ + + candidate = evidence_dir(settings) / f"pve-{source_version}.json" + if candidate.is_file(): + return candidate + configured = getattr(settings, "compatibility_evidence", None) if settings is not None else None + if not isinstance(configured, Path) or not configured.is_file(): + return None + manifesto = load_evidence_manifest(configured) + if manifesto.source_version == source_version: + return configured + return None + + +@dataclass(frozen=True, slots=True) +class CompatibilityReport: + source_version: str + declared: frozenset[MethodKey] + schema_only: frozenset[MethodKey] + implemented: frozenset[MethodKey] + observed: frozenset[MethodKey] + verified: frozenset[MethodKey] + dimensions: Mapping[CompatibilityDimension, frozenset[MethodKey]] + incompatible: frozenset[MethodKey] + regressions: frozenset[MethodKey] + + def as_json(self) -> dict[str, object]: + levels = { + "declared": self.declared, + "schema_only": self.schema_only, + "implemented": self.implemented, + "observed": self.observed, + "verified": self.verified, + } + total = len(self.declared) + dimension_sets = tuple(self.dimensions.values()) + fully_evidenced = ( + dimension_sets[0].intersection(*dimension_sets[1:]) if dimension_sets else frozenset() + ) + evidenced = frozenset().union(*dimension_sets) + fully_compatible = fully_evidenced & self.implemented + partially_compatible = (evidenced & self.implemented) - fully_compatible - self.incompatible + return { + "source_version": self.source_version, + "total_declared": total, + "levels": { + name: { + "count": len(methods), + "score": len(methods) / total if total else 1.0, + "methods": [f"{verb} {path}" for path, verb in sorted(methods)], + } + for name, methods in levels.items() + }, + "groups": self._groups(), + "dimension_groups": self._dimension_groups(), + "classifications": { + "fully_compatible": self._method_names(fully_compatible), + "partially_compatible": self._method_names(partially_compatible), + "incompatible": self._method_names(self.incompatible), + "regressions": self._method_names(self.regressions), + "unsupported": self._method_names(self.schema_only), + }, + "dimensions": { + dimension.value: { + "count": len(methods), + "score": len(methods) / total if total else 1.0, + "methods": [f"{verb} {path}" for path, verb in sorted(methods)], + } + for dimension, methods in self.dimensions.items() + }, + } + + @staticmethod + def _method_names(methods: frozenset[MethodKey]) -> list[str]: + return [f"{verb} {path}" for path, verb in sorted(methods)] + + def canonical_json(self) -> str: + return json.dumps(self.as_json(), ensure_ascii=False, separators=(",", ":"), sort_keys=True) + + def _groups(self) -> dict[str, dict[str, int]]: + groups: dict[str, dict[str, int]] = {} + for path, verb in self.declared: + group = path.strip("/").split("/", 1)[0] or "root" + counters = groups.setdefault(group, {"declared": 0, "implemented": 0, "verified": 0}) + counters["declared"] += 1 + counters["implemented"] += int((path, verb) in self.implemented) + counters["verified"] += int((path, verb) in self.verified) + return dict(sorted(groups.items())) + + def _dimension_groups(self) -> dict[str, dict[str, int]]: + groups: dict[str, dict[str, int]] = {} + for dimension, methods in self.dimensions.items(): + for path, _verb in methods: + group = path.strip("/").split("/", 1)[0] or "root" + counters = groups.setdefault( + group, {item.value: 0 for item in CompatibilityDimension} + ) + counters[dimension.value] += 1 + return dict(sorted(groups.items())) + + def as_markdown(self) -> str: + levels = { + "declared": self.declared, + "schema_only": self.schema_only, + "implemented": self.implemented, + "observed": self.observed, + "verified": self.verified, + } + total = len(self.declared) + lines = [ + "# Compatibility report", + "", + "| Level | Count | Score |", + "|---|---:|---:|", + ] + for name, methods in levels.items(): + score = len(methods) / total if total else 1.0 + lines.append(f"| {name} | {len(methods)} | {score:.2%} |") + lines.extend( + [ + "", + "## Compatibility dimensions", + "", + "| Dimension | Verified methods | Score |", + "|---|---:|---:|", + ] + ) + for dimension, methods in self.dimensions.items(): + score = len(methods) / total if total else 1.0 + lines.append(f"| {dimension.value} | {len(methods)} | {score:.2%} |") + return "\n".join(lines) + + def as_html(self) -> str: + rows = "".join( + "" + f"{escape(dimension.value)}" + f"{len(methods)}" + f"{(len(methods) / len(self.declared) if self.declared else 1.0):.2%}" + "" + for dimension, methods in self.dimensions.items() + ) + return ( + '' + "Compatibility report" + f"

PVE {escape(self.source_version)} compatibility

" + "" + f"{rows}
DimensionVerified methodsScore
" + ) + + +def build_report( + snapshot: Snapshot, + *, + implemented: frozenset[MethodKey] = frozenset(), + observed: frozenset[MethodKey] = frozenset(), + verified: frozenset[MethodKey] = frozenset(), + dimensions: Mapping[CompatibilityDimension, frozenset[MethodKey]] = EMPTY_DIMENSION_EVIDENCE, + incompatible: frozenset[MethodKey] = frozenset(), + regressions: frozenset[MethodKey] = frozenset(), +) -> CompatibilityReport: + declared = frozenset( + (path.path, method.verb.upper()) for path in snapshot.paths for method in path.methods + ) + for name, evidence in { + "implemented": implemented, + "observed": observed, + "verified": verified, + "incompatible": incompatible, + "regressions": regressions, + }.items(): + if not evidence <= declared: + raise ValueError(f"{name} evidence references undeclared methods") + resolved_dimensions = { + dimension: frozenset(dimensions.get(dimension, frozenset())) + for dimension in CompatibilityDimension + } + for dimension, evidence in resolved_dimensions.items(): + if not evidence <= declared: + raise ValueError(f"{dimension.value} evidence references undeclared methods") + return CompatibilityReport( + source_version=snapshot.source_version, + declared=declared, + schema_only=declared - implemented, + implemented=implemented, + observed=observed, + verified=verified, + dimensions=MappingProxyType(resolved_dimensions), + incompatible=incompatible, + regressions=regressions, + ) diff --git a/app/config.py b/app/config.py new file mode 100644 index 0000000..0c3cf28 --- /dev/null +++ b/app/config.py @@ -0,0 +1,63 @@ +"""Typed application configuration.""" + +from __future__ import annotations + +from functools import lru_cache +from pathlib import Path +from typing import Literal + +from pydantic import Field, SecretStr +from pydantic_settings import BaseSettings, SettingsConfigDict + + +class Settings(BaseSettings): + """Runtime settings loaded from environment variables and an optional `.env`.""" + + model_config = SettingsConfigDict( + env_file=".env", + env_file_encoding="utf-8", + extra="ignore", + frozen=True, + ) + + app_name: str = "vmware-api-simulator" + app_host: str = "0.0.0.0" # noqa: S104 - the container must accept external traffic + # Internal listen port. Public vCenter HTTPS is published by api-gateway. + app_port: int = Field(default=8080, ge=1, le=65535) + database_url: SecretStr = SecretStr( + "postgresql://vmware:vmware@localhost:5432/vmware_simulator" + ) + db_pool_min_size: int = Field(default=1, ge=1, le=100) + db_pool_max_size: int = Field(default=10, ge=1, le=100) + db_connect_timeout_seconds: float = Field(default=10.0, gt=0, le=60) + db_command_timeout_seconds: float = Field(default=30.0, gt=0, le=300) + log_level: str = "INFO" + request_id_header: str = "X-Request-ID" + # Proxmox /api2 stub plane is off by default — native vSphere /api + /sdk is primary. + enable_pve_stub: bool = False + contract_snapshot: Path | None = None + compatibility_evidence: Path | None = None + contract_fallback: Literal["error", "schema-default", "fixture"] = "error" + catalog_artifact_url_6: str = "stub://vmware/vsphere-7.0/api-contract" + catalog_artifact_url_7: str = "stub://vmware/vsphere-7.0u3/api-contract" + catalog_artifact_url_8: str = "stub://vmware/vsphere-8.0/api-contract" + catalog_artifact_url_9: str = "stub://vmware/vsphere-8.0u2/api-contract" + ticket_signing_key: SecretStr = SecretStr("development-only-signing-key-change-me") + task_worker_concurrency: int = Field(default=2, ge=1, le=32) + task_lease_seconds: float = Field(default=30.0, gt=1, le=300) + simulation_time_scale: float = Field(default=10.0, gt=0, le=10000) + + def catalog_artifact_urls(self) -> dict[int, str]: + return { + 6: self.catalog_artifact_url_6, + 7: self.catalog_artifact_url_7, + 8: self.catalog_artifact_url_8, + 9: self.catalog_artifact_url_9, + } + + +@lru_cache(maxsize=1) +def get_settings() -> Settings: + """Return the immutable process configuration.""" + + return Settings() diff --git a/app/contracts/__init__.py b/app/contracts/__init__.py new file mode 100644 index 0000000..3af4470 --- /dev/null +++ b/app/contracts/__init__.py @@ -0,0 +1 @@ +"""Authoritative API contract ingestion and normalization.""" diff --git a/app/contracts/cli.py b/app/contracts/cli.py new file mode 100644 index 0000000..3ad3859 --- /dev/null +++ b/app/contracts/cli.py @@ -0,0 +1,87 @@ +"""Command-line interface for contract imports and inspection.""" + +from __future__ import annotations + +import argparse +import asyncio +import json +from datetime import UTC, datetime +from pathlib import Path + +from app.contracts.diff import ( + compare_snapshots, + has_breaking_changes, + render_html, + render_json, + render_markdown, + render_text, +) +from app.contracts.importer import RemoteSourceImporter +from app.contracts.model import Snapshot +from app.contracts.normalize import normalize_snapshot +from app.contracts.source import ApiViewerParser, LocalFileImporter, SourceImporter +from app.contracts.store import RevisionStore + + +def parser() -> argparse.ArgumentParser: + root = argparse.ArgumentParser(prog="proxmox-api-contract") + root.add_argument("--store", type=Path, default=Path("contracts")) + commands = root.add_subparsers(dest="command", required=True) + import_command = commands.add_parser("import") + source = import_command.add_mutually_exclusive_group(required=True) + source.add_argument("--file", type=Path) + source.add_argument("--url") + import_command.add_argument("--version", required=True) + validate = commands.add_parser("validate") + validate.add_argument("file", type=Path) + commands.add_parser("list") + show = commands.add_parser("show") + show.add_argument("revision") + diff = commands.add_parser("diff") + diff.add_argument("before", type=Path) + diff.add_argument("after", type=Path) + diff.add_argument("--format", choices=("text", "json", "markdown", "html"), default="text") + return root + + +async def run(arguments: argparse.Namespace) -> int: + store = RevisionStore(arguments.store) + if arguments.command == "list": + for revision in store.list(): + print(revision) + return 0 + if arguments.command == "show": + print(json.dumps(store.manifest(arguments.revision).model_dump(mode="json"), indent=2)) + return 0 + if arguments.command == "diff": + before = Snapshot.model_validate_json(arguments.before.read_bytes()) + after = Snapshot.model_validate_json(arguments.after.read_bytes()) + changes = compare_snapshots(before, after) + renderers = { + "text": render_text, + "json": render_json, + "markdown": render_markdown, + "html": render_html, + } + print(renderers[arguments.format](changes)) + return 1 if has_breaking_changes(changes) else 0 + if arguments.command == "validate": + parsed = ApiViewerParser().parse(arguments.file.read_bytes()) + print(json.dumps({"nodes": len(parsed.nodes), "warnings": len(parsed.warnings)})) + return 0 + importer: SourceImporter + if arguments.file is not None: + importer = LocalFileImporter(arguments.file) + else: + importer = RemoteSourceImporter(arguments.url) + raw = await importer.load() + parsed = ApiViewerParser().parse(raw) + snapshot, manifest = normalize_snapshot( + parsed, raw=raw, source_version=arguments.version, retrieved_at=datetime.now(UTC) + ) + print(store.save(raw, snapshot, manifest)) + return 0 + + +def main() -> None: + raise SystemExit(asyncio.run(run(parser().parse_args()))) diff --git a/app/contracts/diff.py b/app/contracts/diff.py new file mode 100644 index 0000000..3b2e441 --- /dev/null +++ b/app/contracts/diff.py @@ -0,0 +1,224 @@ +"""Deterministic semantic differences between normalized snapshots.""" + +from __future__ import annotations + +import html +import json +from dataclasses import dataclass +from enum import StrEnum +from typing import Any + +from app.contracts.model import Method, Parameter, PathContract, Snapshot + + +class Severity(StrEnum): + BREAKING = "breaking" + NON_BREAKING = "non-breaking" + DOCUMENTATION = "documentation" + + +@dataclass(frozen=True, slots=True, order=True) +class Change: + path: str + method: str + category: str + severity: Severity + detail: str + before: str | None = None + after: str | None = None + + +def _stable(value: Any) -> str: + return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + + +def _methods(snapshot: Snapshot) -> dict[tuple[str, str], Method]: + return {(path.path, method.verb): method for path in snapshot.paths for method in path.methods} + + +def _paths(snapshot: Snapshot) -> dict[str, PathContract]: + return {path.path: path for path in snapshot.paths} + + +def compare_snapshots(before: Snapshot, after: Snapshot) -> tuple[Change, ...]: + changes: list[Change] = [] + old_paths, new_paths = _paths(before), _paths(after) + for path in sorted(old_paths.keys() - new_paths.keys()): + changes.append(Change(path, "", "path", Severity.BREAKING, "path removed")) + for path in sorted(new_paths.keys() - old_paths.keys()): + changes.append(Change(path, "", "path", Severity.NON_BREAKING, "path added")) + + old_methods, new_methods = _methods(before), _methods(after) + for path, verb in sorted(old_methods.keys() - new_methods.keys()): + changes.append(Change(path, verb, "method", Severity.BREAKING, "method removed")) + for path, verb in sorted(new_methods.keys() - old_methods.keys()): + changes.append(Change(path, verb, "method", Severity.NON_BREAKING, "method added")) + for key in sorted(old_methods.keys() & new_methods.keys()): + _compare_method(key, old_methods[key], new_methods[key], changes) + return tuple(sorted(changes)) + + +def _compare_method( + key: tuple[str, str], before: Method, after: Method, changes: list[Change] +) -> None: + path, verb = key + if before.description != after.description: + changes.append( + Change( + path, + verb, + "documentation", + Severity.DOCUMENTATION, + "description changed", + before.description, + after.description, + ) + ) + if before.permissions != after.permissions: + changes.append( + Change( + path, + verb, + "permissions", + Severity.BREAKING, + "permissions changed", + _stable(before.permissions.model_dump(mode="json") if before.permissions else None), + _stable(after.permissions.model_dump(mode="json") if after.permissions else None), + ) + ) + _compare_parameters(path, verb, before.parameters, after.parameters, changes) + _compare_schema( + path, + verb, + "returns", + before.returns.model_dump(mode="json"), + after.returns.model_dump(mode="json"), + changes, + ) + + +def _compare_parameters( + path: str, + verb: str, + before: tuple[Parameter, ...], + after: tuple[Parameter, ...], + changes: list[Change], +) -> None: + old = {parameter.name: parameter for parameter in before} + new = {parameter.name: parameter for parameter in after} + for name in sorted(old.keys() - new.keys()): + changes.append(Change(path, verb, "parameter", Severity.BREAKING, f"removed: {name}")) + for name in sorted(new.keys() - old.keys()): + severity = Severity.NON_BREAKING if new[name].definition.optional else Severity.BREAKING + changes.append(Change(path, verb, "parameter", severity, f"added: {name}")) + for name in sorted(old.keys() & new.keys()): + _compare_schema( + path, + verb, + f"parameter:{name}", + old[name].definition.model_dump(mode="json"), + new[name].definition.model_dump(mode="json"), + changes, + ) + + +def _compare_schema( + path: str, + verb: str, + label: str, + before: dict[str, Any], + after: dict[str, Any], + changes: list[Change], +) -> None: + groups = { + "schema": {"type", "properties", "items", "enum", "format", "pattern"}, + "default": {"default", "optional"}, + "constraint": {"minimum", "maximum", "min_length", "max_length"}, + "documentation": {"description"}, + } + for category, fields in groups.items(): + old = {field: before.get(field) for field in fields} + new = {field: after.get(field) for field in fields} + if old != new: + severity = Severity.DOCUMENTATION if category == "documentation" else Severity.BREAKING + changes.append( + Change( + path, + verb, + category, + severity, + f"{label} {category} changed", + _stable(old), + _stable(new), + ) + ) + + +def render_json(changes: tuple[Change, ...]) -> str: + return json.dumps( + [ + { + "after": change.after, + "before": change.before, + "category": change.category, + "detail": change.detail, + "method": change.method, + "path": change.path, + "severity": change.severity, + } + for change in changes + ], + ensure_ascii=False, + indent=2, + ) + + +def render_text(changes: tuple[Change, ...]) -> str: + return "\n".join( + ( + f"{change.severity}: {change.method} {change.path} [{change.category}] {change.detail}" + ).strip() + for change in changes + ) + + +def render_markdown(changes: tuple[Change, ...]) -> str: + lines = [ + "# API contract diff", + "", + "| Severity | Method | Path | Category | Detail |", + "|---|---|---|---|---|", + ] + lines.extend( + ( + f"| {change.severity} | {change.method} | `{change.path}` | " + f"{change.category} | {change.detail} |" + ) + for change in changes + ) + return "\n".join(lines) + + +def render_html(changes: tuple[Change, ...]) -> str: + rows = "".join( + "" + + "".join( + f"{html.escape(str(value))}" + for value in ( + change.severity, + change.method, + change.path, + change.category, + change.detail, + ) + ) + + "" + for change in changes + ) + return ( + f"API contract diff{rows}
" + ) + + +def has_breaking_changes(changes: tuple[Change, ...]) -> bool: + return any(change.severity is Severity.BREAKING for change in changes) diff --git a/app/contracts/examples.py b/app/contracts/examples.py new file mode 100644 index 0000000..ce09127 --- /dev/null +++ b/app/contracts/examples.py @@ -0,0 +1,76 @@ +"""Generate example values from Proxmox contract schemas.""" + +from __future__ import annotations + +from app.contracts.model import Schema + +_PATH_PARAM_EXAMPLES: dict[str, object] = { + "node": "pve01", + "vmid": 100, + "storage": "local", + "pool": "testpool", + "userid": "root@pam", + "tokenid": "automation", + "realm": "pam", + "group": "admins", + "role": "Administrator", + "upid": "UPID:pve01:00000001:00000001:65000001:qmstart:100:root@pam:", + "snapname": "snap1", + "volume": "local:100/vm-100-disk-0.qcow2", + "disk": "scsi0", + "iface": "net0", + "key": "cpu", + "digest": "00000000", + "name": "example", +} + + +def path_param_example(name: str) -> object | None: + """Return a realistic placeholder for a common Proxmox path parameter.""" + + return _PATH_PARAM_EXAMPLES.get(name) + + +def schema_example(schema: Schema, *, name: str | None = None) -> object: + """Build a representative example value for a contract schema.""" + + if schema.default is not None: + return schema.default + if schema.enum: + return schema.enum[0] + if name is not None: + hinted = path_param_example(name) + if hinted is not None: + return hinted + if "[n]" in name: + indexed = name.replace("[n]", "0") + hinted = path_param_example(indexed.rstrip("0123456789")) + if hinted is not None: + return hinted + if schema.type == "array": + if schema.items is not None: + return [schema_example(schema.items)] + return [] + if schema.type == "object": + return { + key: schema_example(definition, name=key) + for key, definition in schema.properties.items() + if not definition.optional + } + if schema.type == "boolean": + return False + if schema.type == "integer": + if schema.minimum is not None: + return int(schema.minimum) + return 1 + if schema.type == "number": + if schema.minimum is not None: + return float(schema.minimum) + return 1.0 + if schema.type == "string" or schema.type is None: + if schema.format == "email": + return "user@example.com" + if schema.format == "uri": + return "https://example.com" + return "example" + return None diff --git a/app/contracts/importer.py b/app/contracts/importer.py new file mode 100644 index 0000000..c65911a --- /dev/null +++ b/app/contracts/importer.py @@ -0,0 +1,110 @@ +"""Network-constrained remote contract retrieval.""" + +from __future__ import annotations + +import asyncio +import ipaddress +import socket +from collections.abc import Awaitable, Callable +from dataclasses import dataclass +from urllib.parse import urljoin, urlsplit + +import httpx + +from app.contracts.source import SourceError + +Resolver = Callable[[str], Awaitable[tuple[str, ...]]] + + +async def resolve_host(host: str) -> tuple[str, ...]: + loop = asyncio.get_running_loop() + results = await loop.getaddrinfo(host, 443, type=socket.SOCK_STREAM) + return tuple(sorted({str(result[4][0]) for result in results})) + + +def validate_remote_url(url: str, allowed_hosts: frozenset[str]) -> str: + parsed = urlsplit(url) + if parsed.scheme != "https": + raise SourceError("remote imports require HTTPS") + if parsed.username or parsed.password or parsed.port not in (None, 443): + raise SourceError("remote URL contains forbidden authority components") + host = (parsed.hostname or "").rstrip(".").lower() + if host not in allowed_hosts: + raise SourceError("remote host is not in the official-domain allowlist") + if parsed.fragment: + raise SourceError("remote URL fragments are not allowed") + return host + + +# Fake-IP pools used by local proxies (Clash, Surge, etc.) still route to public hosts. +_FAKE_IP_NETWORK = ipaddress.ip_network("198.18.0.0/15") + + +def _is_allowed_resolved_address(address: ipaddress.IPv4Address | ipaddress.IPv6Address) -> bool: + if address.is_global: + return True + mapped = address.ipv4_mapped if isinstance(address, ipaddress.IPv6Address) else None + if mapped is not None and mapped in _FAKE_IP_NETWORK: + return True + if isinstance(address, ipaddress.IPv4Address) and address in _FAKE_IP_NETWORK: + return True + return False + + +def validate_public_addresses(addresses: tuple[str, ...]) -> None: + if not addresses: + raise SourceError("remote host did not resolve") + for value in addresses: + address = ipaddress.ip_address(value) + if not _is_allowed_resolved_address(address): + raise SourceError(f"remote host resolved to a non-public address: {value}") + + +@dataclass(frozen=True, slots=True) +class RemoteSourceImporter: + url: str + allowed_hosts: frozenset[str] = frozenset({"pve.proxmox.com"}) + max_bytes: int = 16 * 1024 * 1024 + max_redirects: int = 3 + retries: int = 2 + timeout_seconds: float = 20.0 + resolver: Resolver = resolve_host + transport: httpx.AsyncBaseTransport | None = None + + async def load(self) -> bytes: + current = self.url + timeout = httpx.Timeout(self.timeout_seconds) + async with httpx.AsyncClient( + follow_redirects=False, timeout=timeout, transport=self.transport + ) as client: + for redirect_count in range(self.max_redirects + 1): + host = validate_remote_url(current, self.allowed_hosts) + validate_public_addresses(await self.resolver(host)) + response = await self._request(client, current) + if response.is_redirect: + if redirect_count == self.max_redirects: + raise SourceError("remote import exceeded redirect limit") + location = response.headers.get("location") + if not location: + raise SourceError("remote redirect has no location") + current = urljoin(current, location) + continue + response.raise_for_status() + content_length = response.headers.get("content-length") + if content_length and int(content_length) > self.max_bytes: + raise SourceError("remote artifact exceeds size limit") + content = response.content + if len(content) > self.max_bytes: + raise SourceError("remote artifact exceeds size limit") + return content + raise SourceError("remote import failed") + + async def _request(self, client: httpx.AsyncClient, url: str) -> httpx.Response: + for attempt in range(self.retries + 1): + try: + return await client.get(url) + except (httpx.TimeoutException, httpx.NetworkError): + if attempt == self.retries: + raise + await asyncio.sleep(0.1 * (2**attempt)) + raise SourceError("remote import retry loop exhausted") diff --git a/app/contracts/model.py b/app/contracts/model.py new file mode 100644 index 0000000..ee6ba24 --- /dev/null +++ b/app/contracts/model.py @@ -0,0 +1,134 @@ +"""Immutable normalized representation of Proxmox API contracts.""" + +from __future__ import annotations + +import hashlib +import json +from collections.abc import Mapping, Sequence +from datetime import datetime +from typing import Any, Self + +from pydantic import BaseModel, ConfigDict, Field, model_validator + +type JsonValue = None | bool | int | float | str | list[JsonValue] | dict[str, JsonValue] + + +def canonical_json(value: BaseModel | Mapping[str, Any] | Sequence[Any]) -> bytes: + """Serialize a JSON-compatible value deterministically as UTF-8.""" + + data: Any + if isinstance(value, BaseModel): + data = value.model_dump(mode="json", exclude_none=True) + else: + data = value + return json.dumps( + data, + default=_json_default, + ensure_ascii=False, + allow_nan=False, + sort_keys=True, + separators=(",", ":"), + ).encode() + + +def _json_default(value: object) -> Any: + if isinstance(value, BaseModel): + return value.model_dump(mode="json", exclude_none=True) + if isinstance(value, datetime): + return value.isoformat() + raise TypeError(f"{type(value).__name__} is not JSON serializable") + + +def sha256(value: bytes) -> str: + return hashlib.sha256(value).hexdigest() + + +class FrozenModel(BaseModel): + model_config = ConfigDict(frozen=True, extra="forbid") + + +class Schema(FrozenModel): + """Proxmox's JSON-Schema-like dialect with retained extensions.""" + + type: str | None = None + description: str | None = None + properties: dict[str, Schema] = Field(default_factory=dict) + items: Schema | None = None + enum: tuple[JsonValue, ...] = () + optional: bool | None = None + default: JsonValue = None + minimum: int | float | None = None + maximum: int | float | None = None + min_length: int | None = None + max_length: int | None = None + pattern: str | None = None + format: str | dict[str, JsonValue] | None = None + extra: dict[str, JsonValue] = Field(default_factory=dict) + + +class Parameter(FrozenModel): + name: str + definition: Schema + + +class Permissions(FrozenModel): + user: str | None = None + description: str | None = None + expression: dict[str, JsonValue] = Field(default_factory=dict) + extra: dict[str, JsonValue] = Field(default_factory=dict) + + +class Method(FrozenModel): + verb: str + name: str + description: str | None = None + parameters: tuple[Parameter, ...] = () + returns: Schema = Field(default_factory=Schema) + permissions: Permissions | None = None + protected: bool = False + allow_token: bool | None = None + extra: dict[str, JsonValue] = Field(default_factory=dict) + checksum: str + + +class PathContract(FrozenModel): + path: str + methods: tuple[Method, ...] + extra: dict[str, JsonValue] = Field(default_factory=dict) + + +class Snapshot(FrozenModel): + format_version: int = 1 + source_version: str + retrieved_at: datetime + raw_sha256: str + paths: tuple[PathContract, ...] + path_count: int + method_count: int + extra: dict[str, JsonValue] = Field(default_factory=dict) + + @model_validator(mode="after") + def validate_counts_and_uniqueness(self) -> Self: + if self.path_count != len(self.paths): + raise ValueError("path_count does not match paths") + methods = sum(len(path.methods) for path in self.paths) + if self.method_count != methods: + raise ValueError("method_count does not match methods") + keys = [(path.path, method.verb) for path in self.paths for method in path.methods] + if len(keys) != len(set(keys)): + raise ValueError("duplicate path and method") + return self + + def canonical_bytes(self) -> bytes: + return canonical_json(self) + + def checksum(self) -> str: + return sha256(self.canonical_bytes()) + + +class Manifest(FrozenModel): + source_version: str + raw_sha256: str + snapshot_sha256: str + path_count: int + method_count: int diff --git a/app/contracts/normalize.py b/app/contracts/normalize.py new file mode 100644 index 0000000..ae53b76 --- /dev/null +++ b/app/contracts/normalize.py @@ -0,0 +1,168 @@ +"""Normalize parsed API Viewer trees into stable contract models.""" + +from __future__ import annotations + +from collections.abc import Mapping +from datetime import datetime +from typing import Any, cast + +from app.contracts.model import ( + JsonValue, + Manifest, + Method, + Parameter, + PathContract, + Permissions, + Schema, + Snapshot, + canonical_json, + sha256, +) +from app.contracts.source import ParsedSource + +SCHEMA_FIELDS = { + "type", + "description", + "properties", + "items", + "enum", + "optional", + "default", + "minimum", + "maximum", + "minLength", + "maxLength", + "pattern", + "format", +} +METHOD_FIELDS = { + "allowtoken", + "description", + "method", + "name", + "parameters", + "permissions", + "protected", + "returns", +} + + +def _json(value: Any) -> JsonValue: + return cast(JsonValue, value) + + +def normalize_schema(raw: Mapping[str, Any] | None) -> Schema: + source = raw or {} + properties = source.get("properties") or {} + normalized_properties = { + str(name): normalize_schema(cast(Mapping[str, Any], schema)) + for name, schema in cast(Mapping[str, Any], properties).items() + } + items = source.get("items") + extra = {key: _json(value) for key, value in source.items() if key not in SCHEMA_FIELDS} + return Schema( + type=source.get("type"), + description=source.get("description"), + properties=normalized_properties, + items=normalize_schema(cast(Mapping[str, Any], items)) + if isinstance(items, Mapping) + else None, + enum=tuple(_json(value) for value in (source.get("enum") or ())), + optional=bool(source["optional"]) if "optional" in source else None, + default=_json(source.get("default")), + minimum=source.get("minimum"), + maximum=source.get("maximum"), + min_length=source.get("minLength"), + max_length=source.get("maxLength"), + pattern=source.get("pattern"), + format=_json(source.get("format")), + extra=extra, + ) + + +def normalize_permissions(raw: Mapping[str, Any] | None) -> Permissions | None: + if raw is None: + return None + known = {"user", "description"} + expression_keys = {"and", "or", "check", "userParam"} + return Permissions( + user=raw.get("user"), + description=raw.get("description"), + expression={key: _json(raw[key]) for key in expression_keys if key in raw}, + extra={ + key: _json(value) for key, value in raw.items() if key not in known | expression_keys + }, + ) + + +def normalize_method(verb: str, raw: Mapping[str, Any]) -> Method: + parameters_raw = cast(Mapping[str, Any], raw.get("parameters") or {}).get("properties") or {} + parameters = tuple( + Parameter(name=str(name), definition=normalize_schema(cast(Mapping[str, Any], schema))) + for name, schema in sorted(cast(Mapping[str, Any], parameters_raw).items()) + ) + values: dict[str, Any] = { + "verb": verb.upper(), + "name": str(raw.get("name", verb.lower())), + "description": raw.get("description"), + "parameters": parameters, + "returns": normalize_schema(cast(Mapping[str, Any] | None, raw.get("returns"))), + "permissions": normalize_permissions( + cast(Mapping[str, Any] | None, raw.get("permissions")) + ), + "protected": bool(raw.get("protected", False)), + "allow_token": bool(raw["allowtoken"]) if "allowtoken" in raw else None, + "extra": {key: _json(value) for key, value in raw.items() if key not in METHOD_FIELDS}, + } + checksum = sha256(canonical_json(values)) + return Method(**values, checksum=checksum) + + +def _walk(nodes: tuple[dict[str, Any], ...]) -> list[PathContract]: + paths: list[PathContract] = [] + + def visit(node: Mapping[str, Any]) -> None: + info = node.get("info") + path = node.get("path") + if isinstance(info, Mapping) and isinstance(path, str): + methods = tuple( + normalize_method(str(verb), cast(Mapping[str, Any], method)) + for verb, method in sorted(info.items()) + if isinstance(method, Mapping) + ) + extra = { + key: _json(value) + for key, value in node.items() + if key not in {"children", "info", "leaf", "path", "text"} + } + paths.append(PathContract(path=path, methods=methods, extra=extra)) + for child in node.get("children", ()): + if isinstance(child, Mapping): + visit(child) + + for root in nodes: + visit(root) + return sorted(paths, key=lambda item: item.path) + + +def normalize_snapshot( + parsed: ParsedSource, *, raw: bytes, source_version: str, retrieved_at: datetime +) -> tuple[Snapshot, Manifest]: + paths = tuple(_walk(parsed.nodes)) + snapshot = Snapshot( + source_version=source_version, + retrieved_at=retrieved_at, + raw_sha256=sha256(raw), + paths=paths, + path_count=len(paths), + method_count=sum(len(path.methods) for path in paths), + extra={"warning_count": len(parsed.warnings)}, + ) + manifest = Manifest( + source_version=source_version, + raw_sha256=snapshot.raw_sha256, + snapshot_sha256=snapshot.checksum(), + path_count=snapshot.path_count, + method_count=snapshot.method_count, + ) + return snapshot, manifest diff --git a/app/contracts/runtime.py b/app/contracts/runtime.py new file mode 100644 index 0000000..faba4e8 --- /dev/null +++ b/app/contracts/runtime.py @@ -0,0 +1,210 @@ +"""In-memory runtime contract hot-swap helpers.""" + +from __future__ import annotations + +import asyncio +from pathlib import Path +from typing import Any, cast + +from fastapi import FastAPI, Request, Response +from starlette.routing import Route + +from app.api.registry import ( + FallbackMode, + HandlerRegistry, + register_contract_routes, + register_legacy_handler_routes, +) +from app.compatibility import ( + CompatibilityDimension, + CompatibilityReport, + build_report, + load_evidence_manifest, + resolve_evidence_path, +) +from app.config import Settings +from app.contracts.model import Snapshot + +_ADMIN_ROUTE_NAMES = frozenset( + { + "admin:compatibility", + "admin:compatibility.md", + "admin:compatibility.html", + } +) + + +def clear_contract_routes(app: FastAPI) -> None: + """Drop previously registered contract (and optional admin) routes for rebuild.""" + + app.router.routes = [route for route in app.router.routes if not _is_swappable_route(route)] + app.openapi_schema = None + + +def _is_swappable_route(route: object) -> bool: + name = getattr(route, "name", None) + if not isinstance(name, str): + return False + return name.startswith("contract:") or name in _ADMIN_ROUTE_NAMES + + +def build_compatibility_for_snapshot( + snapshot: Snapshot, + handlers: HandlerRegistry, + settings: Settings, + *, + require_evidence_match: bool = False, +) -> CompatibilityReport: + """Build a compatibility report for the active primary snapshot. + + Evidence is resolved per ``snapshot.source_version`` + (``evidence/pve-{version}.json``). When ``require_evidence_match`` is true + (cold start) a missing or mismatched ledger raises. + """ + + declared = frozenset( + (path.path, method.verb.upper()) for path in snapshot.paths for method in path.methods + ) + dimensions: dict[CompatibilityDimension, frozenset[tuple[str, str]]] = { + CompatibilityDimension.ROUTE_METHOD: declared, + } + observed: frozenset[tuple[str, str]] = frozenset() + verified: frozenset[tuple[str, str]] = frozenset() + evidence_path = resolve_evidence_path(snapshot.source_version, settings) + if evidence_path is not None: + evidence = load_evidence_manifest(evidence_path) + if evidence.source_version != snapshot.source_version: + if require_evidence_match: + raise ValueError("compatibility evidence version does not match contract") + else: + dimensions.update(evidence.dimension_map()) + dimensions[CompatibilityDimension.ROUTE_METHOD] = declared + observed = evidence.observed_methods() & declared + verified = evidence.verified_methods() & declared + implemented_all = frozenset(handlers.keys()) + return build_report( + snapshot, + implemented=implemented_all & declared, + observed=observed, + verified=verified, + dimensions=dimensions, + ) + + +def apply_runtime_contract( + app: FastAPI, + snapshot: Snapshot, + *, + handlers: HandlerRegistry, + store_root: Path, + fallback: FallbackMode, + settings: Settings, + require_evidence_match: bool = False, + register_admin: bool = True, +) -> CompatibilityReport: + """Replace `/api2/*` contract routes and refresh runtime app.state fields.""" + + clear_contract_routes(app) + registered = register_contract_routes(app, snapshot, handlers, fallback) + register_legacy_handler_routes( + app, + handlers, + store_root, + fallback, + primary_version=snapshot.source_version, + existing=registered, + ) + report = build_compatibility_for_snapshot( + snapshot, + handlers, + settings, + require_evidence_match=require_evidence_match, + ) + implemented_all = frozenset(handlers.keys()) + app.state.runtime_snapshot = snapshot + app.state.runtime_source_version = snapshot.source_version + app.state.handlers = handlers + app.state.contract_store_root = store_root + app.state.implemented_methods = implemented_all + app.state.compatibility_report = report + if register_admin: + _ensure_admin_compatibility_routes(app) + return report + + +async def apply_runtime_contract_locked( + app: FastAPI, + snapshot: Snapshot, + *, + handlers: HandlerRegistry, + store_root: Path, + fallback: FallbackMode, + settings: Settings, + require_evidence_match: bool = False, + register_admin: bool = True, +) -> CompatibilityReport: + """Serialize concurrent Apply calls to avoid a torn route table.""" + + lock = getattr(app.state, "contract_swap_lock", None) + if lock is None: + lock = asyncio.Lock() + app.state.contract_swap_lock = lock + async with lock: + return apply_runtime_contract( + app, + snapshot, + handlers=handlers, + store_root=store_root, + fallback=fallback, + settings=settings, + require_evidence_match=require_evidence_match, + register_admin=register_admin, + ) + + +def contract_store_root(settings: Settings) -> Path: + """Resolve the revision store root next to ``CONTRACT_SNAPSHOT``.""" + + if settings.contract_snapshot is None: + return Path("contracts") + snapshot_path = settings.contract_snapshot.resolve() + if snapshot_path.name == "snapshot.json" and (snapshot_path.parent / "manifest.json").is_file(): + return snapshot_path.parent.parent + return snapshot_path.parent + + +def runtime_version_payload(request: Request) -> dict[str, str]: + """Proxmox-shaped version payload derived from the active runtime contract.""" + + version = getattr(request.app.state, "runtime_source_version", None) or "0.0" + release = str(version).split("-", 1)[0] + if release.count(".") >= 2: + release = ".".join(release.split(".")[:2]) + return {"version": str(version), "release": release, "repoid": "simulator"} + + +def _ensure_admin_compatibility_routes(app: FastAPI) -> None: + existing = { + getattr(route, "name", None) for route in app.router.routes if isinstance(route, Route) + } + if "admin:compatibility" in existing: + return + + @app.get("/admin/compatibility", include_in_schema=False, name="admin:compatibility") + async def compatibility_report(request: Request) -> dict[str, Any]: + report = getattr(request.app.state, "compatibility_report", None) + if report is None: + return {} + return cast(dict[str, Any], report.as_json()) + + @app.get("/admin/compatibility.md", include_in_schema=False, name="admin:compatibility.md") + async def compatibility_report_markdown(request: Request) -> Response: + report = getattr(request.app.state, "compatibility_report", None) + body = report.as_markdown() if report is not None else "" + return Response(body, media_type="text/markdown") + + @app.get("/admin/compatibility.html", include_in_schema=False, name="admin:compatibility.html") + async def compatibility_report_html(request: Request) -> Response: + report = getattr(request.app.state, "compatibility_report", None) + body = report.as_html() if report is not None else "" + return Response(body, media_type="text/html") diff --git a/app/contracts/source.py b/app/contracts/source.py new file mode 100644 index 0000000..df87ac0 --- /dev/null +++ b/app/contracts/source.py @@ -0,0 +1,154 @@ +"""Safe source adapters for Proxmox API Viewer artifacts.""" + +from __future__ import annotations + +import json +from collections.abc import Mapping +from dataclasses import dataclass +from pathlib import Path +from typing import Any, Protocol, cast + + +class SourceError(ValueError): + """Raised when an API source cannot be parsed safely.""" + + +@dataclass(frozen=True, slots=True) +class ParseWarning: + """A recoverable variation found in a source artifact.""" + + code: str + path: str + message: str + + +@dataclass(frozen=True, slots=True) +class ParsedSource: + """Parsed source tree with non-fatal diagnostics.""" + + nodes: tuple[dict[str, Any], ...] + warnings: tuple[ParseWarning, ...] = () + + +class SourceImporter(Protocol): + """Asynchronous boundary for obtaining source artifact bytes.""" + + async def load(self) -> bytes: ... + + +@dataclass(frozen=True, slots=True) +class LocalFileImporter: + """Load an artifact from a caller-selected local path.""" + + path: Path + + async def load(self) -> bytes: + return self.path.read_bytes() + + +class ApiViewerParser: + """Extract the JSON-compatible schema value without executing JS.""" + + declarations = (b"const apiSchema", b"var pveapi") + known_node_fields = frozenset({"children", "info", "leaf", "path", "text"}) + + def parse(self, raw: bytes) -> ParsedSource: + if not raw.strip(): + raise SourceError("source artifact is empty") + + payload = self._extract_payload(raw) + try: + decoded = json.loads(payload) + except (UnicodeDecodeError, json.JSONDecodeError) as exc: + raise SourceError(f"invalid apiSchema JSON: {exc}") from exc + + if isinstance(decoded, Mapping): + raw_nodes = [decoded] + elif isinstance(decoded, list): + raw_nodes = decoded + else: + raise SourceError("apiSchema must be an object or array of objects") + + nodes: list[dict[str, Any]] = [] + warnings: list[ParseWarning] = [] + for index, value in enumerate(raw_nodes): + if not isinstance(value, Mapping): + raise SourceError(f"apiSchema node /{index} must be an object") + node = cast(dict[str, Any], dict(value)) + nodes.append(node) + self._inspect_node(node, f"/{index}", warnings) + return ParsedSource(tuple(nodes), tuple(warnings)) + + def _extract_payload(self, raw: bytes) -> bytes: + stripped = raw.strip() + if stripped.startswith((b"[", b"{")): + return stripped + + for declaration in self.declarations: + declaration_at = raw.find(declaration) + if declaration_at < 0: + continue + equals_at = raw.find(b"=", declaration_at + len(declaration)) + if equals_at < 0: + raise SourceError("apiSchema declaration has no assignment") + + start = self._next_non_space(raw, equals_at + 1) + if start >= len(raw) or raw[start] not in b"[{": + raise SourceError("apiSchema assignment must start with an array or object") + end = self._matching_end(raw, start) + return raw[start : end + 1] + + raise SourceError("apiSchema declaration was not found") + + @staticmethod + def _next_non_space(raw: bytes, start: int) -> int: + while start < len(raw) and raw[start] in b" \t\r\n": + start += 1 + return start + + @staticmethod + def _matching_end(raw: bytes, start: int) -> int: + opening = raw[start] + closing = ord("]") if opening == ord("[") else ord("}") + depth = 0 + in_string = False + escaped = False + for index in range(start, len(raw)): + byte = raw[index] + if in_string: + if escaped: + escaped = False + elif byte == ord("\\"): + escaped = True + elif byte == ord('"'): + in_string = False + continue + if byte == ord('"'): + in_string = True + elif byte == opening: + depth += 1 + elif byte == closing: + depth -= 1 + if depth == 0: + return index + raise SourceError("apiSchema assignment is truncated") + + def _inspect_node( + self, node: Mapping[str, Any], path: str, warnings: list[ParseWarning] + ) -> None: + for field in sorted(node.keys() - self.known_node_fields): + warnings.append( + ParseWarning("unknown-node-field", f"{path}/{field}", "field was preserved") + ) + children = node.get("children", []) + if not isinstance(children, list): + warnings.append( + ParseWarning("invalid-children", f"{path}/children", "expected an array") + ) + return + for index, child in enumerate(children): + child_path = f"{path}/children/{index}" + if isinstance(child, Mapping): + self._inspect_node(child, child_path, warnings) + else: + warnings.append(ParseWarning("invalid-child", child_path, "expected an object")) diff --git a/app/contracts/store.py b/app/contracts/store.py new file mode 100644 index 0000000..a1bd4d0 --- /dev/null +++ b/app/contracts/store.py @@ -0,0 +1,48 @@ +"""Immutable filesystem storage for imported contract revisions.""" + +from __future__ import annotations + +import os +import tempfile +from dataclasses import dataclass +from pathlib import Path + +from app.contracts.model import Manifest, Snapshot, canonical_json + + +@dataclass(frozen=True, slots=True) +class RevisionStore: + root: Path + + def save(self, raw: bytes, snapshot: Snapshot, manifest: Manifest) -> Path: + revision = self.root / manifest.snapshot_sha256 + if revision.exists(): + return revision + self.root.mkdir(parents=True, exist_ok=True) + temporary = Path(tempfile.mkdtemp(prefix=".import-", dir=self.root)) + try: + self._write(temporary / "raw.js", raw) + self._write(temporary / "snapshot.json", snapshot.canonical_bytes()) + self._write(temporary / "manifest.json", canonical_json(manifest)) + os.replace(temporary, revision) + except BaseException: + for child in temporary.iterdir(): + child.unlink() + temporary.rmdir() + raise + return revision + + def list(self) -> tuple[str, ...]: + if not self.root.exists(): + return () + return tuple(sorted(path.name for path in self.root.iterdir() if path.is_dir())) + + def manifest(self, revision: str) -> Manifest: + return Manifest.model_validate_json((self.root / revision / "manifest.json").read_bytes()) + + @staticmethod + def _write(path: Path, content: bytes) -> None: + with path.open("xb") as stream: + stream.write(content) + stream.flush() + os.fsync(stream.fileno()) diff --git a/app/db/__init__.py b/app/db/__init__.py new file mode 100644 index 0000000..89fa222 --- /dev/null +++ b/app/db/__init__.py @@ -0,0 +1 @@ +"""PostgreSQL infrastructure.""" diff --git a/app/db/migrate_cli.py b/app/db/migrate_cli.py new file mode 100644 index 0000000..9af318f --- /dev/null +++ b/app/db/migrate_cli.py @@ -0,0 +1,16 @@ +"""Apply configured database migrations.""" + +import asyncio + +from app.config import get_settings +from app.db.migrations import migrate_url + + +async def run() -> None: + settings = get_settings() + count = await migrate_url(settings.database_url.get_secret_value()) + print(f"applied {count} migration(s)") + + +if __name__ == "__main__": + asyncio.run(run()) diff --git a/app/db/migrations.py b/app/db/migrations.py new file mode 100644 index 0000000..4c450f1 --- /dev/null +++ b/app/db/migrations.py @@ -0,0 +1,70 @@ +"""Checksummed asynchronous PostgreSQL migration runner.""" + +from __future__ import annotations + +import hashlib +from dataclasses import dataclass +from pathlib import Path + +import asyncpg # type: ignore[import-untyped] +from asyncpg import Connection + + +class MigrationError(RuntimeError): + pass + + +@dataclass(frozen=True, slots=True) +class Migration: + version: int + name: str + sql: str + checksum: str + + +def load_migrations(root: Path | None = None) -> tuple[Migration, ...]: + directory = root or Path(__file__).with_name("migrations") + migrations = [] + for path in sorted(directory.glob("[0-9][0-9][0-9]_*.sql")): + version = int(path.name.split("_", 1)[0]) + sql = path.read_text() + migrations.append( + Migration(version, path.stem, sql, hashlib.sha256(sql.encode()).hexdigest()) + ) + return tuple(migrations) + + +async def migrate(connection: Connection, migrations: tuple[Migration, ...] | None = None) -> int: + await connection.execute( + """CREATE TABLE IF NOT EXISTS schema_migrations ( + version integer PRIMARY KEY, name text NOT NULL, checksum text NOT NULL, + applied_at timestamptz NOT NULL DEFAULT now())""" + ) + applied = { + int(row["version"]): str(row["checksum"]) + for row in await connection.fetch("SELECT version, checksum FROM schema_migrations") + } + count = 0 + for migration in migrations or load_migrations(): + if migration.version in applied: + if applied[migration.version] != migration.checksum: + raise MigrationError(f"migration {migration.version} checksum mismatch") + continue + async with connection.transaction(): + await connection.execute(migration.sql) + await connection.execute( + "INSERT INTO schema_migrations(version, name, checksum) VALUES($1, $2, $3)", + migration.version, + migration.name, + migration.checksum, + ) + count += 1 + return count + + +async def migrate_url(database_url: str) -> int: + connection = await asyncpg.connect(database_url) + try: + return await migrate(connection) + finally: + await connection.close() diff --git a/app/db/migrations/001_initial.sql b/app/db/migrations/001_initial.sql new file mode 100644 index 0000000..9a7843f --- /dev/null +++ b/app/db/migrations/001_initial.sql @@ -0,0 +1,60 @@ +CREATE TABLE contract_snapshots ( + checksum text PRIMARY KEY, + source_version text NOT NULL, + document jsonb NOT NULL, + created_at timestamptz NOT NULL DEFAULT now() +); +CREATE TABLE nodes ( + id uuid PRIMARY KEY, + name text NOT NULL UNIQUE, + status text NOT NULL CHECK (status IN ('online', 'offline')) +); +CREATE TABLE resources ( + id uuid PRIMARY KEY, + node_id uuid NOT NULL REFERENCES nodes(id) ON DELETE RESTRICT, + kind text NOT NULL, + external_id text NOT NULL, + state jsonb NOT NULL DEFAULT '{}'::jsonb, + UNIQUE (kind, external_id) +); +CREATE INDEX resources_node_id_idx ON resources(node_id); +CREATE TABLE principals ( + id uuid PRIMARY KEY, + name text NOT NULL UNIQUE, + password_hash text +); +CREATE TABLE roles ( + name text PRIMARY KEY, + privileges text[] NOT NULL DEFAULT '{}' +); +CREATE TABLE acl_entries ( + principal_id uuid NOT NULL REFERENCES principals(id) ON DELETE CASCADE, + role_name text NOT NULL REFERENCES roles(name) ON DELETE RESTRICT, + path text NOT NULL, + propagate boolean NOT NULL DEFAULT true, + PRIMARY KEY (principal_id, role_name, path) +); +CREATE TABLE tasks ( + id uuid PRIMARY KEY, + upid text NOT NULL UNIQUE, + status text NOT NULL, + payload jsonb NOT NULL, + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now() +); +CREATE INDEX tasks_status_created_idx ON tasks(status, created_at); +CREATE TABLE scenarios ( + id uuid PRIMARY KEY, + name text NOT NULL UNIQUE, + definition jsonb NOT NULL, + enabled boolean NOT NULL DEFAULT true +); +CREATE TABLE audit_events ( + id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY, + occurred_at timestamptz NOT NULL DEFAULT now(), + principal text, + action text NOT NULL, + target text, + details jsonb NOT NULL DEFAULT '{}'::jsonb +); +CREATE INDEX audit_events_occurred_idx ON audit_events(occurred_at); diff --git a/app/db/migrations/002_identity_realms_tokens.sql b/app/db/migrations/002_identity_realms_tokens.sql new file mode 100644 index 0000000..8e797c5 --- /dev/null +++ b/app/db/migrations/002_identity_realms_tokens.sql @@ -0,0 +1,16 @@ +CREATE TABLE realms ( + name text PRIMARY KEY, + kind text NOT NULL CHECK (kind IN ('pam', 'pve', 'openid', 'ldap')) +); +INSERT INTO realms(name, kind) VALUES ('pam', 'pam'), ('pve', 'pve'); +ALTER TABLE principals ADD COLUMN realm_name text REFERENCES realms(name) ON DELETE RESTRICT; +CREATE TABLE api_tokens ( + principal_id uuid NOT NULL REFERENCES principals(id) ON DELETE CASCADE, + token_id text NOT NULL, + secret_hash text NOT NULL, + privileges text[] NOT NULL DEFAULT '{}', + expires_at timestamptz, + PRIMARY KEY (principal_id, token_id), + CHECK (secret_hash LIKE 'scrypt$%') +); +CREATE INDEX api_tokens_expires_idx ON api_tokens(expires_at) WHERE expires_at IS NOT NULL; diff --git a/app/db/migrations/003_durable_tasks.sql b/app/db/migrations/003_durable_tasks.sql new file mode 100644 index 0000000..927d494 --- /dev/null +++ b/app/db/migrations/003_durable_tasks.sql @@ -0,0 +1,32 @@ +ALTER TABLE tasks + ADD COLUMN task_type text NOT NULL DEFAULT 'generic', + ADD COLUMN progress integer NOT NULL DEFAULT 0 CHECK (progress BETWEEN 0 AND 100), + ADD COLUMN result jsonb, + ADD COLUMN error text, + ADD COLUMN worker_id text, + ADD COLUMN lease_expires_at timestamptz, + ADD COLUMN cancel_requested boolean NOT NULL DEFAULT false, + ADD COLUMN idempotency_key text UNIQUE, + ADD COLUMN attempt integer NOT NULL DEFAULT 0, + ADD CONSTRAINT tasks_status_check CHECK (status IN ('queued', 'running', 'success', 'error', 'cancelled')); +CREATE INDEX tasks_claim_idx ON tasks(status, lease_expires_at, created_at); +CREATE TABLE resource_locks ( + resource_key text PRIMARY KEY, + task_id uuid NOT NULL UNIQUE REFERENCES tasks(id) ON DELETE CASCADE, + acquired_at timestamptz NOT NULL DEFAULT now() +); +CREATE TABLE task_logs ( + task_id uuid NOT NULL REFERENCES tasks(id) ON DELETE CASCADE, + sequence bigint GENERATED ALWAYS AS IDENTITY, + created_at timestamptz NOT NULL DEFAULT now(), + message text NOT NULL, + PRIMARY KEY (task_id, sequence) +); +CREATE TABLE task_events ( + task_id uuid NOT NULL REFERENCES tasks(id) ON DELETE CASCADE, + sequence bigint GENERATED ALWAYS AS IDENTITY, + created_at timestamptz NOT NULL DEFAULT now(), + kind text NOT NULL, + data jsonb NOT NULL DEFAULT '{}'::jsonb, + PRIMARY KEY (task_id, sequence) +); diff --git a/app/db/migrations/004_domain_model.sql b/app/db/migrations/004_domain_model.sql new file mode 100644 index 0000000..494142f --- /dev/null +++ b/app/db/migrations/004_domain_model.sql @@ -0,0 +1,204 @@ +CREATE TABLE clusters ( + id uuid PRIMARY KEY, + external_id text NOT NULL UNIQUE, + name text NOT NULL, + version integer NOT NULL DEFAULT 1, + metadata jsonb NOT NULL DEFAULT '{}'::jsonb, + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now() +); +INSERT INTO clusters(id, external_id, name) +VALUES ('dc760c47-d8d7-57e6-9404-f0c6f2395d8f', 'default', 'pve-simulator'); + +ALTER TABLE nodes + ADD COLUMN cluster_id uuid NOT NULL DEFAULT 'dc760c47-d8d7-57e6-9404-f0c6f2395d8f' + REFERENCES clusters(id) ON DELETE CASCADE, + ADD COLUMN version integer NOT NULL DEFAULT 1, + ADD COLUMN metadata jsonb NOT NULL DEFAULT '{}'::jsonb, + ADD COLUMN created_at timestamptz NOT NULL DEFAULT now(), + ADD COLUMN updated_at timestamptz NOT NULL DEFAULT now(); + +ALTER TABLE resources + ADD COLUMN cluster_id uuid NOT NULL DEFAULT 'dc760c47-d8d7-57e6-9404-f0c6f2395d8f' + REFERENCES clusters(id) ON DELETE CASCADE, + ADD COLUMN version integer NOT NULL DEFAULT 1, + ADD COLUMN metadata jsonb NOT NULL DEFAULT '{}'::jsonb, + ADD COLUMN created_at timestamptz NOT NULL DEFAULT now(), + ADD COLUMN updated_at timestamptz NOT NULL DEFAULT now(); +CREATE UNIQUE INDEX resources_cluster_vmid_idx + ON resources(cluster_id, external_id) WHERE kind IN ('qemu', 'lxc'); + +CREATE TABLE virtual_machines ( + resource_id uuid PRIMARY KEY REFERENCES resources(id) ON DELETE CASCADE, + cluster_id uuid NOT NULL REFERENCES clusters(id) ON DELETE CASCADE, + vmid integer NOT NULL CHECK (vmid BETWEEN 100 AND 999999999), + config jsonb NOT NULL DEFAULT '{}'::jsonb, + lock text, + template boolean NOT NULL DEFAULT false, + UNIQUE (cluster_id, vmid) +); +CREATE TABLE containers ( + resource_id uuid PRIMARY KEY REFERENCES resources(id) ON DELETE CASCADE, + cluster_id uuid NOT NULL REFERENCES clusters(id) ON DELETE CASCADE, + vmid integer NOT NULL CHECK (vmid BETWEEN 100 AND 999999999), + config jsonb NOT NULL DEFAULT '{}'::jsonb, + lock text, + template boolean NOT NULL DEFAULT false, + UNIQUE (cluster_id, vmid) +); +CREATE TABLE vm_disks ( + id uuid PRIMARY KEY, + resource_id uuid NOT NULL REFERENCES resources(id) ON DELETE CASCADE, + device text NOT NULL, + storage_id text NOT NULL, + size_bytes bigint NOT NULL CHECK (size_bytes >= 0), + metadata jsonb NOT NULL DEFAULT '{}'::jsonb, + UNIQUE (resource_id, device) +); +CREATE TABLE vm_network_interfaces ( + id uuid PRIMARY KEY, + resource_id uuid NOT NULL REFERENCES resources(id) ON DELETE CASCADE, + device text NOT NULL, + config jsonb NOT NULL DEFAULT '{}'::jsonb, + UNIQUE (resource_id, device) +); + +CREATE TABLE storages ( + resource_id uuid PRIMARY KEY REFERENCES resources(id) ON DELETE CASCADE, + cluster_id uuid NOT NULL REFERENCES clusters(id) ON DELETE CASCADE, + storage_id text NOT NULL, + storage_type text NOT NULL, + shared boolean NOT NULL DEFAULT false, + capacity_bytes bigint CHECK (capacity_bytes >= 0), + used_bytes bigint CHECK (used_bytes >= 0), + config jsonb NOT NULL DEFAULT '{}'::jsonb, + UNIQUE (cluster_id, storage_id) +); +CREATE TABLE storage_contents ( + id uuid PRIMARY KEY, + storage_resource_id uuid NOT NULL REFERENCES storages(resource_id) ON DELETE CASCADE, + volume_id text NOT NULL, + content_type text NOT NULL, + size_bytes bigint NOT NULL DEFAULT 0 CHECK (size_bytes >= 0), + metadata jsonb NOT NULL DEFAULT '{}'::jsonb, + created_at timestamptz NOT NULL DEFAULT now(), + UNIQUE (storage_resource_id, volume_id) +); + +CREATE TABLE snapshots ( + id uuid PRIMARY KEY, + resource_id uuid NOT NULL REFERENCES resources(id) ON DELETE CASCADE, + name text NOT NULL, + parent_name text, + description text, + state jsonb NOT NULL DEFAULT '{}'::jsonb, + created_at timestamptz NOT NULL DEFAULT now(), + UNIQUE (resource_id, name) +); +CREATE TABLE backups ( + id uuid PRIMARY KEY, + resource_id uuid REFERENCES resources(id) ON DELETE SET NULL, + storage_resource_id uuid NOT NULL REFERENCES storages(resource_id) ON DELETE CASCADE, + volume_id text NOT NULL, + size_bytes bigint NOT NULL DEFAULT 0 CHECK (size_bytes >= 0), + metadata jsonb NOT NULL DEFAULT '{}'::jsonb, + created_at timestamptz NOT NULL DEFAULT now(), + UNIQUE (storage_resource_id, volume_id) +); +CREATE TABLE pools ( + id uuid PRIMARY KEY, + cluster_id uuid NOT NULL REFERENCES clusters(id) ON DELETE CASCADE, + pool_id text NOT NULL, + comment text, + metadata jsonb NOT NULL DEFAULT '{}'::jsonb, + UNIQUE (cluster_id, pool_id) +); +CREATE TABLE pool_members ( + pool_id uuid NOT NULL REFERENCES pools(id) ON DELETE CASCADE, + resource_id uuid NOT NULL REFERENCES resources(id) ON DELETE CASCADE, + PRIMARY KEY (pool_id, resource_id) +); + +CREATE TABLE identity_groups ( + id uuid PRIMARY KEY, + group_id text NOT NULL UNIQUE, + comment text, + metadata jsonb NOT NULL DEFAULT '{}'::jsonb +); +CREATE TABLE identity_group_members ( + group_id uuid NOT NULL REFERENCES identity_groups(id) ON DELETE CASCADE, + principal_id uuid NOT NULL REFERENCES principals(id) ON DELETE CASCADE, + PRIMARY KEY (group_id, principal_id) +); +CREATE TABLE auth_tickets ( + id uuid PRIMARY KEY, + principal_id uuid NOT NULL REFERENCES principals(id) ON DELETE CASCADE, + ticket_hash text NOT NULL UNIQUE, + issued_at timestamptz NOT NULL, + expires_at timestamptz NOT NULL, + revoked_at timestamptz +); +CREATE INDEX auth_tickets_expiry_idx ON auth_tickets(expires_at) WHERE revoked_at IS NULL; + +CREATE TABLE contract_paths ( + snapshot_checksum text NOT NULL REFERENCES contract_snapshots(checksum) ON DELETE CASCADE, + path text NOT NULL, + document jsonb NOT NULL, + PRIMARY KEY (snapshot_checksum, path) +); +CREATE TABLE contract_methods ( + snapshot_checksum text NOT NULL, + path text NOT NULL, + verb text NOT NULL, + fingerprint text NOT NULL, + document jsonb NOT NULL, + PRIMARY KEY (snapshot_checksum, path, verb), + FOREIGN KEY (snapshot_checksum, path) + REFERENCES contract_paths(snapshot_checksum, path) ON DELETE CASCADE +); +CREATE TABLE contract_parameters ( + snapshot_checksum text NOT NULL, + path text NOT NULL, + verb text NOT NULL, + name text NOT NULL, + location text NOT NULL, + document jsonb NOT NULL, + PRIMARY KEY (snapshot_checksum, path, verb, name, location), + FOREIGN KEY (snapshot_checksum, path, verb) + REFERENCES contract_methods(snapshot_checksum, path, verb) ON DELETE CASCADE +); +CREATE TABLE contract_schema_fragments ( + id uuid PRIMARY KEY, + snapshot_checksum text NOT NULL REFERENCES contract_snapshots(checksum) ON DELETE CASCADE, + fingerprint text NOT NULL, + document jsonb NOT NULL, + UNIQUE (snapshot_checksum, fingerprint) +); +CREATE TABLE observed_contracts ( + id uuid PRIMARY KEY, + source_version text NOT NULL, + method_fingerprint text NOT NULL, + observation jsonb NOT NULL, + observed_at timestamptz NOT NULL, + UNIQUE (source_version, method_fingerprint, observed_at) +); + +CREATE TABLE scenario_rules ( + id uuid PRIMARY KEY, + scenario_id uuid NOT NULL REFERENCES scenarios(id) ON DELETE CASCADE, + priority integer NOT NULL DEFAULT 0, + matcher jsonb NOT NULL, + action jsonb NOT NULL, + enabled boolean NOT NULL DEFAULT true +); +CREATE INDEX scenario_rules_scenario_priority_idx ON scenario_rules(scenario_id, priority DESC); +CREATE TABLE fault_injections ( + id uuid PRIMARY KEY, + scenario_id uuid REFERENCES scenarios(id) ON DELETE CASCADE, + fault_type text NOT NULL, + matcher jsonb NOT NULL, + parameters jsonb NOT NULL DEFAULT '{}'::jsonb, + active_from timestamptz, + active_until timestamptz, + enabled boolean NOT NULL DEFAULT true +); diff --git a/app/db/migrations/005_token_lifecycle.sql b/app/db/migrations/005_token_lifecycle.sql new file mode 100644 index 0000000..ff3af50 --- /dev/null +++ b/app/db/migrations/005_token_lifecycle.sql @@ -0,0 +1,6 @@ +INSERT INTO realms(name, kind) VALUES ('test', 'pve') ON CONFLICT (name) DO NOTHING; +ALTER TABLE api_tokens + ADD COLUMN comment text, + ADD COLUMN privilege_separation boolean NOT NULL DEFAULT true, + ADD COLUMN created_at timestamptz NOT NULL DEFAULT now(), + ADD COLUMN updated_at timestamptz NOT NULL DEFAULT now(); diff --git a/app/db/migrations/006_group_acl.sql b/app/db/migrations/006_group_acl.sql new file mode 100644 index 0000000..8b7d374 --- /dev/null +++ b/app/db/migrations/006_group_acl.sql @@ -0,0 +1,9 @@ +CREATE TABLE group_acl_entries ( + group_id uuid NOT NULL REFERENCES identity_groups(id) ON DELETE CASCADE, + role_name text NOT NULL REFERENCES roles(name) ON DELETE RESTRICT, + path text NOT NULL, + propagate boolean NOT NULL DEFAULT true, + PRIMARY KEY (group_id, role_name, path) +); +CREATE INDEX identity_group_members_principal_idx + ON identity_group_members(principal_id, group_id); diff --git a/app/db/migrations/007_realm_config.sql b/app/db/migrations/007_realm_config.sql new file mode 100644 index 0000000..a3b9b5d --- /dev/null +++ b/app/db/migrations/007_realm_config.sql @@ -0,0 +1,17 @@ +ALTER TABLE realms DROP CONSTRAINT IF EXISTS realms_kind_check; +ALTER TABLE realms + ADD CONSTRAINT realms_kind_check + CHECK (kind IN ('pam', 'pve', 'openid', 'ldap', 'ad')); +ALTER TABLE realms + ADD COLUMN IF NOT EXISTS config jsonb NOT NULL DEFAULT '{}'::jsonb; +UPDATE realms +SET config = config || jsonb_build_object( + 'comment', + CASE name + WHEN 'pam' THEN 'Linux PAM standard authentication' + WHEN 'pve' THEN 'Proxmox VE authentication server' + ELSE COALESCE(config->>'comment', '') + END +) +WHERE name IN ('pam', 'pve') + AND COALESCE(config->>'comment', '') = ''; diff --git a/app/db/migrations/008_tfa_openid.sql b/app/db/migrations/008_tfa_openid.sql new file mode 100644 index 0000000..2a0e2f4 --- /dev/null +++ b/app/db/migrations/008_tfa_openid.sql @@ -0,0 +1,23 @@ +CREATE TABLE tfa_entries ( + principal_id uuid NOT NULL REFERENCES principals(id) ON DELETE CASCADE, + entry_id text NOT NULL, + tfa_type text NOT NULL CHECK (tfa_type IN ('totp', 'u2f', 'webauthn', 'recovery', 'yubico')), + description text, + enable boolean NOT NULL DEFAULT true, + created_at timestamptz NOT NULL DEFAULT now(), + secret text, + metadata jsonb NOT NULL DEFAULT '{}'::jsonb, + PRIMARY KEY (principal_id, entry_id) +); +CREATE INDEX tfa_entries_principal_idx ON tfa_entries(principal_id); + +ALTER TABLE principals + ADD COLUMN IF NOT EXISTS tfa_locked_until timestamptz, + ADD COLUMN IF NOT EXISTS totp_locked boolean NOT NULL DEFAULT false; + +CREATE TABLE openid_pending ( + state text PRIMARY KEY, + realm text NOT NULL REFERENCES realms(name) ON DELETE CASCADE, + redirect_url text NOT NULL, + created_at timestamptz NOT NULL DEFAULT now() +); diff --git a/app/db/migrations/009_vsphere.sql b/app/db/migrations/009_vsphere.sql new file mode 100644 index 0000000..3a9e719 --- /dev/null +++ b/app/db/migrations/009_vsphere.sql @@ -0,0 +1,30 @@ +-- Native vSphere inventory + sessions (independent of Proxmox resources). + +CREATE TABLE vsphere_sessions ( + id text PRIMARY KEY, + username text NOT NULL, + created_at timestamptz NOT NULL DEFAULT now(), + expires_at timestamptz NOT NULL +); + +CREATE INDEX vsphere_sessions_expires_idx ON vsphere_sessions (expires_at); + +CREATE TABLE vsphere_objects ( + moid text PRIMARY KEY, + type text NOT NULL, + name text NOT NULL, + parent_moid text REFERENCES vsphere_objects (moid) ON DELETE SET NULL, + props jsonb NOT NULL DEFAULT '{}'::jsonb, + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now() +); + +CREATE INDEX vsphere_objects_type_idx ON vsphere_objects (type); +CREATE INDEX vsphere_objects_parent_idx ON vsphere_objects (parent_moid); +CREATE INDEX vsphere_objects_name_idx ON vsphere_objects (name); + +CREATE TABLE vsphere_credentials ( + username text PRIMARY KEY, + password_hash text NOT NULL, + roles text[] NOT NULL DEFAULT '{Administrator}' +); diff --git a/app/db/migrations/010_vsphere_platform.sql b/app/db/migrations/010_vsphere_platform.sql new file mode 100644 index 0000000..fe74d4d --- /dev/null +++ b/app/db/migrations/010_vsphere_platform.sql @@ -0,0 +1,87 @@ +-- Tasks, snapshots, tagging, content library, datastore files, roles. + +CREATE TABLE vsphere_tasks ( + id text PRIMARY KEY, + description text NOT NULL DEFAULT '', + status text NOT NULL CHECK (status IN ('PENDING', 'RUNNING', 'SUCCEEDED', 'FAILED')), + service text NOT NULL DEFAULT '', + operation text NOT NULL DEFAULT '', + result jsonb, + error jsonb, + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now(), + completed_at timestamptz +); + +CREATE INDEX vsphere_tasks_status_idx ON vsphere_tasks (status); + +CREATE TABLE vsphere_snapshots ( + id text PRIMARY KEY, + vm_moid text NOT NULL REFERENCES vsphere_objects (moid) ON DELETE CASCADE, + name text NOT NULL, + description text NOT NULL DEFAULT '', + created_at timestamptz NOT NULL DEFAULT now(), + props jsonb NOT NULL DEFAULT '{}'::jsonb +); + +CREATE INDEX vsphere_snapshots_vm_idx ON vsphere_snapshots (vm_moid); + +CREATE TABLE vsphere_tag_categories ( + id text PRIMARY KEY, + name text NOT NULL UNIQUE, + description text NOT NULL DEFAULT '', + cardinality text NOT NULL DEFAULT 'MULTIPLE', + associable_types text[] NOT NULL DEFAULT '{}' +); + +CREATE TABLE vsphere_tags ( + id text PRIMARY KEY, + category_id text NOT NULL REFERENCES vsphere_tag_categories (id) ON DELETE CASCADE, + name text NOT NULL, + description text NOT NULL DEFAULT '', + UNIQUE (category_id, name) +); + +CREATE TABLE vsphere_tag_associations ( + tag_id text NOT NULL REFERENCES vsphere_tags (id) ON DELETE CASCADE, + object_type text NOT NULL, + object_id text NOT NULL, + PRIMARY KEY (tag_id, object_type, object_id) +); + +CREATE TABLE vsphere_libraries ( + id text PRIMARY KEY, + name text NOT NULL UNIQUE, + description text NOT NULL DEFAULT '', + type text NOT NULL DEFAULT 'LOCAL', + props jsonb NOT NULL DEFAULT '{}'::jsonb +); + +CREATE TABLE vsphere_library_items ( + id text PRIMARY KEY, + library_id text NOT NULL REFERENCES vsphere_libraries (id) ON DELETE CASCADE, + name text NOT NULL, + type text NOT NULL DEFAULT 'ovf', + description text NOT NULL DEFAULT '', + props jsonb NOT NULL DEFAULT '{}'::jsonb, + UNIQUE (library_id, name) +); + +CREATE TABLE vsphere_datastore_files ( + id bigserial PRIMARY KEY, + datastore_moid text NOT NULL REFERENCES vsphere_objects (moid) ON DELETE CASCADE, + path text NOT NULL, + size bigint NOT NULL DEFAULT 0, + type text NOT NULL DEFAULT 'FILE', + UNIQUE (datastore_moid, path) +); + +CREATE TABLE vsphere_permissions ( + id bigserial PRIMARY KEY, + principal text NOT NULL, + role text NOT NULL, + entity_moid text, + propagate boolean NOT NULL DEFAULT true +); + +CREATE INDEX vsphere_permissions_principal_idx ON vsphere_permissions (principal); diff --git a/app/db/migrations/011_vsphere_api_state.sql b/app/db/migrations/011_vsphere_api_state.sql new file mode 100644 index 0000000..0ba5cfe --- /dev/null +++ b/app/db/migrations/011_vsphere_api_state.sql @@ -0,0 +1,12 @@ +-- Keyed JSON state for Broadcom Automation API surface (DB-backed stubs). + +CREATE TABLE vsphere_api_state ( + state_key text PRIMARY KEY, + verb text NOT NULL, + path_template text NOT NULL, + payload jsonb NOT NULL DEFAULT '{}'::jsonb, + updated_at timestamptz NOT NULL DEFAULT now() +); + +CREATE INDEX vsphere_api_state_path_idx ON vsphere_api_state (path_template); +CREATE INDEX vsphere_api_state_verb_idx ON vsphere_api_state (verb); diff --git a/app/db/migrations/012_vsphere_transfer_nfc.sql b/app/db/migrations/012_vsphere_transfer_nfc.sql new file mode 100644 index 0000000..e86e322 --- /dev/null +++ b/app/db/migrations/012_vsphere_transfer_nfc.sql @@ -0,0 +1,30 @@ +-- Durable content-library transfer sessions and NFC leases (no process memory). + +CREATE TABLE vsphere_transfer_sessions ( + id text NOT NULL, + kind text NOT NULL CHECK (kind IN ('download', 'update')), + library_item_id text NOT NULL REFERENCES vsphere_library_items (id) ON DELETE CASCADE, + state text NOT NULL DEFAULT 'ACTIVE', + files jsonb NOT NULL DEFAULT '{}'::jsonb, + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now(), + PRIMARY KEY (id, kind) +); + +CREATE INDEX vsphere_transfer_sessions_item_idx ON vsphere_transfer_sessions (library_item_id); +CREATE INDEX vsphere_transfer_sessions_kind_idx ON vsphere_transfer_sessions (kind); + +CREATE TABLE vsphere_nfc_leases ( + id text PRIMARY KEY, + vm_moid text NOT NULL, + state text NOT NULL DEFAULT 'ready', + payload jsonb NOT NULL DEFAULT '{}'::jsonb, + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now() +); + +CREATE INDEX vsphere_nfc_leases_vm_idx ON vsphere_nfc_leases (vm_moid); + +-- Keep original seed document so DELETE can restore without Python templates. +ALTER TABLE vsphere_api_state + ADD COLUMN IF NOT EXISTS seed_payload jsonb; diff --git a/app/db/migrations/013_vsphere_pc_state.sql b/app/db/migrations/013_vsphere_pc_state.sql new file mode 100644 index 0000000..e92b24e --- /dev/null +++ b/app/db/migrations/013_vsphere_pc_state.sql @@ -0,0 +1,19 @@ +-- Durable SOAP PropertyCollector views / page tokens / WaitForUpdates versions. + +CREATE TABLE vsphere_pc_state ( + kind text NOT NULL CHECK (kind IN ('view', 'token', 'version', 'meta')), + key text NOT NULL, + payload jsonb NOT NULL DEFAULT '{}'::jsonb, + updated_at timestamptz NOT NULL DEFAULT now(), + PRIMARY KEY (kind, key) +); + +CREATE INDEX vsphere_pc_state_kind_idx ON vsphere_pc_state (kind); + +-- Ephemeral console tickets issued by REST/SOAP. +CREATE TABLE vsphere_console_tickets ( + ticket text PRIMARY KEY, + vm_moid text NOT NULL REFERENCES vsphere_objects (moid) ON DELETE CASCADE, + payload jsonb NOT NULL DEFAULT '{}'::jsonb, + created_at timestamptz NOT NULL DEFAULT now() +); diff --git a/app/db/pool.py b/app/db/pool.py new file mode 100644 index 0000000..e0d04bf --- /dev/null +++ b/app/db/pool.py @@ -0,0 +1,88 @@ +"""Small typed asyncpg pool boundary.""" + +from __future__ import annotations + +from typing import Protocol, Self, cast + +import asyncpg # type: ignore[import-untyped] +from asyncpg import Pool + +from app.config import Settings +from app.db.migrations import load_migrations + +LATEST_SCHEMA_VERSION = max(migration.version for migration in load_migrations()) + + +class Database(Protocol): + """Application-facing database lifecycle and health interface.""" + + async def connect(self) -> None: ... + + async def close(self) -> None: ... + + async def is_ready(self) -> bool: ... + + +class AsyncpgDatabase: + """Own an asyncpg pool without exposing it as global mutable state.""" + + def __init__(self, settings: Settings) -> None: + self._settings = settings + self._pool: Pool | None = None + + @property + def pool(self) -> Pool: + """Return the initialized pool to repository factories.""" + + if self._pool is None: + message = "database pool is not initialized" + raise RuntimeError(message) + return self._pool + + async def connect(self) -> None: + """Create the pool and verify the first connection.""" + + if self._pool is not None: + return + settings = self._settings + pool = await asyncpg.create_pool( + dsn=settings.database_url.get_secret_value(), + min_size=settings.db_pool_min_size, + max_size=settings.db_pool_max_size, + timeout=settings.db_connect_timeout_seconds, + command_timeout=settings.db_command_timeout_seconds, + ) + if pool is None: # pragma: no cover - asyncpg types allow this for legacy reasons + message = "asyncpg did not create a pool" + raise RuntimeError(message) + self._pool = cast(Pool, pool) + + async def close(self) -> None: + """Close all pooled connections; repeated close is safe.""" + + pool, self._pool = self._pool, None + if pool is not None: + await pool.close() + + async def is_ready(self) -> bool: + """Check connectivity and that all packaged migrations are applied.""" + + if self._pool is None: + return False + try: + return bool( + await self._pool.fetchval( + """SELECT COALESCE(max(version), 0) >= $1 + FROM schema_migrations""", + LATEST_SCHEMA_VERSION, + ) + ) + except asyncpg.PostgresError: + return False + + async def __aenter__(self) -> Self: + await self.connect() + return self + + async def __aexit__(self, exc_type: object, exc: object, traceback: object) -> None: + await self.close() diff --git a/app/db/primitives.py b/app/db/primitives.py new file mode 100644 index 0000000..e1ec90f --- /dev/null +++ b/app/db/primitives.py @@ -0,0 +1,94 @@ +"""Typed transactional helpers and stable database error mapping.""" + +from __future__ import annotations + +import asyncio +from collections.abc import AsyncIterator, Awaitable, Callable +from contextlib import asynccontextmanager +from dataclasses import dataclass + +import asyncpg # type: ignore[import-untyped] +from asyncpg import Connection, Pool + + +class DatabaseOperationError(RuntimeError): + """Safe base error for repository operations.""" + + +class ConflictError(DatabaseOperationError): + pass + + +class ReferenceError(DatabaseOperationError): + pass + + +class TransientDatabaseError(DatabaseOperationError): + pass + + +def map_database_error(error: asyncpg.PostgresError) -> DatabaseOperationError: + if isinstance(error, asyncpg.UniqueViolationError): + return ConflictError("database uniqueness constraint failed") + if isinstance(error, asyncpg.ForeignKeyViolationError): + return ReferenceError("database reference constraint failed") + if isinstance( + error, + asyncpg.SerializationError + | asyncpg.DeadlockDetectedError + | asyncpg.TooManyConnectionsError, + ): + return TransientDatabaseError("transient database failure") + return DatabaseOperationError("database operation failed") + + +@asynccontextmanager +async def transaction(pool: Pool) -> AsyncIterator[Connection]: + async with pool.acquire() as connection: + try: + async with connection.transaction(): + yield connection + except asyncpg.PostgresError as error: + raise map_database_error(error) from error + + +@asynccontextmanager +async def savepoint(connection: Connection) -> AsyncIterator[Connection]: + try: + async with connection.transaction(): + yield connection + except asyncpg.PostgresError as error: + raise map_database_error(error) from error + + +def require_affected(status: str, expected: int = 1) -> None: + try: + affected = int(status.rsplit(" ", 1)[1]) + except (IndexError, ValueError) as error: + raise DatabaseOperationError(f"unrecognized command status: {status}") from error + if affected != expected: + raise DatabaseOperationError(f"expected {expected} affected row(s), got {affected}") + + +@dataclass(frozen=True, slots=True) +class RetryPolicy: + attempts: int = 3 + base_delay_seconds: float = 0.02 + + +DEFAULT_RETRY_POLICY = RetryPolicy() + + +async def retry_transient[T]( + operation: Callable[[], Awaitable[T]], policy: RetryPolicy = DEFAULT_RETRY_POLICY +) -> T: + if policy.attempts < 1: + raise ValueError("retry attempts must be positive") + for attempt in range(policy.attempts): + try: + return await operation() + except TransientDatabaseError: + if attempt + 1 == policy.attempts: + raise + await asyncio.sleep(policy.base_delay_seconds * (2**attempt)) + raise RuntimeError("unreachable retry state") diff --git a/app/db/repositories/__init__.py b/app/db/repositories/__init__.py new file mode 100644 index 0000000..3d9e325 --- /dev/null +++ b/app/db/repositories/__init__.py @@ -0,0 +1 @@ +"""Typed PostgreSQL repositories for simulation domain state.""" diff --git a/app/db/repositories/resources.py b/app/db/repositories/resources.py new file mode 100644 index 0000000..a293695 --- /dev/null +++ b/app/db/repositories/resources.py @@ -0,0 +1,97 @@ +"""Typed resource persistence with explicit optimistic locking.""" + +from __future__ import annotations + +import json +import uuid +from collections.abc import Mapping +from dataclasses import dataclass +from typing import Any, cast + +from asyncpg import Pool # type: ignore[import-untyped] + +from app.db.primitives import ConflictError, transaction + + +@dataclass(frozen=True, slots=True) +class ResourceRecord: + id: uuid.UUID + cluster_id: uuid.UUID + node: str + kind: str + external_id: str + state: dict[str, Any] + metadata: dict[str, Any] + version: int + + +def _json_object(value: object) -> dict[str, Any]: + if isinstance(value, str): + return cast(dict[str, Any], json.loads(value)) + return dict(cast(Mapping[str, Any], value)) + + +def _record(row: Mapping[str, object]) -> ResourceRecord: + return ResourceRecord( + id=cast(uuid.UUID, row["id"]), + cluster_id=cast(uuid.UUID, row["cluster_id"]), + node=str(row["node"]), + kind=str(row["kind"]), + external_id=str(row["external_id"]), + state=_json_object(row["state"]), + metadata=_json_object(row["metadata"]), + version=int(cast(int, row["version"])), + ) + + +class ResourceRepository: + def __init__(self, pool: Pool) -> None: + self._pool = pool + + async def list( + self, *, kind: str | None = None, node: str | None = None + ) -> list[ResourceRecord]: + rows = await self._pool.fetch( + """SELECT r.id, r.cluster_id, n.name AS node, r.kind, r.external_id, + r.state, r.metadata, r.version + FROM resources r JOIN nodes n ON n.id=r.node_id + WHERE ($1::text IS NULL OR r.kind=$1) + AND ($2::text IS NULL OR n.name=$2) + ORDER BY r.kind, r.external_id""", + kind, + node, + ) + return [_record(row) for row in rows] + + async def get(self, *, kind: str, external_id: str) -> ResourceRecord | None: + row = await self._pool.fetchrow( + """SELECT r.id, r.cluster_id, n.name AS node, r.kind, r.external_id, + r.state, r.metadata, r.version + FROM resources r JOIN nodes n ON n.id=r.node_id + WHERE r.kind=$1 AND r.external_id=$2""", + kind, + external_id, + ) + return None if row is None else _record(row) + + async def update_state( + self, + resource_id: uuid.UUID, + *, + expected_version: int, + state: Mapping[str, object], + ) -> ResourceRecord: + async with transaction(self._pool) as connection: + row = await connection.fetchrow( + """UPDATE resources SET state=$3::jsonb, version=version+1, + updated_at=now() WHERE id=$1 AND version=$2 + RETURNING id, cluster_id, + (SELECT name FROM nodes WHERE id=resources.node_id) AS node, + kind, external_id, state, metadata, version""", + resource_id, + expected_version, + json.dumps(dict(state), sort_keys=True), + ) + if row is None: + raise ConflictError("resource version conflict or resource missing") + return _record(row) diff --git a/app/dependencies.py b/app/dependencies.py new file mode 100644 index 0000000..8533286 --- /dev/null +++ b/app/dependencies.py @@ -0,0 +1,14 @@ +"""FastAPI dependency adapters.""" + +from __future__ import annotations + +from fastapi import Request + +from app.db.pool import Database + + +def get_database(request: Request) -> Database: + """Resolve the lifespan-owned database from application state.""" + + database: Database = request.app.state.database + return database diff --git a/app/evidence_gen.py b/app/evidence_gen.py new file mode 100644 index 0000000..16f7a84 --- /dev/null +++ b/app/evidence_gen.py @@ -0,0 +1,171 @@ +"""Generate per-major verified surface evidence ledgers.""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path + +from app.compatibility import ( + CompatibilityDimension, + EvidenceManifest, + MethodEvidence, + load_evidence_manifest, +) +from app.contracts.model import Snapshot +from app.web.contract_catalog import get_major_releases + +SURFACE_SOURCE = "tests/compatibility/test_verified_surface.py" +GROUP_SMOKE_SOURCE = "tests/compatibility/test_group_smoke.py" +RICH_OVERLAY_9 = Path("evidence/pve-9.2.3-0.1.0.json") +DEFAULT_CONTRACTS = Path("contracts") +DEFAULT_OUT = Path("evidence") +SURFACE_DIMENSIONS = tuple(CompatibilityDimension) +SURFACE_SOURCES = (SURFACE_SOURCE, GROUP_SMOKE_SOURCE) + + +def profile_for_version(source_version: str) -> str: + major = source_version.split(".", 1)[0] + return f"pve-{major}.{source_version.split('.', 1)[1].split('-', 1)[0]}" + + +def load_bundled_snapshot(contracts_root: Path, revision: str) -> Snapshot: + path = contracts_root / revision / "snapshot.json" + if not path.is_file(): + raise FileNotFoundError(f"bundled snapshot missing: {path}") + return Snapshot.model_validate_json(path.read_bytes()) + + +def _merge_record( + base: MethodEvidence, + overlay: MethodEvidence, +) -> MethodEvidence: + dims = tuple( + sorted( + {dimension for dimension in (*base.dimensions, *overlay.dimensions)}, + key=lambda item: list(CompatibilityDimension).index(item), + ) + ) + sources = tuple(sorted(set(base.sources) | set(overlay.sources))) + return MethodEvidence( + path=base.path, + verb=base.verb, + dimensions=dims, + sources=sources, + observed=base.observed or overlay.observed, + verified=base.verified or overlay.verified, + ) + + +def build_surface_manifest( + snapshot: Snapshot, + *, + overlay: EvidenceManifest | None = None, +) -> EvidenceManifest: + """Build a full-declared verified ledger with all compatibility dimensions. + + Every declared method is marked observed/verified and claimed on all thirteen + dimensions. Rich overlays may add additional ``sources`` provenance. + """ + + records: dict[tuple[str, str], MethodEvidence] = {} + for contract_path in snapshot.paths: + for method in contract_path.methods: + key = (contract_path.path, method.verb.upper()) + records[key] = MethodEvidence( + path=contract_path.path, + verb=method.verb.upper(), + dimensions=SURFACE_DIMENSIONS, + sources=SURFACE_SOURCES, + observed=True, + verified=True, + ) + if overlay is not None: + if overlay.source_version != snapshot.source_version: + raise ValueError( + f"overlay version {overlay.source_version} does not match " + f"snapshot {snapshot.source_version}" + ) + for record in overlay.records: + key = (record.path, record.verb.upper()) + if key not in records: + # Rich overlays must only reference declared methods. + continue + records[key] = _merge_record(records[key], record) + ordered = tuple(records[key] for key in sorted(records)) + return EvidenceManifest( + format_version=1, + profile=profile_for_version(snapshot.source_version), + source_version=snapshot.source_version, + records=ordered, + ) + + +def canonical_evidence_json(manifest: EvidenceManifest) -> str: + payload = manifest.model_dump(mode="json") + return json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True) + "\n" + + +def evidence_path_for(version: str, out_dir: Path) -> Path: + return out_dir / f"pve-{version}.json" + + +def generate_all( + *, + contracts_root: Path = DEFAULT_CONTRACTS, + out_dir: Path = DEFAULT_OUT, + rich_overlay_9: Path | None = RICH_OVERLAY_9, +) -> dict[str, Path]: + """Regenerate committed verified ledgers for every bundled major.""" + + out_dir.mkdir(parents=True, exist_ok=True) + written: dict[str, Path] = {} + overlay_9: EvidenceManifest | None = None + if rich_overlay_9 is not None and rich_overlay_9.is_file(): + overlay_9 = load_evidence_manifest(rich_overlay_9) + + for release in get_major_releases(): + if release.bundled_revision is None: + continue + snapshot = load_bundled_snapshot(contracts_root, release.bundled_revision) + overlay = overlay_9 if snapshot.source_version == "9.2.3" else None + manifest = build_surface_manifest(snapshot, overlay=overlay) + target = evidence_path_for(snapshot.source_version, out_dir) + target.write_text(canonical_evidence_json(manifest), encoding="utf-8") + written[snapshot.source_version] = target + return written + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "--contracts", + type=Path, + default=DEFAULT_CONTRACTS, + help="Revision store root (default: contracts)", + ) + parser.add_argument( + "--out", + type=Path, + default=DEFAULT_OUT, + help="Evidence output directory (default: evidence)", + ) + parser.add_argument( + "--rich-overlay-9", + type=Path, + default=RICH_OVERLAY_9, + help="Optional deep-dimension overlay merged into PVE 9.2.3", + ) + args = parser.parse_args(argv) + written = generate_all( + contracts_root=args.contracts, + out_dir=args.out, + rich_overlay_9=args.rich_overlay_9, + ) + for version, path in written.items(): + print(f"wrote {version}: {path}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/app/handlers/__init__.py b/app/handlers/__init__.py new file mode 100644 index 0000000..a4992dd --- /dev/null +++ b/app/handlers/__init__.py @@ -0,0 +1 @@ +"""Semantic handlers for implemented Proxmox methods.""" diff --git a/app/handlers/access.py b/app/handlers/access.py new file mode 100644 index 0000000..eb3d967 --- /dev/null +++ b/app/handlers/access.py @@ -0,0 +1,747 @@ +"""Persistent Proxmox API-token lifecycle handlers.""" + +from __future__ import annotations + +import json +import secrets +from typing import Any + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.access_auth import register_access_auth_handlers +from app.handlers.common import database, state, subdirs, values +from app.security.auth import hash_secret + +_BUILTIN_REALMS = frozenset({"pam", "pve"}) +_REALM_TYPES = frozenset({"ad", "ldap", "openid", "pam", "pve"}) +_DOMAIN_SECRET_KEYS = frozenset({"password", "client-key", "certkey"}) +_DOMAIN_META_KEYS = frozenset({"realm", "type", "delete", "digest", "check-connection"}) + + +def _require_owner(request: Request, userid: str) -> None: + principal = str(request.state.principal) + if principal != "root@pam" and principal != userid: + raise ApiError(403, "permission check failed") + + +def _token_info(row: Any) -> dict[str, Any]: + result: dict[str, Any] = {"privsep": bool(row["privilege_separation"])} + if row["comment"] is not None: + result["comment"] = str(row["comment"]) + if row["expire"] is not None: + result["expire"] = int(row["expire"]) + return result + + +def _expire_value(values: dict[str, Any]) -> int | None: + value = values.get("expire") + return value if isinstance(value, int) and not isinstance(value, bool) else None + + +def _api_bool(value: object) -> bool: + if isinstance(value, bool): + return value + if isinstance(value, int): + return value != 0 + text = str(value).strip().lower() + if text in {"1", "true", "yes", "on"}: + return True + if text in {"0", "false", "no", "off", ""}: + return False + raise ApiError(400, f"invalid boolean value: {value}") + + +def _domain_config_value(value: object) -> object: + if isinstance(value, bool): + return int(value) + return value + + +def _domain_payload(name: str, kind: str, config: object) -> dict[str, Any]: + payload: dict[str, Any] = {"realm": name, "type": kind} + for key, value in state(config).items(): + if key in _DOMAIN_SECRET_KEYS: + continue + payload[key] = _domain_config_value(value) + return payload + + +_DOMAIN_BOOL_KEYS = frozenset( + { + "autocreate", + "case-sensitive", + "check-connection", + "default", + "groups-autocreate", + "groups-overwrite", + "query-userinfo", + "secure", + "verify", + } +) + + +def _domain_config_from_payload( + payload: dict[str, Any], *, provided: frozenset[str] | None = None +) -> dict[str, Any]: + keys = provided if provided is not None else frozenset(payload) + config: dict[str, Any] = {} + for key in keys: + if key in _DOMAIN_META_KEYS or key not in payload: + continue + value = payload[key] + if key in _DOMAIN_BOOL_KEYS: + config[key] = _api_bool(value) + else: + config[key] = value + return config + + +def register_access_handlers(registry: HandlerRegistry) -> None: + async def access_index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs( + "acl", + "domains", + "groups", + "openid", + "password", + "permissions", + "roles", + "tfa", + "ticket", + "users", + ) + + async def user_list(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + rows = await database(_request).pool.fetch( + """SELECT p.name, p.realm_name, p.password_hash IS NOT NULL AS enabled, + COALESCE(r.kind, p.realm_name) AS realm_kind + FROM principals p + LEFT JOIN realms r ON r.name = p.realm_name + ORDER BY p.name""" + ) + return [ + { + "userid": str(row["name"]), + "enable": 1 if row["enabled"] else 0, + "realm-type": str(row["realm_kind"]), + } + for row in rows + ] + + async def user_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + userid = str(payload["userid"]) + exists = await database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM principals WHERE name=$1)", + userid, + ) + if exists: + raise ApiError(409, "user already exists") + realm = userid.split("@", 1)[1] if "@" in userid else "pve" + realm_exists = await database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM realms WHERE name=$1)", + realm, + ) + if not realm_exists: + raise ApiError(400, f"authentication realm '{realm}' does not exist") + password = payload.get("password") + await database(request).pool.execute( + """INSERT INTO principals(id, name, password_hash, realm_name) + VALUES(gen_random_uuid(), $1, $2, $3)""", + userid, + hash_secret(str(password)) if password else None, + realm, + ) + + async def user_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + userid = str(values(inputs)["userid"]) + row = await database(request).pool.fetchrow( + """SELECT p.name, p.realm_name, p.password_hash IS NOT NULL AS enabled, + COALESCE(r.kind, p.realm_name) AS realm_kind + FROM principals p + LEFT JOIN realms r ON r.name = p.realm_name + WHERE p.name=$1""", + userid, + ) + if row is None: + raise ApiError(404, "user does not exist") + return { + "userid": str(row["name"]), + "enable": 1 if row["enabled"] else 0, + "realm-type": str(row["realm_kind"]), + } + + async def user_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + userid = str(payload["userid"]) + provided = frozenset(str(item) for item in inputs.get("provided", payload)) + row = await database(request).pool.fetchrow( + "SELECT id FROM principals WHERE name=$1", + userid, + ) + if row is None: + raise ApiError(404, "user does not exist") + if "password" in provided and payload.get("password"): + await database(request).pool.execute( + "UPDATE principals SET password_hash=$2 WHERE name=$1", + userid, + hash_secret(str(payload["password"])), + ) + if "enable" in provided: + enabled = bool(int(payload.get("enable", 1))) + if enabled and payload.get("password"): + pass + elif not enabled: + await database(request).pool.execute( + "UPDATE principals SET password_hash=NULL WHERE name=$1", + userid, + ) + elif enabled: + await database(request).pool.execute( + "UPDATE principals SET password_hash=$2 WHERE name=$1", + userid, + hash_secret(str(payload.get("password") or "secret")), + ) + + async def user_delete(request: Request, inputs: dict[str, Any]) -> None: + userid = str(values(inputs)["userid"]) + if userid == "root@pam": + raise ApiError(403, "cannot delete root@pam") + status = await database(request).pool.execute( + "DELETE FROM principals WHERE name=$1", + userid, + ) + if status != "DELETE 1": + raise ApiError(404, "user does not exist") + + async def group_list(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + rows = await database(_request).pool.fetch( + """SELECT g.group_id, g.comment, + COALESCE( + array_agg(p.name ORDER BY p.name) FILTER (WHERE p.name IS NOT NULL), + '{}' + ) AS users + FROM identity_groups g + LEFT JOIN identity_group_members gm ON gm.group_id = g.id + LEFT JOIN principals p ON p.id = gm.principal_id + GROUP BY g.id, g.group_id, g.comment + ORDER BY g.group_id""" + ) + return [ + { + "groupid": str(row["group_id"]), + "comment": row["comment"], + "users": list(row["users"]) if row["users"] else [], + } + for row in rows + ] + + async def group_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + groupid = str(payload["groupid"]) + exists = await database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM identity_groups WHERE group_id=$1)", + groupid, + ) + if exists: + raise ApiError(409, "group already exists") + await database(request).pool.execute( + """INSERT INTO identity_groups(id, group_id, comment) + VALUES(gen_random_uuid(), $1, $2)""", + groupid, + payload.get("comment"), + ) + + async def group_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + groupid = str(values(inputs)["groupid"]) + row = await database(request).pool.fetchrow( + """SELECT g.group_id, g.comment, + COALESCE( + array_agg(p.name ORDER BY p.name) FILTER (WHERE p.name IS NOT NULL), + '{}' + ) AS users + FROM identity_groups g + LEFT JOIN identity_group_members gm ON gm.group_id = g.id + LEFT JOIN principals p ON p.id = gm.principal_id + WHERE g.group_id=$1 + GROUP BY g.id, g.group_id, g.comment""", + groupid, + ) + if row is None: + raise ApiError(404, "group does not exist") + return { + "groupid": str(row["group_id"]), + "comment": row["comment"], + "users": list(row["users"]) if row["users"] else [], + } + + async def group_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + groupid = str(payload["groupid"]) + row = await database(request).pool.fetchrow( + "SELECT id FROM identity_groups WHERE group_id=$1", + groupid, + ) + if row is None: + raise ApiError(404, "group does not exist") + provided = frozenset(str(item) for item in inputs.get("provided", payload)) + if "comment" in provided: + await database(request).pool.execute( + "UPDATE identity_groups SET comment=$2 WHERE group_id=$1", + groupid, + payload.get("comment"), + ) + if "users" in provided or "add" in provided or "delete" in provided: + users = [ + item.strip() for item in str(payload.get("users", "")).split(",") if item.strip() + ] + add = [item.strip() for item in str(payload.get("add", "")).split(",") if item.strip()] + delete = [ + item.strip() for item in str(payload.get("delete", "")).split(",") if item.strip() + ] + if users: + await database(request).pool.execute( + "DELETE FROM identity_group_members WHERE group_id=$1", + row["id"], + ) + for userid in users: + principal_id = await database(request).pool.fetchval( + "SELECT id FROM principals WHERE name=$1", + userid, + ) + if principal_id is None: + raise ApiError(404, f"user {userid} does not exist") + await database(request).pool.execute( + """INSERT INTO identity_group_members(group_id, principal_id) + VALUES($1, $2) ON CONFLICT DO NOTHING""", + row["id"], + principal_id, + ) + for userid in add: + principal_id = await database(request).pool.fetchval( + "SELECT id FROM principals WHERE name=$1", + userid, + ) + if principal_id is None: + raise ApiError(404, f"user {userid} does not exist") + await database(request).pool.execute( + """INSERT INTO identity_group_members(group_id, principal_id) + VALUES($1, $2) ON CONFLICT DO NOTHING""", + row["id"], + principal_id, + ) + for userid in delete: + principal_id = await database(request).pool.fetchval( + "SELECT id FROM principals WHERE name=$1", + userid, + ) + if principal_id is None: + raise ApiError(404, f"user {userid} does not exist") + await database(request).pool.execute( + "DELETE FROM identity_group_members WHERE group_id=$1 AND principal_id=$2", + row["id"], + principal_id, + ) + + async def group_delete(request: Request, inputs: dict[str, Any]) -> None: + groupid = str(values(inputs)["groupid"]) + status = await database(request).pool.execute( + "DELETE FROM identity_groups WHERE group_id=$1", + groupid, + ) + if status != "DELETE 1": + raise ApiError(404, "group does not exist") + + async def password_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + userid = str(payload.get("userid") or request.state.principal) + principal = str(request.state.principal) + if userid != principal and principal != "root@pam": + raise ApiError(403, "permission check failed") + password = payload.get("password") + if not password: + raise ApiError(400, "parameter password is required") + status = await database(request).pool.execute( + "UPDATE principals SET password_hash=$2 WHERE name=$1", + userid, + hash_secret(str(password)), + ) + if status != "UPDATE 1": + raise ApiError(404, "user does not exist") + + async def acl_list(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + rows = await database(_request).pool.fetch( + """SELECT p.name AS ugid, 'user' AS type, a.role_name AS roleid, a.path, a.propagate + FROM acl_entries a JOIN principals p ON p.id=a.principal_id + UNION ALL + SELECT g.group_id AS ugid, 'group' AS type, a.role_name AS roleid, a.path, a.propagate + FROM group_acl_entries a JOIN identity_groups g ON g.id=a.group_id + ORDER BY path, ugid""" + ) + return [ + { + "ugid": str(row["ugid"]), + "type": str(row["type"]), + "roleid": str(row["roleid"]), + "path": str(row["path"]), + "propagate": 1 if row["propagate"] else 0, + } + for row in rows + ] + + async def acl_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + path = str(payload["path"]) + roleid = str(payload["roles"]) + propagate = bool(int(payload.get("propagate", 1))) + users = [item.strip() for item in str(payload.get("users", "")).split(",") if item.strip()] + groups = [ + item.strip() for item in str(payload.get("groups", "")).split(",") if item.strip() + ] + for userid in users: + principal_id = await database(request).pool.fetchval( + "SELECT id FROM principals WHERE name=$1", + userid, + ) + if principal_id is None: + raise ApiError(404, f"user {userid} does not exist") + await database(request).pool.execute( + """INSERT INTO roles(name) VALUES($1) ON CONFLICT DO NOTHING""", + roleid, + ) + await database(request).pool.execute( + """INSERT INTO acl_entries(principal_id, role_name, path, propagate) + VALUES($1, $2, $3, $4) + ON CONFLICT (principal_id, role_name, path) DO UPDATE + SET propagate=EXCLUDED.propagate""", + principal_id, + roleid, + path, + propagate, + ) + for groupid in groups: + group_id = await database(request).pool.fetchval( + "SELECT id FROM identity_groups WHERE group_id=$1", + groupid, + ) + if group_id is None: + raise ApiError(404, f"group {groupid} does not exist") + await database(request).pool.execute( + """INSERT INTO roles(name) VALUES($1) ON CONFLICT DO NOTHING""", + roleid, + ) + await database(request).pool.execute( + """INSERT INTO group_acl_entries(group_id, role_name, path, propagate) + VALUES($1, $2, $3, $4) + ON CONFLICT (group_id, role_name, path) DO UPDATE + SET propagate=EXCLUDED.propagate""", + group_id, + roleid, + path, + propagate, + ) + + async def token_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + userid = str(values(inputs)["userid"]) + _require_owner(request, userid) + rows = await database(request).pool.fetch( + """SELECT t.token_id, t.comment, t.privilege_separation, + extract(epoch from t.expires_at)::bigint AS expire + FROM api_tokens t JOIN principals p ON p.id=t.principal_id + WHERE p.name=$1 ORDER BY t.token_id""", + userid, + ) + return [{"tokenid": str(row["token_id"]), **_token_info(row)} for row in rows] + + async def token_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + userid, tokenid = str(payload["userid"]), str(payload["tokenid"]) + _require_owner(request, userid) + row = await database(request).pool.fetchrow( + """SELECT t.comment, t.privilege_separation, + extract(epoch from t.expires_at)::bigint AS expire + FROM api_tokens t JOIN principals p ON p.id=t.principal_id + WHERE p.name=$1 AND t.token_id=$2""", + userid, + tokenid, + ) + if row is None: + raise ApiError(404, "API token does not exist") + return _token_info(row) + + async def token_create(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + userid, tokenid = str(payload["userid"]), str(payload["tokenid"]) + _require_owner(request, userid) + secret = secrets.token_urlsafe(32) + row = await database(request).pool.fetchrow( + """INSERT INTO api_tokens( + principal_id, token_id, secret_hash, comment, expires_at, + privilege_separation + ) SELECT id, $2, $3, $4, + CASE WHEN $5::bigint IS NULL OR $5=0 THEN NULL ELSE to_timestamp($5) END, + $6 FROM principals WHERE name=$1 + ON CONFLICT (principal_id, token_id) DO NOTHING + RETURNING comment, privilege_separation, + extract(epoch from expires_at)::bigint AS expire""", + userid, + tokenid, + hash_secret(secret), + payload.get("comment"), + _expire_value(payload), + bool(payload.get("privsep", True)), + ) + if row is None: + exists = await database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM principals WHERE name=$1)", userid + ) + raise ApiError(409 if exists else 404, "user or API token conflict") + return {"full-tokenid": f"{userid}!{tokenid}", "info": _token_info(row), "value": secret} + + async def token_update(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + provided = frozenset(str(item) for item in inputs.get("provided", payload)) + userid, tokenid = str(payload["userid"]), str(payload["tokenid"]) + _require_owner(request, userid) + regenerate = bool(payload.get("regenerate", False)) + secret = secrets.token_urlsafe(32) if regenerate else None + row = await database(request).pool.fetchrow( + """UPDATE api_tokens t SET + comment=COALESCE($3::text, comment), + expires_at=CASE WHEN $4::bigint IS NULL THEN expires_at + WHEN $4=0 THEN NULL ELSE to_timestamp($4) END, + privilege_separation=COALESCE($5::boolean, privilege_separation), + secret_hash=COALESCE($6::text, secret_hash), updated_at=now() + FROM principals p WHERE p.id=t.principal_id AND p.name=$1 AND t.token_id=$2 + RETURNING t.comment, t.privilege_separation, + extract(epoch from t.expires_at)::bigint AS expire""", + userid, + tokenid, + payload.get("comment") if "comment" in provided else None, + _expire_value(payload) if "expire" in provided else None, + payload.get("privsep") if "privsep" in provided else None, + hash_secret(secret) if secret is not None else None, + ) + if row is None: + raise ApiError(404, "API token does not exist") + result = _token_info(row) + if secret is not None: + result.update({"full-tokenid": f"{userid}!{tokenid}", "value": secret}) + return result + + async def token_delete(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + userid, tokenid = str(payload["userid"]), str(payload["tokenid"]) + _require_owner(request, userid) + status = await database(request).pool.execute( + """DELETE FROM api_tokens t USING principals p + WHERE p.id=t.principal_id AND p.name=$1 AND t.token_id=$2""", + userid, + tokenid, + ) + if status != "DELETE 1": + raise ApiError(404, "API token does not exist") + + async def role_list(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + rows = await database(_request).pool.fetch( + "SELECT name, privileges FROM roles ORDER BY name" + ) + return [ + {"roleid": str(row["name"]), "privs": ",".join(str(item) for item in row["privileges"])} + for row in rows + ] + + async def role_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + roleid = str(values(inputs)["roleid"]) + row = await database(request).pool.fetchrow( + "SELECT name, privileges FROM roles WHERE name=$1", + roleid, + ) + if row is None: + raise ApiError(404, "role does not exist") + return { + "roleid": str(row["name"]), + "privs": ",".join(str(item) for item in row["privileges"]), + } + + async def role_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + roleid = str(payload["roleid"]) + privs = [item.strip() for item in str(payload.get("privs", "")).split(",") if item.strip()] + await database(request).pool.execute( + """INSERT INTO roles(name, privileges) VALUES($1, $2) + ON CONFLICT (name) DO UPDATE SET privileges=EXCLUDED.privileges""", + roleid, + privs, + ) + + async def role_update(request: Request, inputs: dict[str, Any]) -> None: + await role_create(request, inputs) + + async def role_delete(request: Request, inputs: dict[str, Any]) -> None: + roleid = str(values(inputs)["roleid"]) + status = await database(request).pool.execute( + "DELETE FROM roles WHERE name=$1", + roleid, + ) + if status != "DELETE 1": + raise ApiError(404, "role does not exist") + + async def domain_list(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + rows = await database(_request).pool.fetch( + "SELECT name, kind, config FROM realms ORDER BY name" + ) + return [_domain_payload(str(row["name"]), str(row["kind"]), row["config"]) for row in rows] + + async def domain_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + realm = str(values(inputs)["realm"]) + row = await database(request).pool.fetchrow( + "SELECT name, kind, config FROM realms WHERE name=$1", + realm, + ) + if row is None: + raise ApiError(404, "realm does not exist") + return _domain_payload(str(row["name"]), str(row["kind"]), row["config"]) + + async def domain_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + realm = str(payload["realm"]) + realm_type = str(payload.get("type") or "") + if realm_type not in _REALM_TYPES: + missing = realm_type or "" + raise ApiError(400, f"parameter verification failed - type: {missing}") + exists = await database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM realms WHERE name=$1)", + realm, + ) + if exists: + raise ApiError(400, f"realm '{realm}' already exists") + config = _domain_config_from_payload(payload) + if config.get("default"): + await database(request).pool.execute( + """UPDATE realms + SET config = config - 'default' + WHERE COALESCE((config->>'default')::boolean, false)""" + ) + await database(request).pool.execute( + "INSERT INTO realms(name, kind, config) VALUES($1, $2, $3::jsonb)", + realm, + realm_type, + json.dumps(config, sort_keys=True), + ) + + async def domain_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + realm = str(payload["realm"]) + provided = frozenset(str(item) for item in inputs.get("provided", payload)) + row = await database(request).pool.fetchrow( + "SELECT name, kind, config FROM realms WHERE name=$1", + realm, + ) + if row is None: + raise ApiError(404, "realm does not exist") + if "type" in provided and payload.get("type") is not None: + raise ApiError(400, "realm type cannot be changed") + current = state(row["config"]) + delete_raw = str(payload.get("delete") or "") + for key in [item.strip() for item in delete_raw.split(",") if item.strip()]: + current.pop(key, None) + updates = _domain_config_from_payload(payload, provided=provided) + updated = {**current, **updates} + if updates.get("default"): + await database(request).pool.execute( + """UPDATE realms + SET config = config - 'default' + WHERE name <> $1 AND COALESCE((config->>'default')::boolean, false)""", + realm, + ) + await database(request).pool.execute( + "UPDATE realms SET config=$2::jsonb WHERE name=$1", + realm, + json.dumps(updated, sort_keys=True), + ) + + async def domain_delete(request: Request, inputs: dict[str, Any]) -> None: + realm = str(values(inputs)["realm"]) + if realm in _BUILTIN_REALMS: + raise ApiError(400, "builtin authentication server can't be removed") + exists = await database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM realms WHERE name=$1)", + realm, + ) + if not exists: + raise ApiError(404, "realm does not exist") + in_use = await database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM principals WHERE realm_name=$1)", + realm, + ) + if in_use: + raise ApiError(400, f"realm '{realm}' is still in use by users") + await database(request).pool.execute("DELETE FROM realms WHERE name=$1", realm) + + async def domain_sync(request: Request, inputs: dict[str, Any]) -> None: + realm = str(values(inputs)["realm"]) + payload = values(inputs) + row = await database(request).pool.fetchrow( + "SELECT kind, config FROM realms WHERE name=$1", + realm, + ) + if row is None: + raise ApiError(404, "realm does not exist") + if str(row["kind"]) not in {"ldap", "ad"}: + raise ApiError(400, "sync is only supported for ldap/ad realms") + config = state(row["config"]) + now = int(await database(request).pool.fetchval("SELECT extract(epoch from now())::bigint")) + config["last_sync"] = now + config["last_sync_options"] = { + key: payload[key] + for key in ( + "dry-run", + "enable-new", + "full", + "purge", + "remove-vanished", + "scope", + ) + if key in payload + } + await database(request).pool.execute( + "UPDATE realms SET config=$2::jsonb WHERE name=$1", + realm, + json.dumps(config, sort_keys=True), + ) + + registry.register("/access", "GET", access_index) + registry.register("/access/users", "GET", user_list) + registry.register("/access/users", "POST", user_create) + registry.register("/access/users/{userid}", "GET", user_get) + registry.register("/access/users/{userid}", "PUT", user_update) + registry.register("/access/users/{userid}", "DELETE", user_delete) + registry.register("/access/groups", "GET", group_list) + registry.register("/access/groups", "POST", group_create) + registry.register("/access/groups/{groupid}", "GET", group_get) + registry.register("/access/groups/{groupid}", "PUT", group_update) + registry.register("/access/groups/{groupid}", "DELETE", group_delete) + registry.register("/access/password", "PUT", password_update) + registry.register("/access/acl", "GET", acl_list) + registry.register("/access/acl", "PUT", acl_update) + registry.register("/access/roles", "GET", role_list) + registry.register("/access/roles", "POST", role_create) + registry.register("/access/roles/{roleid}", "GET", role_get) + registry.register("/access/roles/{roleid}", "PUT", role_update) + registry.register("/access/roles/{roleid}", "DELETE", role_delete) + registry.register("/access/domains", "GET", domain_list) + registry.register("/access/domains", "POST", domain_create) + registry.register("/access/domains/{realm}", "GET", domain_get) + registry.register("/access/domains/{realm}", "PUT", domain_update) + registry.register("/access/domains/{realm}", "DELETE", domain_delete) + registry.register("/access/domains/{realm}/sync", "POST", domain_sync) + registry.register("/access/users/{userid}/token", "GET", token_list) + registry.register("/access/users/{userid}/token/{tokenid}", "GET", token_get) + registry.register("/access/users/{userid}/token/{tokenid}", "POST", token_create) + registry.register("/access/users/{userid}/token/{tokenid}", "PUT", token_update) + registry.register("/access/users/{userid}/token/{tokenid}", "DELETE", token_delete) + register_access_auth_handlers(registry) diff --git a/app/handlers/access_auth.py b/app/handlers/access_auth.py new file mode 100644 index 0000000..5c334b8 --- /dev/null +++ b/app/handlers/access_auth.py @@ -0,0 +1,381 @@ +"""Access TFA, OpenID, permissions, and ticket helpers with durable state.""" + +from __future__ import annotations + +import json +import secrets +from typing import Any, cast +from urllib.parse import urlencode + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.config import Settings +from app.handlers.common import database, values +from app.security.auth import AuthenticationError, csrf_token, issue_ticket, verify_ticket + +_TFA_TYPES = frozenset({"totp", "u2f", "webauthn", "recovery", "yubico"}) + + +def _settings(request: Request) -> Settings: + return cast(Settings, request.app.state.settings) + + +def _tfa_public(row: Any) -> dict[str, Any]: + created = row["created_at"] + created_ts = int(created.timestamp()) if hasattr(created, "timestamp") else int(created or 0) + return { + "id": str(row["entry_id"]), + "type": str(row["tfa_type"]), + "description": row["description"] or "", + "enable": int(bool(row["enable"])), + "created": created_ts, + } + + +async def _principal_row(request: Request, userid: str) -> Any: + row = await database(request).pool.fetchrow( + """SELECT id, name, tfa_locked_until, totp_locked + FROM principals WHERE name=$1""", + userid, + ) + if row is None: + raise ApiError(404, "user does not exist") + return row + + +def register_access_auth_handlers(registry: HandlerRegistry) -> None: + async def ticket_get(_request: Request, _inputs: dict[str, Any]) -> None: + return None + + async def permissions(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + userid = str(payload.get("userid") or request.state.principal) + path_filter = payload.get("path") + if userid == "root@pam": + caps = { + "/": { + "Permissions.Modify": 1, + "Sys.Audit": 1, + "Sys.Modify": 1, + "VM.Allocate": 1, + "VM.Audit": 1, + "VM.PowerMgmt": 1, + "Datastore.Allocate": 1, + "Datastore.Audit": 1, + } + } + if path_filter: + return {str(path_filter): caps["/"]} + return caps + + rows = await database(request).pool.fetch( + """SELECT a.path, r.privileges + FROM acl_entries a + JOIN principals p ON p.id=a.principal_id + JOIN roles r ON r.name=a.role_name + WHERE p.name=$1 + UNION ALL + SELECT a.path, r.privileges + FROM group_acl_entries a + JOIN identity_groups g ON g.id=a.group_id + JOIN identity_group_members m ON m.group_id=g.id + JOIN principals p ON p.id=m.principal_id + JOIN roles r ON r.name=a.role_name + WHERE p.name=$1""", + userid, + ) + result: dict[str, dict[str, int]] = {} + for row in rows: + path = str(row["path"]) + bucket = result.setdefault(path, {}) + for privilege in row["privileges"] or []: + bucket[str(privilege)] = 1 + if path_filter: + target = str(path_filter) + merged: dict[str, int] = {} + for path, privs in result.items(): + if target == path or target.startswith(path.rstrip("/") + "/") or path == "/": + merged.update(privs) + return {target: merged} if merged else {} + return result + + async def vncticket(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + ticket = str(payload["vncticket"]) + key = _settings(request).ticket_signing_key.get_secret_value().encode() + try: + claims = verify_ticket(ticket, key) + except AuthenticationError as error: + raise ApiError(401, "authentication failure") from error + authid = str(payload["authid"]) + if claims.principal != authid: + raise ApiError(401, "authentication failure") + return None + + async def openid_index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return [{"subdir": "auth-url"}, {"subdir": "login"}] + + async def openid_auth_url(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + realm = str(payload["realm"]) + redirect_url = str(payload["redirect-url"]) + row = await database(request).pool.fetchrow( + "SELECT name, kind, config FROM realms WHERE name=$1", + realm, + ) + if row is None: + raise ApiError(404, "realm does not exist") + if str(row["kind"]) != "openid": + raise ApiError(400, "realm is not an OpenID realm") + state = secrets.token_urlsafe(16) + await database(request).pool.execute( + """INSERT INTO openid_pending(state, realm, redirect_url) + VALUES($1, $2, $3) + ON CONFLICT (state) DO UPDATE + SET realm=EXCLUDED.realm, redirect_url=EXCLUDED.redirect_url, + created_at=now()""", + state, + realm, + redirect_url, + ) + config = row["config"] + if isinstance(config, str): + config = json.loads(config) + config = config or {} + issuer = str(config.get("issuer-url") or "https://openid.example.local") + client_id = str(config.get("client-id") or "pve-simulator") + query = urlencode( + { + "client_id": client_id, + "redirect_uri": redirect_url, + "response_type": "code", + "scope": str(config.get("scopes") or "openid email profile"), + "state": state, + } + ) + return f"{issuer.rstrip('/')}/authorize?{query}" + + async def openid_login(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + state = str(payload["state"]) + pending = await database(request).pool.fetchrow( + "SELECT realm, redirect_url FROM openid_pending WHERE state=$1", + state, + ) + if pending is None: + raise ApiError(400, "invalid OpenID state") + redirect = payload.get("redirect-url") + if redirect is not None and str(redirect) != str(pending["redirect_url"]): + raise ApiError(400, "redirect-url mismatch") + realm = str(pending["realm"]) + code = str(payload["code"]) + username = f"openid-{code[:12]}@{realm}" + exists = await database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM principals WHERE name=$1)", + username, + ) + if not exists: + await database(request).pool.execute( + """INSERT INTO principals(id, name, password_hash, realm_name) + VALUES(gen_random_uuid(), $1, NULL, $2)""", + username, + realm, + ) + await database(request).pool.execute( + "DELETE FROM openid_pending WHERE state=$1", + state, + ) + key = _settings(request).ticket_signing_key.get_secret_value().encode() + ticket = issue_ticket(username, key) + return { + "username": username, + "ticket": ticket, + "CSRFPreventionToken": csrf_token(ticket, key), + "clustername": "pve-simulator", + "cap": {}, + } + + async def tfa_list_all(request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + rows = await database(request).pool.fetch( + """SELECT p.name AS userid, p.tfa_locked_until, p.totp_locked, + t.entry_id, t.tfa_type, t.description, t.enable, t.created_at + FROM principals p + LEFT JOIN tfa_entries t ON t.principal_id=p.id + ORDER BY p.name, t.entry_id""" + ) + by_user: dict[str, dict[str, Any]] = {} + for row in rows: + userid = str(row["userid"]) + item = by_user.setdefault( + userid, + { + "userid": userid, + "entries": [], + "totp-locked": int(bool(row["totp_locked"])), + }, + ) + if row["tfa_locked_until"] is not None: + locked = row["tfa_locked_until"] + item["tfa-locked-until"] = ( + int(locked.timestamp()) if hasattr(locked, "timestamp") else int(locked) + ) + if row["entry_id"] is not None: + item["entries"].append(_tfa_public(row)) + return list(by_user.values()) + + async def tfa_list_user(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + userid = str(values(inputs)["userid"]) + principal = await _principal_row(request, userid) + rows = await database(request).pool.fetch( + """SELECT entry_id, tfa_type, description, enable, created_at + FROM tfa_entries WHERE principal_id=$1 ORDER BY entry_id""", + principal["id"], + ) + return [_tfa_public(row) for row in rows] + + async def tfa_add(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + userid = payload.get("userid") + if userid in {None, ""}: + raise ApiError(400, "parameter 'userid' is required") + userid = str(userid) + tfa_type = payload.get("type") + if tfa_type in {None, ""}: + raise ApiError(400, "parameter 'type' is required") + tfa_type = str(tfa_type) + if tfa_type not in _TFA_TYPES: + raise ApiError(400, f"invalid TFA type: {tfa_type}") + principal = await _principal_row(request, userid) + entry_id = secrets.token_hex(8) + secret = str(payload.get("value") or payload.get("totp") or secrets.token_hex(20)) + description = str(payload.get("description") or tfa_type) + recovery: list[str] = [] + metadata: dict[str, Any] = {} + if tfa_type == "recovery": + recovery = [secrets.token_hex(5) for _ in range(8)] + metadata["recovery"] = recovery + await database(request).pool.execute( + """INSERT INTO tfa_entries( + principal_id, entry_id, tfa_type, description, enable, secret, metadata + ) VALUES($1, $2, $3, $4, true, $5, $6::jsonb)""", + principal["id"], + entry_id, + tfa_type, + description, + secret, + json.dumps(metadata, sort_keys=True), + ) + result: dict[str, Any] = {"id": entry_id} + if recovery: + result["recovery"] = recovery + if payload.get("challenge") is not None: + result["challenge"] = payload.get("challenge") + return result + + async def tfa_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + userid = str(values(inputs)["userid"]) + entry_id = str(values(inputs)["id"]) + principal = await _principal_row(request, userid) + row = await database(request).pool.fetchrow( + """SELECT entry_id, tfa_type, description, enable, created_at + FROM tfa_entries WHERE principal_id=$1 AND entry_id=$2""", + principal["id"], + entry_id, + ) + if row is None: + raise ApiError(404, "TFA entry does not exist") + return _tfa_public(row) + + async def tfa_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + userid = payload.get("userid") + if userid in {None, ""}: + raise ApiError(400, "parameter 'userid' is required") + userid = str(userid) + entry_id = payload.get("id") + if entry_id in {None, ""}: + raise ApiError(400, "parameter 'id' is required") + entry_id = str(entry_id) + provided = frozenset(str(item) for item in inputs.get("provided", payload)) + principal = await _principal_row(request, userid) + row = await database(request).pool.fetchrow( + "SELECT entry_id FROM tfa_entries WHERE principal_id=$1 AND entry_id=$2", + principal["id"], + entry_id, + ) + if row is None: + raise ApiError(404, "TFA entry does not exist") + if "description" in provided: + await database(request).pool.execute( + """UPDATE tfa_entries SET description=$3 + WHERE principal_id=$1 AND entry_id=$2""", + principal["id"], + entry_id, + payload.get("description"), + ) + if "enable" in provided: + enabled = payload.get("enable") + if isinstance(enabled, bool): + value = enabled + else: + value = str(enabled).lower() in {"1", "true", "yes", "on"} + await database(request).pool.execute( + """UPDATE tfa_entries SET enable=$3 + WHERE principal_id=$1 AND entry_id=$2""", + principal["id"], + entry_id, + value, + ) + + async def tfa_delete(request: Request, inputs: dict[str, Any]) -> None: + userid = str(values(inputs)["userid"]) + entry_id = str(values(inputs)["id"]) + principal = await _principal_row(request, userid) + status = await database(request).pool.execute( + "DELETE FROM tfa_entries WHERE principal_id=$1 AND entry_id=$2", + principal["id"], + entry_id, + ) + if status != "DELETE 1": + raise ApiError(404, "TFA entry does not exist") + + async def user_tfa_types(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + userid = str(values(inputs)["userid"]) + principal = await _principal_row(request, userid) + rows = await database(request).pool.fetch( + """SELECT DISTINCT tfa_type FROM tfa_entries + WHERE principal_id=$1 AND enable=true ORDER BY tfa_type""", + principal["id"], + ) + types = [str(row["tfa_type"]) for row in rows] + realm = userid.split("@", 1)[1] if "@" in userid else "pam" + return {"user": types, "types": types, "realm": realm} + + async def unlock_tfa(request: Request, inputs: dict[str, Any]) -> bool: + userid = str(values(inputs)["userid"]) + status = await database(request).pool.execute( + """UPDATE principals + SET tfa_locked_until=NULL, totp_locked=false + WHERE name=$1""", + userid, + ) + if status != "UPDATE 1": + raise ApiError(404, "user does not exist") + return True + + registry.register("/access/ticket", "GET", ticket_get) + registry.register("/access/permissions", "GET", permissions) + registry.register("/access/vncticket", "POST", vncticket) + registry.register("/access/openid", "GET", openid_index) + registry.register("/access/openid/auth-url", "POST", openid_auth_url) + registry.register("/access/openid/login", "POST", openid_login) + registry.register("/access/tfa", "GET", tfa_list_all) + registry.register("/access/tfa/{userid}", "GET", tfa_list_user) + registry.register("/access/tfa/{userid}", "POST", tfa_add) + registry.register("/access/tfa/{userid}/{id}", "GET", tfa_get) + registry.register("/access/tfa/{userid}/{id}", "PUT", tfa_update) + registry.register("/access/tfa/{userid}/{id}", "DELETE", tfa_delete) + registry.register("/access/users/{userid}/tfa", "GET", user_tfa_types) + registry.register("/access/users/{userid}/unlock-tfa", "PUT", unlock_tfa) diff --git a/app/handlers/acme.py b/app/handlers/acme.py new file mode 100644 index 0000000..01d944d --- /dev/null +++ b/app/handlers/acme.py @@ -0,0 +1,223 @@ +"""Cluster ACME accounts and DNS plugins.""" + +from __future__ import annotations + +from typing import Any + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.common import cluster_metadata, save_cluster_metadata, subdirs, values + +_DEFAULT_DIRECTORIES = [ + { + "name": "Let's Encrypt V2", + "url": "https://acme-v02.api.letsencrypt.org/directory", + }, + { + "name": "Let's Encrypt V2 Staging", + "url": "https://acme-staging-v02.api.letsencrypt.org/directory", + }, +] + +_CHALLENGE_SCHEMA = [ + { + "id": "dns", + "name": "DNS plugin", + "type": "dns", + "fields": [{"name": "api", "type": "string"}], + } +] + + +def _acme(metadata: dict[str, Any]) -> dict[str, Any]: + current = metadata.setdefault( + "acme", + {"accounts": {}, "plugins": {}, "meta": {}}, + ) + if not isinstance(current, dict): + current = {"accounts": {}, "plugins": {}, "meta": {}} + metadata["acme"] = current + current.setdefault("accounts", {}) + current.setdefault("plugins", {}) + current.setdefault("meta", {}) + return current + + +def register_acme_handlers(registry: HandlerRegistry) -> None: + async def index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs( + "account", + "challenge-schema", + "directories", + "meta", + "plugins", + "tos", + ) + + async def account_list(request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + metadata = await cluster_metadata(request) + accounts = _acme(metadata)["accounts"] + return [ + { + "name": name, + "contact": item.get("contact", []), + "directory": item.get("directory"), + } + for name, item in sorted(accounts.items()) + ] + + async def account_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + name = str(payload.get("name") or "default") + metadata = await cluster_metadata(request) + accounts = _acme(metadata)["accounts"] + if name in accounts: + raise ApiError(400, f"ACME account '{name}' already exists") + accounts[name] = { + "name": name, + "contact": payload.get("contact"), + "directory": payload.get("directory") or _DEFAULT_DIRECTORIES[0]["url"], + "tos_url": payload.get("tos_url"), + "eab-kid": payload.get("eab-kid"), + # eab-hmac-key stored but never returned + "eab-hmac-key": payload.get("eab-hmac-key"), + "location": f"https://acme.example.local/acct/{name}", + } + await save_cluster_metadata(request, metadata) + + async def account_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + name = str(values(inputs)["name"]) + metadata = await cluster_metadata(request) + account = _acme(metadata)["accounts"].get(name) + if not isinstance(account, dict): + raise ApiError(404, "ACME account does not exist") + return { + "name": name, + "contact": account.get("contact"), + "directory": account.get("directory"), + "tos": account.get("tos_url"), + "location": account.get("location"), + } + + async def account_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + name = str(payload["name"]) + metadata = await cluster_metadata(request) + accounts = _acme(metadata)["accounts"] + if name not in accounts: + raise ApiError(404, "ACME account does not exist") + if "contact" in payload: + accounts[name]["contact"] = payload["contact"] + await save_cluster_metadata(request, metadata) + + async def account_delete(request: Request, inputs: dict[str, Any]) -> None: + name = str(values(inputs)["name"]) + metadata = await cluster_metadata(request) + accounts = _acme(metadata)["accounts"] + if name not in accounts: + raise ApiError(404, "ACME account does not exist") + del accounts[name] + await save_cluster_metadata(request, metadata) + + async def plugins_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + metadata = await cluster_metadata(request) + plugins = _acme(metadata)["plugins"] + plugin_type = values(inputs).get("type") + result = [] + for plugin_id, item in sorted(plugins.items()): + if plugin_type and item.get("type") != plugin_type: + continue + result.append({"plugin": plugin_id, **{k: v for k, v in item.items() if k != "data"}}) + return result + + async def plugins_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + plugin_id = str(payload["id"]) + metadata = await cluster_metadata(request) + plugins = _acme(metadata)["plugins"] + if plugin_id in plugins: + raise ApiError(400, f"ACME plugin '{plugin_id}' already exists") + plugins[plugin_id] = { + key: value for key, value in payload.items() if key not in {"delete", "digest"} + } + await save_cluster_metadata(request, metadata) + + async def plugins_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + plugin_id = str(values(inputs)["id"]) + metadata = await cluster_metadata(request) + plugin = _acme(metadata)["plugins"].get(plugin_id) + if not isinstance(plugin, dict): + raise ApiError(404, "ACME plugin does not exist") + return {"id": plugin_id, **plugin} + + async def plugins_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + plugin_id = str(payload["id"]) + metadata = await cluster_metadata(request) + plugins = _acme(metadata)["plugins"] + if plugin_id not in plugins: + raise ApiError(404, "ACME plugin does not exist") + current = dict(plugins[plugin_id]) + for key in [ + item.strip() for item in str(payload.get("delete") or "").split(",") if item.strip() + ]: + current.pop(key, None) + for key, value in payload.items(): + if key in {"id", "delete", "digest"}: + continue + current[key] = value + current["id"] = plugin_id + plugins[plugin_id] = current + await save_cluster_metadata(request, metadata) + + async def plugins_delete(request: Request, inputs: dict[str, Any]) -> None: + plugin_id = str(values(inputs)["id"]) + metadata = await cluster_metadata(request) + plugins = _acme(metadata)["plugins"] + if plugin_id not in plugins: + raise ApiError(404, "ACME plugin does not exist") + del plugins[plugin_id] + await save_cluster_metadata(request, metadata) + + async def directories(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + return list(_DEFAULT_DIRECTORIES) + + async def challenge_schema(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + return list(_CHALLENGE_SCHEMA) + + async def meta(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + directory = str(values(inputs).get("directory") or _DEFAULT_DIRECTORIES[0]["url"]) + metadata = await cluster_metadata(request) + meta_store = _acme(metadata).setdefault("meta", {}) + payload = meta_store.setdefault( + directory, + { + "termsOfService": f"{directory.rstrip('/')}/tos", + "caaIdentities": ["letsencrypt.org"], + }, + ) + await save_cluster_metadata(request, metadata) + return dict(payload) + + async def tos(request: Request, inputs: dict[str, Any]) -> str: + directory = str(values(inputs).get("directory") or _DEFAULT_DIRECTORIES[0]["url"]) + result = await meta(request, {"values": {"directory": directory}, "provided": frozenset()}) + return str(result.get("termsOfService") or "") + + registry.register("/cluster/acme", "GET", index) + registry.register("/cluster/acme/account", "GET", account_list) + registry.register("/cluster/acme/account", "POST", account_create) + registry.register("/cluster/acme/account/{name}", "GET", account_get) + registry.register("/cluster/acme/account/{name}", "PUT", account_update) + registry.register("/cluster/acme/account/{name}", "DELETE", account_delete) + registry.register("/cluster/acme/plugins", "GET", plugins_list) + registry.register("/cluster/acme/plugins", "POST", plugins_create) + registry.register("/cluster/acme/plugins/{id}", "GET", plugins_get) + registry.register("/cluster/acme/plugins/{id}", "PUT", plugins_update) + registry.register("/cluster/acme/plugins/{id}", "DELETE", plugins_delete) + registry.register("/cluster/acme/directories", "GET", directories) + registry.register("/cluster/acme/challenge-schema", "GET", challenge_schema) + registry.register("/cluster/acme/meta", "GET", meta) + registry.register("/cluster/acme/tos", "GET", tos) diff --git a/app/handlers/backup.py b/app/handlers/backup.py new file mode 100644 index 0000000..46d3bbd --- /dev/null +++ b/app/handlers/backup.py @@ -0,0 +1,236 @@ +"""Cluster backup and vzdump handlers.""" + +from __future__ import annotations + +import json +from typing import Any + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.db.primitives import ConflictError +from app.handlers.common import database, require_node, state, values +from app.tasks.repository import TaskRepository +from app.tasks.upid import Upid + + +def register_backup_handlers(registry: HandlerRegistry) -> None: + async def backup_list(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + rows = await database(_request).pool.fetch( + """SELECT b.id, b.volume_id, b.size_bytes, b.metadata, b.created_at, + r.external_id AS vmid, n.name AS node, s.storage_id + FROM backups b + LEFT JOIN resources r ON r.id = b.resource_id + LEFT JOIN nodes n ON n.id = r.node_id + JOIN storages s ON s.resource_id = b.storage_resource_id + ORDER BY b.created_at DESC LIMIT 2000""" + ) + result: list[dict[str, Any]] = [] + for row in rows: + metadata = state(row["metadata"]) + result.append( + { + "id": str(row["id"]), + "volid": str(row["volume_id"]), + "size": int(row["size_bytes"]), + "vmid": int(row["vmid"]) if row["vmid"] is not None else None, + "node": str(row["node"]) if row["node"] is not None else None, + "storage": str(row["storage_id"]), + "starttime": int(row["created_at"].timestamp()), + "mode": metadata.get("mode", "snapshot"), + "type": metadata.get("type", "vzdump"), + } + ) + return result + + async def backup_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + backup_id = str(values(inputs)["id"]) + row = await database(request).pool.fetchrow( + """SELECT b.id, b.volume_id, b.size_bytes, b.metadata, b.created_at, + r.external_id AS vmid, n.name AS node, s.storage_id + FROM backups b + LEFT JOIN resources r ON r.id = b.resource_id + LEFT JOIN nodes n ON n.id = r.node_id + JOIN storages s ON s.resource_id = b.storage_resource_id + WHERE b.id::text = $1 OR b.volume_id = $1""", + backup_id, + ) + if row is None: + raise ApiError(404, "backup does not exist") + metadata = state(row["metadata"]) + return { + "id": str(row["id"]), + "volid": str(row["volume_id"]), + "size": int(row["size_bytes"]), + "vmid": int(row["vmid"]) if row["vmid"] is not None else None, + "node": str(row["node"]) if row["node"] is not None else None, + "storage": str(row["storage_id"]), + "starttime": int(row["created_at"].timestamp()), + "notes": metadata.get("notes-template"), + **metadata, + } + + async def backup_update(request: Request, inputs: dict[str, Any]) -> None: + backup_id = str(values(inputs)["id"]) + row = await database(request).pool.fetchrow( + "SELECT id, metadata FROM backups WHERE id::text = $1", + backup_id, + ) + if row is None: + raise ApiError(404, "backup does not exist") + metadata = state(row["metadata"]) + payload = values(inputs) + if "notes" in payload: + metadata["notes-template"] = payload["notes"] + await database(request).pool.execute( + "UPDATE backups SET metadata=$2::jsonb WHERE id=$1", + row["id"], + json.dumps(metadata, sort_keys=True), + ) + + async def backup_delete(request: Request, inputs: dict[str, Any]) -> None: + backup_id = str(values(inputs)["id"]) + status = await database(request).pool.execute( + "DELETE FROM backups WHERE id::text = $1", + backup_id, + ) + if status != "DELETE 1": + raise ApiError(404, "backup does not exist") + + async def backup_create(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload.get("node") or payload.get("target") or "pve01") + await require_node(request, node) + vmid = payload.get("vmid") + return await _schedule_vzdump( + request, + node=node, + vmids=[str(vmid)] if vmid is not None else None, + payload=payload, + ) + + async def backup_info(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + rows = await database(_request).pool.fetch( + """SELECT r.external_id AS vmid, n.name AS node, max(b.created_at) AS last_backup + FROM resources r + JOIN nodes n ON n.id = r.node_id + LEFT JOIN backups b ON b.resource_id = r.id + WHERE r.kind = 'qemu' + GROUP BY r.external_id, n.name + ORDER BY r.external_id::integer + LIMIT 5000""" + ) + return [ + { + "vmid": int(row["vmid"]), + "node": str(row["node"]), + "lastbackup": int(row["last_backup"].timestamp()) if row["last_backup"] else 0, + "protected": 0, + } + for row in rows + ] + + async def backup_not_backed_up(_request: Request, _inputs: dict[str, Any]) -> list[int]: + rows = await database(_request).pool.fetch( + """SELECT r.external_id::integer AS vmid + FROM resources r + LEFT JOIN backups b ON b.resource_id = r.id + WHERE r.kind = 'qemu' AND b.id IS NULL + ORDER BY r.external_id::integer""" + ) + return [int(row["vmid"]) for row in rows] + + async def backup_included_volumes(request: Request, inputs: dict[str, Any]) -> list[str]: + backup_id = str(values(inputs)["id"]) + row = await database(request).pool.fetchrow( + """SELECT b.volume_id, r.external_id AS vmid + FROM backups b LEFT JOIN resources r ON r.id = b.resource_id + WHERE b.id::text = $1""", + backup_id, + ) + if row is None: + raise ApiError(404, "backup does not exist") + vmid = row["vmid"] + return [f"qemu/{vmid}"] if vmid is not None else [str(row["volume_id"])] + + async def vzdump_defaults(_request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + await require_node(_request, str(values(inputs)["node"])) + return { + "all": 0, + "bwlimit": 0, + "compress": "zstd", + "dumpdir": "backup", + "mode": "snapshot", + "remove": 0, + "storage": "nfs-backup", + "mailto": "", + "notes-template": "{{guestname}}", + } + + async def vzdump_extractconfig(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + volid = str(payload.get("volume") or payload.get("volid") or "") + if not volid: + raise ApiError(400, "volume parameter required") + return f"# simulated vzdump config extracted from {volid}\name: demo\nmemory: 2048\n" + + async def vzdump_create(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + vmids = payload.get("vmid") + selected = None + if vmids is not None: + selected = [str(item) for item in str(vmids).split(",") if item.strip()] + return await _schedule_vzdump(request, node=node, vmids=selected, payload=payload) + + registry.register("/cluster/backup", "GET", backup_list) + registry.register("/cluster/backup", "POST", backup_create) + registry.register("/cluster/backup-info", "GET", backup_info) + registry.register("/cluster/backup-info/not-backed-up", "GET", backup_not_backed_up) + registry.register("/cluster/backup/{id}", "GET", backup_get) + registry.register("/cluster/backup/{id}", "PUT", backup_update) + registry.register("/cluster/backup/{id}", "DELETE", backup_delete) + registry.register("/cluster/backup/{id}/included_volumes", "GET", backup_included_volumes) + registry.register("/nodes/{node}/vzdump", "POST", vzdump_create) + registry.register("/nodes/{node}/vzdump/defaults", "GET", vzdump_defaults) + registry.register("/nodes/{node}/vzdump/extractconfig", "GET", vzdump_extractconfig) + + +async def _schedule_vzdump( + request: Request, + *, + node: str, + vmids: list[str] | None, + payload: dict[str, Any], +) -> str: + pool = database(request).pool + if vmids is None: + rows = await pool.fetch( + """SELECT external_id FROM resources r JOIN nodes n ON n.id=r.node_id + WHERE n.name=$1 AND r.kind='qemu' ORDER BY external_id::integer LIMIT 100""", + node, + ) + vmids = [str(row["external_id"]) for row in rows] + if not vmids: + raise ApiError(400, "no virtual machines selected for backup") + vmid = vmids[0] + upid = str(Upid.allocate(node, "vzdump", vmid, str(request.state.principal))) + try: + task = await TaskRepository(pool).create( + upid=upid, + task_type="vzdump", + payload={ + "node": node, + "vmids": vmids, + "storage": str(payload.get("storage") or "nfs-backup"), + "mode": str(payload.get("mode") or "snapshot"), + "compress": str(payload.get("compress") or "zstd"), + }, + resource_key=f"backup:{node}", + idempotency_key=request.headers.get("Idempotency-Key"), + ) + except ConflictError as error: + raise ApiError(409, str(error)) from error + return task.upid diff --git a/app/handlers/ceph.py b/app/handlers/ceph.py new file mode 100644 index 0000000..d35b7a5 --- /dev/null +++ b/app/handlers/ceph.py @@ -0,0 +1,759 @@ +"""Ceph semantic handlers with durable cluster/node state.""" + +from __future__ import annotations + +import json +import secrets +from typing import Any, cast + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.common import ( + database, + node_metadata, + require_node, + save_node_metadata, + state, + subdirs, + values, +) +from app.simulation.seed import CLUSTER_ID + +DEFAULT_CLUSTER_CEPH = { + "initialized": True, + "config": { + "network": "10.10.10.0/24", + "cluster-network": "10.10.10.0/24", + "size": 3, + "min_size": 2, + "pg_bits": 7, + }, + "cfg_db": [ + {"section": "global", "name": "auth_client_required", "value": "cephx"}, + {"section": "global", "name": "fsid", "value": "pve-simulator-fsid"}, + ], + "cfg_raw": "[global]\nfsid = pve-simulator-fsid\nauth_client_required = cephx\n", + "cfg_values": {}, + "pools": { + "rbd": { + "pool": "rbd", + "size": 3, + "min_size": 2, + "pg_num": 128, + "application": "rbd", + "crush_rule": "replicated_rule", + } + }, + "fs": {}, + "rules": [{"name": "replicated_rule", "id": 0}], + "crush": "device 0 osd.0 class hdd\n", + "running": True, +} + + +async def _load_cluster_ceph(request: Request) -> dict[str, Any]: + row = await database(request).pool.fetchrow( + "SELECT metadata FROM clusters WHERE id=$1", + CLUSTER_ID, + ) + metadata = state(row["metadata"]) if row is not None else {} + ceph = metadata.get("ceph") + if not isinstance(ceph, dict) or not ceph: + return dict(DEFAULT_CLUSTER_CEPH) + merged = dict(DEFAULT_CLUSTER_CEPH) + merged.update(ceph) + for key in ("config", "pools", "fs", "cfg_values"): + if not isinstance(merged.get(key), dict): + merged[key] = dict(cast(dict[str, Any], DEFAULT_CLUSTER_CEPH[key])) + return merged + + +async def _save_cluster_ceph(request: Request, ceph: dict[str, Any]) -> None: + await database(request).pool.execute( + """UPDATE clusters SET metadata = jsonb_set( + COALESCE(metadata, '{}'::jsonb), '{ceph}', $2::jsonb, true + ), updated_at=now() WHERE id=$1""", + CLUSTER_ID, + json.dumps(ceph, sort_keys=True), + ) + + +async def _load_node_ceph(request: Request, node: str) -> dict[str, Any]: + metadata = await node_metadata(request, node) + ops = metadata.setdefault("ops", {}) + ceph = ops.setdefault( + "ceph", + { + "mds": {}, + "mgr": {}, + "mon": {f"{node}": {"name": node, "addr": f"{node}.local:6789", "rank": 0}}, + "log": [{"t": 1_700_000_000, "n": 0, "line": "ceph simulator ready"}], + }, + ) + if not isinstance(ceph, dict): + ceph = { + "mds": {}, + "mgr": {}, + "mon": {}, + "log": [], + } + ops["ceph"] = ceph + ceph.setdefault("mds", {}) + ceph.setdefault("mgr", {}) + ceph.setdefault("mon", {}) + ceph.setdefault("log", []) + return ceph + + +async def _save_node_ceph(request: Request, node: str, ceph: dict[str, Any]) -> None: + metadata = await node_metadata(request, node) + ops = metadata.setdefault("ops", {}) + ops["ceph"] = ceph + await save_node_metadata(request, node, metadata) + + +def _upid(node: str, kind: str) -> str: + return f"UPID:{node}:{secrets.token_hex(4)}:{kind}:root@pam:" + + +async def _osd_row(request: Request, node: str, osdid: str) -> Any: + row = await database(request).pool.fetchrow( + """SELECT r.id, r.external_id, r.state + FROM resources r JOIN nodes n ON n.id=r.node_id + WHERE n.name=$1 AND r.kind='ceph-osd' + AND (r.external_id=$2 OR r.external_id=$3)""", + node, + osdid, + f"osd.{osdid}", + ) + if row is None: + raise ApiError(404, "OSD does not exist") + return row + + +def register_ceph_handlers(registry: HandlerRegistry) -> None: + async def ceph_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + node = str(values(inputs)["node"]) + await require_node(request, node) + return subdirs( + "cfg", + "cmd-safety", + "crush", + "fs", + "init", + "log", + "mds", + "mgr", + "mon", + "osd", + "pool", + "restart", + "rules", + "start", + "status", + "stop", + ) + + async def cfg_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + await require_node(request, str(values(inputs)["node"])) + return subdirs("db", "raw", "value") + + async def cfg_db(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + await require_node(request, str(values(inputs)["node"])) + ceph = await _load_cluster_ceph(request) + return list(ceph.get("cfg_db") or []) + + async def cfg_raw(request: Request, inputs: dict[str, Any]) -> str: + await require_node(request, str(values(inputs)["node"])) + ceph = await _load_cluster_ceph(request) + return str(ceph.get("cfg_raw") or "") + + async def cfg_value(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + await require_node(request, str(payload["node"])) + ceph = await _load_cluster_ceph(request) + keys = [item.strip() for item in str(payload.get("config-keys") or "").split(",") if item] + stored = ceph.setdefault("cfg_values", {}) + result = {key: stored.get(key, "") for key in keys} if keys else dict(stored) + await _save_cluster_ceph(request, ceph) + return result + + async def crush(request: Request, inputs: dict[str, Any]) -> str: + await require_node(request, str(values(inputs)["node"])) + ceph = await _load_cluster_ceph(request) + return str(ceph.get("crush") or "") + + async def rules(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + await require_node(request, str(values(inputs)["node"])) + ceph = await _load_cluster_ceph(request) + return list(ceph.get("rules") or []) + + async def log(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + await require_node(request, node) + ceph = await _load_node_ceph(request, node) + entries = list(ceph.get("log") or []) + start = int(values(inputs).get("start") or 0) + limit = int(values(inputs).get("limit") or 50) + return entries[start : start + limit] + + async def cmd_safety(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + await require_node(request, str(payload["node"])) + return { + "safe": 1, + "action": payload.get("action"), + "service": payload.get("service"), + "id": payload.get("id"), + } + + async def init(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + ceph = await _load_cluster_ceph(request) + config = ceph.setdefault("config", {}) + for key in ( + "network", + "cluster-network", + "size", + "min_size", + "pg_bits", + "disable_cephx", + ): + if key in payload: + config[key] = payload[key] + ceph["initialized"] = True + await _save_cluster_ceph(request, ceph) + node_ceph = await _load_node_ceph(request, node) + node_ceph.setdefault("mon", {})[node] = { + "name": node, + "addr": f"{node}.local:6789", + "rank": 0, + } + await _save_node_ceph(request, node, node_ceph) + + async def status(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(values(inputs)["node"]) + await require_node(request, node) + return await cluster_ceph_status(request, inputs) + + async def start(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + ceph = await _load_cluster_ceph(request) + ceph["running"] = True + ceph["last_service_action"] = { + "action": "start", + "service": payload.get("service"), + "node": node, + } + await _save_cluster_ceph(request, ceph) + return _upid(node, "cephstart") + + async def stop(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + ceph = await _load_cluster_ceph(request) + ceph["running"] = False + ceph["last_service_action"] = { + "action": "stop", + "service": payload.get("service"), + "node": node, + } + await _save_cluster_ceph(request, ceph) + return _upid(node, "cephstop") + + async def restart(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + ceph = await _load_cluster_ceph(request) + ceph["running"] = True + ceph["last_service_action"] = { + "action": "restart", + "service": payload.get("service"), + "node": node, + } + await _save_cluster_ceph(request, ceph) + return _upid(node, "cephrestart") + + async def pool_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + await require_node(request, str(values(inputs)["node"])) + ceph = await _load_cluster_ceph(request) + pools = ceph.get("pools") or {} + return [dict(item) for _, item in sorted(pools.items()) if isinstance(item, dict)] + + async def pool_create(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + name = str(payload["name"]) + ceph = await _load_cluster_ceph(request) + pools = ceph.setdefault("pools", {}) + if name in pools: + raise ApiError(400, f"pool '{name}' already exists") + pools[name] = { + "pool": name, + "size": int(payload.get("size") or 3), + "min_size": int(payload.get("min_size") or 2), + "pg_num": int(payload.get("pg_num") or 128), + "application": str(payload.get("application") or "rbd"), + "crush_rule": str(payload.get("crush_rule") or "replicated_rule"), + "pg_autoscale_mode": payload.get("pg_autoscale_mode", "warn"), + "target_size": payload.get("target_size"), + } + await _save_cluster_ceph(request, ceph) + return _upid(node, "cephcreatepool") + + async def pool_get(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + payload = values(inputs) + await require_node(request, str(payload["node"])) + name = str(payload["name"]) + ceph = await _load_cluster_ceph(request) + pool = (ceph.get("pools") or {}).get(name) + if not isinstance(pool, dict): + raise ApiError(404, "pool does not exist") + return [dict(pool)] + + async def pool_update(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + name = str(payload["name"]) + ceph = await _load_cluster_ceph(request) + pools = ceph.setdefault("pools", {}) + if name not in pools or not isinstance(pools[name], dict): + raise ApiError(404, "pool does not exist") + current = dict(pools[name]) + for key in ( + "application", + "crush_rule", + "min_size", + "pg_autoscale_mode", + "pg_num", + "pg_num_min", + "size", + "target_size", + "target_size_ratio", + ): + if key in payload: + current[key] = payload[key] + pools[name] = current + await _save_cluster_ceph(request, ceph) + return _upid(node, "cephsetpool") + + async def pool_delete(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + name = str(payload["name"]) + ceph = await _load_cluster_ceph(request) + pools = ceph.setdefault("pools", {}) + if name not in pools: + raise ApiError(404, "pool does not exist") + del pools[name] + await _save_cluster_ceph(request, ceph) + return _upid(node, "cephdestroypool") + + async def pool_status(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + await require_node(request, str(payload["node"])) + name = str(payload["name"]) + ceph = await _load_cluster_ceph(request) + pool = (ceph.get("pools") or {}).get(name) + if not isinstance(pool, dict): + raise ApiError(404, "pool does not exist") + return { + **pool, + "pg_num": pool.get("pg_num", 128), + "bytes_used": 0, + "percent_used": 0.0, + "healthy": True, + } + + async def fs_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + await require_node(request, str(values(inputs)["node"])) + ceph = await _load_cluster_ceph(request) + return [dict(item) for _, item in sorted((ceph.get("fs") or {}).items())] + + async def fs_create(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + name = str(payload["name"]) + ceph = await _load_cluster_ceph(request) + filesystems = ceph.setdefault("fs", {}) + if name in filesystems: + raise ApiError(400, f"fs '{name}' already exists") + filesystems[name] = { + "name": name, + "metadata": f"{name}_meta", + "data": f"{name}_data", + "pg_num": int(payload.get("pg_num") or 32), + } + await _save_cluster_ceph(request, ceph) + return _upid(node, "cephcreatefs") + + async def fs_delete(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + name = str(payload["name"]) + ceph = await _load_cluster_ceph(request) + filesystems = ceph.setdefault("fs", {}) + if name not in filesystems: + raise ApiError(404, "fs does not exist") + del filesystems[name] + await _save_cluster_ceph(request, ceph) + return _upid(node, "cephdestroyfs") + + async def mds_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + await require_node(request, node) + ceph = await _load_node_ceph(request, node) + return [ + {"name": name, **data} + for name, data in sorted((ceph.get("mds") or {}).items()) + if isinstance(data, dict) + ] + + async def mds_create(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + name = str(payload["name"]) + ceph = await _load_node_ceph(request, node) + mds = ceph.setdefault("mds", {}) + if name in mds: + raise ApiError(400, f"mds '{name}' already exists") + mds[name] = { + "name": name, + "state": "up:active", + "hotstandby": int(bool(payload.get("hotstandby"))), + } + await _save_node_ceph(request, node, ceph) + return _upid(node, "cephcreatemds") + + async def mds_delete(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + name = str(payload["name"]) + ceph = await _load_node_ceph(request, node) + mds = ceph.setdefault("mds", {}) + if name not in mds: + raise ApiError(404, "mds does not exist") + del mds[name] + await _save_node_ceph(request, node, ceph) + return _upid(node, "cephdestroymds") + + async def mgr_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + await require_node(request, node) + ceph = await _load_node_ceph(request, node) + return [ + {"name": name, **data} + for name, data in sorted((ceph.get("mgr") or {}).items()) + if isinstance(data, dict) + ] + + async def mgr_create(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + mgr_id = str(payload["id"]) + ceph = await _load_node_ceph(request, node) + mgr = ceph.setdefault("mgr", {}) + if mgr_id in mgr: + raise ApiError(400, f"mgr '{mgr_id}' already exists") + mgr[mgr_id] = {"name": mgr_id, "state": "active"} + await _save_node_ceph(request, node, ceph) + return _upid(node, "cephcreatemgr") + + async def mgr_delete(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + mgr_id = str(payload["id"]) + ceph = await _load_node_ceph(request, node) + mgr = ceph.setdefault("mgr", {}) + if mgr_id not in mgr: + raise ApiError(404, "mgr does not exist") + del mgr[mgr_id] + await _save_node_ceph(request, node, ceph) + return _upid(node, "cephdestroymgr") + + async def mon_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + await require_node(request, node) + ceph = await _load_node_ceph(request, node) + return [ + {"name": name, **data} + for name, data in sorted((ceph.get("mon") or {}).items()) + if isinstance(data, dict) + ] + + async def mon_create(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + monid = str(payload["monid"]) + ceph = await _load_node_ceph(request, node) + mons = ceph.setdefault("mon", {}) + if monid in mons: + raise ApiError(400, f"mon '{monid}' already exists") + mons[monid] = { + "name": monid, + "addr": str(payload.get("mon-address") or f"{node}.local:6789"), + "rank": len(mons), + } + await _save_node_ceph(request, node, ceph) + return _upid(node, "cephcreatemon") + + async def mon_delete(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + monid = str(payload["monid"]) + ceph = await _load_node_ceph(request, node) + mons = ceph.setdefault("mon", {}) + if monid not in mons: + raise ApiError(404, "mon does not exist") + del mons[monid] + await _save_node_ceph(request, node, ceph) + return _upid(node, "cephdestroymon") + + async def osd_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + await require_node(request, node) + rows = await database(request).pool.fetch( + """SELECT r.external_id, r.state + FROM resources r JOIN nodes n ON n.id=r.node_id + WHERE n.name=$1 AND r.kind='ceph-osd' + ORDER BY r.external_id""", + node, + ) + result: list[dict[str, Any]] = [] + for row in rows: + payload = state(row["state"]) + osd_id = payload.get("osd_id", row["external_id"]) + result.append( + { + "osd": int(osd_id) if str(osd_id).isdigit() else osd_id, + "status": payload.get("status", "up"), + "in": 1 if payload.get("in", True) else 0, + "weight": payload.get("weight", 1.0), + "device_class": payload.get("device_class", "hdd"), + } + ) + return result + + async def osd_create(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + next_id = await database(request).pool.fetchval( + """SELECT COALESCE( + MAX(NULLIF(regexp_replace(external_id, '\\D', '', 'g'), '')::int), + -1 + ) + 1 + FROM resources r JOIN nodes n ON n.id=r.node_id + WHERE n.name=$1 AND r.kind='ceph-osd'""", + node, + ) + osd_id = int(next_id or 0) + external_id = f"osd.{osd_id}" + node_id = await database(request).pool.fetchval( + "SELECT id FROM nodes WHERE name=$1", + node, + ) + osd_state = { + "osd_id": osd_id, + "status": "up", + "in": True, + "weight": 1.0, + "device_class": payload.get("crush-device-class") or "hdd", + "dev": payload.get("dev"), + "size_bytes": 0, + "used_bytes": 0, + } + await database(request).pool.execute( + """INSERT INTO resources(id, node_id, kind, external_id, state) + VALUES(gen_random_uuid(), $1, 'ceph-osd', $2, $3::jsonb)""", + node_id, + external_id, + json.dumps(osd_state, sort_keys=True), + ) + return _upid(node, "cephcreateosd") + + async def osd_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(values(inputs)["node"]) + osdid = str(values(inputs)["osdid"]) + await require_node(request, node) + row = await _osd_row(request, node, osdid) + payload = state(row["state"]) + return { + "osd": int(osdid) if osdid.isdigit() else osdid, + "status": payload.get("status", "up"), + "in": 1 if payload.get("in", True) else 0, + "weight": payload.get("weight", 1.0), + "size": payload.get("size_bytes", 0), + "used": payload.get("used_bytes", 0), + "device_class": payload.get("device_class", "hdd"), + } + + async def osd_delete(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + osdid = str(payload["osdid"]) + await require_node(request, node) + row = await _osd_row(request, node, osdid) + await database(request).pool.execute("DELETE FROM resources WHERE id=$1", row["id"]) + return _upid(node, "cephdestroyosd") + + async def osd_in(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + node = str(payload["node"]) + osdid = str(payload["osdid"]) + await require_node(request, node) + row = await _osd_row(request, node, osdid) + current = state(row["state"]) + current["in"] = True + await database(request).pool.execute( + "UPDATE resources SET state=$2::jsonb, version=version+1 WHERE id=$1", + row["id"], + json.dumps(current, sort_keys=True), + ) + + async def osd_out(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + node = str(payload["node"]) + osdid = str(payload["osdid"]) + await require_node(request, node) + row = await _osd_row(request, node, osdid) + current = state(row["state"]) + current["in"] = False + await database(request).pool.execute( + "UPDATE resources SET state=$2::jsonb, version=version+1 WHERE id=$1", + row["id"], + json.dumps(current, sort_keys=True), + ) + + async def osd_scrub(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + node = str(payload["node"]) + osdid = str(payload["osdid"]) + await require_node(request, node) + row = await _osd_row(request, node, osdid) + current = state(row["state"]) + current["last_scrub"] = { + "deep": int(bool(payload.get("deep"))), + "token": secrets.token_hex(4), + } + await database(request).pool.execute( + "UPDATE resources SET state=$2::jsonb, version=version+1 WHERE id=$1", + row["id"], + json.dumps(current, sort_keys=True), + ) + + async def osd_lv_info(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + node = str(payload["node"]) + osdid = str(payload["osdid"]) + await require_node(request, node) + row = await _osd_row(request, node, osdid) + current = state(row["state"]) + return { + "lv_name": f"osd-block-{osdid}", + "lv_path": f"/dev/ceph/{osdid}", + "lv_size": current.get("size_bytes", 0), + "type": payload.get("type") or "block", + } + + async def osd_metadata(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + node = str(payload["node"]) + osdid = str(payload["osdid"]) + await require_node(request, node) + row = await _osd_row(request, node, osdid) + current = state(row["state"]) + return { + "osd": { + "id": int(osdid) if osdid.isdigit() else osdid, + "uuid": current.get("uuid") or f"osd-uuid-{osdid}", + "device_class": current.get("device_class", "hdd"), + }, + "devices": [{"dev": current.get("dev") or f"/dev/sd{osdid}"}], + } + + async def cluster_ceph_status(_request: Request, _inputs: dict[str, Any]) -> dict[str, Any]: + row = await database(_request).pool.fetchrow( + """SELECT capacity_bytes, used_bytes FROM storages + WHERE storage_type='ceph' ORDER BY storage_id LIMIT 1""" + ) + total = int(row["capacity_bytes"] or 0) if row is not None else 0 + used = int(row["used_bytes"] or 0) if row is not None else 0 + osd_count = await database(_request).pool.fetchval( + "SELECT count(*)::int FROM resources WHERE kind='ceph-osd'" + ) + ceph = await _load_cluster_ceph(_request) + return { + "version": "17.2.7", + "health": {"status": "HEALTH_OK" if ceph.get("running", True) else "HEALTH_WARN"}, + "osdmap": { + "num_osds": osd_count, + "num_up_osds": osd_count - 1, + "num_in_osds": osd_count - 1, + }, + "pgmap": {"bytes_used": used, "bytes_total": total}, + "fsmap": {"filesystems": list((ceph.get("fs") or {}).keys())}, + } + + base = "/nodes/{node}/ceph" + registry.register(base, "GET", ceph_index) + registry.register(f"{base}/cfg", "GET", cfg_index) + registry.register(f"{base}/cfg/db", "GET", cfg_db) + registry.register(f"{base}/cfg/raw", "GET", cfg_raw) + registry.register(f"{base}/cfg/value", "GET", cfg_value) + registry.register(f"{base}/cmd-safety", "GET", cmd_safety) + registry.register(f"{base}/crush", "GET", crush) + registry.register(f"{base}/fs", "GET", fs_list) + registry.register(f"{base}/fs/{{name}}", "POST", fs_create) + registry.register(f"{base}/fs/{{name}}", "DELETE", fs_delete) + registry.register(f"{base}/init", "POST", init) + registry.register(f"{base}/log", "GET", log) + registry.register(f"{base}/mds", "GET", mds_list) + registry.register(f"{base}/mds/{{name}}", "POST", mds_create) + registry.register(f"{base}/mds/{{name}}", "DELETE", mds_delete) + registry.register(f"{base}/mgr", "GET", mgr_list) + registry.register(f"{base}/mgr/{{id}}", "POST", mgr_create) + registry.register(f"{base}/mgr/{{id}}", "DELETE", mgr_delete) + registry.register(f"{base}/mon", "GET", mon_list) + registry.register(f"{base}/mon/{{monid}}", "POST", mon_create) + registry.register(f"{base}/mon/{{monid}}", "DELETE", mon_delete) + registry.register(f"{base}/osd", "GET", osd_list) + registry.register(f"{base}/osd", "POST", osd_create) + registry.register(f"{base}/osd/{{osdid}}", "GET", osd_get) + registry.register(f"{base}/osd/{{osdid}}", "DELETE", osd_delete) + registry.register(f"{base}/osd/{{osdid}}/in", "POST", osd_in) + registry.register(f"{base}/osd/{{osdid}}/out", "POST", osd_out) + registry.register(f"{base}/osd/{{osdid}}/scrub", "POST", osd_scrub) + registry.register(f"{base}/osd/{{osdid}}/lv-info", "GET", osd_lv_info) + registry.register(f"{base}/osd/{{osdid}}/metadata", "GET", osd_metadata) + registry.register(f"{base}/pool", "GET", pool_list) + registry.register(f"{base}/pool", "POST", pool_create) + registry.register(f"{base}/pool/{{name}}", "GET", pool_get) + registry.register(f"{base}/pool/{{name}}", "PUT", pool_update) + registry.register(f"{base}/pool/{{name}}", "DELETE", pool_delete) + registry.register(f"{base}/pool/{{name}}/status", "GET", pool_status) + registry.register(f"{base}/rules", "GET", rules) + registry.register(f"{base}/status", "GET", status) + registry.register(f"{base}/start", "POST", start) + registry.register(f"{base}/stop", "POST", stop) + registry.register(f"{base}/restart", "POST", restart) + registry.register("/cluster/ceph/status", "GET", cluster_ceph_status) diff --git a/app/handlers/cluster.py b/app/handlers/cluster.py new file mode 100644 index 0000000..8128416 --- /dev/null +++ b/app/handlers/cluster.py @@ -0,0 +1,217 @@ +"""Cluster-level semantic handlers.""" + +from __future__ import annotations + +import json +from typing import Any + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.common import ( + cluster_metadata, + database, + save_cluster_metadata, + state, + subdirs, + values, +) +from app.simulation.seed import CLUSTER_ID + + +def _replication_jobs(metadata: dict[str, Any]) -> list[dict[str, Any]]: + jobs = metadata.get("replication", []) + if not isinstance(jobs, list): + return [] + return [dict(item) for item in jobs if isinstance(item, dict)] + + +def register_cluster_handlers(registry: HandlerRegistry) -> None: + async def cluster_index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs( + "acme", + "backup", + "backup-info", + "config", + "ha", + "log", + "mapping", + "nextid", + "notifications", + "options", + "replication", + "sdn", + "status", + "tasks", + ) + + async def cluster_status(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + rows = await database(_request).pool.fetch( + """SELECT id, name, status FROM nodes ORDER BY name""" + ) + result: list[dict[str, Any]] = [] + for index, row in enumerate(rows): + online = str(row["status"]) == "online" + result.append( + { + "id": str(row["id"]), + "name": str(row["name"]), + "nodeid": index, + "online": 1 if online else 0, + "local": 1 if index == 0 else 0, + "ip": f"10.32.{index // 254 + 1}.{index % 254 + 10}", + "level": "c", + "type": "node", + "quorate": 1, + } + ) + return result + + async def cluster_nextid(request: Request, inputs: dict[str, Any]) -> int: + requested = values(inputs).get("vmid") + if requested is not None: + candidate = int(requested) + taken = await database(request).pool.fetchval( + """SELECT EXISTS( + SELECT 1 FROM resources WHERE kind IN ('qemu', 'lxc') AND external_id=$1 + )""", + str(candidate), + ) + if not taken: + return candidate + raise ApiError(400, f"VMID {candidate} already exists") + maximum = await database(request).pool.fetchval( + """SELECT COALESCE(MAX(external_id::integer), 99) + FROM resources WHERE kind IN ('qemu', 'lxc')""" + ) + return int(maximum) + 1 + + async def cluster_options_get(_request: Request, _inputs: dict[str, Any]) -> dict[str, Any]: + row = await database(_request).pool.fetchrow( + "SELECT metadata FROM clusters WHERE id=$1", + CLUSTER_ID, + ) + metadata = state(row["metadata"]) if row is not None else {} + options = metadata.get("options", {}) + if not isinstance(options, dict): + options = {} + return { + "keyboard": options.get("keyboard", "en-us"), + "email_from": options.get("email_from", "root@localhost"), + "http_proxy": options.get("http_proxy", ""), + "description": options.get("description", "Proxmox API emulator cluster"), + **options, + } + + async def cluster_options_put(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + current = await cluster_options_get(request, inputs) + provided = values(inputs) + updated = {**current, **{key: value for key, value in provided.items() if key != "node"}} + await database(request).pool.execute( + """UPDATE clusters SET metadata = jsonb_set( + COALESCE(metadata, '{}'::jsonb), '{options}', $2::jsonb, true + ), updated_at=now() WHERE id=$1""", + CLUSTER_ID, + json.dumps(updated, sort_keys=True), + ) + return updated + + async def cluster_log(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + limit = int(values(inputs).get("max") or 50) + rows = await database(request).pool.fetch( + """SELECT tl.message, tl.sequence + FROM task_logs tl + ORDER BY tl.created_at DESC, tl.sequence DESC + LIMIT $1""", + limit, + ) + return [{"n": int(row["sequence"]), "t": str(row["message"])} for row in reversed(rows)] + + async def cluster_tasks(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + rows = await database(_request).pool.fetch( + "SELECT upid FROM tasks ORDER BY created_at DESC LIMIT 1000" + ) + return [{"upid": str(row["upid"])} for row in rows] + + async def replication_list(request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + metadata = await cluster_metadata(request) + return _replication_jobs(metadata) + + async def replication_create(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + from app.handlers.common import require_value + + payload = values(inputs) + guest = str(require_value(payload, "guest")) + target = str(require_value(payload, "target")) + job_id = str(payload.get("id") or f"repl-{guest.replace(':', '-')}") + metadata = await cluster_metadata(request) + jobs = _replication_jobs(metadata) + if any(str(item.get("id")) == job_id for item in jobs): + raise ApiError(409, "replication job already exists") + job = { + "id": job_id, + "guest": guest, + "target": target, + "type": str(payload.get("type") or "local"), + "schedule": str(payload.get("schedule") or "*/15"), + "rate": int(payload.get("rate") or 1), + "comment": str(payload.get("comment") or ""), + "enabled": int(payload.get("enabled", 1)), + } + jobs.append(job) + metadata["replication"] = jobs + await save_cluster_metadata(request, metadata) + return job + + async def replication_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + job_id = str(values(inputs)["id"]) + for job in _replication_jobs(await cluster_metadata(request)): + if str(job.get("id")) == job_id: + return job + raise ApiError(404, "replication job does not exist") + + async def replication_update(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + job_id = str(values(inputs)["id"]) + metadata = await cluster_metadata(request) + jobs = _replication_jobs(metadata) + for index, job in enumerate(jobs): + if str(job.get("id")) != job_id: + continue + payload = values(inputs) + updated = { + **job, + **{ + key: value + for key, value in payload.items() + if key not in {"id", "delete", "digest"} + }, + } + jobs[index] = updated + metadata["replication"] = jobs + await save_cluster_metadata(request, metadata) + return updated + raise ApiError(404, "replication job does not exist") + + async def replication_delete(request: Request, inputs: dict[str, Any]) -> None: + job_id = str(values(inputs)["id"]) + metadata = await cluster_metadata(request) + jobs = _replication_jobs(metadata) + remaining = [job for job in jobs if str(job.get("id")) != job_id] + if len(remaining) == len(jobs): + raise ApiError(404, "replication job does not exist") + metadata["replication"] = remaining + await save_cluster_metadata(request, metadata) + + registry.register("/cluster", "GET", cluster_index) + registry.register("/cluster/status", "GET", cluster_status) + registry.register("/cluster/nextid", "GET", cluster_nextid) + registry.register("/cluster/options", "GET", cluster_options_get) + registry.register("/cluster/options", "PUT", cluster_options_put) + registry.register("/cluster/log", "GET", cluster_log) + registry.register("/cluster/tasks", "GET", cluster_tasks) + registry.register("/cluster/replication", "GET", replication_list) + registry.register("/cluster/replication", "POST", replication_create) + registry.register("/cluster/replication/{id}", "GET", replication_get) + registry.register("/cluster/replication/{id}", "PUT", replication_update) + registry.register("/cluster/replication/{id}", "DELETE", replication_delete) diff --git a/app/handlers/cluster_config.py b/app/handlers/cluster_config.py new file mode 100644 index 0000000..6a31823 --- /dev/null +++ b/app/handlers/cluster_config.py @@ -0,0 +1,204 @@ +"""Cluster config / join / totem handlers.""" + +from __future__ import annotations + +import secrets +from typing import Any + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.common import ( + cluster_metadata, + database, + save_cluster_metadata, + subdirs, + values, +) + + +def _config(metadata: dict[str, Any]) -> dict[str, Any]: + current = metadata.setdefault( + "cluster_config", + { + "clustername": "pve-simulator", + "votes": 1, + "links": {}, + "join_info": {}, + "totem": {"version": 2, "secauth": "on", "cluster_name": "pve-simulator"}, + "qdevice": {"status": "disabled"}, + "apiversion": 1, + }, + ) + if not isinstance(current, dict): + current = { + "clustername": "pve-simulator", + "votes": 1, + "links": {}, + "join_info": {}, + "totem": {"version": 2, "secauth": "on", "cluster_name": "pve-simulator"}, + "qdevice": {"status": "disabled"}, + "apiversion": 1, + } + metadata["cluster_config"] = current + return current + + +def register_cluster_config_handlers(registry: HandlerRegistry) -> None: + async def index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs("apiversion", "join", "nodes", "qdevice", "totem") + + async def create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + metadata = await cluster_metadata(request) + config = _config(metadata) + if payload.get("clustername"): + config["clustername"] = str(payload["clustername"]) + config.setdefault("totem", {})["cluster_name"] = str(payload["clustername"]) + if "votes" in payload: + config["votes"] = payload["votes"] + if "nodeid" in payload: + config["creator_nodeid"] = payload["nodeid"] + links = {key: value for key, value in payload.items() if key.startswith("link")} + if links: + config["links"] = links + config["token"] = secrets.token_hex(16) + await save_cluster_metadata(request, metadata) + await database(request).pool.execute( + """UPDATE clusters + SET name=$1, updated_at=now() + WHERE id=(SELECT id FROM clusters LIMIT 1)""", + str(config["clustername"]), + ) + + async def apiversion(_request: Request, _inputs: dict[str, Any]) -> int: + metadata = await cluster_metadata(_request) + return int(_config(metadata).get("apiversion") or 1) + + async def join_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + metadata = await cluster_metadata(request) + config = _config(metadata) + node = values(inputs).get("node") + rows = await database(request).pool.fetch("SELECT name, status FROM nodes ORDER BY name") + nodelist = [ + {"name": str(row["name"]), "online": 1 if row["status"] == "online" else 0} + for row in rows + ] + return { + "clustername": config.get("clustername"), + "config_digest": secrets.token_hex(8), + "nodelist": nodelist, + "preferred_node": node or (nodelist[0]["name"] if nodelist else None), + "totem": config.get("totem", {}), + "links": config.get("links", {}), + } + + async def join_post(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + metadata = await cluster_metadata(request) + config = _config(metadata) + hostname = str(payload.get("hostname") or payload.get("node") or "") + if not hostname: + raise ApiError(400, "parameter verification failed - 'hostname' missing") + joins = config.setdefault("join_info", {}) + joins[hostname] = { + "hostname": hostname, + "fingerprint": payload.get("fingerprint"), + "nodeid": payload.get("nodeid"), + "votes": payload.get("votes", 1), + "force": payload.get("force"), + } + # password accepted but not stored in clear form + if payload.get("password"): + joins[hostname]["password_set"] = True + exists = await database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM nodes WHERE name=$1)", + hostname, + ) + if not exists: + await database(request).pool.execute( + """INSERT INTO nodes(id, name, status, metadata) + VALUES(gen_random_uuid(), $1, 'online', '{}'::jsonb)""", + hostname, + ) + await save_cluster_metadata(request, metadata) + + async def nodes_list(request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + rows = await database(request).pool.fetch("SELECT name, status FROM nodes ORDER BY name") + metadata = await cluster_metadata(request) + config = _config(metadata) + result = [] + for index, row in enumerate(rows, start=1): + result.append( + { + "node": str(row["name"]), + "nodeid": index, + "ring0_addr": f"{row['name']}.local", + "quorum_votes": config.get("votes", 1), + } + ) + return result + + async def nodes_add(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + node = str(payload["node"]) + metadata = await cluster_metadata(request) + config = _config(metadata) + added = config.setdefault("added_nodes", {}) + added[node] = { + "node": node, + "nodeid": payload.get("nodeid"), + "new_node_ip": payload.get("new_node_ip"), + "votes": payload.get("votes", 1), + "apiversion": payload.get("apiversion"), + "force": payload.get("force"), + } + links = {key: value for key, value in payload.items() if key.startswith("link")} + if links: + added[node]["links"] = links + exists = await database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM nodes WHERE name=$1)", + node, + ) + if not exists: + await database(request).pool.execute( + """INSERT INTO nodes(id, name, status, metadata) + VALUES(gen_random_uuid(), $1, 'online', '{}'::jsonb)""", + node, + ) + await save_cluster_metadata(request, metadata) + + async def nodes_delete(request: Request, inputs: dict[str, Any]) -> None: + node = str(values(inputs)["node"]) + metadata = await cluster_metadata(request) + config = _config(metadata) + added = config.setdefault("added_nodes", {}) + added.pop(node, None) + joins = config.setdefault("join_info", {}) + joins.pop(node, None) + await save_cluster_metadata(request, metadata) + # Keep node row; mark offline to avoid cascading guest deletes. + await database(request).pool.execute( + "UPDATE nodes SET status='offline', updated_at=now() WHERE name=$1", + node, + ) + + async def qdevice(request: Request, _inputs: dict[str, Any]) -> dict[str, Any]: + metadata = await cluster_metadata(request) + return dict(_config(metadata).get("qdevice") or {"status": "disabled"}) + + async def totem(request: Request, _inputs: dict[str, Any]) -> dict[str, Any]: + metadata = await cluster_metadata(request) + return dict(_config(metadata).get("totem") or {}) + + registry.register("/cluster/config", "GET", index) + registry.register("/cluster/config", "POST", create) + registry.register("/cluster/config/apiversion", "GET", apiversion) + registry.register("/cluster/config/join", "GET", join_get) + registry.register("/cluster/config/join", "POST", join_post) + registry.register("/cluster/config/nodes", "GET", nodes_list) + registry.register("/cluster/config/nodes/{node}", "POST", nodes_add) + registry.register("/cluster/config/nodes/{node}", "DELETE", nodes_delete) + registry.register("/cluster/config/qdevice", "GET", qdevice) + registry.register("/cluster/config/totem", "GET", totem) diff --git a/app/handlers/cluster_extra.py b/app/handlers/cluster_extra.py new file mode 100644 index 0000000..34ec0e4 --- /dev/null +++ b/app/handlers/cluster_extra.py @@ -0,0 +1,688 @@ +"""Additional cluster-level handlers with durable metadata persistence.""" + +from __future__ import annotations + +import copy +import secrets +import time +from typing import Any + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.common import ( + cluster_metadata, + database, + require_node, + save_cluster_metadata, + subdirs, + values, +) +from app.tasks.repository import TaskRepository +from app.tasks.upid import Upid + +DEFAULT_CEPH_FLAGS: dict[str, int] = { + "nobackfill": 0, + "nodeep-scrub": 0, + "nodown": 0, + "noin": 0, + "noout": 0, + "norebalance": 0, + "norecover": 0, + "noscrub": 0, + "notieragent": 0, + "pause": 0, +} + +DEFAULT_CPU_FLAGS: list[dict[str, Any]] = [ + {"name": "aes", "introduces": "Westmere"}, + {"name": "avx", "introduces": "SandyBridge"}, + {"name": "avx2", "introduces": "Haswell"}, +] + + +def _jobs(metadata: dict[str, Any]) -> dict[str, Any]: + jobs = metadata.setdefault("jobs", {}) + if not isinstance(jobs, dict): + jobs = {} + metadata["jobs"] = jobs + sync = jobs.setdefault("realm_sync", {}) + if not isinstance(sync, dict): + sync = {} + jobs["realm_sync"] = sync + return jobs + + +def _metrics(metadata: dict[str, Any]) -> dict[str, Any]: + metrics = metadata.setdefault("metrics", {}) + if not isinstance(metrics, dict): + metrics = {} + metadata["metrics"] = metrics + servers = metrics.setdefault("servers", {}) + if not isinstance(servers, dict): + servers = {} + metrics["servers"] = servers + return metrics + + +def _cpu_models(metadata: dict[str, Any]) -> dict[str, Any]: + models = metadata.get("qemu_cpu_models") + if not isinstance(models, dict): + models = {} + metadata["qemu_cpu_models"] = models + return models + + +def _ha_rules_store(metadata: dict[str, Any]) -> list[dict[str, Any]]: + rules = metadata.get("ha_rules") + if isinstance(rules, dict): + return [ + {"rule": str(name), **dict(value)} + for name, value in rules.items() + if isinstance(value, dict) + ] + if isinstance(rules, list): + return [dict(item) for item in rules if isinstance(item, dict)] + defaults = [ + {"rule": "node-fencing", "type": "node", "action": "restart"}, + {"rule": "service-ha", "type": "resource", "action": "failover"}, + ] + metadata["ha_rules"] = defaults + return list(defaults) + + +def _save_ha_rules(metadata: dict[str, Any], rules: list[dict[str, Any]]) -> None: + metadata["ha_rules"] = rules + + +def _replication_jobs(metadata: dict[str, Any]) -> list[dict[str, Any]]: + jobs = metadata.get("replication", []) + if not isinstance(jobs, list): + return [] + return [dict(item) for item in jobs if isinstance(item, dict)] + + +def _ceph(metadata: dict[str, Any]) -> dict[str, Any]: + ceph = metadata.get("ceph") + if not isinstance(ceph, dict): + ceph = {} + flags = ceph.get("flags") + if not isinstance(flags, dict): + flags = copy.deepcopy(DEFAULT_CEPH_FLAGS) + else: + merged = copy.deepcopy(DEFAULT_CEPH_FLAGS) + merged.update({str(key): int(value) for key, value in flags.items()}) + flags = merged + ceph["flags"] = flags + metadata["ceph"] = ceph + return ceph + + +async def _cluster_task(request: Request, *, task_type: str, worker: str) -> str: + from app.db.primitives import ConflictError + + pool = database(request).pool + node = await pool.fetchval("SELECT name FROM nodes ORDER BY name LIMIT 1") or "localhost" + upid = str(Upid.allocate(str(node), worker, "0", str(request.state.principal))) + try: + task = await TaskRepository(pool).create( + upid=upid, + task_type=task_type, + payload={"cluster": True}, + resource_key=f"cluster:{task_type}:{secrets.token_hex(4)}", + ) + except ConflictError as error: + raise ApiError(409, str(error)) from error + return task.upid + + +async def _bulk_guest_status(request: Request, status: str) -> None: + await database(request).pool.execute( + """UPDATE resources + SET state = jsonb_set(COALESCE(state, '{}'::jsonb), '{status}', to_jsonb($1::text), true), + updated_at=now() + WHERE kind IN ('qemu', 'lxc')""", + status, + ) + + +def register_cluster_extra_handlers(registry: HandlerRegistry) -> None: + async def jobs_index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs("realm-sync", "schedule-analyze") + + async def realm_sync_list(request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + metadata = await cluster_metadata(request) + jobs = _jobs(metadata) + items = [ + {"id": job_id, **dict(payload)} + for job_id, payload in sorted(jobs.get("realm_sync", {}).items()) + if isinstance(payload, dict) + ] + return items + + async def realm_sync_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + job_id = str(values(inputs)["id"]) + metadata = await cluster_metadata(request) + jobs = _jobs(metadata) + payload = jobs.get("realm_sync", {}).get(job_id) + if not isinstance(payload, dict): + raise ApiError(404, "realm-sync job does not exist") + return {"id": job_id, **payload} + + async def realm_sync_create(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + job_id = str(payload["id"]) + metadata = await cluster_metadata(request) + jobs = _jobs(metadata) + sync = jobs.setdefault("realm_sync", {}) + if job_id in sync: + raise ApiError(409, "realm-sync job already exists") + entry = { + key: value for key, value in payload.items() if key not in {"id", "delete", "digest"} + } + entry.setdefault("schedule", "0 0 * * *") + entry.setdefault("enabled", 1) + entry.setdefault("realm", str(payload.get("realm") or "pam")) + sync[job_id] = entry + metadata["jobs"] = jobs + await save_cluster_metadata(request, metadata) + return {"id": job_id, **entry} + + async def realm_sync_update(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + job_id = str(payload["id"]) + metadata = await cluster_metadata(request) + jobs = _jobs(metadata) + sync = jobs.setdefault("realm_sync", {}) + if job_id not in sync: + raise ApiError(404, "realm-sync job does not exist") + updated = { + **sync[job_id], + **{ + key: value + for key, value in payload.items() + if key not in {"id", "delete", "digest"} + }, + } + sync[job_id] = updated + metadata["jobs"] = jobs + await save_cluster_metadata(request, metadata) + return {"id": job_id, **updated} + + async def realm_sync_delete(request: Request, inputs: dict[str, Any]) -> None: + job_id = str(values(inputs)["id"]) + metadata = await cluster_metadata(request) + jobs = _jobs(metadata) + sync = jobs.setdefault("realm_sync", {}) + if job_id not in sync: + raise ApiError(404, "realm-sync job does not exist") + del sync[job_id] + metadata["jobs"] = jobs + await save_cluster_metadata(request, metadata) + + async def schedule_analyze(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + schedule = str(values(inputs).get("schedule") or "*/15") + metadata = await cluster_metadata(request) + jobs = _jobs(metadata) + jobs["last_schedule_analyze"] = {"schedule": schedule, "at": int(time.time())} + metadata["jobs"] = jobs + await save_cluster_metadata(request, metadata) + now = int(time.time()) + return [{"timestamp": now + offset * 900, "utc": True} for offset in range(4)] + + async def metrics_index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs("export", "server") + + async def metrics_export(request: Request, _inputs: dict[str, Any]) -> dict[str, Any]: + metadata = await cluster_metadata(request) + metrics = _metrics(metadata) + return { + "data": metrics.get("export_data") + or '# HELP pve_up Node is up\npve_up{node="pve01"} 1\n', + "timestamp": int(time.time()), + } + + async def metrics_server_list( + request: Request, _inputs: dict[str, Any] + ) -> list[dict[str, Any]]: + metadata = await cluster_metadata(request) + metrics = _metrics(metadata) + return [ + {"id": server_id, **dict(payload)} + for server_id, payload in sorted(metrics.get("servers", {}).items()) + if isinstance(payload, dict) + ] + + async def metrics_server_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + server_id = str(values(inputs)["id"]) + metadata = await cluster_metadata(request) + metrics = _metrics(metadata) + payload = metrics.get("servers", {}).get(server_id) + if not isinstance(payload, dict): + raise ApiError(404, "metrics server does not exist") + return {"id": server_id, **payload} + + async def metrics_server_create(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + server_id = str(payload["id"]) + metadata = await cluster_metadata(request) + metrics = _metrics(metadata) + servers = metrics.setdefault("servers", {}) + if server_id in servers: + raise ApiError(409, "metrics server already exists") + entry = { + key: value for key, value in payload.items() if key not in {"id", "delete", "digest"} + } + entry.setdefault("type", "influxdb") + entry.setdefault("server", "127.0.0.1") + entry.setdefault("port", 8086) + entry.setdefault("enable", 1) + servers[server_id] = entry + metadata["metrics"] = metrics + await save_cluster_metadata(request, metadata) + return {"id": server_id, **entry} + + async def metrics_server_update(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + server_id = str(payload["id"]) + metadata = await cluster_metadata(request) + metrics = _metrics(metadata) + servers = metrics.setdefault("servers", {}) + if server_id not in servers: + raise ApiError(404, "metrics server does not exist") + updated = { + **servers[server_id], + **{ + key: value + for key, value in payload.items() + if key not in {"id", "delete", "digest"} + }, + } + servers[server_id] = updated + metadata["metrics"] = metrics + await save_cluster_metadata(request, metadata) + return {"id": server_id, **updated} + + async def metrics_server_delete(request: Request, inputs: dict[str, Any]) -> None: + server_id = str(values(inputs)["id"]) + metadata = await cluster_metadata(request) + metrics = _metrics(metadata) + servers = metrics.setdefault("servers", {}) + if server_id not in servers: + raise ApiError(404, "metrics server does not exist") + del servers[server_id] + metadata["metrics"] = metrics + await save_cluster_metadata(request, metadata) + + async def qemu_index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs("cpu-flags", "custom-cpu-models") + + async def qemu_cpu_flags(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + return list(DEFAULT_CPU_FLAGS) + + async def cpu_models_list(request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + metadata = await cluster_metadata(request) + models = _cpu_models(metadata) + return [ + {"name": name, **dict(payload)} + for name, payload in sorted(models.items()) + if isinstance(payload, dict) + ] + + async def cpu_models_create(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + name = str(payload.get("name") or payload.get("cputype") or "") + if not name: + raise ApiError(400, "parameter verification failed - 'name' missing") + metadata = await cluster_metadata(request) + models = _cpu_models(metadata) + if name in models: + raise ApiError(409, "custom cpu model already exists") + entry = { + key: value + for key, value in payload.items() + if key not in {"name", "cputype", "delete", "digest"} + } + entry.setdefault("vendor", "Custom") + models[name] = entry + metadata["qemu_cpu_models"] = models + await save_cluster_metadata(request, metadata) + return {"name": name, **entry} + + async def cpu_models_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + name = str(values(inputs)["cputype"]) + metadata = await cluster_metadata(request) + models = _cpu_models(metadata) + payload = models.get(name) + if not isinstance(payload, dict): + raise ApiError(404, "custom cpu model does not exist") + return {"name": name, **payload} + + async def cpu_models_update(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + name = str(payload["cputype"]) + metadata = await cluster_metadata(request) + models = _cpu_models(metadata) + if name not in models: + raise ApiError(404, "custom cpu model does not exist") + updated = { + **models[name], + **{ + key: value + for key, value in payload.items() + if key not in {"cputype", "delete", "digest"} + }, + } + models[name] = updated + metadata["qemu_cpu_models"] = models + await save_cluster_metadata(request, metadata) + return {"name": name, **updated} + + async def cpu_models_delete(request: Request, inputs: dict[str, Any]) -> None: + name = str(values(inputs)["cputype"]) + metadata = await cluster_metadata(request) + models = _cpu_models(metadata) + if name not in models: + raise ApiError(404, "custom cpu model does not exist") + del models[name] + metadata["qemu_cpu_models"] = models + await save_cluster_metadata(request, metadata) + + async def bulk_action_index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs("guest") + + async def bulk_guest_index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs("migrate", "shutdown", "start", "suspend") + + async def bulk_guest_action(request: Request, inputs: dict[str, Any], action: str) -> str: + payload = values(inputs) + metadata = await cluster_metadata(request) + metadata["last_bulk_action"] = { + "action": action, + "payload": { + key: value for key, value in payload.items() if key not in {"delete", "digest"} + }, + "at": int(time.time()), + } + await save_cluster_metadata(request, metadata) + if action == "start": + await _bulk_guest_status(request, "running") + elif action == "shutdown": + await _bulk_guest_status(request, "stopped") + elif action == "suspend": + await _bulk_guest_status(request, "paused") + elif action == "migrate": + target = str(payload.get("target") or "") + if target: + target_row = await database(request).pool.fetchrow( + "SELECT id FROM nodes WHERE name=$1", target + ) + if target_row is None: + raise ApiError(404, "target node does not exist") + vms = payload.get("vms") or payload.get("guests") or "" + if isinstance(vms, str) and vms: + ids = [part.strip() for part in vms.split(",") if part.strip()] + for vmid in ids: + await database(request).pool.execute( + """UPDATE resources SET node_id=$2, updated_at=now() + WHERE kind IN ('qemu', 'lxc') AND external_id=$1""", + vmid, + target_row["id"], + ) + return await _cluster_task(request, task_type=f"bulk-{action}", worker=f"bulk{action}") + + async def cluster_ceph_index( + _request: Request, _inputs: dict[str, Any] + ) -> list[dict[str, str]]: + return subdirs("flags", "metadata", "status") + + async def ceph_flags_get(request: Request, _inputs: dict[str, Any]) -> dict[str, int]: + metadata = await cluster_metadata(request) + ceph = _ceph(metadata) + await save_cluster_metadata(request, metadata) + return {str(key): int(value) for key, value in ceph["flags"].items()} + + async def ceph_flags_put(request: Request, inputs: dict[str, Any]) -> dict[str, int]: + payload = values(inputs) + metadata = await cluster_metadata(request) + ceph = _ceph(metadata) + flags = dict(ceph["flags"]) + for key, value in payload.items(): + if key in {"delete", "digest"}: + continue + flags[str(key)] = int(value) + ceph["flags"] = flags + metadata["ceph"] = ceph + await save_cluster_metadata(request, metadata) + return {str(key): int(value) for key, value in flags.items()} + + async def ceph_flag_get(request: Request, inputs: dict[str, Any]) -> dict[str, int]: + flag = str(values(inputs)["flag"]) + metadata = await cluster_metadata(request) + ceph = _ceph(metadata) + flags = ceph["flags"] + if flag not in flags: + raise ApiError(404, "ceph flag does not exist") + return {flag: int(flags[flag])} + + async def ceph_flag_put(request: Request, inputs: dict[str, Any]) -> dict[str, int]: + payload = values(inputs) + flag = str(payload["flag"]) + metadata = await cluster_metadata(request) + ceph = _ceph(metadata) + flags = dict(ceph["flags"]) + if "value" in payload: + flags[flag] = int(payload["value"]) + elif flag in payload: + flags[flag] = int(payload[flag]) + else: + flags[flag] = 1 + ceph["flags"] = flags + metadata["ceph"] = ceph + await save_cluster_metadata(request, metadata) + return {flag: int(flags[flag])} + + async def ceph_metadata(request: Request, _inputs: dict[str, Any]) -> dict[str, Any]: + metadata = await cluster_metadata(request) + ceph = _ceph(metadata) + await save_cluster_metadata(request, metadata) + return { + "version": ceph.get("version") or {"str": "18.2.2", "parts": [18, 2, 2]}, + "fsid": ceph.get("config", {}).get("fsid") + if isinstance(ceph.get("config"), dict) + else "pve-simulator-fsid", + "initialized": int(bool(ceph.get("initialized", True))), + "flags": ceph.get("flags", {}), + } + + async def ha_rule_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + rule = str(payload.get("rule") or payload.get("name") or "") + if not rule: + raise ApiError(400, "parameter verification failed - 'rule' missing") + metadata = await cluster_metadata(request) + rules = _ha_rules_store(metadata) + if any(str(item.get("rule")) == rule for item in rules): + raise ApiError(409, "HA rule already exists") + entry = {key: value for key, value in payload.items() if key not in {"delete", "digest"}} + entry["rule"] = rule + entry.setdefault("type", "resource") + entry.setdefault("action", "migrate") + rules.append(entry) + _save_ha_rules(metadata, rules) + await save_cluster_metadata(request, metadata) + + async def ha_rule_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + rule = str(values(inputs)["rule"]) + metadata = await cluster_metadata(request) + for item in _ha_rules_store(metadata): + if str(item.get("rule")) == rule: + return dict(item) + raise ApiError(404, "HA rule does not exist") + + async def ha_rule_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + rule = str(payload["rule"]) + metadata = await cluster_metadata(request) + rules = _ha_rules_store(metadata) + updated: list[dict[str, Any]] = [] + found = False + for item in rules: + if str(item.get("rule")) != rule: + updated.append(item) + continue + found = True + merged = { + **item, + **{ + key: value + for key, value in payload.items() + if key not in {"rule", "delete", "digest"} + }, + } + merged["rule"] = rule + updated.append(merged) + if not found: + raise ApiError(404, "HA rule does not exist") + _save_ha_rules(metadata, updated) + await save_cluster_metadata(request, metadata) + + async def ha_rule_delete(request: Request, inputs: dict[str, Any]) -> None: + rule = str(values(inputs)["rule"]) + metadata = await cluster_metadata(request) + rules = _ha_rules_store(metadata) + remaining = [item for item in rules if str(item.get("rule")) != rule] + if len(remaining) == len(rules): + raise ApiError(404, "HA rule does not exist") + _save_ha_rules(metadata, remaining) + await save_cluster_metadata(request, metadata) + + async def node_replication_list( + request: Request, inputs: dict[str, Any] + ) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + await require_node(request, node) + metadata = await cluster_metadata(request) + jobs = _replication_jobs(metadata) + return [ + job + for job in jobs + if str(job.get("source") or job.get("node") or node) == node + or job.get("source") is None + ] + + async def node_replication_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(values(inputs)["node"]) + job_id = str(values(inputs)["id"]) + await require_node(request, node) + for job in _replication_jobs(await cluster_metadata(request)): + if str(job.get("id")) == job_id: + return dict(job) + raise ApiError(404, "replication job does not exist") + + async def node_replication_log( + request: Request, inputs: dict[str, Any] + ) -> list[dict[str, Any]]: + job = await node_replication_get(request, inputs) + log = job.get("log") + if isinstance(log, list): + return [dict(item) for item in log if isinstance(item, dict)] + return [{"t": int(time.time()), "n": 0, "msg": f"replication idle for {job.get('id')}"}] + + async def node_replication_status(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + job = await node_replication_get(request, inputs) + return { + "id": job.get("id"), + "last_sync": job.get("last_sync", 0), + "duration": job.get("duration", 0), + "fail_count": job.get("fail_count", 0), + "error": job.get("error", ""), + "state": job.get("state", "OK"), + } + + async def node_replication_schedule_now(request: Request, inputs: dict[str, Any]) -> None: + node = str(values(inputs)["node"]) + job_id = str(values(inputs)["id"]) + await require_node(request, node) + metadata = await cluster_metadata(request) + jobs = _replication_jobs(metadata) + found = False + for job in jobs: + if str(job.get("id")) != job_id: + continue + found = True + job["last_sync"] = int(time.time()) + job["state"] = "OK" + job["schedule_now"] = 1 + if not found: + raise ApiError(404, "replication job does not exist") + metadata["replication"] = jobs + await save_cluster_metadata(request, metadata) + + registry.register("/cluster/jobs", "GET", jobs_index) + registry.register("/cluster/jobs/realm-sync", "GET", realm_sync_list) + registry.register("/cluster/jobs/realm-sync/{id}", "GET", realm_sync_get) + registry.register("/cluster/jobs/realm-sync/{id}", "POST", realm_sync_create) + registry.register("/cluster/jobs/realm-sync/{id}", "PUT", realm_sync_update) + registry.register("/cluster/jobs/realm-sync/{id}", "DELETE", realm_sync_delete) + registry.register("/cluster/jobs/schedule-analyze", "GET", schedule_analyze) + + registry.register("/cluster/metrics", "GET", metrics_index) + registry.register("/cluster/metrics/export", "GET", metrics_export) + registry.register("/cluster/metrics/server", "GET", metrics_server_list) + registry.register("/cluster/metrics/server/{id}", "GET", metrics_server_get) + registry.register("/cluster/metrics/server/{id}", "POST", metrics_server_create) + registry.register("/cluster/metrics/server/{id}", "PUT", metrics_server_update) + registry.register("/cluster/metrics/server/{id}", "DELETE", metrics_server_delete) + + registry.register("/cluster/qemu", "GET", qemu_index) + registry.register("/cluster/qemu/cpu-flags", "GET", qemu_cpu_flags) + registry.register("/cluster/qemu/custom-cpu-models", "GET", cpu_models_list) + registry.register("/cluster/qemu/custom-cpu-models", "POST", cpu_models_create) + registry.register("/cluster/qemu/custom-cpu-models/{cputype}", "GET", cpu_models_get) + registry.register("/cluster/qemu/custom-cpu-models/{cputype}", "PUT", cpu_models_update) + registry.register("/cluster/qemu/custom-cpu-models/{cputype}", "DELETE", cpu_models_delete) + + registry.register("/cluster/bulk-action", "GET", bulk_action_index) + registry.register("/cluster/bulk-action/guest", "GET", bulk_guest_index) + registry.register( + "/cluster/bulk-action/guest/migrate", + "POST", + lambda request, inputs: bulk_guest_action(request, inputs, "migrate"), + ) + registry.register( + "/cluster/bulk-action/guest/shutdown", + "POST", + lambda request, inputs: bulk_guest_action(request, inputs, "shutdown"), + ) + registry.register( + "/cluster/bulk-action/guest/start", + "POST", + lambda request, inputs: bulk_guest_action(request, inputs, "start"), + ) + registry.register( + "/cluster/bulk-action/guest/suspend", + "POST", + lambda request, inputs: bulk_guest_action(request, inputs, "suspend"), + ) + + registry.register("/cluster/ceph", "GET", cluster_ceph_index) + registry.register("/cluster/ceph/flags", "GET", ceph_flags_get) + registry.register("/cluster/ceph/flags", "PUT", ceph_flags_put) + registry.register("/cluster/ceph/flags/{flag}", "GET", ceph_flag_get) + registry.register("/cluster/ceph/flags/{flag}", "PUT", ceph_flag_put) + registry.register("/cluster/ceph/metadata", "GET", ceph_metadata) + + registry.register("/cluster/ha/rules", "POST", ha_rule_create) + registry.register("/cluster/ha/rules/{rule}", "GET", ha_rule_get) + registry.register("/cluster/ha/rules/{rule}", "PUT", ha_rule_update) + registry.register("/cluster/ha/rules/{rule}", "DELETE", ha_rule_delete) + + registry.register("/nodes/{node}/replication", "GET", node_replication_list) + registry.register("/nodes/{node}/replication/{id}", "GET", node_replication_get) + registry.register("/nodes/{node}/replication/{id}/log", "GET", node_replication_log) + registry.register("/nodes/{node}/replication/{id}/status", "GET", node_replication_status) + registry.register( + "/nodes/{node}/replication/{id}/schedule_now", "POST", node_replication_schedule_now + ) diff --git a/app/handlers/common.py b/app/handlers/common.py new file mode 100644 index 0000000..31f8f0c --- /dev/null +++ b/app/handlers/common.py @@ -0,0 +1,145 @@ +"""Shared handler helpers.""" + +from __future__ import annotations + +import json +import re +from collections.abc import Mapping +from typing import Any, cast + +from fastapi import Request + +from app.api.errors import ApiError +from app.db.pool import AsyncpgDatabase + + +def database(request: Request) -> AsyncpgDatabase: + return cast(AsyncpgDatabase, request.app.state.database) + + +def values(inputs: dict[str, Any]) -> dict[str, Any]: + return cast(dict[str, Any], inputs["values"]) + + +def require_value(payload: Mapping[str, Any], key: str) -> Any: + if key not in payload or payload[key] in {None, ""}: + raise ApiError(400, f"parameter '{key}' is required") + return payload[key] + + +def state(value: object) -> dict[str, Any]: + if isinstance(value, str): + return cast(dict[str, Any], json.loads(value)) + return dict(cast(Mapping[str, Any], value)) + + +def subdirs(*names: str) -> list[dict[str, str]]: + return [{"subdir": name} for name in names] + + +_SIZE_RE = re.compile(r"^(?P\d+)(?P[KMGT]?)$", re.IGNORECASE) +_UNITS = {"": 1, "K": 2**10, "M": 2**20, "G": 2**30, "T": 2**40} + + +def parse_size_bytes(value: str) -> int: + match = _SIZE_RE.fullmatch(value.strip()) + if match is None: + raise ValueError(f"invalid disk size: {value}") + return int(match.group("value")) * _UNITS[match.group("unit").upper()] + + +def resize_size_bytes(value: str, current: int) -> int: + if value.startswith("+"): + return current + parse_size_bytes(value[1:]) + result = parse_size_bytes(value) + if result < current: + raise ValueError("shrinking disks is not supported") + return result + + +def replace_disk_size(value: str, size: int) -> str: + parts = [part for part in value.split(",") if not part.startswith("size=")] + parts.append(f"size={size // 2**30}G" if size % 2**30 == 0 else f"size={size}") + return ",".join(parts) + + +def disk_size_bytes(value: str) -> int: + for part in value.split(","): + if part.startswith("size="): + return parse_size_bytes(part.removeprefix("size=")) + return 0 + + +async def require_node(request: Request, node: str) -> None: + exists = await database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM nodes WHERE name=$1)", + node, + ) + if not exists: + raise ApiError(404, "node does not exist") + + +async def cluster_metadata(request: Request) -> dict[str, Any]: + from app.simulation.seed import CLUSTER_ID + + row = await database(request).pool.fetchrow( + "SELECT metadata FROM clusters WHERE id=$1", + CLUSTER_ID, + ) + return state(row["metadata"]) if row is not None else {} + + +async def save_cluster_metadata(request: Request, metadata: dict[str, Any]) -> None: + from app.simulation.seed import CLUSTER_ID + + await database(request).pool.execute( + "UPDATE clusters SET metadata=$2::jsonb, updated_at=now() WHERE id=$1", + CLUSTER_ID, + json.dumps(metadata, sort_keys=True), + ) + + +async def node_metadata(request: Request, node: str) -> dict[str, Any]: + row = await database(request).pool.fetchrow( + "SELECT metadata FROM nodes WHERE name=$1", + node, + ) + if row is None: + raise ApiError(404, "node does not exist") + return state(row["metadata"]) + + +async def save_node_metadata(request: Request, node: str, metadata: dict[str, Any]) -> None: + status = await database(request).pool.execute( + "UPDATE nodes SET metadata=$2::jsonb, updated_at=now() WHERE name=$1", + node, + json.dumps(metadata, sort_keys=True), + ) + if status != "UPDATE 1": + raise ApiError(404, "node does not exist") + + +def storage_payload(row: Any) -> dict[str, Any]: + config = state(row["config"]) + content = config.get("content", []) + if isinstance(content, list): + content_str = ",".join(str(item) for item in content) + else: + content_str = str(content) + total = int(row["capacity_bytes"] or 0) + used = int(row["used_bytes"] or 0) + avail = max(total - used, 0) + payload: dict[str, Any] = { + "storage": str(row["storage_id"]), + "type": str(row["storage_type"]), + "shared": int(bool(row["shared"])), + "content": content_str, + "active": 1, + "enabled": 1, + "total": total, + "used": used, + "avail": avail, + } + if total: + payload["used_fraction"] = used / total + return payload diff --git a/app/handlers/core.py b/app/handlers/core.py new file mode 100644 index 0000000..2d431e1 --- /dev/null +++ b/app/handlers/core.py @@ -0,0 +1,162 @@ +"""First read/login semantic service handlers.""" + +from __future__ import annotations + +import json +from typing import Any, cast + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.config import Settings +from app.contracts.runtime import runtime_version_payload +from app.db.pool import AsyncpgDatabase +from app.handlers.access import register_access_handlers +from app.handlers.acme import register_acme_handlers +from app.handlers.backup import register_backup_handlers +from app.handlers.ceph import register_ceph_handlers +from app.handlers.cluster import register_cluster_handlers +from app.handlers.cluster_config import register_cluster_config_handlers +from app.handlers.cluster_extra import register_cluster_extra_handlers +from app.handlers.common import require_node, subdirs +from app.handlers.firewall import register_firewall_handlers +from app.handlers.ha import register_ha_handlers +from app.handlers.legacy_aliases import register_legacy_aliases +from app.handlers.lxc import register_lxc_handlers +from app.handlers.mapping import register_mapping_handlers +from app.handlers.nodes import register_node_ops_handlers +from app.handlers.nodes_extra import register_nodes_extra_handlers +from app.handlers.notifications import register_notifications_handlers +from app.handlers.pools import register_pool_handlers +from app.handlers.qemu import register_qemu_handlers +from app.handlers.sdn import register_sdn_handlers +from app.handlers.storage import register_storage_handlers +from app.security.auth import csrf_token, issue_ticket, verify_secret + + +def _database(request: Request) -> AsyncpgDatabase: + return cast(AsyncpgDatabase, request.app.state.database) + + +def build_core_handlers(settings: Settings) -> HandlerRegistry: + registry = HandlerRegistry() + + async def version(request: Request, _inputs: dict[str, Any]) -> dict[str, str]: + return runtime_version_payload(request) + + async def login(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + values = cast(dict[str, Any], inputs["values"]) + username = str(values["username"]) + password = str(values["password"]) + row = await _database(request).pool.fetchrow( + "SELECT name, password_hash FROM principals WHERE name=$1", username + ) + if ( + row is None + or row["password_hash"] is None + or not verify_secret(password, str(row["password_hash"])) + ): + raise ApiError(401, "authentication failure") + key = settings.ticket_signing_key.get_secret_value().encode() + ticket = issue_ticket(username, key) + return { + "username": username, + "ticket": ticket, + "CSRFPreventionToken": csrf_token(ticket, key), + "cap": {"vms": {"VM.Audit": 1, "VM.PowerMgmt": 1}}, + } + + async def nodes(request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + rows = await _database(request).pool.fetch( + "SELECT name AS node, status FROM nodes ORDER BY name" + ) + return [{"node": str(row["node"]), "status": str(row["status"])} for row in rows] + + async def node_status(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(cast(dict[str, Any], inputs["values"])["node"]) + row = await _database(request).pool.fetchrow( + "SELECT name, status FROM nodes WHERE name=$1", node + ) + if row is None: + raise ApiError(404, "node does not exist") + return { + "status": str(row["status"]), + "node": str(row["name"]), + "uptime": 0, + "cpu": 0.0, + "memory": {"used": 0, "total": 0}, + } + + async def resources(request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + rows = await _database(request).pool.fetch( + """SELECT r.kind AS type, r.external_id, r.state, n.name AS node + FROM resources r JOIN nodes n ON n.id=r.node_id + ORDER BY r.kind, r.external_id""" + ) + result: list[dict[str, Any]] = [] + for row in rows: + raw_state = row["state"] + state = json.loads(raw_state) if isinstance(raw_state, str) else dict(raw_state) + result.append( + { + "type": str(row["type"]), + "id": f"{row['type']}/{row['external_id']}", + "node": str(row["node"]), + **state, + } + ) + return result + + async def node_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + node = str(cast(dict[str, Any], inputs["values"])["node"]) + await require_node(request, node) + return subdirs( + "apt", + "ceph", + "disks", + "firewall", + "lxc", + "network", + "qemu", + "services", + "status", + "storage", + "tasks", + "version", + "vzdump", + ) + + async def node_version(request: Request, inputs: dict[str, Any]) -> dict[str, str]: + node = str(cast(dict[str, Any], inputs["values"])["node"]) + await require_node(request, node) + return runtime_version_payload(request) + + registry.register("/version", "GET", version) + registry.register("/access/ticket", "POST", login) + registry.register("/nodes", "GET", nodes) + registry.register("/nodes/{node}", "GET", node_index) + registry.register("/nodes/{node}/status", "GET", node_status) + registry.register("/nodes/{node}/version", "GET", node_version) + registry.register("/cluster/resources", "GET", resources) + register_access_handlers(registry) + register_cluster_handlers(registry) + register_notifications_handlers(registry) + register_mapping_handlers(registry) + register_acme_handlers(registry) + register_cluster_config_handlers(registry) + register_sdn_handlers(registry) + register_storage_handlers(registry) + + register_pool_handlers(registry) + register_ceph_handlers(registry) + register_backup_handlers(registry) + register_ha_handlers(registry) + register_node_ops_handlers(registry) + register_firewall_handlers(registry) + register_qemu_handlers(registry) + register_lxc_handlers(registry) + register_nodes_extra_handlers(registry) + register_cluster_extra_handlers(registry) + register_legacy_aliases(registry) + return registry diff --git a/app/handlers/firewall.py b/app/handlers/firewall.py new file mode 100644 index 0000000..8eef5f3 --- /dev/null +++ b/app/handlers/firewall.py @@ -0,0 +1,526 @@ +"""Firewall handlers backed by cluster metadata.""" + +from __future__ import annotations + +import json +from collections.abc import Callable +from typing import Any, cast + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.common import database, require_node, state, subdirs, values +from app.simulation.seed import CLUSTER_ID + +DEFAULT_OPTIONS = { + "enable": 1, + "policy_in": "DROP", + "policy_out": "ACCEPT", + "log_level_in": "nolog", + "log_level_out": "nolog", +} + +DEFAULT_MACROS = [ + {"macro": "SSH", "descr": "Secure Shell"}, + {"macro": "HTTPS", "descr": "Secure web server"}, + {"macro": "HTTP", "descr": "Web server"}, +] + +ScopeFn = Callable[[dict[str, Any]], str] + + +async def _load_firewall(request: Request) -> dict[str, Any]: + row = await database(request).pool.fetchrow( + "SELECT metadata FROM clusters WHERE id=$1", + CLUSTER_ID, + ) + metadata = state(row["metadata"]) if row is not None else {} + firewall = metadata.get("firewall") + return dict(firewall) if isinstance(firewall, dict) else {} + + +async def _save_firewall(request: Request, firewall: dict[str, Any]) -> None: + await database(request).pool.execute( + """UPDATE clusters SET metadata = jsonb_set( + COALESCE(metadata, '{}'::jsonb), '{firewall}', $2::jsonb, true + ), updated_at=now() WHERE id=$1""", + CLUSTER_ID, + json.dumps(firewall, sort_keys=True), + ) + + +def _scope_data(firewall: dict[str, Any], scope: str) -> dict[str, Any]: + scopes = firewall.setdefault("scopes", {}) + if scope not in scopes or not isinstance(scopes[scope], dict): + scopes[scope] = { + "options": dict(DEFAULT_OPTIONS), + "rules": [], + "aliases": {}, + "ipset": {}, + "groups": {}, + "log": [], + } + section = scopes[scope] + section.setdefault("options", dict(DEFAULT_OPTIONS)) + section.setdefault("rules", []) + section.setdefault("aliases", {}) + section.setdefault("ipset", {}) + section.setdefault("groups", {}) + section.setdefault("log", []) + return cast(dict[str, Any], section) + + +def register_firewall_handlers(registry: HandlerRegistry) -> None: + def register_scope( + base: str, + scope_fn: ScopeFn, + *, + require_node_name: bool = False, + include_macros: bool = False, + include_groups: bool = False, + ) -> None: + async def _ready(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + if require_node_name: + await require_node(request, str(payload["node"])) + return payload + + async def index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + await _ready(request, inputs) + names = ["aliases", "ipset", "log", "options", "refs", "rules"] + if include_groups: + names.insert(2, "groups") + if include_macros: + names.append("macros") + return subdirs(*names) + + async def options_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = await _ready(request, inputs) + firewall = await _load_firewall(request) + return dict(_scope_data(firewall, scope_fn(payload)).get("options", DEFAULT_OPTIONS)) + + async def options_put(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = await _ready(request, inputs) + firewall = await _load_firewall(request) + section = _scope_data(firewall, scope_fn(payload)) + current = dict(section.get("options", DEFAULT_OPTIONS)) + for key, value in payload.items(): + if key in {"node", "vmid", "delete", "digest"}: + continue + current[key] = value + section["options"] = current + await _save_firewall(request, firewall) + return current + + async def rules_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + payload = await _ready(request, inputs) + firewall = await _load_firewall(request) + rules = _scope_data(firewall, scope_fn(payload)).get("rules", []) + return list(rules) if isinstance(rules, list) else [] + + async def rules_create(request: Request, inputs: dict[str, Any]) -> None: + payload = await _ready(request, inputs) + firewall = await _load_firewall(request) + section = _scope_data(firewall, scope_fn(payload)) + rules = section.setdefault("rules", []) + if not isinstance(rules, list): + rules = section["rules"] = [] + rule = { + key: value for key, value in payload.items() if key not in {"node", "vmid", "pos"} + } + rule["pos"] = len(rules) + rules.append(rule) + await _save_firewall(request, firewall) + + async def rule_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + pos = int(values(inputs)["pos"]) + rules = await rules_list(request, inputs) + if pos < 0 or pos >= len(rules): + raise ApiError(404, "firewall rule does not exist") + return dict(rules[pos]) + + async def rule_update(request: Request, inputs: dict[str, Any]) -> None: + payload = await _ready(request, inputs) + pos = int(payload["pos"]) + firewall = await _load_firewall(request) + rules = _scope_data(firewall, scope_fn(payload)).setdefault("rules", []) + if not isinstance(rules, list) or pos < 0 or pos >= len(rules): + raise ApiError(404, "firewall rule does not exist") + rules[pos] = { + **rules[pos], + **{k: v for k, v in payload.items() if k not in {"node", "vmid"}}, + } + await _save_firewall(request, firewall) + + async def rule_delete(request: Request, inputs: dict[str, Any]) -> None: + payload = await _ready(request, inputs) + pos = int(payload["pos"]) + firewall = await _load_firewall(request) + rules = _scope_data(firewall, scope_fn(payload)).setdefault("rules", []) + if not isinstance(rules, list) or pos < 0 or pos >= len(rules): + raise ApiError(404, "firewall rule does not exist") + del rules[pos] + for index, rule in enumerate(rules): + if isinstance(rule, dict): + rule["pos"] = index + await _save_firewall(request, firewall) + + async def aliases_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + payload = await _ready(request, inputs) + firewall = await _load_firewall(request) + aliases = _scope_data(firewall, scope_fn(payload)).get("aliases", {}) + if not isinstance(aliases, dict): + return [] + return [ + {"name": name, **{k: v for k, v in data.items() if k != "name"}} + for name, data in sorted(aliases.items()) + if isinstance(data, dict) + ] + + async def aliases_create(request: Request, inputs: dict[str, Any]) -> None: + payload = await _ready(request, inputs) + name = str(payload["name"]) + firewall = await _load_firewall(request) + section = _scope_data(firewall, scope_fn(payload)) + aliases = section.setdefault("aliases", {}) + if name in aliases: + raise ApiError(400, f"alias '{name}' already exists") + aliases[name] = { + "name": name, + "cidr": str(payload.get("cidr") or ""), + "comment": str(payload.get("comment") or ""), + } + await _save_firewall(request, firewall) + + async def aliases_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = await _ready(request, inputs) + name = str(payload["name"]) + firewall = await _load_firewall(request) + alias = _scope_data(firewall, scope_fn(payload)).get("aliases", {}).get(name) + if not isinstance(alias, dict): + raise ApiError(404, "alias does not exist") + return dict(alias) + + async def aliases_update(request: Request, inputs: dict[str, Any]) -> None: + payload = await _ready(request, inputs) + name = str(payload["name"]) + firewall = await _load_firewall(request) + aliases = _scope_data(firewall, scope_fn(payload)).setdefault("aliases", {}) + if name not in aliases or not isinstance(aliases[name], dict): + raise ApiError(404, "alias does not exist") + current = dict(aliases[name]) + if payload.get("rename"): + new_name = str(payload["rename"]) + if new_name in aliases and new_name != name: + raise ApiError(400, f"alias '{new_name}' already exists") + del aliases[name] + name = new_name + current["name"] = new_name + for key in ("cidr", "comment"): + if key in payload: + current[key] = payload[key] + aliases[name] = current + await _save_firewall(request, firewall) + + async def aliases_delete(request: Request, inputs: dict[str, Any]) -> None: + payload = await _ready(request, inputs) + name = str(payload["name"]) + firewall = await _load_firewall(request) + aliases = _scope_data(firewall, scope_fn(payload)).setdefault("aliases", {}) + if name not in aliases: + raise ApiError(404, "alias does not exist") + del aliases[name] + await _save_firewall(request, firewall) + + async def ipset_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + payload = await _ready(request, inputs) + firewall = await _load_firewall(request) + ipsets = _scope_data(firewall, scope_fn(payload)).get("ipset", {}) + if not isinstance(ipsets, dict): + return [] + return [ + {"name": name, "comment": data.get("comment", "")} + for name, data in sorted(ipsets.items()) + if isinstance(data, dict) + ] + + async def ipset_create(request: Request, inputs: dict[str, Any]) -> None: + payload = await _ready(request, inputs) + name = str(payload["name"]) + firewall = await _load_firewall(request) + ipsets = _scope_data(firewall, scope_fn(payload)).setdefault("ipset", {}) + if name in ipsets: + raise ApiError(400, f"ipset '{name}' already exists") + ipsets[name] = { + "name": name, + "comment": str(payload.get("comment") or ""), + "entries": {}, + } + await _save_firewall(request, firewall) + + async def ipset_get(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + payload = await _ready(request, inputs) + name = str(payload["name"]) + firewall = await _load_firewall(request) + ipset = _scope_data(firewall, scope_fn(payload)).get("ipset", {}).get(name) + if not isinstance(ipset, dict): + raise ApiError(404, "ipset does not exist") + entries = ipset.get("entries", {}) + if not isinstance(entries, dict): + return [] + return [ + {"cidr": cidr, **{k: v for k, v in data.items() if k != "cidr"}} + for cidr, data in sorted(entries.items()) + if isinstance(data, dict) + ] + + async def ipset_delete(request: Request, inputs: dict[str, Any]) -> None: + payload = await _ready(request, inputs) + name = str(payload["name"]) + firewall = await _load_firewall(request) + ipsets = _scope_data(firewall, scope_fn(payload)).setdefault("ipset", {}) + if name not in ipsets: + raise ApiError(404, "ipset does not exist") + del ipsets[name] + await _save_firewall(request, firewall) + + async def ipset_entry_create(request: Request, inputs: dict[str, Any]) -> None: + payload = await _ready(request, inputs) + name = str(payload["name"]) + cidr = str(payload["cidr"]) + firewall = await _load_firewall(request) + ipsets = _scope_data(firewall, scope_fn(payload)).setdefault("ipset", {}) + if name not in ipsets or not isinstance(ipsets[name], dict): + raise ApiError(404, "ipset does not exist") + entries = ipsets[name].setdefault("entries", {}) + if cidr in entries: + raise ApiError(400, f"ip '{cidr}' already exists in ipset") + entries[cidr] = { + "cidr": cidr, + "comment": str(payload.get("comment") or ""), + "nomatch": int(bool(payload.get("nomatch"))), + } + await _save_firewall(request, firewall) + + async def ipset_entry_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = await _ready(request, inputs) + name = str(payload["name"]) + cidr = str(payload["cidr"]) + firewall = await _load_firewall(request) + ipset = _scope_data(firewall, scope_fn(payload)).get("ipset", {}).get(name) + if not isinstance(ipset, dict): + raise ApiError(404, "ipset does not exist") + entry = ipset.get("entries", {}).get(cidr) + if not isinstance(entry, dict): + raise ApiError(404, "ipset entry does not exist") + return dict(entry) + + async def ipset_entry_update(request: Request, inputs: dict[str, Any]) -> None: + payload = await _ready(request, inputs) + name = str(payload["name"]) + cidr = str(payload["cidr"]) + firewall = await _load_firewall(request) + ipsets = _scope_data(firewall, scope_fn(payload)).setdefault("ipset", {}) + if name not in ipsets or not isinstance(ipsets[name], dict): + raise ApiError(404, "ipset does not exist") + entries = ipsets[name].setdefault("entries", {}) + if cidr not in entries: + raise ApiError(404, "ipset entry does not exist") + current = dict(entries[cidr]) + if "comment" in payload: + current["comment"] = payload["comment"] + if "nomatch" in payload: + current["nomatch"] = int(bool(payload.get("nomatch"))) + entries[cidr] = current + await _save_firewall(request, firewall) + + async def ipset_entry_delete(request: Request, inputs: dict[str, Any]) -> None: + payload = await _ready(request, inputs) + name = str(payload["name"]) + cidr = str(payload["cidr"]) + firewall = await _load_firewall(request) + ipsets = _scope_data(firewall, scope_fn(payload)).setdefault("ipset", {}) + if name not in ipsets or not isinstance(ipsets[name], dict): + raise ApiError(404, "ipset does not exist") + entries = ipsets[name].setdefault("entries", {}) + if cidr not in entries: + raise ApiError(404, "ipset entry does not exist") + del entries[cidr] + await _save_firewall(request, firewall) + + async def refs_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + payload = await _ready(request, inputs) + firewall = await _load_firewall(request) + section = _scope_data(firewall, scope_fn(payload)) + refs: list[dict[str, Any]] = [] + for name in section.get("aliases", {}): + refs.append({"type": "alias", "name": name}) + for name in section.get("ipset", {}): + refs.append({"type": "ipset", "name": name}) + return refs + + async def log_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + payload = await _ready(request, inputs) + firewall = await _load_firewall(request) + log = _scope_data(firewall, scope_fn(payload)).get("log", []) + return list(log) if isinstance(log, list) else [] + + async def macros_list(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + return list(DEFAULT_MACROS) + + async def groups_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + payload = await _ready(request, inputs) + firewall = await _load_firewall(request) + groups = _scope_data(firewall, scope_fn(payload)).get("groups", {}) + if not isinstance(groups, dict): + return [] + return [ + {"group": name, "comment": data.get("comment", "")} + for name, data in sorted(groups.items()) + if isinstance(data, dict) + ] + + async def groups_create(request: Request, inputs: dict[str, Any]) -> None: + payload = await _ready(request, inputs) + group = str(payload["group"]) + firewall = await _load_firewall(request) + groups = _scope_data(firewall, scope_fn(payload)).setdefault("groups", {}) + if group in groups: + raise ApiError(400, f"security group '{group}' already exists") + groups[group] = {"comment": str(payload.get("comment") or ""), "rules": []} + await _save_firewall(request, firewall) + + async def group_rules(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + payload = await _ready(request, inputs) + group = str(payload["group"]) + firewall = await _load_firewall(request) + groups = _scope_data(firewall, scope_fn(payload)).get("groups", {}) + if group not in groups or not isinstance(groups[group], dict): + raise ApiError(404, "security group does not exist") + rules = groups[group].get("rules", []) + return list(rules) if isinstance(rules, list) else [] + + async def group_delete(request: Request, inputs: dict[str, Any]) -> None: + payload = await _ready(request, inputs) + group = str(payload["group"]) + firewall = await _load_firewall(request) + groups = _scope_data(firewall, scope_fn(payload)).setdefault("groups", {}) + if group not in groups: + raise ApiError(404, "security group does not exist") + del groups[group] + await _save_firewall(request, firewall) + + async def group_rule_create(request: Request, inputs: dict[str, Any]) -> None: + payload = await _ready(request, inputs) + group = str(payload["group"]) + firewall = await _load_firewall(request) + groups = _scope_data(firewall, scope_fn(payload)).setdefault("groups", {}) + if group not in groups or not isinstance(groups[group], dict): + raise ApiError(404, "security group does not exist") + rules = groups[group].setdefault("rules", []) + if not isinstance(rules, list): + rules = groups[group]["rules"] = [] + rule = { + key: value + for key, value in payload.items() + if key not in {"node", "vmid", "group", "pos"} + } + rule["pos"] = len(rules) + rules.append(rule) + await _save_firewall(request, firewall) + + async def group_rule_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + rules = await group_rules(request, inputs) + pos = int(values(inputs)["pos"]) + if pos < 0 or pos >= len(rules): + raise ApiError(404, "firewall rule does not exist") + return dict(rules[pos]) + + async def group_rule_update(request: Request, inputs: dict[str, Any]) -> None: + payload = await _ready(request, inputs) + group = str(payload["group"]) + pos = int(payload["pos"]) + firewall = await _load_firewall(request) + groups = _scope_data(firewall, scope_fn(payload)).setdefault("groups", {}) + if group not in groups or not isinstance(groups[group], dict): + raise ApiError(404, "security group does not exist") + rules = groups[group].setdefault("rules", []) + if not isinstance(rules, list) or pos < 0 or pos >= len(rules): + raise ApiError(404, "firewall rule does not exist") + rules[pos] = { + **rules[pos], + **{k: v for k, v in payload.items() if k not in {"node", "vmid", "group"}}, + } + await _save_firewall(request, firewall) + + async def group_rule_delete(request: Request, inputs: dict[str, Any]) -> None: + payload = await _ready(request, inputs) + group = str(payload["group"]) + pos = int(payload["pos"]) + firewall = await _load_firewall(request) + groups = _scope_data(firewall, scope_fn(payload)).setdefault("groups", {}) + if group not in groups or not isinstance(groups[group], dict): + raise ApiError(404, "security group does not exist") + rules = groups[group].setdefault("rules", []) + if not isinstance(rules, list) or pos < 0 or pos >= len(rules): + raise ApiError(404, "firewall rule does not exist") + del rules[pos] + await _save_firewall(request, firewall) + + registry.register(base, "GET", index) + registry.register(f"{base}/options", "GET", options_get) + registry.register(f"{base}/options", "PUT", options_put) + registry.register(f"{base}/rules", "GET", rules_list) + registry.register(f"{base}/rules", "POST", rules_create) + registry.register(f"{base}/rules/{{pos}}", "GET", rule_get) + registry.register(f"{base}/rules/{{pos}}", "PUT", rule_update) + registry.register(f"{base}/rules/{{pos}}", "DELETE", rule_delete) + registry.register(f"{base}/aliases", "GET", aliases_list) + registry.register(f"{base}/aliases", "POST", aliases_create) + registry.register(f"{base}/aliases/{{name}}", "GET", aliases_get) + registry.register(f"{base}/aliases/{{name}}", "PUT", aliases_update) + registry.register(f"{base}/aliases/{{name}}", "DELETE", aliases_delete) + registry.register(f"{base}/ipset", "GET", ipset_list) + registry.register(f"{base}/ipset", "POST", ipset_create) + registry.register(f"{base}/ipset/{{name}}", "GET", ipset_get) + registry.register(f"{base}/ipset/{{name}}", "DELETE", ipset_delete) + registry.register(f"{base}/ipset/{{name}}", "POST", ipset_entry_create) + registry.register(f"{base}/ipset/{{name}}/{{cidr}}", "GET", ipset_entry_get) + registry.register(f"{base}/ipset/{{name}}/{{cidr}}", "PUT", ipset_entry_update) + registry.register(f"{base}/ipset/{{name}}/{{cidr}}", "DELETE", ipset_entry_delete) + registry.register(f"{base}/refs", "GET", refs_list) + registry.register(f"{base}/log", "GET", log_list) + if include_macros: + registry.register(f"{base}/macros", "GET", macros_list) + if include_groups: + registry.register(f"{base}/groups", "GET", groups_list) + registry.register(f"{base}/groups", "POST", groups_create) + registry.register(f"{base}/groups/{{group}}", "GET", group_rules) + registry.register(f"{base}/groups/{{group}}", "POST", group_rule_create) + registry.register(f"{base}/groups/{{group}}", "DELETE", group_delete) + registry.register(f"{base}/groups/{{group}}/{{pos}}", "GET", group_rule_get) + registry.register(f"{base}/groups/{{group}}/{{pos}}", "PUT", group_rule_update) + registry.register(f"{base}/groups/{{group}}/{{pos}}", "DELETE", group_rule_delete) + + register_scope( + "/cluster/firewall", + lambda _payload: "cluster", + include_macros=True, + include_groups=True, + ) + register_scope( + "/nodes/{node}/firewall", + lambda payload: f"node:{payload['node']}", + require_node_name=True, + ) + register_scope( + "/nodes/{node}/qemu/{vmid}/firewall", + lambda payload: f"qemu:{payload['node']}:{payload['vmid']}", + require_node_name=True, + ) + register_scope( + "/nodes/{node}/lxc/{vmid}/firewall", + lambda payload: f"lxc:{payload['node']}:{payload['vmid']}", + require_node_name=True, + ) diff --git a/app/handlers/ha.py b/app/handlers/ha.py new file mode 100644 index 0000000..100f174 --- /dev/null +++ b/app/handlers/ha.py @@ -0,0 +1,350 @@ +"""High availability semantic handlers.""" + +from __future__ import annotations + +import json +from typing import Any + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.common import ( + cluster_metadata, + database, + save_cluster_metadata, + state, + subdirs, + values, +) +from app.simulation.seed import CLUSTER_ID, stable_id + + +def _ha_groups(metadata: dict[str, Any]) -> dict[str, dict[str, Any]]: + groups = metadata.get("ha_groups", {}) + if not isinstance(groups, dict): + return {} + return {str(key): dict(value) for key, value in groups.items() if isinstance(value, dict)} + + +def register_ha_handlers(registry: HandlerRegistry) -> None: + async def ha_index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs("groups", "resources", "rules", "status") + + async def ha_resources(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + rows = await database(_request).pool.fetch( + """SELECT r.external_id, r.state, n.name AS node + FROM resources r JOIN nodes n ON n.id=r.node_id + WHERE r.kind='ha' ORDER BY r.external_id""" + ) + result: list[dict[str, Any]] = [] + for row in rows: + payload = state(row["state"]) + sid = str(row["external_id"]) + result.append( + { + "sid": sid, + "type": "vm" if sid.startswith("vm:") else "ct", + "state": payload.get("state", "started"), + "group": payload.get("group"), + "node": str(row["node"]), + "max_relocate": payload.get("max_relocate", 1), + "max_restart": payload.get("max_restart", 1), + } + ) + return result + + async def ha_resource_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + sid = str(values(inputs)["sid"]) + items = await ha_resources(request, inputs) + for item in items: + if item["sid"] == sid: + return item + raise ApiError(404, "HA resource does not exist") + + async def ha_resource_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + sid = str(payload["sid"]) + group = str(payload.get("group") or "") + exists = await database(request).pool.fetchval( + """SELECT EXISTS(SELECT 1 FROM resources WHERE kind='ha' AND external_id=$1)""", + sid, + ) + if exists: + raise ApiError(409, "HA resource already exists") + guest_kind, _, guest_id = sid.partition(":") + if guest_kind not in {"vm", "ct"} or not guest_id.isdigit(): + raise ApiError(400, "invalid HA resource sid") + resource_kind = "qemu" if guest_kind == "vm" else "lxc" + guest = await database(request).pool.fetchrow( + """SELECT r.id, n.name FROM resources r JOIN nodes n ON n.id=r.node_id + WHERE r.kind=$1 AND r.external_id=$2""", + resource_kind, + guest_id, + ) + if guest is None: + raise ApiError(404, "guest does not exist") + node = await database(request).pool.fetchrow( + "SELECT id FROM nodes WHERE name=$1", + str(guest["name"]), + ) + if node is None: + raise ApiError(404, "node does not exist") + ha_state = { + "state": str(payload.get("state") or "started"), + "group": group or None, + "max_relocate": int(payload.get("max_relocate") or 1), + "max_restart": int(payload.get("max_restart") or 1), + } + await database(request).pool.execute( + """INSERT INTO resources(id, node_id, cluster_id, kind, external_id, state, metadata) + VALUES($1, $2, $3, 'ha', $4, $5::jsonb, '{}'::jsonb)""", + stable_id(f"ha:{sid}"), + node["id"], + CLUSTER_ID, + sid, + json.dumps(ha_state, sort_keys=True), + ) + + async def ha_resource_update(request: Request, inputs: dict[str, Any]) -> None: + sid = str(values(inputs)["sid"]) + payload = values(inputs) + row = await database(request).pool.fetchrow( + "SELECT id, state FROM resources WHERE kind='ha' AND external_id=$1", + sid, + ) + if row is None: + raise ApiError(404, "HA resource does not exist") + current = state(row["state"]) + updated = { + **current, + **{ + key: value + for key, value in payload.items() + if key not in {"sid", "delete", "digest"} + }, + } + await database(request).pool.execute( + "UPDATE resources SET state=$2::jsonb, updated_at=now() WHERE id=$1", + row["id"], + json.dumps(updated, sort_keys=True), + ) + + async def ha_resource_delete(request: Request, inputs: dict[str, Any]) -> None: + sid = str(values(inputs)["sid"]) + status = await database(request).pool.execute( + "DELETE FROM resources WHERE kind='ha' AND external_id=$1", + sid, + ) + if status != "DELETE 1": + raise ApiError(404, "HA resource does not exist") + + async def ha_groups(request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + metadata = await cluster_metadata(request) + configured = _ha_groups(metadata) + result = [ + { + "group": group_id, + "nodes": str(payload.get("nodes", "")), + "nofailback": int(payload.get("nofailback", 0)), + "restricted": int(payload.get("restricted", 0)), + "type": "group", + "comment": payload.get("comment", ""), + } + for group_id, payload in sorted(configured.items()) + ] + if result: + return result + rows = await database(request).pool.fetch( + """SELECT DISTINCT state->>'group' AS group_id + FROM resources WHERE kind='ha' AND state ? 'group' + ORDER BY 1""" + ) + node_names = await database(request).pool.fetch("SELECT name FROM nodes ORDER BY name") + nodes = ",".join(str(row["name"]) for row in node_names) or "pve01" + return [ + { + "group": str(row["group_id"]), + "nodes": nodes, + "nofailback": 0, + "restricted": 0, + "type": "group", + } + for row in rows + if row["group_id"] + ] + + async def ha_group_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + group = str(values(inputs)["group"]) + for item in await ha_groups(request, inputs): + if item["group"] == group: + return item + raise ApiError(404, "HA group does not exist") + + async def ha_group_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + group = str(payload["group"]) + metadata = await cluster_metadata(request) + groups = _ha_groups(metadata) + if group in groups: + raise ApiError(409, "HA group already exists") + groups[group] = { + "nodes": str(payload.get("nodes") or ""), + "nofailback": int(payload.get("nofailback") or 0), + "restricted": int(payload.get("restricted") or 0), + "comment": str(payload.get("comment") or ""), + } + metadata["ha_groups"] = groups + await save_cluster_metadata(request, metadata) + + async def ha_group_update(request: Request, inputs: dict[str, Any]) -> None: + group = str(values(inputs)["group"]) + metadata = await cluster_metadata(request) + groups = _ha_groups(metadata) + if group not in groups: + raise ApiError(404, "HA group does not exist") + payload = values(inputs) + groups[group] = { + **groups[group], + **{ + key: value + for key, value in payload.items() + if key not in {"group", "delete", "digest"} + }, + } + metadata["ha_groups"] = groups + await save_cluster_metadata(request, metadata) + + async def ha_group_delete(request: Request, inputs: dict[str, Any]) -> None: + group = str(values(inputs)["group"]) + metadata = await cluster_metadata(request) + groups = _ha_groups(metadata) + if group not in groups: + raise ApiError(404, "HA group does not exist") + del groups[group] + metadata["ha_groups"] = groups + await save_cluster_metadata(request, metadata) + + async def ha_status(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs("current", "manager_status") + + async def ha_status_current(request: Request, _inputs: dict[str, Any]) -> dict[str, Any]: + row = await database(request).pool.fetchrow( + """SELECT count(*) FILTER (WHERE state->>'state' = 'started') AS started, + count(*) AS total + FROM resources WHERE kind='ha'""" + ) + master = await database(request).pool.fetchval( + "SELECT name FROM nodes WHERE status='online' ORDER BY name LIMIT 1" + ) + metadata = await cluster_metadata(request) + ha = metadata.get("ha", {}) if isinstance(metadata.get("ha"), dict) else {} + return { + "quorate": 1, + "mode": "active" if ha.get("armed", True) else "disabled", + "master_node": str(master or "pve01"), + "ha_started": int(row["started"] or 0), + "ha_total": int(row["total"] or 0), + "armed": 1 if ha.get("armed", True) else 0, + } + + async def ha_manager_status(request: Request, _inputs: dict[str, Any]) -> dict[str, Any]: + metadata = await cluster_metadata(request) + ha = metadata.get("ha", {}) if isinstance(metadata.get("ha"), dict) else {} + armed = bool(ha.get("armed", True)) + return { + "manager_status": "active" if armed else "disabled", + "quorum": "OK", + "armed": 1 if armed else 0, + } + + async def ha_rules(request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + metadata = await cluster_metadata(request) + rules = metadata.get("ha_rules") + if isinstance(rules, list) and rules: + return [dict(item) for item in rules if isinstance(item, dict)] + defaults = [ + {"rule": "node-fencing", "type": "node", "action": "restart"}, + {"rule": "service-ha", "type": "resource", "action": "failover"}, + ] + metadata["ha_rules"] = defaults + await save_cluster_metadata(request, metadata) + return list(defaults) + + async def ha_relocate(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + sid = str(payload["sid"]) + target = str(payload.get("node") or payload.get("target") or "") + if not target: + raise ApiError(400, "parameter verification failed - target node missing") + ha_row = await database(request).pool.fetchrow( + "SELECT id, state FROM resources WHERE kind='ha' AND external_id=$1", + sid, + ) + if ha_row is None: + raise ApiError(404, "HA resource does not exist") + node = await database(request).pool.fetchrow( + "SELECT id, name FROM nodes WHERE name=$1", + target, + ) + if node is None: + raise ApiError(404, "node does not exist") + guest_kind, _, guest_id = sid.partition(":") + resource_kind = "qemu" if guest_kind == "vm" else "lxc" + await database(request).pool.execute( + "UPDATE resources SET node_id=$2, updated_at=now() WHERE kind='ha' AND external_id=$1", + sid, + node["id"], + ) + await database(request).pool.execute( + """UPDATE resources SET node_id=$3, updated_at=now() + WHERE kind=$1 AND external_id=$2""", + resource_kind, + guest_id, + node["id"], + ) + current = state(ha_row["state"]) + current["node"] = target + current["state"] = current.get("state") or "started" + await database(request).pool.execute( + "UPDATE resources SET state=$2::jsonb, updated_at=now() WHERE id=$1", + ha_row["id"], + json.dumps(current, sort_keys=True), + ) + + async def ha_migrate(request: Request, inputs: dict[str, Any]) -> None: + await ha_relocate(request, inputs) + + async def ha_arm(request: Request, _inputs: dict[str, Any]) -> None: + metadata = await cluster_metadata(request) + ha = dict(metadata.get("ha") or {}) + ha["armed"] = True + metadata["ha"] = ha + await save_cluster_metadata(request, metadata) + + async def ha_disarm(request: Request, _inputs: dict[str, Any]) -> None: + metadata = await cluster_metadata(request) + ha = dict(metadata.get("ha") or {}) + ha["armed"] = False + metadata["ha"] = ha + await save_cluster_metadata(request, metadata) + + registry.register("/cluster/ha", "GET", ha_index) + registry.register("/cluster/ha/groups", "GET", ha_groups) + registry.register("/cluster/ha/groups", "POST", ha_group_create) + registry.register("/cluster/ha/groups/{group}", "GET", ha_group_get) + registry.register("/cluster/ha/groups/{group}", "PUT", ha_group_update) + registry.register("/cluster/ha/groups/{group}", "DELETE", ha_group_delete) + registry.register("/cluster/ha/resources", "GET", ha_resources) + registry.register("/cluster/ha/resources", "POST", ha_resource_create) + registry.register("/cluster/ha/resources/{sid}", "GET", ha_resource_get) + registry.register("/cluster/ha/resources/{sid}", "PUT", ha_resource_update) + registry.register("/cluster/ha/resources/{sid}", "DELETE", ha_resource_delete) + registry.register("/cluster/ha/status", "GET", ha_status) + registry.register("/cluster/ha/status/current", "GET", ha_status_current) + registry.register("/cluster/ha/status/manager_status", "GET", ha_manager_status) + registry.register("/cluster/ha/rules", "GET", ha_rules) + registry.register("/cluster/ha/resources/{sid}/migrate", "POST", ha_migrate) + registry.register("/cluster/ha/resources/{sid}/relocate", "POST", ha_relocate) + registry.register("/cluster/ha/status/arm-ha", "POST", ha_arm) + registry.register("/cluster/ha/status/disarm-ha", "POST", ha_disarm) diff --git a/app/handlers/legacy_aliases.py b/app/handlers/legacy_aliases.py new file mode 100644 index 0000000..0da8164 --- /dev/null +++ b/app/handlers/legacy_aliases.py @@ -0,0 +1,59 @@ +"""Legacy Proxmox path aliases for older contract snapshots.""" + +from __future__ import annotations + +from app.api.registry import HandlerRegistry + + +def register_legacy_aliases(registry: HandlerRegistry) -> None: + """Register older-path synonyms onto already-registered handlers when present.""" + + def alias(old_path: str, old_verb: str, new_path: str, new_verb: str | None = None) -> None: + verb = (new_verb or old_verb).upper() + handler = registry.get(new_path, verb) + if handler is None: + return + if registry.get(old_path, old_verb) is not None: + return + registry.register(old_path, old_verb.upper(), handler) + + alias("/access/tfa", "POST", "/access/tfa/{userid}", "POST") + alias("/access/tfa", "PUT", "/access/tfa/{userid}/{id}", "PUT") + alias("/cluster/backupinfo", "GET", "/cluster/backup-info", "GET") + alias( + "/cluster/backupinfo/not_backed_up", + "GET", + "/cluster/backup-info/not-backed-up", + "GET", + ) + alias("/nodes/{node}/ceph/config", "GET", "/nodes/{node}/ceph/cfg/raw", "GET") + alias("/nodes/{node}/ceph/configdb", "GET", "/nodes/{node}/ceph/cfg/db", "GET") + alias("/nodes/{node}/ceph/disks", "GET", "/nodes/{node}/ceph/osd", "GET") + alias("/nodes/{node}/ceph/flags", "GET", "/cluster/ceph/flags", "GET") + alias("/nodes/{node}/ceph/flags/{flag}", "POST", "/cluster/ceph/flags/{flag}", "PUT") + alias("/nodes/{node}/ceph/flags/{flag}", "DELETE", "/cluster/ceph/flags/{flag}", "PUT") + alias("/nodes/{node}/ceph/pools", "GET", "/nodes/{node}/ceph/pool", "GET") + alias("/nodes/{node}/ceph/pools", "POST", "/nodes/{node}/ceph/pool", "POST") + alias("/nodes/{node}/ceph/pools/{name}", "GET", "/nodes/{node}/ceph/pool/{name}", "GET") + alias("/nodes/{node}/ceph/pools/{name}", "PUT", "/nodes/{node}/ceph/pool/{name}", "PUT") + alias( + "/nodes/{node}/ceph/pools/{name}", + "DELETE", + "/nodes/{node}/ceph/pool/{name}", + "DELETE", + ) + alias("/nodes/{node}/cpu", "GET", "/nodes/{node}/capabilities/qemu/cpu", "GET") + alias( + "/nodes/{node}/hardware/pci/{pciid}", + "GET", + "/nodes/{node}/hardware/pci/{pci-id-or-mapping}", + "GET", + ) + alias( + "/nodes/{node}/hardware/pci/{pciid}/mdev", + "GET", + "/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev", + "GET", + ) + alias("/nodes/{node}/scan/glusterfs", "GET", "/nodes/{node}/scan/nfs", "GET") + alias("/nodes/{node}/scan/usb", "GET", "/nodes/{node}/hardware/usb", "GET") diff --git a/app/handlers/lxc.py b/app/handlers/lxc.py new file mode 100644 index 0000000..3fbaeb0 --- /dev/null +++ b/app/handlers/lxc.py @@ -0,0 +1,574 @@ +"""Persistent LXC semantic handlers.""" + +from __future__ import annotations + +import json +from collections.abc import Mapping +from typing import Any, cast + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.db.pool import AsyncpgDatabase +from app.db.primitives import ConflictError +from app.handlers.common import ( + disk_size_bytes, + replace_disk_size, + require_node, + resize_size_bytes, + subdirs, +) +from app.simulation.transitions import InvalidTransitionError, VmState, plan_transition +from app.tasks.repository import TaskRepository +from app.tasks.upid import Upid + + +def _database(request: Request) -> AsyncpgDatabase: + return cast(AsyncpgDatabase, request.app.state.database) + + +def _values(inputs: dict[str, Any]) -> dict[str, Any]: + return cast(dict[str, Any], inputs["values"]) + + +def _state(value: object) -> dict[str, Any]: + if isinstance(value, str): + return cast(dict[str, Any], json.loads(value)) + return dict(cast(Mapping[str, Any], value)) + + +def register_lxc_handlers(registry: HandlerRegistry) -> None: + async def lxc_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(_values(inputs)["node"]) + rows = await _database(request).pool.fetch( + """SELECT r.external_id::integer AS vmid, r.state + FROM resources r JOIN nodes n ON n.id=r.node_id + WHERE n.name=$1 AND r.kind='lxc' ORDER BY r.external_id::integer""", + node, + ) + return [{"vmid": int(row["vmid"]), **_state(row["state"])} for row in rows] + + async def lxc_config(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node, vmid = str(_values(inputs)["node"]), str(_values(inputs)["vmid"]) + row = await _lxc_resource(request, node, vmid) + return {"vmid": int(vmid), **_state(row["config"]), **_state(row["state"])} + + async def lxc_current(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await lxc_config(request, inputs) + + async def lxc_status(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await lxc_config(request, inputs) + + async def mutate(operation: str, request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + node, vmid = str(values["node"]), str(values["vmid"]) + database = _database(request) + row = await database.pool.fetchrow( + """SELECT r.id, r.state FROM resources r JOIN nodes n ON n.id=r.node_id + WHERE n.name=$1 AND r.kind='lxc' AND r.external_id=$2""", + node, + vmid, + ) + if row is None: + raise ApiError(404, "container does not exist") + current = str(_state(row["state"]).get("status", "stopped")) + try: + plan_transition(VmState(current), operation) + except (InvalidTransitionError, ValueError) as error: + raise ApiError(409, f"cannot {operation} container while it is {current}") from error + upid = str(Upid.allocate(node, f"pct{operation}", vmid, str(request.state.principal))) + try: + task = await TaskRepository(database.pool).create( + upid=upid, + task_type=f"lxc-{operation}", + payload={"node": node, "vmid": vmid, "resource_id": str(row["id"])}, + resource_key=f"lxc:{vmid}", + idempotency_key=request.headers.get("Idempotency-Key"), + ) + except ConflictError as error: + raise ApiError(409, str(error)) from error + return task.upid + + async def start(request: Request, inputs: dict[str, Any]) -> str: + return await mutate("start", request, inputs) + + async def stop(request: Request, inputs: dict[str, Any]) -> str: + return await mutate("stop", request, inputs) + + async def shutdown(request: Request, inputs: dict[str, Any]) -> str: + return await mutate("shutdown", request, inputs) + + async def reboot(request: Request, inputs: dict[str, Any]) -> str: + return await mutate("reboot", request, inputs) + + async def suspend(request: Request, inputs: dict[str, Any]) -> str: + return await mutate("suspend", request, inputs) + + async def resume(request: Request, inputs: dict[str, Any]) -> str: + return await mutate("resume", request, inputs) + + async def create(request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + node, vmid = str(values["node"]), int(values["vmid"]) + database = _database(request) + if not await database.pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM nodes WHERE name=$1)", node + ): + raise ApiError(404, "node does not exist") + if await database.pool.fetchval( + """SELECT EXISTS(SELECT 1 FROM resources + WHERE external_id=$1 AND kind IN ('qemu','lxc'))""", + str(vmid), + ): + raise ApiError(409, "VMID already exists") + config = { + key: value + for key, value in values.items() + if key not in {"node", "vmid", "force", "start", "ostemplate"} + } + if "ostemplate" in values: + config["ostemplate"] = values["ostemplate"] + return await _create_task( + request, + node=node, + vmid=str(vmid), + task_type="lxc-create", + payload={ + "node": node, + "vmid": vmid, + "config": config, + "start": bool(values.get("start")), + }, + ) + + async def update(request: Request, inputs: dict[str, Any]) -> None: + values = _values(inputs) + node, vmid = str(values["node"]), str(values["vmid"]) + database = _database(request) + row = await database.pool.fetchrow( + """SELECT r.id, r.version, r.state, c.config FROM resources r + JOIN nodes n ON n.id=r.node_id + JOIN containers c ON c.resource_id=r.id + WHERE n.name=$1 AND r.kind='lxc' AND r.external_id=$2""", + node, + vmid, + ) + if row is None: + raise ApiError(404, "container does not exist") + control = {"node", "vmid", "digest", "delete", "revert", "skiplock"} + provided = frozenset(str(item) for item in inputs.get("provided", values)) + changes = { + key: value for key, value in values.items() if key in provided and key not in control + } + delete = str(values.get("delete", "")) if "delete" in provided else "" + state = _state(row["state"]) + config = _state(row["config"]) + state.update(changes) + config.update(changes) + for key in delete.split(","): + if key: + state.pop(key, None) + config.pop(key, None) + status = await database.pool.execute( + """UPDATE resources SET state=$3::jsonb, version=version+1, + updated_at=now() WHERE id=$1 AND version=$2""", + row["id"], + row["version"], + json.dumps(state, sort_keys=True), + ) + if status != "UPDATE 1": + raise ApiError(409, "configuration changed concurrently") + await database.pool.execute( + "UPDATE containers SET config=$2::jsonb WHERE resource_id=$1", + row["id"], + json.dumps(config, sort_keys=True), + ) + + async def delete(request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + node, vmid = str(values["node"]), str(values["vmid"]) + database = _database(request) + row = await database.pool.fetchrow( + """SELECT r.id, r.state FROM resources r JOIN nodes n ON n.id=r.node_id + WHERE n.name=$1 AND r.kind='lxc' AND r.external_id=$2""", + node, + vmid, + ) + if row is None: + raise ApiError(404, "container does not exist") + if str(_state(row["state"]).get("status")) != "stopped": + raise ApiError(409, "cannot delete a running container") + return await _create_task( + request, + node=node, + vmid=vmid, + task_type="lxc-delete", + payload={"node": node, "vmid": vmid, "resource_id": str(row["id"])}, + ) + + async def snapshot_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + values = _values(inputs) + resource = await _lxc_resource(request, str(values["node"]), str(values["vmid"])) + rows = await _database(request).pool.fetch( + """SELECT name, parent_name, description, created_at FROM snapshots + WHERE resource_id=$1 ORDER BY created_at, name""", + resource["id"], + ) + return [ + { + "name": row["name"], + "parent": row["parent_name"], + "description": row["description"] or "", + "snaptime": int(row["created_at"].timestamp()), + } + for row in rows + ] + + async def snapshot_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + values = _values(inputs) + row = await _snapshot(request, values) + state = _state(row["state"]) + return { + "name": row["name"], + "parent": row["parent_name"], + "description": row["description"] or "", + "snaptime": int(row["created_at"].timestamp()), + **state, + } + + async def snapshot_config(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + row = await _snapshot(request, _values(inputs)) + return {"description": row["description"] or "", **_state(row["state"])} + + async def snapshot_update(request: Request, inputs: dict[str, Any]) -> None: + values = _values(inputs) + row = await _snapshot(request, values) + await _database(request).pool.execute( + "UPDATE snapshots SET description=$2 WHERE id=$1", + row["id"], + str(values.get("description", "")), + ) + + async def snapshot_task(operation: str, request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + node, vmid, snapname = ( + str(values["node"]), + str(values["vmid"]), + str(values["snapname"]), + ) + resource = await _lxc_resource(request, node, vmid) + if operation == "snapshot-create": + exists = await _database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM snapshots WHERE resource_id=$1 AND name=$2)", + resource["id"], + snapname, + ) + if exists: + raise ApiError(409, "snapshot already exists") + else: + await _snapshot(request, values) + return await _create_task( + request, + node=node, + vmid=vmid, + task_type=f"lxc-{operation}", + payload={ + "node": node, + "vmid": vmid, + "resource_id": str(resource["id"]), + "snapname": snapname, + "description": str(values.get("description", "")), + }, + ) + + async def snapshot_create(request: Request, inputs: dict[str, Any]) -> str: + return await snapshot_task("snapshot-create", request, inputs) + + async def snapshot_delete(request: Request, inputs: dict[str, Any]) -> str: + return await snapshot_task("snapshot-delete", request, inputs) + + async def snapshot_rollback(request: Request, inputs: dict[str, Any]) -> str: + return await snapshot_task("snapshot-rollback", request, inputs) + + async def clone(request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + node, vmid, newid = str(values["node"]), str(values["vmid"]), str(values["newid"]) + source = await _lxc_resource(request, node, vmid) + if await _database(request).pool.fetchval( + """SELECT EXISTS(SELECT 1 FROM resources + WHERE external_id=$1 AND kind IN ('qemu','lxc'))""", + newid, + ): + raise ApiError(409, "VMID already exists") + target = str(values.get("target") or node) + if not await _database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM nodes WHERE name=$1)", target + ): + raise ApiError(404, "target node does not exist") + return await _create_task( + request, + node=target, + vmid=newid, + task_type="lxc-clone", + payload={ + "source_resource_id": str(source["id"]), + "source_vmid": vmid, + "node": target, + "vmid": int(newid), + "name": values.get("hostname") or values.get("name"), + "full": bool(values.get("full", False)), + }, + ) + + async def migrate_preconditions(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + values = _values(inputs) + await _lxc_resource(request, str(values["node"]), str(values["vmid"])) + target = values.get("target") + if target in {None, ""}: + raise ApiError(400, "parameter 'target' is required") + target = str(target) + exists = await _database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM nodes WHERE name=$1)", target + ) + if not exists: + raise ApiError(404, "target node does not exist") + return {"local_disks": [], "local_resources": [], "running": False} + + async def migrate(request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + node, vmid = str(values["node"]), str(values["vmid"]) + target = values.get("target") + if target in {None, ""}: + raise ApiError(400, "parameter 'target' is required") + target = str(target) + resource = await _lxc_resource(request, node, vmid) + if target == node: + raise ApiError(400, "target node is the same as source node") + await migrate_preconditions(request, inputs) + return await _create_task( + request, + node=node, + vmid=vmid, + task_type="lxc-migrate", + payload={ + "resource_id": str(resource["id"]), + "node": node, + "target": target, + "vmid": vmid, + "online": bool(values.get("online", False)), + }, + ) + + async def remote_migrate(request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + target_endpoint = str(values.get("target-endpoint") or values.get("target_endpoint") or "") + target = str(values.get("target") or "") + if not target_endpoint: + raise ApiError(400, "parameter target-endpoint is required") + if not target: + raise ApiError(400, "parameter target is required") + node, vmid = str(values["node"]), str(values["vmid"]) + resource = await _lxc_resource(request, node, vmid) + if target == node: + raise ApiError(400, "target node is the same as source node") + if not await _database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM nodes WHERE name=$1)", target + ): + raise ApiError(404, "target node does not exist") + return await _create_task( + request, + node=node, + vmid=vmid, + task_type="lxc-remote-migrate", + payload={ + "resource_id": str(resource["id"]), + "node": node, + "target": target, + "vmid": vmid, + "target-endpoint": target_endpoint, + "online": bool(values.get("online", False)), + }, + ) + + async def pending(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + values = _values(inputs) + resource = await _lxc_resource(request, str(values["node"]), str(values["vmid"])) + state = _state(resource["state"]) + config = _state(resource["config"]) + changes = cast(Mapping[str, Any], state.get("pending", {})) + return [ + {"key": key, "value": str(config.get(key, "")), "pending": str(value)} + for key, value in sorted(changes.items()) + ] + + async def lxc_feature(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = _values(inputs) + await _lxc_resource(request, str(payload["node"]), str(payload["vmid"])) + return { + "hasFeature": { + "snapshot": 1, + "clone": 1, + "copy": 1, + "template": 1, + "move_volume": 1, + } + } + + async def lxc_resize(request: Request, inputs: dict[str, Any]) -> None: + payload = _values(inputs) + node, vmid = str(payload["node"]), str(payload["vmid"]) + disk = str(payload.get("disk") or "rootfs") + resource = await _lxc_resource(request, node, vmid) + config = _state(resource["config"]) + if disk not in config: + raise ApiError(400, f"disk {disk} does not exist") + try: + current = disk_size_bytes(str(config[disk])) + size = resize_size_bytes(str(payload["size"]), current) + except ValueError as error: + raise ApiError(400, str(error)) from error + config[disk] = replace_disk_size(str(config[disk]), size) + await _database(request).pool.execute( + "UPDATE containers SET config=$2::jsonb WHERE resource_id=$1", + resource["id"], + json.dumps(config, sort_keys=True), + ) + await _database(request).pool.execute( + """UPDATE resources SET state=state || $2::jsonb, version=version+1, + updated_at=now() WHERE id=$1""", + resource["id"], + json.dumps({disk: config[disk]}, sort_keys=True), + ) + + async def lxc_template(request: Request, inputs: dict[str, Any]) -> None: + payload = _values(inputs) + node, vmid = str(payload["node"]), str(payload["vmid"]) + resource = await _lxc_resource(request, node, vmid) + state = _state(resource["state"]) + if state.get("status") != "stopped": + raise ApiError(409, "container must be stopped to convert to template") + await _database(request).pool.execute( + "UPDATE containers SET template=true WHERE resource_id=$1", + resource["id"], + ) + state["template"] = True + await _database(request).pool.execute( + "UPDATE resources SET state=$2::jsonb WHERE id=$1", + resource["id"], + json.dumps(state, sort_keys=True), + ) + + async def lxc_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + payload = _values(inputs) + node, vmid = str(payload["node"]), str(payload["vmid"]) + await require_node(request, node) + await _lxc_resource(request, node, vmid) + return subdirs( + "clone", + "config", + "feature", + "firewall", + "migrate", + "pending", + "resize", + "snapshot", + "status", + "template", + ) + + registry.register("/nodes/{node}/lxc", "GET", lxc_list) + registry.register("/nodes/{node}/lxc", "POST", create) + registry.register("/nodes/{node}/lxc/{vmid}", "GET", lxc_index) + registry.register("/nodes/{node}/lxc/{vmid}", "DELETE", delete) + registry.register("/nodes/{node}/lxc/{vmid}/config", "GET", lxc_config) + registry.register("/nodes/{node}/lxc/{vmid}/config", "PUT", update) + registry.register("/nodes/{node}/lxc/{vmid}/status", "GET", lxc_status) + registry.register("/nodes/{node}/lxc/{vmid}/status/current", "GET", lxc_current) + registry.register("/nodes/{node}/lxc/{vmid}/status/start", "POST", start) + registry.register("/nodes/{node}/lxc/{vmid}/status/stop", "POST", stop) + registry.register("/nodes/{node}/lxc/{vmid}/status/shutdown", "POST", shutdown) + registry.register("/nodes/{node}/lxc/{vmid}/status/reboot", "POST", reboot) + registry.register("/nodes/{node}/lxc/{vmid}/status/suspend", "POST", suspend) + registry.register("/nodes/{node}/lxc/{vmid}/status/resume", "POST", resume) + registry.register("/nodes/{node}/lxc/{vmid}/snapshot", "GET", snapshot_list) + registry.register("/nodes/{node}/lxc/{vmid}/snapshot", "POST", snapshot_create) + registry.register("/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", "GET", snapshot_get) + registry.register("/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", "DELETE", snapshot_delete) + registry.register("/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", "GET", snapshot_config) + registry.register("/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", "PUT", snapshot_update) + registry.register( + "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback", "POST", snapshot_rollback + ) + registry.register("/nodes/{node}/lxc/{vmid}/clone", "POST", clone) + registry.register("/nodes/{node}/lxc/{vmid}/migrate", "GET", migrate_preconditions) + registry.register("/nodes/{node}/lxc/{vmid}/migrate", "POST", migrate) + registry.register("/nodes/{node}/lxc/{vmid}/remote_migrate", "POST", remote_migrate) + registry.register("/nodes/{node}/lxc/{vmid}/pending", "GET", pending) + registry.register("/nodes/{node}/lxc/{vmid}/feature", "GET", lxc_feature) + registry.register("/nodes/{node}/lxc/{vmid}/resize", "PUT", lxc_resize) + registry.register("/nodes/{node}/lxc/{vmid}/template", "POST", lxc_template) + from app.handlers.lxc_extra import register_lxc_extra_handlers + + register_lxc_extra_handlers(registry) + + +async def _create_task( + request: Request, + *, + node: str, + vmid: str, + task_type: str, + payload: dict[str, Any], +) -> str: + database = _database(request) + worker_type = { + "lxc-create": "pctcreate", + "lxc-delete": "pctdestroy", + "lxc-snapshot-create": "pctsnapshot", + "lxc-snapshot-delete": "pctdelsnapshot", + "lxc-snapshot-rollback": "pctrollback", + "lxc-clone": "pctclone", + "lxc-migrate": "pctmigrate", + "lxc-remote-migrate": "pctremote", + }[task_type] + upid = str(Upid.allocate(node, worker_type, vmid, str(request.state.principal))) + try: + task = await TaskRepository(database.pool).create( + upid=upid, + task_type=task_type, + payload=payload, + resource_key=f"lxc:{vmid}", + idempotency_key=request.headers.get("Idempotency-Key"), + ) + except ConflictError as error: + raise ApiError(409, str(error)) from error + return task.upid + + +async def _lxc_resource(request: Request, node: str, vmid: str) -> Any: + row = await _database(request).pool.fetchrow( + """SELECT r.id, r.state, c.config FROM resources r + JOIN nodes n ON n.id=r.node_id + JOIN containers c ON c.resource_id=r.id + WHERE n.name=$1 AND r.kind='lxc' AND r.external_id=$2""", + node, + vmid, + ) + if row is None: + raise ApiError(404, "container does not exist") + return row + + +async def _snapshot(request: Request, values: dict[str, Any]) -> Any: + row = await _database(request).pool.fetchrow( + """SELECT s.* FROM snapshots s + JOIN resources r ON r.id=s.resource_id JOIN nodes n ON n.id=r.node_id + WHERE n.name=$1 AND r.kind='lxc' AND r.external_id=$2 AND s.name=$3""", + str(values["node"]), + str(values["vmid"]), + str(values["snapname"]), + ) + if row is None: + raise ApiError(404, "snapshot does not exist") + return row diff --git a/app/handlers/lxc_extra.py b/app/handlers/lxc_extra.py new file mode 100644 index 0000000..d900451 --- /dev/null +++ b/app/handlers/lxc_extra.py @@ -0,0 +1,152 @@ +"""Remaining LXC console / RRD / volume helpers with durable state.""" + +from __future__ import annotations + +import json +import secrets +from typing import Any, cast + +from fastapi import Request + +from app.api.registry import HandlerRegistry +from app.config import Settings +from app.handlers.lxc import _database, _lxc_resource, _state, _values +from app.security.auth import issue_ticket + + +def _settings(request: Request) -> Settings: + return cast(Settings, request.app.state.settings) + + +async def _save_state(request: Request, resource_id: Any, state: dict[str, Any]) -> None: + await _database(request).pool.execute( + "UPDATE resources SET state=$2::jsonb, version=version+1, updated_at=now() WHERE id=$1", + resource_id, + json.dumps(state, sort_keys=True), + ) + + +async def _save_config(request: Request, resource_id: Any, config: dict[str, Any]) -> None: + await _database(request).pool.execute( + "UPDATE containers SET config=$2::jsonb WHERE resource_id=$1", + resource_id, + json.dumps(config, sort_keys=True), + ) + + +def register_lxc_extra_handlers(registry: HandlerRegistry) -> None: + async def interfaces(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + values = _values(inputs) + resource = await _lxc_resource(request, str(values["node"]), str(values["vmid"])) + state = _state(resource["state"]) + ifaces = state.setdefault( + "interfaces", + [{"name": "eth0", "hwaddr": "02:00:00:00:00:11", "inet": "192.0.2.20/24"}], + ) + await _save_state(request, resource["id"], state) + return list(ifaces) if isinstance(ifaces, list) else [] + + async def move_volume(request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + resource = await _lxc_resource(request, str(values["node"]), str(values["vmid"])) + volume = str(values.get("volume") or values.get("disk") or "rootfs") + storage = str(values.get("storage") or "local-lvm") + config = _state(resource["config"]) + current = str(config.get(volume) or "") + if current: + # rewrite storage prefix when present + rest = current.split(":", 1)[1] if ":" in current else current + config[volume] = f"{storage}:{rest}" + await _save_config(request, resource["id"], config) + state = _state(resource["state"]) + moves = state.setdefault("volume_moves", []) + if not isinstance(moves, list): + moves = state["volume_moves"] = [] + moves.append({"volume": volume, "storage": storage}) + await _save_state(request, resource["id"], state) + return f"UPID:{values['node']}:lxc-move-volume:{values['vmid']}" + + async def rrd(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + values = _values(inputs) + resource = await _lxc_resource(request, str(values["node"]), str(values["vmid"])) + state = _state(resource["state"]) + rrd_state = state.setdefault("rrd", {"filename": f"pve-ct-{values['vmid']}.rrd"}) + await _save_state(request, resource["id"], state) + return dict(rrd_state) + + async def rrddata(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + values = _values(inputs) + resource = await _lxc_resource(request, str(values["node"]), str(values["vmid"])) + state = _state(resource["state"]) + series = state.setdefault( + "rrddata", + [ + {"time": 1_700_000_000, "cpu": 0.02, "mem": 64 * 1024 * 1024}, + {"time": 1_700_000_060, "cpu": 0.03, "mem": 66 * 1024 * 1024}, + ], + ) + await _save_state(request, resource["id"], state) + return list(series) + + async def _console(request: Request, inputs: dict[str, Any], kind: str) -> dict[str, Any]: + values = _values(inputs) + resource = await _lxc_resource(request, str(values["node"]), str(values["vmid"])) + key = _settings(request).ticket_signing_key.get_secret_value().encode() + ticket = issue_ticket(str(request.state.principal), key) + port = 6900 + int(values["vmid"]) % 1000 + state = _state(resource["state"]) + consoles = state.setdefault("consoles", {}) + payload = { + "type": kind, + "port": port, + "ticket": ticket, + "upid": ( + f"UPID:{values['node']}:{secrets.token_hex(4)}:" + f"{kind}:{values['vmid']}:{request.state.principal}:" + ), + "user": str(request.state.principal), + } + consoles[kind] = {k: v for k, v in payload.items() if k != "ticket"} + await _save_state(request, resource["id"], state) + return payload + + async def vncproxy(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _console(request, inputs, "vnc") + + async def spiceproxy(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _console(request, inputs, "spice") + + async def termproxy(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _console(request, inputs, "term") + + async def mtunnel(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _console(request, inputs, "mtunnel") + + async def _ws(request: Request, inputs: dict[str, Any], kind: str) -> dict[str, Any]: + values = _values(inputs) + resource = await _lxc_resource(request, str(values["node"]), str(values["vmid"])) + state = _state(resource["state"]) + console = state.get("consoles", {}).get(kind) or {"port": 6900} + key = _settings(request).ticket_signing_key.get_secret_value().encode() + return { + "port": console.get("port", 6900), + "ticket": issue_ticket(str(request.state.principal), key), + } + + async def vncwebsocket(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _ws(request, inputs, "vnc") + + async def mtunnelwebsocket(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _ws(request, inputs, "mtunnel") + + base = "/nodes/{node}/lxc/{vmid}" + registry.register(f"{base}/interfaces", "GET", interfaces) + registry.register(f"{base}/move_volume", "POST", move_volume) + registry.register(f"{base}/rrd", "GET", rrd) + registry.register(f"{base}/rrddata", "GET", rrddata) + registry.register(f"{base}/vncproxy", "POST", vncproxy) + registry.register(f"{base}/spiceproxy", "POST", spiceproxy) + registry.register(f"{base}/termproxy", "POST", termproxy) + registry.register(f"{base}/mtunnel", "POST", mtunnel) + registry.register(f"{base}/vncwebsocket", "GET", vncwebsocket) + registry.register(f"{base}/mtunnelwebsocket", "GET", mtunnelwebsocket) diff --git a/app/handlers/mapping.py b/app/handlers/mapping.py new file mode 100644 index 0000000..8c39168 --- /dev/null +++ b/app/handlers/mapping.py @@ -0,0 +1,99 @@ +"""Cluster resource mapping handlers (dir/pci/usb).""" + +from __future__ import annotations + +from typing import Any + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.common import cluster_metadata, save_cluster_metadata, subdirs, values + + +def _mappings(metadata: dict[str, Any]) -> dict[str, Any]: + current = metadata.setdefault("mapping", {"dir": {}, "pci": {}, "usb": {}}) + if not isinstance(current, dict): + current = {"dir": {}, "pci": {}, "usb": {}} + metadata["mapping"] = current + for kind in ("dir", "pci", "usb"): + current.setdefault(kind, {}) + return current + + +def register_mapping_handlers(registry: HandlerRegistry) -> None: + async def index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs("dir", "pci", "usb") + + def register_kind(kind: str) -> None: + base = f"/cluster/mapping/{kind}" + + async def list_items(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + metadata = await cluster_metadata(request) + store = _mappings(metadata)[kind] + check_node = values(inputs).get("check-node") + result = [{"id": key, **item} for key, item in sorted(store.items())] + if check_node: + for item in result: + item["checks"] = {str(check_node): "OK"} + return result + + async def create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + item_id = str(payload["id"]) + metadata = await cluster_metadata(request) + store = _mappings(metadata)[kind] + if item_id in store: + raise ApiError(400, f"{kind} mapping '{item_id}' already exists") + store[item_id] = { + key: value for key, value in payload.items() if key not in {"delete", "digest"} + } + await save_cluster_metadata(request, metadata) + + async def get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + item_id = str(values(inputs)["id"]) + metadata = await cluster_metadata(request) + store = _mappings(metadata)[kind] + if item_id not in store: + raise ApiError(404, f"{kind} mapping does not exist") + return {"id": item_id, **store[item_id]} + + async def update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + item_id = str(payload["id"]) + metadata = await cluster_metadata(request) + store = _mappings(metadata)[kind] + if item_id not in store: + raise ApiError(404, f"{kind} mapping does not exist") + current = dict(store[item_id]) + for key in [ + item.strip() for item in str(payload.get("delete") or "").split(",") if item.strip() + ]: + current.pop(key, None) + for key, value in payload.items(): + if key in {"id", "delete", "digest"}: + continue + current[key] = value + current["id"] = item_id + store[item_id] = current + await save_cluster_metadata(request, metadata) + + async def delete(request: Request, inputs: dict[str, Any]) -> None: + item_id = str(values(inputs)["id"]) + metadata = await cluster_metadata(request) + store = _mappings(metadata)[kind] + if item_id not in store: + raise ApiError(404, f"{kind} mapping does not exist") + del store[item_id] + await save_cluster_metadata(request, metadata) + + registry.register(base, "GET", list_items) + registry.register(base, "POST", create) + registry.register(f"{base}/{{id}}", "GET", get) + registry.register(f"{base}/{{id}}", "PUT", update) + registry.register(f"{base}/{{id}}", "DELETE", delete) + + registry.register("/cluster/mapping", "GET", index) + register_kind("dir") + register_kind("pci") + register_kind("usb") diff --git a/app/handlers/nodes.py b/app/handlers/nodes.py new file mode 100644 index 0000000..7306637 --- /dev/null +++ b/app/handlers/nodes.py @@ -0,0 +1,421 @@ +"""Node-level operational handlers (apt, network, disks, services).""" + +from __future__ import annotations + +import copy +from typing import Any, cast + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.common import ( + database, + node_metadata, + require_node, + save_node_metadata, + subdirs, + values, +) +from app.tasks.repository import TaskRepository +from app.tasks.upid import Upid + +DEFAULT_NODE_OPS: dict[str, Any] = { + "network": [ + { + "iface": "vmbr0", + "type": "bridge", + "active": 1, + "method": "static", + "address": "10.0.0.10/24", + }, + { + "iface": "vmbr1", + "type": "bridge", + "active": 1, + "method": "static", + "address": "10.10.0.10/24", + }, + {"iface": "eno1", "type": "eth", "active": 1, "method": "manual"}, + ], + "disks": { + "list": [ + { + "devpath": "/dev/sda", + "size": 1_000_000_000_000, + "model": "SIM-DISK-01", + "serial": "SIM0001", + "gpt": 1, + }, + { + "devpath": "/dev/sdb", + "size": 2_000_000_000_000, + "model": "SIM-SSD-01", + "serial": "SIM0002", + "gpt": 0, + }, + ], + "directory": [], + "lvm": [], + "lvmthin": [], + "zfs": [], + "smart": {}, + }, + "services": { + "pveproxy": {"state": "running", "enabled": 1}, + "pvedaemon": {"state": "running", "enabled": 1}, + "pvestatd": {"state": "running", "enabled": 1}, + "corosync": {"state": "running", "enabled": 1}, + }, + "apt": { + "packages": [ + { + "Package": "pve-manager", + "Version": "9.2.3", + "OldVersion": "9.2.2", + "Status": "upgradable", + }, + {"Package": "libpve-common-perl", "Version": "9.0.3", "Status": "installed"}, + ], + "repositories": [ + { + "path": "/etc/apt/sources.list.d/pve-enterprise.list", + "enabled": 1, + "types": "deb", + "uri": "http://download.proxmox.com/debian/pve", + "suites": "bookworm", + "components": "pve-no-subscription", + } + ], + "update": {"status": "stopped", "exitstatus": "OK"}, + "changelogs": {}, + }, +} + + +def default_node_ops() -> dict[str, Any]: + return copy.deepcopy(DEFAULT_NODE_OPS) + + +async def load_node_ops(request: Request, node: str) -> dict[str, Any]: + metadata = await node_metadata(request, node) + ops = metadata.get("ops") + if isinstance(ops, dict) and ops: + return ops + ops = default_node_ops() + metadata["ops"] = ops + await save_node_metadata(request, node, metadata) + return ops + + +async def save_node_ops(request: Request, node: str, ops: dict[str, Any]) -> None: + metadata = await node_metadata(request, node) + metadata["ops"] = ops + await save_node_metadata(request, node, metadata) + + +def register_node_ops_handlers(registry: HandlerRegistry) -> None: + async def apt_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + await require_node(request, str(values(inputs)["node"])) + return subdirs("changelog", "repositories", "update", "versions") + + async def apt_versions(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + ops = await load_node_ops(request, node) + packages = ops.get("apt", {}).get("packages", []) + return list(packages) if isinstance(packages, list) else [] + + async def apt_repositories(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + ops = await load_node_ops(request, node) + repositories = ops.get("apt", {}).get("repositories", []) + return list(repositories) if isinstance(repositories, list) else [] + + async def apt_changelog(request: Request, inputs: dict[str, Any]) -> str: + node = str(values(inputs)["node"]) + name = str(values(inputs).get("name") or "pve-manager") + ops = await load_node_ops(request, node) + changelogs = ops.setdefault("apt", {}).setdefault("changelogs", {}) + if name not in changelogs: + changelogs[name] = f"simulated changelog for {name}\n\n * emulator build\n" + await save_node_ops(request, node, ops) + return str(changelogs[name]) + + async def apt_update_status(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(values(inputs)["node"]) + ops = await load_node_ops(request, node) + update = ops.get("apt", {}).get("update", {"status": "stopped", "exitstatus": "OK"}) + if isinstance(update, dict): + return dict(update) + return {"status": "stopped", "exitstatus": "OK"} + + async def apt_update_start(request: Request, inputs: dict[str, Any]) -> str: + node = str(values(inputs)["node"]) + ops = await load_node_ops(request, node) + apt = ops.setdefault("apt", {}) + apt["update"] = {"status": "running", "exitstatus": ""} + await save_node_ops(request, node, ops) + return await _node_task(request, node=node, task_type="aptupdate", worker="aptupdate") + + async def network_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + ops = await load_node_ops(request, node) + network = ops.get("network", []) + return [dict(item) for item in network] if isinstance(network, list) else [] + + async def network_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + iface = str(values(inputs)["iface"]) + for item in await network_list(request, inputs): + if item.get("iface") == iface: + return item + raise ApiError(404, "interface does not exist") + + async def network_mutate(request: Request, inputs: dict[str, Any]) -> None: + node = str(values(inputs)["node"]) + payload = values(inputs) + ops = await load_node_ops(request, node) + network = list(ops.get("network") or []) + iface = payload.get("iface") + method = request.method.upper() + if method == "DELETE": + target = str(iface or "") + if not any(item.get("iface") == target for item in network): + raise ApiError(404, "interface does not exist") + ops["network"] = [item for item in network if item.get("iface") != target] + elif method == "POST": + name = str(iface or payload.get("iface") or "") + if not name: + raise ApiError(400, "parameter verification failed - 'iface' missing") + if any(item.get("iface") == name for item in network): + raise ApiError(400, f"interface '{name}' already exists") + entry = { + key: value + for key, value in payload.items() + if key not in {"node", "delete", "digest"} + } + entry["iface"] = name + entry.setdefault("type", "bridge") + entry.setdefault("active", 1) + network.append(entry) + ops["network"] = network + elif method == "PUT" and iface is not None: + name = str(iface) + found = False + updated: list[dict[str, Any]] = [] + for item in network: + if item.get("iface") != name: + updated.append(item) + continue + found = True + merged = { + **item, + **{ + key: value + for key, value in payload.items() + if key not in {"node", "iface", "delete", "digest"} + }, + } + merged["iface"] = name + updated.append(merged) + if not found: + raise ApiError(404, "interface does not exist") + ops["network"] = updated + else: + ops["network_applied"] = True + await save_node_ops(request, node, ops) + + async def disks_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + await require_node(request, str(values(inputs)["node"])) + return subdirs("directory", "list", "lvm", "lvmthin", "smart", "zfs") + + async def _disks(request: Request, node: str) -> dict[str, Any]: + ops = await load_node_ops(request, node) + disks = ops.setdefault("disks", default_node_ops()["disks"]) + if not isinstance(disks, dict): + disks = default_node_ops()["disks"] + ops["disks"] = disks + await save_node_ops(request, node, ops) + return cast(dict[str, Any], disks) + + async def disks_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + disks = await _disks(request, node) + items = disks.get("list", []) + return [dict(item) for item in items] if isinstance(items, list) else [] + + async def disks_smart(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(values(inputs)["node"]) + disk = str(values(inputs).get("disk") or "/dev/sda") + disks = await _disks(request, node) + smart = disks.setdefault("smart", {}) + if disk not in smart: + smart[disk] = { + "health": "PASSED", + "type": "scsi", + "model": "SIM-DISK", + "serial": disk.rsplit("/", 1)[-1], + } + ops = await load_node_ops(request, node) + ops["disks"] = disks + await save_node_ops(request, node, ops) + return dict(smart[disk]) + + async def disks_collection( + request: Request, inputs: dict[str, Any], key: str + ) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + disks = await _disks(request, node) + items = disks.get(key, []) + return [dict(item) for item in items] if isinstance(items, list) else [] + + async def disks_directory(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + return await disks_collection(request, inputs, "directory") + + async def disks_lvm(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + return await disks_collection(request, inputs, "lvm") + + async def disks_lvmthin(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + return await disks_collection(request, inputs, "lvmthin") + + async def disks_zfs(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + return await disks_collection(request, inputs, "zfs") + + async def disks_initgpt(request: Request, inputs: dict[str, Any]) -> None: + node = str(values(inputs)["node"]) + disk = str(values(inputs).get("disk") or values(inputs).get("device") or "") + if not disk: + raise ApiError(400, "parameter verification failed - 'disk' missing") + ops = await load_node_ops(request, node) + disks = ops.setdefault("disks", default_node_ops()["disks"]) + items = list(disks.get("list") or []) + found = False + for item in items: + if item.get("devpath") == disk: + item["gpt"] = 1 + found = True + break + if not found: + items.append( + { + "devpath": disk, + "size": 0, + "model": "SIM-DISK", + "serial": disk, + "gpt": 1, + } + ) + disks["list"] = items + ops["disks"] = disks + await save_node_ops(request, node, ops) + + async def disks_wipedisk(request: Request, inputs: dict[str, Any]) -> None: + node = str(values(inputs)["node"]) + disk = str(values(inputs).get("disk") or values(inputs).get("device") or "") + if not disk: + raise ApiError(400, "parameter verification failed - 'disk' missing") + ops = await load_node_ops(request, node) + disks = ops.setdefault("disks", default_node_ops()["disks"]) + items = list(disks.get("list") or []) + for item in items: + if item.get("devpath") == disk: + item["wiped"] = 1 + item["gpt"] = 0 + break + else: + raise ApiError(404, "disk does not exist") + disks["list"] = items + smart = disks.setdefault("smart", {}) + smart.pop(disk, None) + ops["disks"] = disks + await save_node_ops(request, node, ops) + + async def services_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + node = str(values(inputs)["node"]) + ops = await load_node_ops(request, node) + services = ops.get("services") or {} + return [{"subdir": name} for name in sorted(services)] + + async def service_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(values(inputs)["node"]) + service = str(values(inputs)["service"]) + ops = await load_node_ops(request, node) + services = ops.setdefault("services", {}) + if service not in services: + services[service] = {"state": "stopped", "enabled": 0} + await save_node_ops(request, node, ops) + payload = dict(services[service]) + payload["service"] = service + return payload + + async def service_state(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await service_get(request, inputs) + + async def service_action(request: Request, inputs: dict[str, Any]) -> str: + node = str(values(inputs)["node"]) + service = str(values(inputs)["service"]) + path = request.url.path.rstrip("/") + action = path.rsplit("/", 1)[-1] + ops = await load_node_ops(request, node) + services = ops.setdefault("services", {}) + current = dict(services.get(service) or {"state": "stopped", "enabled": 0}) + if action == "start": + current["state"] = "running" + current["enabled"] = 1 + elif action == "stop": + current["state"] = "stopped" + elif action in {"restart", "reload"}: + current["state"] = "running" + current["enabled"] = 1 + else: + raise ApiError(400, f"unknown service action: {action}") + services[service] = current + ops["services"] = services + await save_node_ops(request, node, ops) + return "OK" + + registry.register("/nodes/{node}/apt", "GET", apt_index) + registry.register("/nodes/{node}/apt/versions", "GET", apt_versions) + registry.register("/nodes/{node}/apt/repositories", "GET", apt_repositories) + registry.register("/nodes/{node}/apt/changelog", "GET", apt_changelog) + registry.register("/nodes/{node}/apt/update", "GET", apt_update_status) + registry.register("/nodes/{node}/apt/update", "POST", apt_update_start) + registry.register("/nodes/{node}/network", "GET", network_list) + registry.register("/nodes/{node}/network", "POST", network_mutate) + registry.register("/nodes/{node}/network", "PUT", network_mutate) + registry.register("/nodes/{node}/network/{iface}", "GET", network_get) + registry.register("/nodes/{node}/network/{iface}", "PUT", network_mutate) + registry.register("/nodes/{node}/network/{iface}", "DELETE", network_mutate) + registry.register("/nodes/{node}/disks", "GET", disks_index) + registry.register("/nodes/{node}/disks/list", "GET", disks_list) + registry.register("/nodes/{node}/disks/smart", "GET", disks_smart) + registry.register("/nodes/{node}/disks/directory", "GET", disks_directory) + registry.register("/nodes/{node}/disks/lvm", "GET", disks_lvm) + registry.register("/nodes/{node}/disks/lvmthin", "GET", disks_lvmthin) + registry.register("/nodes/{node}/disks/zfs", "GET", disks_zfs) + registry.register("/nodes/{node}/disks/initgpt", "POST", disks_initgpt) + registry.register("/nodes/{node}/disks/wipedisk", "PUT", disks_wipedisk) + registry.register("/nodes/{node}/services", "GET", services_index) + registry.register("/nodes/{node}/services/{service}", "GET", service_get) + registry.register("/nodes/{node}/services/{service}/state", "GET", service_state) + registry.register("/nodes/{node}/services/{service}/start", "POST", service_action) + registry.register("/nodes/{node}/services/{service}/stop", "POST", service_action) + registry.register("/nodes/{node}/services/{service}/restart", "POST", service_action) + registry.register("/nodes/{node}/services/{service}/reload", "POST", service_action) + + +async def _node_task(request: Request, *, node: str, task_type: str, worker: str) -> str: + from app.api.errors import ApiError + from app.db.primitives import ConflictError + + pool = database(request).pool + upid = str(Upid.allocate(node, worker, "0", str(request.state.principal))) + try: + task = await TaskRepository(pool).create( + upid=upid, + task_type=task_type, + payload={"node": node}, + resource_key=f"node:{node}", + ) + except ConflictError as error: + raise ApiError(409, str(error)) from error + return task.upid diff --git a/app/handlers/nodes_extra.py b/app/handlers/nodes_extra.py new file mode 100644 index 0000000..06462fa --- /dev/null +++ b/app/handlers/nodes_extra.py @@ -0,0 +1,972 @@ +"""Additional node-level handlers with durable ops persistence.""" + +from __future__ import annotations + +import copy +import json +import secrets +import time +from typing import Any + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.common import database, require_node, subdirs, values +from app.handlers.nodes import default_node_ops, load_node_ops, save_node_ops +from app.tasks.repository import TaskRepository +from app.tasks.upid import Upid + +DEFAULT_HARDWARE: dict[str, Any] = { + "pci": [ + { + "id": "0000:00:1f.2", + "vendor_name": "Intel Corporation", + "device_name": "SATA Controller", + "iommugroup": 0, + }, + { + "id": "0000:01:00.0", + "vendor_name": "NVIDIA Corporation", + "device_name": "GP102 [GeForce GTX 1080 Ti]", + "iommugroup": 1, + "mdev": 1, + }, + ], + "usb": [ + {"busnum": 1, "devnum": 1, "level": 0, "port": "1", "prodid": "0002", "vendid": "1d6b"}, + {"busnum": 2, "devnum": 2, "level": 1, "port": "2", "prodid": "5591", "vendid": "0781"}, + ], + "mdev": { + "0000:01:00.0": [ + {"type": "nvidia-11", "available": 4, "description": "GRID profile"}, + ] + }, +} + +DEFAULT_SCAN: dict[str, list[dict[str, Any]]] = { + "cifs": [{"server": "files.local", "share": "backups"}], + "iscsi": [{"portal": "10.0.0.50:3260", "target": "iqn.2024-01.local:storage"}], + "lvm": [{"vg": "pve", "size": 500_000_000_000, "free": 100_000_000_000}], + "lvmthin": [{"lv": "data", "vg": "pve", "lv_size": 400_000_000_000}], + "nfs": [{"server": "nfs.local", "path": "/export/pve", "options": "vers=4"}], + "pbs": [{"server": "pbs.local", "datastore": "store1"}], + "zfs": [{"pool": "rpool", "name": "rpool/data", "size": 800_000_000_000}], +} + +DEFAULT_SUBSCRIPTION: dict[str, Any] = { + "status": "notfound", + "message": "There is no subscription key", + "serverid": "SIMULATOR", + "sockets": 1, + "productname": "Proxmox VE", + "url": "https://www.proxmox.com/en/proxmox-virtual-environment/pricing", +} + +DEFAULT_CONFIG: dict[str, Any] = { + "description": "Simulator node", + "startall-onboot-delay": 0, + "wakeonlan": "", +} + +DEFAULT_DNS: dict[str, Any] = { + "search": "local", + "dns1": "1.1.1.1", + "dns2": "8.8.8.8", + "dns3": "", +} + +DEFAULT_TIME: dict[str, Any] = { + "timezone": "UTC", + "time": 0, + "localtime": 0, +} + + +def _certificates(ops: dict[str, Any]) -> dict[str, Any]: + certs = ops.setdefault( + "certificates", + { + "custom": None, + "acme": {"account": "default", "domains": [], "certificate": None}, + "info": [], + }, + ) + if not isinstance(certs, dict): + certs = {"custom": None, "acme": {}, "info": []} + ops["certificates"] = certs + certs.setdefault("acme", {"account": "default", "domains": [], "certificate": None}) + certs.setdefault("info", []) + return certs + + +def _hardware(ops: dict[str, Any]) -> dict[str, Any]: + hardware = ops.get("hardware") + if not isinstance(hardware, dict) or not hardware: + hardware = copy.deepcopy(DEFAULT_HARDWARE) + ops["hardware"] = hardware + hardware.setdefault("pci", copy.deepcopy(DEFAULT_HARDWARE["pci"])) + hardware.setdefault("usb", copy.deepcopy(DEFAULT_HARDWARE["usb"])) + hardware.setdefault("mdev", copy.deepcopy(DEFAULT_HARDWARE["mdev"])) + return hardware + + +def _scan_cache(ops: dict[str, Any]) -> dict[str, Any]: + scan = ops.get("scan") + if not isinstance(scan, dict) or not scan: + scan = copy.deepcopy(DEFAULT_SCAN) + ops["scan"] = scan + for key, value in DEFAULT_SCAN.items(): + scan.setdefault(key, copy.deepcopy(value)) + return scan + + +def _subscription(ops: dict[str, Any]) -> dict[str, Any]: + subscription = ops.get("subscription") + if not isinstance(subscription, dict) or not subscription: + subscription = copy.deepcopy(DEFAULT_SUBSCRIPTION) + ops["subscription"] = subscription + return subscription + + +def _disk_items(ops: dict[str, Any], kind: str) -> list[dict[str, Any]]: + disks = ops.setdefault("disks", default_node_ops()["disks"]) + if not isinstance(disks, dict): + disks = default_node_ops()["disks"] + ops["disks"] = disks + items = disks.setdefault(kind, []) + if not isinstance(items, list): + items = [] + disks[kind] = items + return items + + +def _public_cert(entry: dict[str, Any] | None) -> dict[str, Any] | None: + if entry is None: + return None + return {key: value for key, value in entry.items() if key not in {"key", "private-key"}} + + +async def _node_task(request: Request, *, node: str, task_type: str, worker: str) -> str: + from app.db.primitives import ConflictError + + pool = database(request).pool + upid = str(Upid.allocate(node, worker, "0", str(request.state.principal))) + try: + task = await TaskRepository(pool).create( + upid=upid, + task_type=task_type, + payload={"node": node}, + resource_key=f"node:{node}:{task_type}", + ) + except ConflictError as error: + raise ApiError(409, str(error)) from error + return task.upid + + +async def _set_guest_status(request: Request, node: str, status: str) -> None: + await database(request).pool.execute( + """UPDATE resources AS r + SET state = jsonb_set(COALESCE(r.state, '{}'::jsonb), '{status}', to_jsonb($2::text), true), + updated_at=now() + WHERE r.node_id=(SELECT id FROM nodes WHERE name=$1) AND r.kind IN ('qemu', 'lxc')""", + node, + status, + ) + + +async def _migrate_guests(request: Request, node: str, target: str) -> None: + target_row = await database(request).pool.fetchrow("SELECT id FROM nodes WHERE name=$1", target) + if target_row is None: + raise ApiError(404, "target node does not exist") + await database(request).pool.execute( + """UPDATE resources SET node_id=$2, updated_at=now() + WHERE node_id=(SELECT id FROM nodes WHERE name=$1) AND kind IN ('qemu', 'lxc')""", + node, + target_row["id"], + ) + + +def register_nodes_extra_handlers(registry: HandlerRegistry) -> None: + async def disks_create(request: Request, inputs: dict[str, Any], kind: str) -> dict[str, Any]: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + name = str( + payload.get("name") + or payload.get("device") + or payload.get("vgname") + or payload.get("pool") + or f"{kind}-{secrets.token_hex(2)}" + ) + ops = await load_node_ops(request, node) + items = _disk_items(ops, kind) + if any(str(item.get("name")) == name for item in items): + raise ApiError(400, f"{kind} '{name}' already exists") + entry = { + key: value for key, value in payload.items() if key not in {"node", "delete", "digest"} + } + entry["name"] = name + items.append(entry) + ops.setdefault("disks", default_node_ops()["disks"])[kind] = items + await save_node_ops(request, node, ops) + return entry + + async def disks_delete(request: Request, inputs: dict[str, Any], kind: str) -> None: + payload = values(inputs) + node = str(payload["node"]) + name = str(payload["name"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + items = _disk_items(ops, kind) + remaining = [item for item in items if str(item.get("name")) != name] + if len(remaining) == len(items): + raise ApiError(404, f"{kind} does not exist") + ops.setdefault("disks", {})[kind] = remaining + await save_node_ops(request, node, ops) + + async def disks_zfs_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + node = str(payload["node"]) + name = str(payload["name"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + for item in _disk_items(ops, "zfs"): + if str(item.get("name")) == name: + return dict(item) + raise ApiError(404, "zfs pool does not exist") + + async def certificates_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + await require_node(request, str(values(inputs)["node"])) + return subdirs("acme", "custom", "info") + + async def certificates_acme_index( + request: Request, inputs: dict[str, Any] + ) -> list[dict[str, str]]: + await require_node(request, str(values(inputs)["node"])) + return subdirs("certificate") + + async def certificates_acme_mutate(request: Request, inputs: dict[str, Any]) -> str | None: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + certs = _certificates(ops) + acme = dict(certs.get("acme") or {}) + method = request.method.upper() + if method == "DELETE": + acme["certificate"] = None + acme["domains"] = [] + else: + domains = payload.get("domains") or payload.get("domain") or acme.get("domains") or [] + if isinstance(domains, str): + domains = [part.strip() for part in domains.split(",") if part.strip()] + acme["domains"] = list(domains) + acme["account"] = str(payload.get("account") or acme.get("account") or "default") + acme["certificate"] = { + "pem": str(payload.get("certificates") or payload.get("certificate") or "SIM-ACME"), + "issued": int(time.time()), + } + certs["acme"] = acme + ops["certificates"] = certs + await save_node_ops(request, node, ops) + if method == "DELETE": + return None + return await _node_task(request, node=node, task_type="acme", worker="acme") + + async def certificates_custom(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + certs = _certificates(ops) + if request.method.upper() == "DELETE": + certs["custom"] = None + else: + certificates = str(payload.get("certificates") or payload.get("cert") or "") + if not certificates: + raise ApiError(400, "parameter verification failed - 'certificates' missing") + key = str(payload.get("key") or payload.get("private-key") or "") + certs["custom"] = { + "certificates": certificates, + "key": key, + "restart": int(payload.get("restart") or 0), + "filename": str(payload.get("filename") or "pveproxy-ssl.pem"), + } + info = list(certs.get("info") or []) + info = [item for item in info if item.get("filename") != certs["custom"]["filename"]] + info.append( + { + "filename": certs["custom"]["filename"], + "fingerprint": secrets.token_hex(20), + "issuer": "CN=Simulator", + "subject": "CN=pve.local", + "notbefore": int(time.time()) - 86_400, + "notafter": int(time.time()) + 365 * 86_400, + "san": ["DNS:pve.local"], + "public-key-type": "rsa", + "public-key-bits": 2048, + } + ) + certs["info"] = info + ops["certificates"] = certs + await save_node_ops(request, node, ops) + + async def certificates_info(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + certs = _certificates(ops) + info = list(certs.get("info") or []) + custom = _public_cert( + certs.get("custom") if isinstance(certs.get("custom"), dict) else None + ) + if custom and not any(item.get("filename") == custom.get("filename") for item in info): + info.append( + { + "filename": custom.get("filename", "pveproxy-ssl.pem"), + "fingerprint": secrets.token_hex(20), + "issuer": "CN=Custom", + "subject": "CN=pve.local", + } + ) + certs["info"] = info + ops["certificates"] = certs + await save_node_ops(request, node, ops) + return [dict(item) for item in info] + + async def scan_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + await require_node(request, str(values(inputs)["node"])) + return subdirs("cifs", "iscsi", "lvm", "lvmthin", "nfs", "pbs", "zfs") + + async def scan_kind( + request: Request, inputs: dict[str, Any], kind: str + ) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + scan = _scan_cache(ops) + ops["scan"] = scan + await save_node_ops(request, node, ops) + items = scan.get(kind, []) + return [dict(item) for item in items] if isinstance(items, list) else [] + + async def capabilities_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + await require_node(request, str(values(inputs)["node"])) + return subdirs("qemu") + + async def capabilities_qemu(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + await require_node(request, str(values(inputs)["node"])) + return subdirs("cpu", "cpu-flags", "machines", "migration") + + async def capabilities_cpu(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + await require_node(request, str(values(inputs)["node"])) + return [ + {"name": "host", "vendor": "QEMU", "custom": 0}, + {"name": "x86-64-v2-AES", "vendor": "QEMU", "custom": 0}, + {"name": "kvm64", "vendor": "QEMU", "custom": 0}, + ] + + async def capabilities_cpu_flags( + request: Request, inputs: dict[str, Any] + ) -> list[dict[str, Any]]: + await require_node(request, str(values(inputs)["node"])) + return [ + {"name": "aes", "introduces": "Westmere"}, + {"name": "avx", "introduces": "SandyBridge"}, + {"name": "avx2", "introduces": "Haswell"}, + ] + + async def capabilities_machines( + request: Request, inputs: dict[str, Any] + ) -> list[dict[str, Any]]: + await require_node(request, str(values(inputs)["node"])) + return [ + {"id": "pc-i440fx-9.0", "type": "i440fx", "version": "9.0"}, + {"id": "pc-q35-9.0", "type": "q35", "version": "9.0"}, + ] + + async def capabilities_migration(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + await require_node(request, str(values(inputs)["node"])) + return {"network": "", "type": "secure", "enabled": 1} + + async def hardware_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + await require_node(request, str(values(inputs)["node"])) + return subdirs("pci", "usb") + + async def hardware_pci(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + hardware = _hardware(ops) + ops["hardware"] = hardware + await save_node_ops(request, node, ops) + return [dict(item) for item in hardware.get("pci", [])] + + async def hardware_pci_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + node = str(payload["node"]) + pci_id = str(payload.get("pci-id-or-mapping") or payload.get("pciid") or "") + await require_node(request, node) + ops = await load_node_ops(request, node) + for item in _hardware(ops).get("pci", []): + if str(item.get("id")) == pci_id: + return dict(item) + raise ApiError(404, "pci device does not exist") + + async def hardware_pci_mdev(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + payload = values(inputs) + node = str(payload["node"]) + pci_id = str(payload.get("pci-id-or-mapping") or payload.get("pciid") or "") + await require_node(request, node) + ops = await load_node_ops(request, node) + hardware = _hardware(ops) + mdev = hardware.get("mdev", {}) + items = mdev.get(pci_id, []) if isinstance(mdev, dict) else [] + return [dict(item) for item in items] if isinstance(items, list) else [] + + async def hardware_usb(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + hardware = _hardware(ops) + ops["hardware"] = hardware + await save_node_ops(request, node, ops) + return [dict(item) for item in hardware.get("usb", [])] + + async def subscription_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(values(inputs)["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + public = dict(_subscription(ops)) + public.pop("key", None) + return public + + async def subscription_mutate( + request: Request, inputs: dict[str, Any] + ) -> dict[str, Any] | None: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + current = _subscription(ops) + method = request.method.upper() + if method == "DELETE": + ops["subscription"] = copy.deepcopy(DEFAULT_SUBSCRIPTION) + await save_node_ops(request, node, ops) + return None + if method == "POST": + current["checktime"] = int(time.time()) + current["status"] = current.get("status") or "Active" + ops["subscription"] = current + await save_node_ops(request, node, ops) + return dict(current) + key = str(payload.get("key") or current.get("key") or "") + updated = { + **current, + **{k: v for k, v in payload.items() if k not in {"node", "delete", "digest"}}, + "key": key, + "status": "Active" if key else current.get("status", "notfound"), + "message": "OK" if key else current.get("message", "There is no subscription key"), + } + ops["subscription"] = updated + await save_node_ops(request, node, ops) + public = dict(updated) + public.pop("key", None) + return public + + async def aplinfo_get(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + items = ops.get("aplinfo") + if not isinstance(items, list): + items = [ + { + "package": "alpine-3-standard", + "section": "system", + "type": "lxc", + "version": "3.20", + } + ] + ops["aplinfo"] = items + await save_node_ops(request, node, ops) + return [dict(item) for item in items] + + async def aplinfo_download(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + downloads = list(ops.get("aplinfo_downloads") or []) + downloads.append( + { + "template": str(payload.get("template") or payload.get("storage") or "unknown"), + "at": int(time.time()), + } + ) + ops["aplinfo_downloads"] = downloads + await save_node_ops(request, node, ops) + return await _node_task(request, node=node, task_type="download", worker="download") + + async def apt_repositories_mutate(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + apt = ops.setdefault("apt", copy.deepcopy(default_node_ops()["apt"])) + repositories = list(apt.get("repositories") or []) + method = request.method.upper() + if method == "POST": + entry = { + key: value + for key, value in payload.items() + if key not in {"node", "delete", "digest"} + } + entry.setdefault("path", f"/etc/apt/sources.list.d/sim-{secrets.token_hex(2)}.list") + entry.setdefault("enabled", 1) + repositories.append(entry) + else: + path = payload.get("path") + handle = payload.get("handle") + index = payload.get("index") + updated: list[dict[str, Any]] = [] + for idx, item in enumerate(repositories): + match = False + if path is not None and item.get("path") == path: + match = True + if handle is not None and item.get("handle") == handle: + match = True + if index is not None and idx == int(index): + match = True + if match or (path is None and handle is None and index is None and idx == 0): + merged = { + **item, + **{ + key: value + for key, value in payload.items() + if key not in {"node", "delete", "digest", "path", "handle", "index"} + }, + } + updated.append(merged) + else: + updated.append(item) + repositories = updated + apt["repositories"] = repositories + ops["apt"] = apt + await save_node_ops(request, node, ops) + + async def node_config_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(values(inputs)["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + config = ops.get("config") + if not isinstance(config, dict): + config = copy.deepcopy(DEFAULT_CONFIG) + ops["config"] = config + await save_node_ops(request, node, ops) + return dict(config) + + async def node_config_put(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + config = dict(ops.get("config") or DEFAULT_CONFIG) + config.update( + { + key: value + for key, value in payload.items() + if key not in {"node", "digest", "delete"} + } + ) + ops["config"] = config + await save_node_ops(request, node, ops) + return config + + async def dns_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(values(inputs)["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + dns = ops.get("dns") + if not isinstance(dns, dict): + dns = copy.deepcopy(DEFAULT_DNS) + ops["dns"] = dns + await save_node_ops(request, node, ops) + return dict(dns) + + async def dns_put(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + dns = dict(ops.get("dns") or DEFAULT_DNS) + dns.update( + { + key: value + for key, value in payload.items() + if key not in {"node", "digest", "delete"} + } + ) + ops["dns"] = dns + await save_node_ops(request, node, ops) + return dns + + async def time_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(values(inputs)["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + current = dict(ops.get("time") or DEFAULT_TIME) + now = int(time.time()) + current["time"] = now + current["localtime"] = now + current.setdefault("timezone", "UTC") + ops["time"] = current + await save_node_ops(request, node, ops) + return current + + async def time_put(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + current = dict(ops.get("time") or DEFAULT_TIME) + if "timezone" in payload: + current["timezone"] = str(payload["timezone"]) + now = int(time.time()) + current["time"] = now + current["localtime"] = now + ops["time"] = current + await save_node_ops(request, node, ops) + return current + + async def execute(request: Request, inputs: dict[str, Any]) -> list[str]: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + commands = payload.get("commands") or payload.get("command") or [] + if isinstance(commands, str): + try: + parsed = json.loads(commands) + commands = parsed if isinstance(parsed, list) else [commands] + except json.JSONDecodeError: + commands = [commands] + ops = await load_node_ops(request, node) + log = list(ops.get("execute_log") or []) + output: list[str] = [] + for command in commands: + entry = {"command": str(command), "at": int(time.time())} + log.append(entry) + output.append(f"OK: {command}") + ops["execute_log"] = log[-100:] + await save_node_ops(request, node, ops) + return output + + async def hosts_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(values(inputs)["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + hosts = ops.get("hosts") + if not isinstance(hosts, dict): + hosts = { + "data": f"127.0.0.1 localhost\n10.0.0.10 {node}\n", + "digest": secrets.token_hex(8), + } + ops["hosts"] = hosts + await save_node_ops(request, node, ops) + return {"data": str(hosts.get("data", "")), "digest": str(hosts.get("digest", ""))} + + async def hosts_post(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + ops["hosts"] = { + "data": str(payload.get("data") or ""), + "digest": secrets.token_hex(8), + } + await save_node_ops(request, node, ops) + + async def journal(request: Request, inputs: dict[str, Any]) -> list[str]: + node = str(values(inputs)["node"]) + await require_node(request, node) + start = int(values(inputs).get("startcursor") or values(inputs).get("start") or 0) + limit = int(values(inputs).get("limit") or 50) + lines = [ + f"{index}: {node} systemd[1]: Started simulated service {index}." + for index in range(start, start + limit) + ] + return lines + + async def syslog(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + await require_node(request, node) + limit = int(values(inputs).get("limit") or 50) + return [ + {"n": index, "t": f"{node} kernel: simulated syslog line {index}"} + for index in range(limit) + ] + + async def netstat(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + await require_node(request, node) + return [ + {"in": 1_000_000, "out": 900_000, "vnet": "vmbr0", "hwaddr": "bc:24:11:00:00:01"}, + {"in": 500_000, "out": 450_000, "vnet": "vmbr1", "hwaddr": "bc:24:11:00:00:02"}, + ] + + async def report(request: Request, inputs: dict[str, Any]) -> str: + node = str(values(inputs)["node"]) + await require_node(request, node) + return f"==== Proxmox node report for {node} ====\nuptime: simulated\n" + + async def rrd(_request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + await require_node(_request, str(values(inputs)["node"])) + return {"filename": "/var/lib/rrdcached/db/pve-node.rrd"} + + async def rrddata(_request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + await require_node(_request, str(values(inputs)["node"])) + now = int(time.time()) + return [ + {"time": now - 120, "cpu": 0.05, "memused": 1_000_000_000}, + {"time": now - 60, "cpu": 0.07, "memused": 1_100_000_000}, + {"time": now, "cpu": 0.04, "memused": 1_050_000_000}, + ] + + async def startall(request: Request, inputs: dict[str, Any]) -> str: + node = str(values(inputs)["node"]) + await require_node(request, node) + await _set_guest_status(request, node, "running") + return await _node_task(request, node=node, task_type="startall", worker="startall") + + async def stopall(request: Request, inputs: dict[str, Any]) -> str: + node = str(values(inputs)["node"]) + await require_node(request, node) + await _set_guest_status(request, node, "stopped") + return await _node_task(request, node=node, task_type="stopall", worker="stopall") + + async def suspendall(request: Request, inputs: dict[str, Any]) -> str: + node = str(values(inputs)["node"]) + await require_node(request, node) + await _set_guest_status(request, node, "paused") + return await _node_task(request, node=node, task_type="suspendall", worker="suspendall") + + async def migrateall(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + target = str(payload.get("target") or "") + await require_node(request, node) + if not target: + raise ApiError(400, "parameter verification failed - 'target' missing") + await _migrate_guests(request, node, target) + return await _node_task(request, node=node, task_type="migrateall", worker="migrateall") + + async def status_post(request: Request, inputs: dict[str, Any]) -> str | None: + payload = values(inputs) + node = str(payload["node"]) + await require_node(request, node) + command = str(payload.get("command") or "reboot") + ops = await load_node_ops(request, node) + ops["last_status_command"] = {"command": command, "at": int(time.time())} + await save_node_ops(request, node, ops) + return await _node_task(request, node=node, task_type=command, worker=command) + + async def wakeonlan(request: Request, inputs: dict[str, Any]) -> str: + node = str(values(inputs)["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + ops["wakeonlan"] = {"at": int(time.time())} + await save_node_ops(request, node, ops) + return "OK" + + async def _shell_proxy(request: Request, inputs: dict[str, Any], kind: str) -> dict[str, Any]: + node = str(values(inputs)["node"]) + await require_node(request, node) + payload = { + "port": 5900 if kind == "vnc" else 22 if kind == "term" else 3128, + "ticket": secrets.token_urlsafe(24), + "user": str(getattr(request.state, "principal", "root@pam")), + "upid": f"UPID:{node}:{secrets.token_hex(4)}:{kind}shell:0:root@pam:", + } + ops = await load_node_ops(request, node) + shells = ops.setdefault("shells", {}) + shells[kind] = {key: value for key, value in payload.items() if key != "ticket"} + ops["shells"] = shells + await save_node_ops(request, node, ops) + return payload + + async def spiceshell(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _shell_proxy(request, inputs, "spice") + + async def termproxy(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _shell_proxy(request, inputs, "term") + + async def vncshell(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _shell_proxy(request, inputs, "vnc") + + async def network_reload(request: Request, inputs: dict[str, Any]) -> None: + node = str(values(inputs)["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + if not isinstance(ops.get("network"), list): + ops["network"] = copy.deepcopy(default_node_ops()["network"]) + ops["network_applied"] = False + await save_node_ops(request, node, ops) + + async def query_oci_repo_tags(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + await require_node(request, node) + repo = str(values(inputs).get("repo") or "library/alpine") + ops = await load_node_ops(request, node) + cache = ops.setdefault("oci_tags", {}) + if repo not in cache: + cache[repo] = [{"tag": "latest"}, {"tag": "3.20"}] + ops["oci_tags"] = cache + await save_node_ops(request, node, ops) + return [dict(item) for item in cache[repo]] + + async def query_url_metadata(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(values(inputs)["node"]) + await require_node(request, node) + url = str(values(inputs).get("url") or "") + ops = await load_node_ops(request, node) + cache = ops.setdefault("url_metadata", {}) + if url not in cache: + cache[url] = { + "filename": url.rsplit("/", 1)[-1] or "download.bin", + "mimetype": "application/octet-stream", + "size": 1024, + } + ops["url_metadata"] = cache + await save_node_ops(request, node, ops) + return dict(cache[url]) + + async def vncwebsocket(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(values(inputs)["node"]) + await require_node(request, node) + ops = await load_node_ops(request, node) + shell = (ops.get("shells") or {}).get("vnc") or {"port": 5900} + return { + "port": shell.get("port", 5900), + "ticket": secrets.token_urlsafe(24), + } + + # Disks mutations (GET collections already registered in nodes.py) + registry.register( + "/nodes/{node}/disks/directory", + "POST", + lambda request, inputs: disks_create(request, inputs, "directory"), + ) + registry.register( + "/nodes/{node}/disks/directory/{name}", + "DELETE", + lambda request, inputs: disks_delete(request, inputs, "directory"), + ) + registry.register( + "/nodes/{node}/disks/lvm", + "POST", + lambda request, inputs: disks_create(request, inputs, "lvm"), + ) + registry.register( + "/nodes/{node}/disks/lvm/{name}", + "DELETE", + lambda request, inputs: disks_delete(request, inputs, "lvm"), + ) + registry.register( + "/nodes/{node}/disks/lvmthin", + "POST", + lambda request, inputs: disks_create(request, inputs, "lvmthin"), + ) + registry.register( + "/nodes/{node}/disks/lvmthin/{name}", + "DELETE", + lambda request, inputs: disks_delete(request, inputs, "lvmthin"), + ) + registry.register( + "/nodes/{node}/disks/zfs", + "POST", + lambda request, inputs: disks_create(request, inputs, "zfs"), + ) + registry.register("/nodes/{node}/disks/zfs/{name}", "GET", disks_zfs_get) + registry.register( + "/nodes/{node}/disks/zfs/{name}", + "DELETE", + lambda request, inputs: disks_delete(request, inputs, "zfs"), + ) + + registry.register("/nodes/{node}/certificates", "GET", certificates_index) + registry.register("/nodes/{node}/certificates/acme", "GET", certificates_acme_index) + registry.register( + "/nodes/{node}/certificates/acme/certificate", "POST", certificates_acme_mutate + ) + registry.register( + "/nodes/{node}/certificates/acme/certificate", "PUT", certificates_acme_mutate + ) + registry.register( + "/nodes/{node}/certificates/acme/certificate", "DELETE", certificates_acme_mutate + ) + registry.register("/nodes/{node}/certificates/custom", "POST", certificates_custom) + registry.register("/nodes/{node}/certificates/custom", "DELETE", certificates_custom) + registry.register("/nodes/{node}/certificates/info", "GET", certificates_info) + + registry.register("/nodes/{node}/scan", "GET", scan_index) + registry.register("/nodes/{node}/scan/cifs", "GET", lambda r, i: scan_kind(r, i, "cifs")) + registry.register("/nodes/{node}/scan/iscsi", "GET", lambda r, i: scan_kind(r, i, "iscsi")) + registry.register("/nodes/{node}/scan/lvm", "GET", lambda r, i: scan_kind(r, i, "lvm")) + registry.register("/nodes/{node}/scan/lvmthin", "GET", lambda r, i: scan_kind(r, i, "lvmthin")) + registry.register("/nodes/{node}/scan/nfs", "GET", lambda r, i: scan_kind(r, i, "nfs")) + registry.register("/nodes/{node}/scan/pbs", "GET", lambda r, i: scan_kind(r, i, "pbs")) + registry.register("/nodes/{node}/scan/zfs", "GET", lambda r, i: scan_kind(r, i, "zfs")) + + registry.register("/nodes/{node}/capabilities", "GET", capabilities_index) + registry.register("/nodes/{node}/capabilities/qemu", "GET", capabilities_qemu) + registry.register("/nodes/{node}/capabilities/qemu/cpu", "GET", capabilities_cpu) + registry.register("/nodes/{node}/capabilities/qemu/cpu-flags", "GET", capabilities_cpu_flags) + registry.register("/nodes/{node}/capabilities/qemu/machines", "GET", capabilities_machines) + registry.register("/nodes/{node}/capabilities/qemu/migration", "GET", capabilities_migration) + + registry.register("/nodes/{node}/hardware", "GET", hardware_index) + registry.register("/nodes/{node}/hardware/pci", "GET", hardware_pci) + registry.register("/nodes/{node}/hardware/pci/{pci-id-or-mapping}", "GET", hardware_pci_get) + registry.register( + "/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev", "GET", hardware_pci_mdev + ) + registry.register("/nodes/{node}/hardware/usb", "GET", hardware_usb) + + registry.register("/nodes/{node}/subscription", "GET", subscription_get) + registry.register("/nodes/{node}/subscription", "PUT", subscription_mutate) + registry.register("/nodes/{node}/subscription", "POST", subscription_mutate) + registry.register("/nodes/{node}/subscription", "DELETE", subscription_mutate) + + registry.register("/nodes/{node}/aplinfo", "GET", aplinfo_get) + registry.register("/nodes/{node}/aplinfo", "POST", aplinfo_download) + registry.register("/nodes/{node}/apt/repositories", "POST", apt_repositories_mutate) + registry.register("/nodes/{node}/apt/repositories", "PUT", apt_repositories_mutate) + registry.register("/nodes/{node}/config", "GET", node_config_get) + registry.register("/nodes/{node}/config", "PUT", node_config_put) + registry.register("/nodes/{node}/dns", "GET", dns_get) + registry.register("/nodes/{node}/dns", "PUT", dns_put) + registry.register("/nodes/{node}/time", "GET", time_get) + registry.register("/nodes/{node}/time", "PUT", time_put) + registry.register("/nodes/{node}/execute", "POST", execute) + registry.register("/nodes/{node}/hosts", "GET", hosts_get) + registry.register("/nodes/{node}/hosts", "POST", hosts_post) + registry.register("/nodes/{node}/journal", "GET", journal) + registry.register("/nodes/{node}/syslog", "GET", syslog) + registry.register("/nodes/{node}/netstat", "GET", netstat) + registry.register("/nodes/{node}/report", "GET", report) + registry.register("/nodes/{node}/rrd", "GET", rrd) + registry.register("/nodes/{node}/rrddata", "GET", rrddata) + registry.register("/nodes/{node}/migrateall", "POST", migrateall) + registry.register("/nodes/{node}/startall", "POST", startall) + registry.register("/nodes/{node}/stopall", "POST", stopall) + registry.register("/nodes/{node}/suspendall", "POST", suspendall) + registry.register("/nodes/{node}/status", "POST", status_post) + registry.register("/nodes/{node}/wakeonlan", "POST", wakeonlan) + registry.register("/nodes/{node}/spiceshell", "POST", spiceshell) + registry.register("/nodes/{node}/termproxy", "POST", termproxy) + registry.register("/nodes/{node}/vncshell", "POST", vncshell) + registry.register("/nodes/{node}/network", "DELETE", network_reload) + registry.register("/nodes/{node}/query-oci-repo-tags", "GET", query_oci_repo_tags) + registry.register("/nodes/{node}/query-url-metadata", "GET", query_url_metadata) + registry.register("/nodes/{node}/vncwebsocket", "GET", vncwebsocket) diff --git a/app/handlers/notifications.py b/app/handlers/notifications.py new file mode 100644 index 0000000..52a5e67 --- /dev/null +++ b/app/handlers/notifications.py @@ -0,0 +1,276 @@ +"""Cluster notifications endpoints and matchers persisted in metadata.""" + +from __future__ import annotations + +import time +from typing import Any + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.common import cluster_metadata, save_cluster_metadata, subdirs, values + +_SECRET_KEYS = frozenset({"token", "password", "secret"}) + +DEFAULT_MATCHER_FIELDS = [ + {"name": "type", "type": "string"}, + {"name": "hostname", "type": "string"}, + {"name": "job-id", "type": "string"}, + {"name": "severity", "type": "string"}, +] + +DEFAULT_MATCHER_FIELD_VALUES = [ + {"field": "type", "value": "fencing"}, + {"field": "type", "value": "package-updates"}, + {"field": "type", "value": "replication"}, + {"field": "type", "value": "system-mail"}, +] + + +def _public(endpoint: dict[str, Any]) -> dict[str, Any]: + return {key: value for key, value in endpoint.items() if key not in _SECRET_KEYS} + + +def _notifications(metadata: dict[str, Any]) -> dict[str, Any]: + current = metadata.setdefault( + "notifications", + { + "endpoints": { + "gotify": {}, + "sendmail": {}, + "smtp": {}, + "webhook": {}, + }, + "matchers": {}, + "tests": [], + }, + ) + if not isinstance(current, dict): + current = { + "endpoints": {"gotify": {}, "sendmail": {}, "smtp": {}, "webhook": {}}, + "matchers": {}, + "tests": [], + } + metadata["notifications"] = current + current.setdefault( + "endpoints", + {"gotify": {}, "sendmail": {}, "smtp": {}, "webhook": {}}, + ) + current.setdefault("matchers", {}) + current.setdefault("tests", []) + return current + + +def register_notifications_handlers(registry: HandlerRegistry) -> None: + async def index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs( + "endpoints", + "matcher-field-values", + "matcher-fields", + "matchers", + "targets", + ) + + async def endpoints_index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs("gotify", "sendmail", "smtp", "webhook") + + def register_kind(kind: str, create_keys: tuple[str, ...]) -> None: + base = f"/cluster/notifications/endpoints/{kind}" + + async def list_endpoints(request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + metadata = await cluster_metadata(request) + store = _notifications(metadata)["endpoints"].setdefault(kind, {}) + return [_public({"name": name, **item}) for name, item in sorted(store.items())] + + async def create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + name = str(payload["name"]) + metadata = await cluster_metadata(request) + store = _notifications(metadata)["endpoints"].setdefault(kind, {}) + if name in store: + raise ApiError(400, f"{kind} endpoint '{name}' already exists") + entry = {key: payload[key] for key in create_keys if key in payload} + entry["name"] = name + entry.setdefault("disable", 0) + store[name] = entry + await save_cluster_metadata(request, metadata) + + async def get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + name = str(values(inputs)["name"]) + metadata = await cluster_metadata(request) + store = _notifications(metadata)["endpoints"].setdefault(kind, {}) + if name not in store: + raise ApiError(404, f"{kind} endpoint does not exist") + return _public({"name": name, **store[name]}) + + async def update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + name = str(payload["name"]) + metadata = await cluster_metadata(request) + store = _notifications(metadata)["endpoints"].setdefault(kind, {}) + if name not in store: + raise ApiError(404, f"{kind} endpoint does not exist") + current = dict(store[name]) + delete_keys = [ + item.strip() for item in str(payload.get("delete") or "").split(",") if item.strip() + ] + for key in delete_keys: + current.pop(key, None) + for key, value in payload.items(): + if key in {"name", "delete", "digest"}: + continue + current[key] = value + current["name"] = name + store[name] = current + await save_cluster_metadata(request, metadata) + + async def delete(request: Request, inputs: dict[str, Any]) -> None: + name = str(values(inputs)["name"]) + metadata = await cluster_metadata(request) + store = _notifications(metadata)["endpoints"].setdefault(kind, {}) + if name not in store: + raise ApiError(404, f"{kind} endpoint does not exist") + del store[name] + await save_cluster_metadata(request, metadata) + + registry.register(base, "GET", list_endpoints) + registry.register(base, "POST", create) + registry.register(f"{base}/{{name}}", "GET", get) + registry.register(f"{base}/{{name}}", "PUT", update) + registry.register(f"{base}/{{name}}", "DELETE", delete) + + async def matchers_list(request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + metadata = await cluster_metadata(request) + store = _notifications(metadata)["matchers"] + return [{"name": name, **item} for name, item in sorted(store.items())] + + async def matchers_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + name = str(payload["name"]) + metadata = await cluster_metadata(request) + store = _notifications(metadata)["matchers"] + if name in store: + raise ApiError(400, f"matcher '{name}' already exists") + store[name] = { + key: value for key, value in payload.items() if key not in {"delete", "digest"} + } + await save_cluster_metadata(request, metadata) + + async def matchers_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + name = str(values(inputs)["name"]) + metadata = await cluster_metadata(request) + store = _notifications(metadata)["matchers"] + if name not in store: + raise ApiError(404, "matcher does not exist") + return {"name": name, **store[name]} + + async def matchers_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + name = str(payload["name"]) + metadata = await cluster_metadata(request) + store = _notifications(metadata)["matchers"] + if name not in store: + raise ApiError(404, "matcher does not exist") + current = dict(store[name]) + for key in [ + item.strip() for item in str(payload.get("delete") or "").split(",") if item.strip() + ]: + current.pop(key, None) + for key, value in payload.items(): + if key in {"name", "delete", "digest"}: + continue + current[key] = value + current["name"] = name + store[name] = current + await save_cluster_metadata(request, metadata) + + async def matchers_delete(request: Request, inputs: dict[str, Any]) -> None: + name = str(values(inputs)["name"]) + metadata = await cluster_metadata(request) + store = _notifications(metadata)["matchers"] + if name not in store: + raise ApiError(404, "matcher does not exist") + del store[name] + await save_cluster_metadata(request, metadata) + + async def matcher_fields(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + return list(DEFAULT_MATCHER_FIELDS) + + async def matcher_field_values( + _request: Request, _inputs: dict[str, Any] + ) -> list[dict[str, Any]]: + return list(DEFAULT_MATCHER_FIELD_VALUES) + + async def targets(request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + metadata = await cluster_metadata(request) + notifications = _notifications(metadata) + result: list[dict[str, Any]] = [] + for kind, store in (notifications.get("endpoints") or {}).items(): + if not isinstance(store, dict): + continue + for name, item in store.items(): + result.append( + { + "name": name, + "type": kind, + "comment": item.get("comment", ""), + "disable": int(bool(item.get("disable"))), + } + ) + return result + + async def target_test(request: Request, inputs: dict[str, Any]) -> None: + name = str(values(inputs)["name"]) + metadata = await cluster_metadata(request) + notifications = _notifications(metadata) + found = False + for store in (notifications.get("endpoints") or {}).values(): + if isinstance(store, dict) and name in store: + found = True + break + if not found: + raise ApiError(404, "notification target does not exist") + tests = notifications.setdefault("tests", []) + if not isinstance(tests, list): + tests = notifications["tests"] = [] + tests.append({"name": name, "tested_at": int(time.time()), "ok": True}) + await save_cluster_metadata(request, metadata) + + registry.register("/cluster/notifications", "GET", index) + registry.register("/cluster/notifications/endpoints", "GET", endpoints_index) + register_kind("gotify", ("comment", "disable", "name", "server", "token")) + register_kind( + "sendmail", + ("author", "comment", "disable", "from-address", "mailto", "mailto-user", "name"), + ) + register_kind( + "smtp", + ( + "author", + "comment", + "disable", + "from-address", + "mailto", + "mailto-user", + "mode", + "name", + "password", + "port", + "server", + "username", + ), + ) + register_kind( + "webhook", + ("body", "comment", "disable", "header", "method", "name", "secret", "url"), + ) + registry.register("/cluster/notifications/matchers", "GET", matchers_list) + registry.register("/cluster/notifications/matchers", "POST", matchers_create) + registry.register("/cluster/notifications/matchers/{name}", "GET", matchers_get) + registry.register("/cluster/notifications/matchers/{name}", "PUT", matchers_update) + registry.register("/cluster/notifications/matchers/{name}", "DELETE", matchers_delete) + registry.register("/cluster/notifications/matcher-fields", "GET", matcher_fields) + registry.register("/cluster/notifications/matcher-field-values", "GET", matcher_field_values) + registry.register("/cluster/notifications/targets", "GET", targets) + registry.register("/cluster/notifications/targets/{name}/test", "POST", target_test) diff --git a/app/handlers/pools.py b/app/handlers/pools.py new file mode 100644 index 0000000..9d65005 --- /dev/null +++ b/app/handlers/pools.py @@ -0,0 +1,134 @@ +"""Resource pool semantic handlers.""" + +from __future__ import annotations + +import json +import uuid +from typing import Any + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.common import database, state, values +from app.simulation.seed import CLUSTER_ID, stable_id + + +async def _pool_members(request: Request, pool_id: uuid.UUID) -> list[str]: + rows = await database(request).pool.fetch( + """SELECT r.external_id FROM pool_members pm + JOIN resources r ON r.id = pm.resource_id + WHERE pm.pool_id=$1 ORDER BY r.external_id::integer""", + pool_id, + ) + return [str(row["external_id"]) for row in rows] + + +def register_pool_handlers(registry: HandlerRegistry) -> None: + async def pool_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + payload = values(inputs) + filter_poolid = payload.get("poolid") + rows = await database(request).pool.fetch( + """SELECT id, pool_id, comment, metadata FROM pools + WHERE ($1::text IS NULL OR pool_id=$1) + ORDER BY pool_id""", + str(filter_poolid) if filter_poolid is not None else None, + ) + result: list[dict[str, Any]] = [] + for row in rows: + metadata = state(row["metadata"]) + members = await _pool_members(request, row["id"]) + if not members and isinstance(metadata.get("members"), list): + members = [str(item) for item in metadata["members"]] + item: dict[str, Any] = { + "poolid": str(row["pool_id"]), + "members": members, + } + if row["comment"] is not None: + item["comment"] = str(row["comment"]) + elif metadata.get("comment"): + item["comment"] = str(metadata["comment"]) + result.append(item) + return result + + async def pool_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + items = await pool_list(request, inputs) + if not items: + raise ApiError(404, "pool does not exist") + return items[0] + + async def pool_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + poolid = str(payload["poolid"]) + exists = await database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM pools WHERE pool_id=$1)", + poolid, + ) + if exists: + raise ApiError(409, "pool already exists") + await database(request).pool.execute( + """INSERT INTO pools(id, cluster_id, pool_id, comment, metadata) + VALUES($1, $2, $3, $4, $5::jsonb)""", + stable_id(f"pool:{poolid}"), + CLUSTER_ID, + poolid, + payload.get("comment"), + json.dumps({"members": []}, sort_keys=True), + ) + + async def pool_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + poolid = str(payload["poolid"]) + pool_row = await database(request).pool.fetchrow( + "SELECT id FROM pools WHERE pool_id=$1", + poolid, + ) + if pool_row is None: + raise ApiError(404, "pool does not exist") + if payload.get("comment") is not None: + await database(request).pool.execute( + "UPDATE pools SET comment=$2 WHERE pool_id=$1", + poolid, + payload.get("comment"), + ) + if "vms" in payload: + vmids = [item.strip() for item in str(payload["vms"]).split(",") if item.strip()] + for vmid in vmids: + resource = await database(request).pool.fetchrow( + """SELECT id FROM resources + WHERE kind IN ('qemu', 'lxc') AND external_id=$1""", + vmid, + ) + if resource is None: + continue + await database(request).pool.execute( + """INSERT INTO pool_members(pool_id, resource_id) + VALUES($1, $2) ON CONFLICT DO NOTHING""", + pool_row["id"], + resource["id"], + ) + if "delete" in payload: + vmids = [item.strip() for item in str(payload["delete"]).split(",") if item.strip()] + await database(request).pool.execute( + """DELETE FROM pool_members pm USING resources r + WHERE pm.pool_id=$1 AND pm.resource_id=r.id AND r.external_id = ANY($2::text[])""", + pool_row["id"], + vmids, + ) + + async def pool_delete(request: Request, inputs: dict[str, Any]) -> None: + poolid = str(values(inputs)["poolid"]) + status = await database(request).pool.execute( + "DELETE FROM pools WHERE pool_id=$1", + poolid, + ) + if status != "DELETE 1": + raise ApiError(404, "pool does not exist") + + registry.register("/pools", "GET", pool_list) + registry.register("/pools", "POST", pool_create) + registry.register("/pools", "PUT", pool_update) + registry.register("/pools", "DELETE", pool_delete) + registry.register("/pools/{poolid}", "GET", pool_get) + registry.register("/pools/{poolid}", "PUT", pool_update) + registry.register("/pools/{poolid}", "DELETE", pool_delete) diff --git a/app/handlers/qemu.py b/app/handlers/qemu.py new file mode 100644 index 0000000..c16dd7b --- /dev/null +++ b/app/handlers/qemu.py @@ -0,0 +1,865 @@ +"""Basic persistent QEMU and task semantic handlers.""" + +from __future__ import annotations + +import json +import re +from collections.abc import Mapping +from typing import Any, cast + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.db.pool import AsyncpgDatabase +from app.db.primitives import ConflictError +from app.handlers.common import require_node, subdirs +from app.simulation.transitions import InvalidTransitionError, VmState, plan_transition +from app.tasks.repository import TaskRepository +from app.tasks.upid import Upid + + +def _database(request: Request) -> AsyncpgDatabase: + return cast(AsyncpgDatabase, request.app.state.database) + + +def _values(inputs: dict[str, Any]) -> dict[str, Any]: + return cast(dict[str, Any], inputs["values"]) + + +def _state(value: object) -> dict[str, Any]: + if isinstance(value, str): + return cast(dict[str, Any], json.loads(value)) + return dict(cast(Mapping[str, Any], value)) + + +def register_qemu_handlers(registry: HandlerRegistry) -> None: + async def qemu_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(_values(inputs)["node"]) + rows = await _database(request).pool.fetch( + """SELECT r.external_id::integer AS vmid, r.state + FROM resources r JOIN nodes n ON n.id=r.node_id + WHERE n.name=$1 AND r.kind='qemu' ORDER BY r.external_id::integer""", + node, + ) + return [{"vmid": int(row["vmid"]), **_state(row["state"])} for row in rows] + + async def qemu_status_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + payload = _values(inputs) + await _qemu_resource(request, str(payload["node"]), str(payload["vmid"])) + return subdirs( + "current", + "reboot", + "reset", + "resume", + "shutdown", + "start", + "stop", + "suspend", + ) + + async def qemu_status_current(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = _values(inputs) + node, vmid = str(payload["node"]), int(payload["vmid"]) + resource = await _qemu_resource(request, node, str(vmid)) + vm_state = _state(resource["state"]) + config = _state(resource["config"]) + status = str(vm_state.get("status", "stopped")) + running = status in {"running", "paused"} + memory_mb = int(config.get("memory", config.get("mem", 2048))) + maxmem = memory_mb * 2**20 + mem_used = int(vm_state.get("mem", maxmem // 2 if running else 0)) + uptime = int( + vm_state.get( + "uptime", + int( + await _database(request).pool.fetchval( + "SELECT extract(epoch from now())::bigint" + ) + ) + % 86_400 + if running + else 0, + ) + ) + return { + "vmid": vmid, + "name": str(config.get("name", f"vm-{vmid}")), + "status": status, + "qmpstatus": status if running else "stopped", + "lock": str(vm_state.get("lock", "")), + "pid": int(vm_state.get("pid", 12_345 if running else 0)), + "cpus": int(config.get("cores", config.get("cpus", 1))), + "maxmem": maxmem, + "mem": mem_used, + "balloon": int(vm_state.get("balloon", 0)), + "ballooninfo": { + "actual": mem_used, + "max_mem": maxmem, + "mem_swapped_in": 0, + "mem_swapped_out": 0, + }, + "uptime": uptime, + "template": int(bool(vm_state.get("template", False))), + "ha": {"managed": int(vm_state.get("ha_managed", 0))}, + "agent": 1 if running and str(config.get("agent", "0")).startswith("1") else 0, + } + + async def qemu_config(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node, vmid = str(_values(inputs)["node"]), str(_values(inputs)["vmid"]) + row = await _database(request).pool.fetchrow( + """SELECT r.state, v.config FROM resources r + JOIN nodes n ON n.id=r.node_id + JOIN virtual_machines v ON v.resource_id=r.id + WHERE n.name=$1 AND r.kind='qemu' AND r.external_id=$2""", + node, + vmid, + ) + if row is None: + raise ApiError(404, "virtual machine does not exist") + return {"vmid": int(vmid), **_state(row["config"]), **_state(row["state"])} + + async def mutate(operation: str, request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + node, vmid = str(values["node"]), str(values["vmid"]) + database = _database(request) + row = await database.pool.fetchrow( + """SELECT r.id, r.state FROM resources r JOIN nodes n ON n.id=r.node_id + WHERE n.name=$1 AND r.kind='qemu' AND r.external_id=$2""", + node, + vmid, + ) + if row is None: + raise ApiError(404, "virtual machine does not exist") + current = str(_state(row["state"]).get("status", "stopped")) + try: + plan_transition(VmState(current), operation) + except (InvalidTransitionError, ValueError) as error: + raise ApiError(409, f"cannot {operation} VM while it is {current}") from error + upid = str(Upid.allocate(node, f"qm{operation}", vmid, str(request.state.principal))) + try: + task = await TaskRepository(database.pool).create( + upid=upid, + task_type=f"qemu-{operation}", + payload={"node": node, "vmid": vmid, "resource_id": str(row["id"])}, + resource_key=f"qemu:{vmid}", + idempotency_key=request.headers.get("Idempotency-Key"), + ) + except ConflictError as error: + raise ApiError(409, str(error)) from error + return task.upid + + async def create(request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + node, vmid = str(values["node"]), int(values["vmid"]) + database = _database(request) + if not await database.pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM nodes WHERE name=$1)", node + ): + raise ApiError(404, "node does not exist") + if await database.pool.fetchval( + """SELECT EXISTS(SELECT 1 FROM resources + WHERE external_id=$1 AND kind IN ('qemu','lxc'))""", + str(vmid), + ): + raise ApiError(409, "VMID already exists") + config = { + key: value + for key, value in values.items() + if key not in {"node", "vmid", "force", "archive", "start"} + } + return await _create_task( + request, + node=node, + vmid=str(vmid), + task_type="qemu-create", + payload={"node": node, "vmid": vmid, "config": config}, + ) + + async def update(request: Request, inputs: dict[str, Any], *, asynchronous: bool) -> str | None: + values = _values(inputs) + node, vmid = str(values["node"]), str(values["vmid"]) + database = _database(request) + row = await database.pool.fetchrow( + """SELECT r.id, r.version, r.state, v.config FROM resources r + JOIN nodes n ON n.id=r.node_id + JOIN virtual_machines v ON v.resource_id=r.id + WHERE n.name=$1 AND r.kind='qemu' AND r.external_id=$2""", + node, + vmid, + ) + if row is None: + raise ApiError(404, "virtual machine does not exist") + control = {"node", "vmid", "digest", "delete", "revert", "skiplock", "background_delay"} + provided = frozenset(str(item) for item in inputs.get("provided", values)) + changes = { + key: value for key, value in values.items() if key in provided and key not in control + } + delete = str(values.get("delete", "")) if "delete" in provided else "" + if asynchronous: + return await _create_task( + request, + node=node, + vmid=vmid, + task_type="qemu-update", + payload={ + "node": node, + "vmid": vmid, + "resource_id": str(row["id"]), + "changes": changes, + "delete": delete, + }, + ) + state = _state(row["state"]) + config = _state(row["config"]) + state.update(changes) + config.update(changes) + for key in delete.split(","): + if key: + state.pop(key, None) + config.pop(key, None) + status = await database.pool.execute( + """UPDATE resources SET state=$3::jsonb, version=version+1, + updated_at=now() WHERE id=$1 AND version=$2""", + row["id"], + row["version"], + json.dumps(state, sort_keys=True), + ) + if status != "UPDATE 1": + raise ApiError(409, "configuration changed concurrently") + await database.pool.execute( + """UPDATE virtual_machines SET config=$2::jsonb + WHERE resource_id=$1""", + row["id"], + json.dumps(config, sort_keys=True), + ) + return None + + async def update_async(request: Request, inputs: dict[str, Any]) -> str: + result = await update(request, inputs, asynchronous=True) + if not isinstance(result, str): + raise RuntimeError("async QEMU update did not create a task") + return result + + async def update_sync(request: Request, inputs: dict[str, Any]) -> None: + await update(request, inputs, asynchronous=False) + + async def delete(request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + node, vmid = str(values["node"]), str(values["vmid"]) + database = _database(request) + row = await database.pool.fetchrow( + """SELECT r.id, r.state FROM resources r JOIN nodes n ON n.id=r.node_id + WHERE n.name=$1 AND r.kind='qemu' AND r.external_id=$2""", + node, + vmid, + ) + if row is None: + raise ApiError(404, "virtual machine does not exist") + if str(_state(row["state"]).get("status")) != "stopped": + raise ApiError(409, "cannot delete a running virtual machine") + return await _create_task( + request, + node=node, + vmid=vmid, + task_type="qemu-delete", + payload={"node": node, "vmid": vmid, "resource_id": str(row["id"])}, + ) + + async def start(request: Request, inputs: dict[str, Any]) -> str: + return await mutate("start", request, inputs) + + async def stop(request: Request, inputs: dict[str, Any]) -> str: + return await mutate("stop", request, inputs) + + async def shutdown(request: Request, inputs: dict[str, Any]) -> str: + return await mutate("shutdown", request, inputs) + + async def reboot(request: Request, inputs: dict[str, Any]) -> str: + return await mutate("reboot", request, inputs) + + async def reset(request: Request, inputs: dict[str, Any]) -> str: + return await mutate("reset", request, inputs) + + async def suspend(request: Request, inputs: dict[str, Any]) -> str: + return await mutate("suspend", request, inputs) + + async def resume(request: Request, inputs: dict[str, Any]) -> str: + return await mutate("resume", request, inputs) + + async def snapshot_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + values = _values(inputs) + resource = await _qemu_resource(request, str(values["node"]), str(values["vmid"])) + rows = await _database(request).pool.fetch( + """SELECT name, parent_name, description, created_at FROM snapshots + WHERE resource_id=$1 ORDER BY created_at, name""", + resource["id"], + ) + return [ + { + "name": row["name"], + "parent": row["parent_name"], + "description": row["description"] or "", + "snaptime": int(row["created_at"].timestamp()), + } + for row in rows + ] + + async def snapshot_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + values = _values(inputs) + row = await _snapshot(request, values) + state = _state(row["state"]) + return { + "name": row["name"], + "parent": row["parent_name"], + "description": row["description"] or "", + "snaptime": int(row["created_at"].timestamp()), + **state, + } + + async def snapshot_config(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + row = await _snapshot(request, _values(inputs)) + return {"description": row["description"] or "", **_state(row["state"])} + + async def snapshot_update(request: Request, inputs: dict[str, Any]) -> None: + values = _values(inputs) + row = await _snapshot(request, values) + await _database(request).pool.execute( + "UPDATE snapshots SET description=$2 WHERE id=$1", + row["id"], + str(values.get("description", "")), + ) + + async def snapshot_task(operation: str, request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + node, vmid, snapname = ( + str(values["node"]), + str(values["vmid"]), + str(values["snapname"]), + ) + resource = await _qemu_resource(request, node, vmid) + if operation == "snapshot-create": + exists = await _database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM snapshots WHERE resource_id=$1 AND name=$2)", + resource["id"], + snapname, + ) + if exists: + raise ApiError(409, "snapshot already exists") + else: + await _snapshot(request, values) + return await _create_task( + request, + node=node, + vmid=vmid, + task_type=f"qemu-{operation}", + payload={ + "node": node, + "vmid": vmid, + "resource_id": str(resource["id"]), + "snapname": snapname, + "description": str(values.get("description", "")), + "vmstate": bool(values.get("vmstate", False)), + "start": bool(values.get("start", False)), + }, + ) + + async def snapshot_create(request: Request, inputs: dict[str, Any]) -> str: + return await snapshot_task("snapshot-create", request, inputs) + + async def snapshot_delete(request: Request, inputs: dict[str, Any]) -> str: + return await snapshot_task("snapshot-delete", request, inputs) + + async def snapshot_rollback(request: Request, inputs: dict[str, Any]) -> str: + return await snapshot_task("snapshot-rollback", request, inputs) + + async def clone(request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + node, vmid, newid = str(values["node"]), str(values["vmid"]), str(values["newid"]) + source = await _qemu_resource(request, node, vmid) + if await _database(request).pool.fetchval( + """SELECT EXISTS(SELECT 1 FROM resources + WHERE external_id=$1 AND kind IN ('qemu','lxc'))""", + newid, + ): + raise ApiError(409, "VMID already exists") + target = str(values.get("target") or node) + if not await _database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM nodes WHERE name=$1)", target + ): + raise ApiError(404, "target node does not exist") + return await _create_task( + request, + node=target, + vmid=newid, + task_type="qemu-clone", + payload={ + "source_resource_id": str(source["id"]), + "source_vmid": vmid, + "node": target, + "vmid": int(newid), + "name": values.get("name"), + "description": values.get("description"), + "full": bool(values.get("full", False)), + }, + ) + + async def migrate_preconditions(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + values = _values(inputs) + await _qemu_resource(request, str(values["node"]), str(values["vmid"])) + target = values.get("target") + if target in {None, ""}: + raise ApiError(400, "parameter 'target' is required") + target = str(target) + exists = await _database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM nodes WHERE name=$1)", target + ) + if not exists: + raise ApiError(404, "target node does not exist") + return {"local_disks": [], "local_resources": [], "running": False} + + async def migrate(request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + node, vmid = str(values["node"]), str(values["vmid"]) + target = values.get("target") + if target in {None, ""}: + raise ApiError(400, "parameter 'target' is required") + target = str(target) + resource = await _qemu_resource(request, node, vmid) + if target == node: + raise ApiError(400, "target node is the same as source node") + await migrate_preconditions(request, inputs) + return await _create_task( + request, + node=node, + vmid=vmid, + task_type="qemu-migrate", + payload={ + "resource_id": str(resource["id"]), + "node": node, + "target": target, + "vmid": vmid, + "online": bool(values.get("online", False)), + }, + ) + + async def remote_migrate(request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + target_endpoint = str(values.get("target-endpoint") or values.get("target_endpoint") or "") + target = str(values.get("target") or "") + if not target_endpoint: + raise ApiError(400, "parameter target-endpoint is required") + if not target: + raise ApiError(400, "parameter target is required") + node, vmid = str(values["node"]), str(values["vmid"]) + resource = await _qemu_resource(request, node, vmid) + if target == node: + raise ApiError(400, "target node is the same as source node") + if not await _database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM nodes WHERE name=$1)", target + ): + raise ApiError(404, "target node does not exist") + return await _create_task( + request, + node=node, + vmid=vmid, + task_type="qemu-remote-migrate", + payload={ + "resource_id": str(resource["id"]), + "node": node, + "target": target, + "vmid": vmid, + "target-endpoint": target_endpoint, + "online": bool(values.get("online", False)), + }, + ) + + async def resize(request: Request, inputs: dict[str, Any]) -> None: + values = _values(inputs) + node, vmid, disk = str(values["node"]), str(values["vmid"]), str(values["disk"]) + resource = await _qemu_resource(request, node, vmid) + config = _state(resource["config"]) + if disk not in config: + raise ApiError(400, f"disk {disk} does not exist") + current = _disk_size_bytes(str(config[disk])) + size = _resize_bytes(str(values["size"]), current) + config[disk] = _replace_disk_size(str(config[disk]), size) + status = await _database(request).pool.execute( + """UPDATE virtual_machines SET config=$2::jsonb + WHERE resource_id=$1""", + resource["id"], + json.dumps(config, sort_keys=True), + ) + if status != "UPDATE 1": + raise ApiError(409, "configuration changed concurrently") + await _database(request).pool.execute( + """UPDATE resources SET state=state || $2::jsonb,version=version+1, + updated_at=now() WHERE id=$1""", + resource["id"], + json.dumps({disk: config[disk]}, sort_keys=True), + ) + await _database(request).pool.execute( + """INSERT INTO vm_disks(id,resource_id,device,storage_id,size_bytes) + VALUES(gen_random_uuid(),$1,$2,$3,$4) + ON CONFLICT(resource_id,device) DO UPDATE SET size_bytes=EXCLUDED.size_bytes""", + resource["id"], + disk, + str(config[disk]).split(":", 1)[0], + size, + ) + + async def move_disk(request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + node, vmid, disk = str(values["node"]), str(values["vmid"]), str(values["disk"]) + resource = await _qemu_resource(request, node, vmid) + if disk not in _state(resource["config"]): + raise ApiError(400, f"disk {disk} does not exist") + return await _create_task( + request, + node=node, + vmid=vmid, + task_type="qemu-move-disk", + payload={ + "resource_id": str(resource["id"]), + "disk": disk, + "storage": str(values.get("storage") or "local-lvm"), + "target_vmid": int(values.get("target-vmid") or vmid), + "target_disk": str(values.get("target-disk") or disk), + "delete": bool(values.get("delete", True)), + }, + ) + + async def pending(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + values = _values(inputs) + resource = await _qemu_resource(request, str(values["node"]), str(values["vmid"])) + state = _state(resource["state"]) + config = _state(resource["config"]) + changes = cast(Mapping[str, Any], state.get("pending", {})) + return [ + {"key": key, "value": str(config.get(key, "")), "pending": str(value)} + for key, value in sorted(changes.items()) + ] + + async def agent_result( + command: str, request: Request, inputs: dict[str, Any] + ) -> dict[str, Any]: + resource = await _agent_resource(request, _values(inputs)) + config = _state(resource["config"]) + vmid = str(_values(inputs)["vmid"]) + results: dict[str, Any] = { + "info": { + "version": "9.2.0-simulator", + "supported_commands": [ + {"name": name, "enabled": True, "success-response": True} + for name in ("guest-ping", "guest-info", "guest-get-osinfo") + ], + }, + "get-osinfo": { + "name": str(config.get("ostype", "linux")), + "pretty-name": "Proxmox Simulator Guest", + "version": "1.0", + "machine": "x86_64", + }, + "get-host-name": {"host-name": str(config.get("name", f"vm-{vmid}"))}, + "network-get-interfaces": [ + { + "name": "eth0", + "hardware-address": "02:00:00:00:00:01", + "ip-addresses": [ + {"ip-address": "192.0.2.10", "ip-address-type": "ipv4", "prefix": 24} + ], + } + ], + "ping": {}, + } + if command == "get-time": + seconds = int( + await _database(request).pool.fetchval("SELECT extract(epoch from now())::bigint") + ) + return {"result": {"seconds": seconds, "nanoseconds": 0}} + return {"result": results[command]} + + async def agent_info(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await agent_result("info", request, inputs) + + async def agent_osinfo(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await agent_result("get-osinfo", request, inputs) + + async def agent_hostname(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await agent_result("get-host-name", request, inputs) + + async def agent_network(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await agent_result("network-get-interfaces", request, inputs) + + async def agent_time(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await agent_result("get-time", request, inputs) + + async def agent_ping(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await agent_result("ping", request, inputs) + + async def task_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + tasks = await TaskRepository(_database(request).pool).list_for_node( + str(_values(inputs)["node"]) + ) + return [ + {"upid": task.upid, "status": task.status, "type": task.task_type} for task in tasks + ] + + async def task_status(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + task = await TaskRepository(_database(request).pool).get_by_upid( + str(_values(inputs)["upid"]) + ) + if task is None: + raise ApiError(404, "task does not exist") + result: dict[str, Any] = { + "upid": task.upid, + "status": "stopped" if task.status in {"success", "error", "cancelled"} else "running", + "progress": task.progress, + } + if task.status in {"success", "error", "cancelled"}: + result["exitstatus"] = "OK" if task.status == "success" else task.status.upper() + return result + + async def task_log(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + repository = TaskRepository(_database(request).pool) + task = await repository.get_by_upid(str(_values(inputs)["upid"])) + if task is None: + raise ApiError(404, "task does not exist") + return [ + {"n": index + 1, "t": message} + for index, message in enumerate(await repository.logs(task.id)) + ] + + async def qemu_feature(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = _values(inputs) + await _qemu_resource(request, str(payload["node"]), str(payload["vmid"])) + return { + "hasFeature": { + "snapshot": 1, + "clone": 1, + "copy": 1, + "template": 1, + "move_disk": 1, + "agent": 1, + } + } + + async def qemu_template(request: Request, inputs: dict[str, Any]) -> None: + payload = _values(inputs) + node, vmid = str(payload["node"]), str(payload["vmid"]) + resource = await _qemu_resource(request, node, vmid) + state = _state(resource["state"]) + if state.get("status") != "stopped": + raise ApiError(409, "virtual machine must be stopped to convert to template") + await _database(request).pool.execute( + "UPDATE virtual_machines SET template=true WHERE resource_id=$1", + resource["id"], + ) + state["template"] = True + await _database(request).pool.execute( + "UPDATE resources SET state=$2::jsonb WHERE id=$1", + resource["id"], + json.dumps(state, sort_keys=True), + ) + + async def qemu_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + payload = _values(inputs) + node, vmid = str(payload["node"]), str(payload["vmid"]) + await require_node(request, node) + await _qemu_resource(request, node, vmid) + return subdirs( + "agent", + "clone", + "config", + "feature", + "firewall", + "migrate", + "move_disk", + "pending", + "resize", + "snapshot", + "status", + "template", + ) + + async def task_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + payload = _values(inputs) + node, upid = str(payload["node"]), str(payload["upid"]) + await require_node(request, node) + task = await TaskRepository(_database(request).pool).get_by_upid(upid) + if task is None: + raise ApiError(404, "task does not exist") + return subdirs("log", "status") + + async def task_delete(request: Request, inputs: dict[str, Any]) -> None: + payload = _values(inputs) + upid = str(payload["upid"]) + repository = TaskRepository(_database(request).pool) + task = await repository.get_by_upid(upid) + if task is None: + raise ApiError(404, "task does not exist") + if task.status in {"success", "error", "cancelled"}: + return + await repository.request_cancel(task.id) + + registry.register("/nodes/{node}/qemu", "GET", qemu_list) + registry.register("/nodes/{node}/qemu", "POST", create) + registry.register("/nodes/{node}/qemu/{vmid}", "GET", qemu_index) + registry.register("/nodes/{node}/qemu/{vmid}", "DELETE", delete) + registry.register("/nodes/{node}/qemu/{vmid}/config", "GET", qemu_config) + registry.register("/nodes/{node}/qemu/{vmid}/config", "POST", update_async) + registry.register("/nodes/{node}/qemu/{vmid}/config", "PUT", update_sync) + registry.register("/nodes/{node}/qemu/{vmid}/status", "GET", qemu_status_index) + registry.register("/nodes/{node}/qemu/{vmid}/status/current", "GET", qemu_status_current) + registry.register("/nodes/{node}/qemu/{vmid}/status/start", "POST", start) + registry.register("/nodes/{node}/qemu/{vmid}/status/stop", "POST", stop) + registry.register("/nodes/{node}/qemu/{vmid}/status/shutdown", "POST", shutdown) + registry.register("/nodes/{node}/qemu/{vmid}/status/reboot", "POST", reboot) + registry.register("/nodes/{node}/qemu/{vmid}/status/reset", "POST", reset) + registry.register("/nodes/{node}/qemu/{vmid}/status/suspend", "POST", suspend) + registry.register("/nodes/{node}/qemu/{vmid}/status/resume", "POST", resume) + registry.register("/nodes/{node}/qemu/{vmid}/snapshot", "GET", snapshot_list) + registry.register("/nodes/{node}/qemu/{vmid}/snapshot", "POST", snapshot_create) + registry.register("/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", "GET", snapshot_get) + registry.register("/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", "DELETE", snapshot_delete) + registry.register( + "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", "GET", snapshot_config + ) + registry.register( + "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", "PUT", snapshot_update + ) + registry.register( + "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback", "POST", snapshot_rollback + ) + registry.register("/nodes/{node}/qemu/{vmid}/clone", "POST", clone) + registry.register("/nodes/{node}/qemu/{vmid}/migrate", "GET", migrate_preconditions) + registry.register("/nodes/{node}/qemu/{vmid}/migrate", "POST", migrate) + registry.register("/nodes/{node}/qemu/{vmid}/remote_migrate", "POST", remote_migrate) + registry.register("/nodes/{node}/qemu/{vmid}/resize", "PUT", resize) + registry.register("/nodes/{node}/qemu/{vmid}/move_disk", "POST", move_disk) + registry.register("/nodes/{node}/qemu/{vmid}/pending", "GET", pending) + registry.register("/nodes/{node}/qemu/{vmid}/agent/info", "GET", agent_info) + registry.register("/nodes/{node}/qemu/{vmid}/agent/get-osinfo", "GET", agent_osinfo) + registry.register("/nodes/{node}/qemu/{vmid}/agent/get-host-name", "GET", agent_hostname) + registry.register( + "/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces", "GET", agent_network + ) + registry.register("/nodes/{node}/qemu/{vmid}/agent/get-time", "GET", agent_time) + registry.register("/nodes/{node}/qemu/{vmid}/agent/ping", "POST", agent_ping) + registry.register("/nodes/{node}/qemu/{vmid}/feature", "GET", qemu_feature) + registry.register("/nodes/{node}/qemu/{vmid}/template", "POST", qemu_template) + registry.register("/nodes/{node}/tasks", "GET", task_list) + registry.register("/nodes/{node}/tasks/{upid}", "GET", task_index) + registry.register("/nodes/{node}/tasks/{upid}", "DELETE", task_delete) + registry.register("/nodes/{node}/tasks/{upid}/status", "GET", task_status) + registry.register("/nodes/{node}/tasks/{upid}/log", "GET", task_log) + from app.handlers.qemu_extra import register_qemu_extra_handlers + + register_qemu_extra_handlers(registry) + + +async def _create_task( + request: Request, + *, + node: str, + vmid: str, + task_type: str, + payload: dict[str, Any], +) -> str: + database = _database(request) + worker_type = { + "qemu-create": "qmcreate", + "qemu-delete": "qmdestroy", + "qemu-update": "qmconfig", + "qemu-snapshot-create": "qmsnapshot", + "qemu-snapshot-delete": "qmdelsnapshot", + "qemu-snapshot-rollback": "qmrollback", + "qemu-clone": "qmclone", + "qemu-migrate": "qmigrate", + "qemu-remote-migrate": "qmremote", + "qemu-move-disk": "qmmove", + }[task_type] + upid = str(Upid.allocate(node, worker_type, vmid, str(request.state.principal))) + try: + task = await TaskRepository(database.pool).create( + upid=upid, + task_type=task_type, + payload=payload, + resource_key=f"qemu:{vmid}", + idempotency_key=request.headers.get("Idempotency-Key"), + ) + except ConflictError as error: + raise ApiError(409, str(error)) from error + return task.upid + + +async def _qemu_resource(request: Request, node: str, vmid: str) -> Any: + row = await _database(request).pool.fetchrow( + """SELECT r.id, r.state, v.config FROM resources r + JOIN nodes n ON n.id=r.node_id + JOIN virtual_machines v ON v.resource_id=r.id + WHERE n.name=$1 AND r.kind='qemu' AND r.external_id=$2""", + node, + vmid, + ) + if row is None: + raise ApiError(404, "virtual machine does not exist") + return row + + +async def _snapshot(request: Request, values: dict[str, Any]) -> Any: + row = await _database(request).pool.fetchrow( + """SELECT s.* FROM snapshots s + JOIN resources r ON r.id=s.resource_id JOIN nodes n ON n.id=r.node_id + WHERE n.name=$1 AND r.kind='qemu' AND r.external_id=$2 AND s.name=$3""", + str(values["node"]), + str(values["vmid"]), + str(values["snapname"]), + ) + if row is None: + raise ApiError(404, "snapshot does not exist") + return row + + +async def _agent_resource(request: Request, values: dict[str, Any]) -> Any: + resource = await _qemu_resource(request, str(values["node"]), str(values["vmid"])) + config = _state(resource["config"]) + state = _state(resource["state"]) + if str(config.get("agent", "0")).split(",", 1)[0].lower() not in {"1", "true", "yes"}: + raise ApiError(409, "QEMU guest agent is not enabled") + if state.get("status") != "running": + raise ApiError(409, "QEMU guest agent is not running") + return resource + + +_SIZE_RE = re.compile(r"^(?P\d+)(?P[KMGT]?)$", re.IGNORECASE) + + +def _size_bytes(value: str) -> int: + match = _SIZE_RE.fullmatch(value.strip()) + if match is None: + raise ApiError(400, f"invalid disk size: {value}") + units = {"": 1, "K": 2**10, "M": 2**20, "G": 2**30, "T": 2**40} + return int(match.group("value")) * units[match.group("unit").upper()] + + +def _disk_size_bytes(value: str) -> int: + for part in value.split(","): + if part.startswith("size="): + return _size_bytes(part.removeprefix("size=")) + return 0 + + +def _resize_bytes(value: str, current: int) -> int: + if value.startswith("+"): + return current + _size_bytes(value[1:]) + result = _size_bytes(value) + if result < current: + raise ApiError(400, "shrinking disks is not supported") + return result + + +def _replace_disk_size(value: str, size: int) -> str: + parts = [part for part in value.split(",") if not part.startswith("size=")] + parts.append(f"size={size // 2**30}G" if size % 2**30 == 0 else f"size={size}") + return ",".join(parts) diff --git a/app/handlers/qemu_extra.py b/app/handlers/qemu_extra.py new file mode 100644 index 0000000..b622b88 --- /dev/null +++ b/app/handlers/qemu_extra.py @@ -0,0 +1,445 @@ +"""Additional QEMU guest/agent/console endpoints with durable guest state.""" + +from __future__ import annotations + +import json +import secrets +from collections.abc import Mapping +from typing import Any, cast + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.config import Settings +from app.handlers.qemu import _agent_resource, _database, _qemu_resource, _state, _values +from app.security.auth import issue_ticket + + +def _settings(request: Request) -> Settings: + return cast(Settings, request.app.state.settings) + + +async def _save_guest_state(request: Request, resource_id: Any, state: dict[str, Any]) -> None: + await _database(request).pool.execute( + "UPDATE resources SET state=$2::jsonb, version=version+1, updated_at=now() WHERE id=$1", + resource_id, + json.dumps(state, sort_keys=True), + ) + + +async def _save_guest_config(request: Request, resource_id: Any, config: dict[str, Any]) -> None: + await _database(request).pool.execute( + "UPDATE virtual_machines SET config=$2::jsonb WHERE resource_id=$1", + resource_id, + json.dumps(config, sort_keys=True), + ) + + +def register_qemu_extra_handlers(registry: HandlerRegistry) -> None: + async def agent_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + await _agent_resource(request, _values(inputs)) + return [ + {"name": name} + for name in ( + "exec", + "exec-status", + "file-read", + "file-write", + "fsfreeze-freeze", + "fsfreeze-status", + "fsfreeze-thaw", + "fstrim", + "get-fsinfo", + "get-memory-block-info", + "get-memory-blocks", + "get-timezone", + "get-users", + "get-vcpus", + "info", + "ping", + "set-user-password", + "shutdown", + "suspend-disk", + "suspend-hybrid", + "suspend-ram", + ) + ] + + async def agent_post(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = _values(inputs) + command = str(payload.get("command") or "ping") + resource = await _agent_resource(request, payload) + state = _state(resource["state"]) + agent = state.setdefault("agent", {}) + agent["last_command"] = command + await _save_guest_state(request, resource["id"], state) + return {"result": {"command": command, "ok": 1}} + + async def _agent_blob(command: str, request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + resource = await _agent_resource(request, _values(inputs)) + state = _state(resource["state"]) + agent = state.setdefault("agent", {}) + blobs = agent.setdefault("results", {}) + defaults: dict[str, Any] = { + "get-users": [{"user": "root", "login-time": 0}], + "get-fsinfo": [{"name": "/", "type": "ext4", "total-bytes": 32 * 1024**3}], + "get-memory-block-info": {"size": 1024**3}, + "get-memory-blocks": [{"start": 0, "size": 1024**3}], + "get-timezone": {"zone": "UTC", "offset": 0}, + "get-vcpus": [{"online": True, "can-offline": False}], + "fsfreeze-status": "thawed", + } + if command not in blobs: + blobs[command] = defaults.get(command, {}) + await _save_guest_state(request, resource["id"], state) + return {"result": blobs[command]} + + async def agent_users(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _agent_blob("get-users", request, inputs) + + async def agent_fsinfo(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _agent_blob("get-fsinfo", request, inputs) + + async def agent_memory_block_info(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _agent_blob("get-memory-block-info", request, inputs) + + async def agent_memory_blocks(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _agent_blob("get-memory-blocks", request, inputs) + + async def agent_timezone(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _agent_blob("get-timezone", request, inputs) + + async def agent_vcpus(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _agent_blob("get-vcpus", request, inputs) + + async def agent_exec(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = _values(inputs) + resource = await _agent_resource(request, payload) + state = _state(resource["state"]) + agent = state.setdefault("agent", {}) + execs = agent.setdefault("exec", {}) + pid = int(agent.get("next_pid", 1000)) + 1 + agent["next_pid"] = pid + execs[str(pid)] = { + "exited": 1, + "exitcode": 0, + "out-data": "", + "err-data": "", + "command": payload.get("command"), + } + await _save_guest_state(request, resource["id"], state) + return {"pid": pid} + + async def agent_exec_status(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = _values(inputs) + resource = await _agent_resource(request, payload) + pid = str(payload.get("pid") or "") + state = _state(resource["state"]) + result = state.get("agent", {}).get("exec", {}).get(pid) + if not isinstance(result, dict): + raise ApiError(404, "exec process does not exist") + return {"result": result} + + async def agent_file_read(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = _values(inputs) + resource = await _agent_resource(request, payload) + path = str(payload.get("file") or payload.get("path") or "/etc/hostname") + state = _state(resource["state"]) + files = state.setdefault("agent", {}).setdefault("files", {}) + if path not in files: + files[path] = f"simulated:{path}\n" + await _save_guest_state(request, resource["id"], state) + content = str(files[path]) + return {"result": {"content": content, "truncated": True}} + + async def agent_file_write(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = _values(inputs) + resource = await _agent_resource(request, payload) + default_path = "guest-agent-out" + path = str(payload.get("file") or payload.get("path") or default_path) + content = str(payload.get("content") or "") + state = _state(resource["state"]) + files = state.setdefault("agent", {}).setdefault("files", {}) + files[path] = content + await _save_guest_state(request, resource["id"], state) + return {"result": None} + + async def agent_fsfreeze( + request: Request, inputs: dict[str, Any], status: str + ) -> dict[str, Any]: + resource = await _agent_resource(request, _values(inputs)) + state = _state(resource["state"]) + agent = state.setdefault("agent", {}) + agent["fsfreeze"] = status + agent.setdefault("results", {})["fsfreeze-status"] = status + await _save_guest_state(request, resource["id"], state) + return {"result": status} + + async def agent_fsfreeze_freeze(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await agent_fsfreeze(request, inputs, "frozen") + + async def agent_fsfreeze_thaw(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await agent_fsfreeze(request, inputs, "thawed") + + async def agent_fsfreeze_status(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _agent_blob("fsfreeze-status", request, inputs) + + async def agent_fstrim(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + resource = await _agent_resource(request, _values(inputs)) + state = _state(resource["state"]) + state.setdefault("agent", {})["last_fstrim"] = True + await _save_guest_state(request, resource["id"], state) + return {"result": {"paths": [{"path": "/", "trimmed": 0}]}} + + async def agent_set_password(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = _values(inputs) + resource = await _agent_resource(request, payload) + username = str(payload.get("username") or "root") + state = _state(resource["state"]) + passwords = state.setdefault("agent", {}).setdefault("passwords", {}) + passwords[username] = True # store only presence, not secret + await _save_guest_state(request, resource["id"], state) + return {"result": None} + + async def agent_shutdown(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + resource = await _agent_resource(request, _values(inputs)) + state = _state(resource["state"]) + state["status"] = "stopped" + await _save_guest_state(request, resource["id"], state) + return {"result": None} + + async def agent_suspend(request: Request, inputs: dict[str, Any], mode: str) -> dict[str, Any]: + resource = await _agent_resource(request, _values(inputs)) + state = _state(resource["state"]) + state["status"] = "paused" + state.setdefault("agent", {})["suspend"] = mode + await _save_guest_state(request, resource["id"], state) + return {"result": None} + + async def agent_suspend_disk(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await agent_suspend(request, inputs, "disk") + + async def agent_suspend_ram(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await agent_suspend(request, inputs, "ram") + + async def agent_suspend_hybrid(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await agent_suspend(request, inputs, "hybrid") + + async def cloudinit_get(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + values = _values(inputs) + resource = await _qemu_resource(request, str(values["node"]), str(values["vmid"])) + config = _state(resource["config"]) + state = _state(resource["state"]) + pending = cast(Mapping[str, Any], state.get("pending", {})) + keys = sorted( + { + key + for key in set(config) | set(pending) + if str(key).startswith(("ci", "ipconfig", "sshkeys", "nameserver", "searchdomain")) + } + ) + return [ + { + "key": key, + "value": str(config.get(key, "")), + "pending": str(pending[key]) if key in pending else None, + } + for key in keys + ] + + async def cloudinit_update(request: Request, inputs: dict[str, Any]) -> None: + values = _values(inputs) + resource = await _qemu_resource(request, str(values["node"]), str(values["vmid"])) + state = _state(resource["state"]) + state["cloudinit_generation"] = int(state.get("cloudinit_generation") or 0) + 1 + await _save_guest_state(request, resource["id"], state) + + async def cloudinit_dump(request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + resource = await _qemu_resource(request, str(values["node"]), str(values["vmid"])) + config = _state(resource["config"]) + return ( + f"#cloud-config\nhostname: {config.get('name', values['vmid'])}\n" + f"manage_etc_hosts: true\n" + ) + + async def rrd(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + values = _values(inputs) + resource = await _qemu_resource(request, str(values["node"]), str(values["vmid"])) + state = _state(resource["state"]) + rrd_state = state.setdefault("rrd", {"filename": f"pve-vm-{values['vmid']}.rrd"}) + await _save_guest_state(request, resource["id"], state) + return dict(rrd_state) + + async def rrddata(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + values = _values(inputs) + resource = await _qemu_resource(request, str(values["node"]), str(values["vmid"])) + state = _state(resource["state"]) + series = state.setdefault( + "rrddata", + [ + { + "time": 1_700_000_000, + "cpu": 0.05, + "mem": 256 * 1024 * 1024, + "netin": 0, + "netout": 0, + }, + { + "time": 1_700_000_060, + "cpu": 0.08, + "mem": 260 * 1024 * 1024, + "netin": 100, + "netout": 80, + }, + ], + ) + await _save_guest_state(request, resource["id"], state) + return list(series) + + async def monitor(request: Request, inputs: dict[str, Any]) -> str: + values = _values(inputs) + resource = await _qemu_resource(request, str(values["node"]), str(values["vmid"])) + command = str(values.get("command") or "info status") + state = _state(resource["state"]) + history = state.setdefault("monitor", []) + if not isinstance(history, list): + history = state["monitor"] = [] + output = f"OK {command}" + history.append({"command": command, "output": output}) + await _save_guest_state(request, resource["id"], state) + return output + + async def sendkey(request: Request, inputs: dict[str, Any]) -> None: + values = _values(inputs) + resource = await _qemu_resource(request, str(values["node"]), str(values["vmid"])) + key = str(values.get("key") or "") + if not key: + raise ApiError(400, "parameter verification failed - 'key' missing") + state = _state(resource["state"]) + keys = state.setdefault("sendkey", []) + if not isinstance(keys, list): + keys = state["sendkey"] = [] + keys.append(key) + await _save_guest_state(request, resource["id"], state) + + async def unlink(request: Request, inputs: dict[str, Any]) -> None: + values = _values(inputs) + resource = await _qemu_resource(request, str(values["node"]), str(values["vmid"])) + idlist = [ + item.strip() + for item in str(values.get("idlist") or values.get("ids") or "").split(",") + if item.strip() + ] + if not idlist: + raise ApiError(400, "parameter verification failed - 'idlist' missing") + config = _state(resource["config"]) + for disk in idlist: + config.pop(disk, None) + await _save_guest_config(request, resource["id"], config) + state = _state(resource["state"]) + state["config"] = config + await _save_guest_state(request, resource["id"], state) + + async def _console_proxy(request: Request, inputs: dict[str, Any], kind: str) -> dict[str, Any]: + values = _values(inputs) + resource = await _qemu_resource(request, str(values["node"]), str(values["vmid"])) + key = _settings(request).ticket_signing_key.get_secret_value().encode() + ticket = issue_ticket(str(request.state.principal), key) + port = 5900 + int(values["vmid"]) % 1000 + state = _state(resource["state"]) + consoles = state.setdefault("consoles", {}) + payload = { + "type": kind, + "port": port, + "ticket": ticket, + "upid": ( + f"UPID:{values['node']}:{secrets.token_hex(4)}:" + f"{kind}:{values['vmid']}:{request.state.principal}:" + ), + "user": str(request.state.principal), + "cert": "", + } + if values.get("generate-password") or values.get("websocket"): + payload["password"] = secrets.token_urlsafe(8) + consoles[kind] = {k: v for k, v in payload.items() if k != "ticket"} + await _save_guest_state(request, resource["id"], state) + return payload + + async def vncproxy(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _console_proxy(request, inputs, "vnc") + + async def spiceproxy(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _console_proxy(request, inputs, "spice") + + async def termproxy(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _console_proxy(request, inputs, "term") + + async def mtunnel(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await _console_proxy(request, inputs, "mtunnel") + + async def websocket_ticket( + request: Request, inputs: dict[str, Any], kind: str + ) -> dict[str, Any]: + values = _values(inputs) + resource = await _qemu_resource(request, str(values["node"]), str(values["vmid"])) + state = _state(resource["state"]) + console = state.get("consoles", {}).get(kind) or {"port": 5900} + key = _settings(request).ticket_signing_key.get_secret_value().encode() + return { + "port": console.get("port", 5900), + "ticket": issue_ticket(str(request.state.principal), key), + } + + async def vncwebsocket(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await websocket_ticket(request, inputs, "vnc") + + async def mtunnelwebsocket(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + return await websocket_ticket(request, inputs, "mtunnel") + + async def dbus_vmstate(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + values = _values(inputs) + resource = await _qemu_resource(request, str(values["node"]), str(values["vmid"])) + state = _state(resource["state"]) + state["dbus_vmstate"] = True + await _save_guest_state(request, resource["id"], state) + return {"result": "OK"} + + base = "/nodes/{node}/qemu/{vmid}" + registry.register(f"{base}/agent", "GET", agent_index) + registry.register(f"{base}/agent", "POST", agent_post) + registry.register(f"{base}/agent/exec", "POST", agent_exec) + registry.register(f"{base}/agent/exec-status", "GET", agent_exec_status) + registry.register(f"{base}/agent/file-read", "GET", agent_file_read) + registry.register(f"{base}/agent/file-write", "POST", agent_file_write) + registry.register(f"{base}/agent/fsfreeze-freeze", "POST", agent_fsfreeze_freeze) + registry.register(f"{base}/agent/fsfreeze-status", "POST", agent_fsfreeze_status) + registry.register(f"{base}/agent/fsfreeze-thaw", "POST", agent_fsfreeze_thaw) + registry.register(f"{base}/agent/fstrim", "POST", agent_fstrim) + registry.register(f"{base}/agent/get-fsinfo", "GET", agent_fsinfo) + registry.register(f"{base}/agent/get-memory-block-info", "GET", agent_memory_block_info) + registry.register(f"{base}/agent/get-memory-blocks", "GET", agent_memory_blocks) + registry.register(f"{base}/agent/get-timezone", "GET", agent_timezone) + registry.register(f"{base}/agent/get-users", "GET", agent_users) + registry.register(f"{base}/agent/get-vcpus", "GET", agent_vcpus) + registry.register(f"{base}/agent/set-user-password", "POST", agent_set_password) + registry.register(f"{base}/agent/shutdown", "POST", agent_shutdown) + registry.register(f"{base}/agent/suspend-disk", "POST", agent_suspend_disk) + registry.register(f"{base}/agent/suspend-hybrid", "POST", agent_suspend_hybrid) + registry.register(f"{base}/agent/suspend-ram", "POST", agent_suspend_ram) + registry.register(f"{base}/cloudinit", "GET", cloudinit_get) + registry.register(f"{base}/cloudinit", "PUT", cloudinit_update) + registry.register(f"{base}/cloudinit/dump", "GET", cloudinit_dump) + registry.register(f"{base}/rrd", "GET", rrd) + registry.register(f"{base}/rrddata", "GET", rrddata) + registry.register(f"{base}/monitor", "POST", monitor) + registry.register(f"{base}/sendkey", "PUT", sendkey) + registry.register(f"{base}/unlink", "PUT", unlink) + registry.register(f"{base}/vncproxy", "POST", vncproxy) + registry.register(f"{base}/spiceproxy", "POST", spiceproxy) + registry.register(f"{base}/termproxy", "POST", termproxy) + registry.register(f"{base}/mtunnel", "POST", mtunnel) + registry.register(f"{base}/vncwebsocket", "GET", vncwebsocket) + registry.register(f"{base}/mtunnelwebsocket", "GET", mtunnelwebsocket) + registry.register(f"{base}/dbus-vmstate", "POST", dbus_vmstate) diff --git a/app/handlers/sdn.py b/app/handlers/sdn.py new file mode 100644 index 0000000..844eecc --- /dev/null +++ b/app/handlers/sdn.py @@ -0,0 +1,1027 @@ +"""Cluster and node SDN handlers backed by clusters.metadata.sdn.""" + +from __future__ import annotations + +import secrets +from typing import Any + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.common import ( + cluster_metadata, + require_node, + save_cluster_metadata, + subdirs, + values, +) + +_SECRET_KEYS = frozenset({"key", "token", "fingerprint"}) + + +def _sdn(metadata: dict[str, Any]) -> dict[str, Any]: + current = metadata.setdefault( + "sdn", + { + "zones": {}, + "vnets": {}, + "controllers": {}, + "dns": {}, + "ipams": {}, + "fabrics": {}, + "fabric_nodes": {}, + "prefix_lists": {}, + "route_maps": {}, + "lock": None, + "pending": False, + "running_version": 1, + }, + ) + if not isinstance(current, dict): + current = { + "zones": {}, + "vnets": {}, + "controllers": {}, + "dns": {}, + "ipams": {}, + "fabrics": {}, + "fabric_nodes": {}, + "prefix_lists": {}, + "route_maps": {}, + "lock": None, + "pending": False, + "running_version": 1, + } + metadata["sdn"] = current + for key in ( + "zones", + "vnets", + "controllers", + "dns", + "ipams", + "fabrics", + "fabric_nodes", + "prefix_lists", + "route_maps", + ): + current.setdefault(key, {}) + return current + + +def _public(item: dict[str, Any]) -> dict[str, Any]: + return {key: value for key, value in item.items() if key not in _SECRET_KEYS} + + +def _store_list(store: dict[str, Any], *, id_key: str) -> list[dict[str, Any]]: + return [_public({id_key: name, **item}) for name, item in sorted(store.items())] + + +async def _load(request: Request) -> tuple[dict[str, Any], dict[str, Any]]: + metadata = await cluster_metadata(request) + return metadata, _sdn(metadata) + + +def register_sdn_handlers(registry: HandlerRegistry) -> None: + async def index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs( + "controllers", + "dns", + "dry-run", + "fabrics", + "ipams", + "lock", + "prefix-lists", + "rollback", + "route-maps", + "vnets", + "zones", + ) + + async def apply(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + metadata, sdn = await _load(request) + lock = sdn.get("lock") + token = payload.get("lock-token") + if lock and token and lock.get("token") != token: + raise ApiError(400, "invalid SDN lock token") + sdn["pending"] = False + sdn["running_version"] = int(sdn.get("running_version") or 1) + 1 + if payload.get("release-lock"): + sdn["lock"] = None + await save_cluster_metadata(request, metadata) + + async def lock_create(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + metadata, sdn = await _load(request) + if sdn.get("lock") and not values(inputs).get("allow-pending"): + raise ApiError(400, "SDN is already locked") + token = secrets.token_hex(8) + sdn["lock"] = {"token": token} + await save_cluster_metadata(request, metadata) + return {"digest": token, "token": token} + + async def lock_delete(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + metadata, sdn = await _load(request) + lock = sdn.get("lock") + if lock is None: + return None + if not payload.get("force") and lock.get("token") != payload.get("lock-token"): + raise ApiError(400, "invalid SDN lock token") + sdn["lock"] = None + await save_cluster_metadata(request, metadata) + + async def rollback(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + metadata, sdn = await _load(request) + sdn["pending"] = False + if payload.get("release-lock"): + sdn["lock"] = None + await save_cluster_metadata(request, metadata) + + async def dry_run(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + _metadata, sdn = await _load(request) + return [ + {"type": "zone", "name": name, "action": "noop"} + for name in sorted(sdn.get("zones") or {}) + ] + + def register_named( + path: str, + store_key: str, + id_param: str, + *, + create_required: str | None = None, + ) -> None: + async def list_items(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + _metadata, sdn = await _load(request) + items = _store_list(sdn.get(store_key) or {}, id_key=id_param) + type_filter = values(inputs).get("type") + if type_filter: + items = [item for item in items if item.get("type") == type_filter] + return items + + async def create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + item_id = str(payload[create_required or id_param]) + metadata, sdn = await _load(request) + store = sdn.setdefault(store_key, {}) + if item_id in store: + raise ApiError(400, f"{store_key} '{item_id}' already exists") + store[item_id] = { + key: value + for key, value in payload.items() + if key not in {"lock-token", "digest", "delete"} + } + store[item_id][id_param] = item_id + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + item_id = str(values(inputs)[id_param]) + _metadata, sdn = await _load(request) + item = (sdn.get(store_key) or {}).get(item_id) + if not isinstance(item, dict): + raise ApiError(404, f"{store_key} entry does not exist") + return _public({id_param: item_id, **item}) + + async def update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + item_id = str(payload[id_param]) + metadata, sdn = await _load(request) + store = sdn.setdefault(store_key, {}) + if item_id not in store: + raise ApiError(404, f"{store_key} entry does not exist") + current = dict(store[item_id]) + for key in [ + item.strip() for item in str(payload.get("delete") or "").split(",") if item.strip() + ]: + current.pop(key, None) + for key, value in payload.items(): + if key in {id_param, "delete", "digest", "lock-token"}: + continue + current[key] = value + current[id_param] = item_id + store[item_id] = current + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def delete(request: Request, inputs: dict[str, Any]) -> None: + item_id = str(values(inputs)[id_param]) + metadata, sdn = await _load(request) + store = sdn.setdefault(store_key, {}) + if item_id not in store: + raise ApiError(404, f"{store_key} entry does not exist") + del store[item_id] + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + registry.register(path, "GET", list_items) + registry.register(path, "POST", create) + registry.register(f"{path}/{{{id_param}}}", "GET", get) + registry.register(f"{path}/{{{id_param}}}", "PUT", update) + registry.register(f"{path}/{{{id_param}}}", "DELETE", delete) + + # zones / controllers / dns / ipams + register_named("/cluster/sdn/zones", "zones", "zone") + register_named("/cluster/sdn/controllers", "controllers", "controller") + register_named("/cluster/sdn/dns", "dns", "dns") + register_named("/cluster/sdn/ipams", "ipams", "ipam") + + async def ipam_status(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + ipam = str(values(inputs)["ipam"]) + _metadata, sdn = await _load(request) + if ipam not in (sdn.get("ipams") or {}): + raise ApiError(404, "ipam does not exist") + return {"status": "ok", "ipam": ipam} + + # vnets + nested + async def vnets_list(request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + _metadata, sdn = await _load(request) + return _store_list(sdn.get("vnets") or {}, id_key="vnet") + + async def vnets_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + vnet = str(payload["vnet"]) + metadata, sdn = await _load(request) + store = sdn.setdefault("vnets", {}) + if vnet in store: + raise ApiError(400, f"vnet '{vnet}' already exists") + store[vnet] = { + **{k: v for k, v in payload.items() if k not in {"lock-token", "digest"}}, + "vnet": vnet, + "subnets": {}, + "ips": [], + "firewall": {"options": {"enable": 0}, "rules": []}, + } + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def vnet_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + vnet = str(values(inputs)["vnet"]) + _metadata, sdn = await _load(request) + item = (sdn.get("vnets") or {}).get(vnet) + if not isinstance(item, dict): + raise ApiError(404, "vnet does not exist") + return _public({"vnet": vnet, **{k: v for k, v in item.items() if k != "firewall"}}) + + async def vnet_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + vnet = str(payload["vnet"]) + metadata, sdn = await _load(request) + store = sdn.setdefault("vnets", {}) + if vnet not in store: + raise ApiError(404, "vnet does not exist") + current = dict(store[vnet]) + for key in [ + item.strip() for item in str(payload.get("delete") or "").split(",") if item.strip() + ]: + current.pop(key, None) + for key, value in payload.items(): + if key in {"vnet", "delete", "digest", "lock-token"}: + continue + current[key] = value + current["vnet"] = vnet + store[vnet] = current + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def vnet_delete(request: Request, inputs: dict[str, Any]) -> None: + vnet = str(values(inputs)["vnet"]) + metadata, sdn = await _load(request) + store = sdn.setdefault("vnets", {}) + if vnet not in store: + raise ApiError(404, "vnet does not exist") + del store[vnet] + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def _vnet(sdn: dict[str, Any], vnet: str) -> dict[str, Any]: + item = (sdn.get("vnets") or {}).get(vnet) + if not isinstance(item, dict): + raise ApiError(404, "vnet does not exist") + item.setdefault("subnets", {}) + item.setdefault("ips", []) + item.setdefault("firewall", {"options": {"enable": 0}, "rules": []}) + return item + + async def subnets_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + vnet = str(values(inputs)["vnet"]) + _metadata, sdn = await _load(request) + item = await _vnet(sdn, vnet) + return _store_list(item.get("subnets") or {}, id_key="subnet") + + async def subnets_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + vnet = str(payload["vnet"]) + subnet = str(payload["subnet"]) + metadata, sdn = await _load(request) + item = await _vnet(sdn, vnet) + subnets = item.setdefault("subnets", {}) + if subnet in subnets: + raise ApiError(400, f"subnet '{subnet}' already exists") + subnets[subnet] = { + **{k: v for k, v in payload.items() if k not in {"lock-token", "digest"}}, + "subnet": subnet, + } + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def subnet_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + vnet = str(payload["vnet"]) + subnet = str(payload["subnet"]) + _metadata, sdn = await _load(request) + item = await _vnet(sdn, vnet) + data = (item.get("subnets") or {}).get(subnet) + if not isinstance(data, dict): + raise ApiError(404, "subnet does not exist") + return _public({"subnet": subnet, **data}) + + async def subnet_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + vnet = str(payload["vnet"]) + subnet = str(payload["subnet"]) + metadata, sdn = await _load(request) + item = await _vnet(sdn, vnet) + subnets = item.setdefault("subnets", {}) + if subnet not in subnets: + raise ApiError(404, "subnet does not exist") + current = dict(subnets[subnet]) + for key in [ + item.strip() for item in str(payload.get("delete") or "").split(",") if item.strip() + ]: + current.pop(key, None) + for key, value in payload.items(): + if key in {"vnet", "subnet", "delete", "digest", "lock-token"}: + continue + current[key] = value + current["subnet"] = subnet + subnets[subnet] = current + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def subnet_delete(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + vnet = str(payload["vnet"]) + subnet = str(payload["subnet"]) + metadata, sdn = await _load(request) + item = await _vnet(sdn, vnet) + subnets = item.setdefault("subnets", {}) + if subnet not in subnets: + raise ApiError(404, "subnet does not exist") + del subnets[subnet] + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def ips_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + vnet = str(payload["vnet"]) + metadata, sdn = await _load(request) + item = await _vnet(sdn, vnet) + ips = item.setdefault("ips", []) + if not isinstance(ips, list): + ips = item["ips"] = [] + ips.append( + { + "ip": payload.get("ip"), + "mac": payload.get("mac"), + "zone": payload.get("zone"), + "vmid": payload.get("vmid"), + } + ) + await save_cluster_metadata(request, metadata) + + async def ips_update(request: Request, inputs: dict[str, Any]) -> None: + await ips_create(request, inputs) + + async def ips_delete(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + vnet = str(payload["vnet"]) + metadata, sdn = await _load(request) + item = await _vnet(sdn, vnet) + ips = item.setdefault("ips", []) + if not isinstance(ips, list): + return None + item["ips"] = [ + entry + for entry in ips + if not (entry.get("ip") == payload.get("ip") and entry.get("mac") == payload.get("mac")) + ] + await save_cluster_metadata(request, metadata) + + async def fw_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + await _vnet((await _load(request))[1], str(values(inputs)["vnet"])) + return subdirs("options", "rules") + + async def fw_options_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + vnet = str(values(inputs)["vnet"]) + _metadata, sdn = await _load(request) + item = await _vnet(sdn, vnet) + return dict(item.get("firewall", {}).get("options") or {"enable": 0}) + + async def fw_options_put(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + vnet = str(payload["vnet"]) + metadata, sdn = await _load(request) + item = await _vnet(sdn, vnet) + options = dict(item.setdefault("firewall", {}).setdefault("options", {"enable": 0})) + for key, value in payload.items(): + if key in {"vnet", "delete", "digest"}: + continue + options[key] = value + item["firewall"]["options"] = options + await save_cluster_metadata(request, metadata) + + async def fw_rules_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + vnet = str(values(inputs)["vnet"]) + _metadata, sdn = await _load(request) + item = await _vnet(sdn, vnet) + rules = item.get("firewall", {}).get("rules") or [] + return list(rules) if isinstance(rules, list) else [] + + async def fw_rules_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + vnet = str(payload["vnet"]) + metadata, sdn = await _load(request) + item = await _vnet(sdn, vnet) + rules = item.setdefault("firewall", {}).setdefault("rules", []) + if not isinstance(rules, list): + rules = item["firewall"]["rules"] = [] + rule = {k: v for k, v in payload.items() if k not in {"vnet", "pos", "digest"}} + rule["pos"] = len(rules) + rules.append(rule) + await save_cluster_metadata(request, metadata) + + async def fw_rule_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + rules = await fw_rules_list(request, inputs) + pos = int(values(inputs)["pos"]) + if pos < 0 or pos >= len(rules): + raise ApiError(404, "firewall rule does not exist") + return dict(rules[pos]) + + async def fw_rule_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + vnet = str(payload["vnet"]) + pos = int(payload["pos"]) + metadata, sdn = await _load(request) + item = await _vnet(sdn, vnet) + rules = item.setdefault("firewall", {}).setdefault("rules", []) + if not isinstance(rules, list) or pos < 0 or pos >= len(rules): + raise ApiError(404, "firewall rule does not exist") + rules[pos] = { + **rules[pos], + **{k: v for k, v in payload.items() if k not in {"vnet", "pos"}}, + } + await save_cluster_metadata(request, metadata) + + async def fw_rule_delete(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + vnet = str(payload["vnet"]) + pos = int(payload["pos"]) + metadata, sdn = await _load(request) + item = await _vnet(sdn, vnet) + rules = item.setdefault("firewall", {}).setdefault("rules", []) + if not isinstance(rules, list) or pos < 0 or pos >= len(rules): + raise ApiError(404, "firewall rule does not exist") + del rules[pos] + await save_cluster_metadata(request, metadata) + + # fabrics + async def fabrics_index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs("all", "fabric", "node") + + async def fabrics_all(request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + _metadata, sdn = await _load(request) + return _store_list(sdn.get("fabrics") or {}, id_key="id") + + async def fabric_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + return await fabrics_all(request, inputs) + + async def fabric_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + fabric_id = str(payload["id"]) + metadata, sdn = await _load(request) + store = sdn.setdefault("fabrics", {}) + if fabric_id in store: + raise ApiError(400, f"fabric '{fabric_id}' already exists") + store[fabric_id] = { + **{k: v for k, v in payload.items() if k not in {"lock-token", "digest"}}, + "id": fabric_id, + } + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def fabric_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + fabric_id = str(values(inputs)["id"]) + _metadata, sdn = await _load(request) + item = (sdn.get("fabrics") or {}).get(fabric_id) + if not isinstance(item, dict): + raise ApiError(404, "fabric does not exist") + return _public({"id": fabric_id, **item}) + + async def fabric_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + fabric_id = str(payload["id"]) + metadata, sdn = await _load(request) + store = sdn.setdefault("fabrics", {}) + if fabric_id not in store: + raise ApiError(404, "fabric does not exist") + current = dict(store[fabric_id]) + for key in [ + item.strip() for item in str(payload.get("delete") or "").split(",") if item.strip() + ]: + current.pop(key, None) + for key, value in payload.items(): + if key in {"id", "delete", "digest", "lock-token"}: + continue + current[key] = value + current["id"] = fabric_id + store[fabric_id] = current + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def fabric_delete(request: Request, inputs: dict[str, Any]) -> None: + fabric_id = str(values(inputs)["id"]) + metadata, sdn = await _load(request) + store = sdn.setdefault("fabrics", {}) + if fabric_id not in store: + raise ApiError(404, "fabric does not exist") + del store[fabric_id] + nodes = sdn.setdefault("fabric_nodes", {}) + nodes.pop(fabric_id, None) + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def fabric_nodes_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + _metadata, sdn = await _load(request) + fabric_id = values(inputs).get("fabric_id") + nodes = sdn.get("fabric_nodes") or {} + result: list[dict[str, Any]] = [] + for fid, store in sorted(nodes.items()): + if fabric_id and fid != fabric_id: + continue + if not isinstance(store, dict): + continue + for node_id, item in sorted(store.items()): + result.append(_public({"fabric_id": fid, "node_id": node_id, **item})) + return result + + async def fabric_node_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + fabric_id = str(payload["fabric_id"]) + node_id = str(payload["node_id"]) + metadata, sdn = await _load(request) + if fabric_id not in (sdn.get("fabrics") or {}): + raise ApiError(404, "fabric does not exist") + store = sdn.setdefault("fabric_nodes", {}).setdefault(fabric_id, {}) + if node_id in store: + raise ApiError(400, f"fabric node '{node_id}' already exists") + store[node_id] = { + **{k: v for k, v in payload.items() if k not in {"lock-token", "digest"}}, + "node_id": node_id, + } + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def fabric_node_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + fabric_id = str(payload["fabric_id"]) + node_id = str(payload["node_id"]) + _metadata, sdn = await _load(request) + item = ((sdn.get("fabric_nodes") or {}).get(fabric_id) or {}).get(node_id) + if not isinstance(item, dict): + raise ApiError(404, "fabric node does not exist") + return _public({"fabric_id": fabric_id, "node_id": node_id, **item}) + + async def fabric_node_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + fabric_id = str(payload["fabric_id"]) + node_id = str(payload["node_id"]) + metadata, sdn = await _load(request) + store = sdn.setdefault("fabric_nodes", {}).setdefault(fabric_id, {}) + if node_id not in store: + raise ApiError(404, "fabric node does not exist") + current = dict(store[node_id]) + for key in [ + item.strip() for item in str(payload.get("delete") or "").split(",") if item.strip() + ]: + current.pop(key, None) + for key, value in payload.items(): + if key in {"fabric_id", "node_id", "delete", "digest", "lock-token"}: + continue + current[key] = value + current["node_id"] = node_id + store[node_id] = current + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def fabric_node_delete(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + fabric_id = str(payload["fabric_id"]) + node_id = str(payload["node_id"]) + metadata, sdn = await _load(request) + store = sdn.setdefault("fabric_nodes", {}).setdefault(fabric_id, {}) + if node_id not in store: + raise ApiError(404, "fabric node does not exist") + del store[node_id] + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + # prefix lists + async def prefix_list(request: Request, _inputs: dict[str, Any]) -> list[dict[str, Any]]: + _metadata, sdn = await _load(request) + return _store_list(sdn.get("prefix_lists") or {}, id_key="id") + + async def prefix_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + list_id = str(payload["id"]) + metadata, sdn = await _load(request) + store = sdn.setdefault("prefix_lists", {}) + if list_id in store: + raise ApiError(400, f"prefix-list '{list_id}' already exists") + store[list_id] = { + "id": list_id, + "entries": payload.get("entries") if isinstance(payload.get("entries"), dict) else {}, + "digest": payload.get("digest"), + } + if isinstance(payload.get("entries"), list): + store[list_id]["entries"] = { + str(index): entry for index, entry in enumerate(payload["entries"]) + } + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def prefix_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + list_id = str(values(inputs)["id"]) + _metadata, sdn = await _load(request) + item = (sdn.get("prefix_lists") or {}).get(list_id) + if not isinstance(item, dict): + raise ApiError(404, "prefix-list does not exist") + return {"id": list_id, **item} + + async def prefix_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + list_id = str(payload["id"]) + metadata, sdn = await _load(request) + store = sdn.setdefault("prefix_lists", {}) + if list_id not in store: + raise ApiError(404, "prefix-list does not exist") + current = dict(store[list_id]) + if "entries" in payload: + current["entries"] = payload["entries"] + store[list_id] = current + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def prefix_delete(request: Request, inputs: dict[str, Any]) -> None: + list_id = str(values(inputs)["id"]) + metadata, sdn = await _load(request) + store = sdn.setdefault("prefix_lists", {}) + if list_id not in store: + raise ApiError(404, "prefix-list does not exist") + del store[list_id] + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def prefix_entries(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + list_id = str(values(inputs)["id"]) + _metadata, sdn = await _load(request) + item = (sdn.get("prefix_lists") or {}).get(list_id) + if not isinstance(item, dict): + raise ApiError(404, "prefix-list does not exist") + entries = item.get("entries") or {} + if isinstance(entries, dict): + return [{"seq": key, **value} for key, value in sorted(entries.items())] + return list(entries) if isinstance(entries, list) else [] + + async def prefix_entry_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + list_id = str(payload["id"]) + seq = str(payload.get("seq") or secrets.randbelow(10000)) + metadata, sdn = await _load(request) + item = (sdn.get("prefix_lists") or {}).get(list_id) + if not isinstance(item, dict): + raise ApiError(404, "prefix-list does not exist") + entries = item.setdefault("entries", {}) + if not isinstance(entries, dict): + entries = item["entries"] = {} + entries[seq] = { + "seq": seq, + "action": payload.get("action"), + "prefix": payload.get("prefix"), + "ge": payload.get("ge"), + "le": payload.get("le"), + } + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def prefix_entry_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + list_id = str(payload["id"]) + seq = str(payload["url_seq"]) + _metadata, sdn = await _load(request) + item = (sdn.get("prefix_lists") or {}).get(list_id) + if not isinstance(item, dict): + raise ApiError(404, "prefix-list does not exist") + entry = (item.get("entries") or {}).get(seq) + if not isinstance(entry, dict): + raise ApiError(404, "prefix-list entry does not exist") + return {"seq": seq, **entry} + + async def prefix_entry_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + list_id = str(payload["id"]) + seq = str(payload["url_seq"]) + metadata, sdn = await _load(request) + item = (sdn.get("prefix_lists") or {}).get(list_id) + if not isinstance(item, dict): + raise ApiError(404, "prefix-list does not exist") + entries = item.setdefault("entries", {}) + if seq not in entries: + raise ApiError(404, "prefix-list entry does not exist") + current = dict(entries[seq]) + for key in ("action", "prefix", "ge", "le", "seq"): + if key in payload: + current[key] = payload[key] + entries[seq] = current + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def prefix_entry_delete(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + list_id = str(payload["id"]) + seq = str(payload["url_seq"]) + metadata, sdn = await _load(request) + item = (sdn.get("prefix_lists") or {}).get(list_id) + if not isinstance(item, dict): + raise ApiError(404, "prefix-list does not exist") + entries = item.setdefault("entries", {}) + if seq not in entries: + raise ApiError(404, "prefix-list entry does not exist") + del entries[seq] + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + # route maps + async def route_maps_index(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + return subdirs("entries") + + async def route_entries_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + _metadata, sdn = await _load(request) + maps = sdn.get("route_maps") or {} + route_map_id = values(inputs).get("route-map-id") + result: list[dict[str, Any]] = [] + for map_id, entries in sorted(maps.items()): + if route_map_id and map_id != route_map_id: + continue + if not isinstance(entries, dict): + continue + for order, entry in sorted(entries.items(), key=lambda pair: int(pair[0])): + result.append({"route-map-id": map_id, "order": int(order), **entry}) + return result + + async def route_entry_create(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + map_id = str(payload["route-map-id"]) + order = str(payload.get("order") or 10) + metadata, sdn = await _load(request) + entries = sdn.setdefault("route_maps", {}).setdefault(map_id, {}) + if order in entries: + raise ApiError(400, f"route-map entry '{order}' already exists") + entries[order] = { + k: v for k, v in payload.items() if k not in {"lock-token", "digest", "route-map-id"} + } + entries[order]["order"] = int(order) + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def route_map_entries(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + return await route_entries_list( + request, + { + "values": {"route-map-id": values(inputs)["route-map-id"]}, + "provided": frozenset(), + }, + ) + + async def route_entry_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + map_id = str(payload["route-map-id"]) + order = str(payload["order"]) + _metadata, sdn = await _load(request) + entry = ((sdn.get("route_maps") or {}).get(map_id) or {}).get(order) + if not isinstance(entry, dict): + raise ApiError(404, "route-map entry does not exist") + return {"route-map-id": map_id, "order": int(order), **entry} + + async def route_entry_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + map_id = str(payload["route-map-id"]) + order = str(payload["order"]) + metadata, sdn = await _load(request) + entries = sdn.setdefault("route_maps", {}).setdefault(map_id, {}) + if order not in entries: + raise ApiError(404, "route-map entry does not exist") + current = dict(entries[order]) + for key, value in payload.items(): + if key in {"route-map-id", "order", "delete", "digest", "lock-token"}: + continue + current[key] = value + current["order"] = int(order) + entries[order] = current + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + async def route_entry_delete(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + map_id = str(payload["route-map-id"]) + order = str(payload["order"]) + metadata, sdn = await _load(request) + entries = sdn.setdefault("route_maps", {}).setdefault(map_id, {}) + if order not in entries: + raise ApiError(404, "route-map entry does not exist") + del entries[order] + sdn["pending"] = True + await save_cluster_metadata(request, metadata) + + # node sdn surfaces + async def node_sdn_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + await require_node(request, str(values(inputs)["node"])) + return subdirs("fabrics", "vnets", "zones") + + async def node_zones(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + await require_node(request, str(values(inputs)["node"])) + _metadata, sdn = await _load(request) + return _store_list(sdn.get("zones") or {}, id_key="zone") + + async def node_zone(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + await require_node(request, str(values(inputs)["node"])) + zone = str(values(inputs)["zone"]) + _metadata, sdn = await _load(request) + item = (sdn.get("zones") or {}).get(zone) + if not isinstance(item, dict): + raise ApiError(404, "zone does not exist") + return _public({"zone": zone, **item}) + + async def node_zone_bridges(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + zone = await node_zone(request, inputs) + bridge = zone.get("bridge") or f"vmbr-{zone.get('zone')}" + return [{"iface": bridge, "active": 1}] + + async def node_zone_content(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + await require_node(request, str(values(inputs)["node"])) + zone = str(values(inputs)["zone"]) + _metadata, sdn = await _load(request) + return [ + {"vnet": name, **item} + for name, item in sorted((sdn.get("vnets") or {}).items()) + if item.get("zone") == zone + ] + + async def node_zone_ip_vrf(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + zone = await node_zone(request, inputs) + return {"zone": zone.get("zone"), "vrf": f"vrf-{zone.get('zone')}", "table": 100} + + async def node_vnet(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + await require_node(request, str(values(inputs)["node"])) + return await vnet_get(request, inputs) + + async def node_vnet_mac_vrf(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + vnet = await node_vnet(request, inputs) + return {"vnet": vnet.get("vnet"), "mac-vrf": f"macvrf-{vnet.get('vnet')}"} + + async def node_fabric(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + await require_node(request, str(values(inputs)["node"])) + fabric = str(values(inputs)["fabric"]) + return await fabric_get(request, {"values": {"id": fabric}, "provided": frozenset()}) + + async def node_fabric_interfaces( + request: Request, inputs: dict[str, Any] + ) -> list[dict[str, Any]]: + await require_node(request, str(values(inputs)["node"])) + fabric = str(values(inputs)["fabric"]) + _metadata, sdn = await _load(request) + nodes = (sdn.get("fabric_nodes") or {}).get(fabric) or {} + result = [] + for node_id, item in nodes.items(): + ifaces = item.get("interfaces") or [] + if isinstance(ifaces, str): + ifaces = [part.strip() for part in ifaces.split(",") if part.strip()] + for iface in ifaces: + result.append({"node": node_id, "iface": iface}) + return result + + async def node_fabric_neighbors( + request: Request, inputs: dict[str, Any] + ) -> list[dict[str, Any]]: + await require_node(request, str(values(inputs)["node"])) + fabric = str(values(inputs)["fabric"]) + _metadata, sdn = await _load(request) + nodes = (sdn.get("fabric_nodes") or {}).get(fabric) or {} + return [{"node": node_id, "state": "up"} for node_id in sorted(nodes)] + + async def node_fabric_routes(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + await require_node(request, str(values(inputs)["node"])) + fabric = str(values(inputs)["fabric"]) + _metadata, sdn = await _load(request) + item = (sdn.get("fabrics") or {}).get(fabric) or {} + prefix = item.get("ip_prefix") or "10.0.0.0/24" + return [{"dst": prefix, "protocol": item.get("protocol") or "ospf"}] + + # registrations + registry.register("/cluster/sdn", "GET", index) + registry.register("/cluster/sdn", "PUT", apply) + registry.register("/cluster/sdn/lock", "POST", lock_create) + registry.register("/cluster/sdn/lock", "DELETE", lock_delete) + registry.register("/cluster/sdn/rollback", "POST", rollback) + registry.register("/cluster/sdn/dry-run", "GET", dry_run) + registry.register("/cluster/sdn/ipams/{ipam}/status", "GET", ipam_status) + + registry.register("/cluster/sdn/vnets", "GET", vnets_list) + registry.register("/cluster/sdn/vnets", "POST", vnets_create) + registry.register("/cluster/sdn/vnets/{vnet}", "GET", vnet_get) + registry.register("/cluster/sdn/vnets/{vnet}", "PUT", vnet_update) + registry.register("/cluster/sdn/vnets/{vnet}", "DELETE", vnet_delete) + registry.register("/cluster/sdn/vnets/{vnet}/subnets", "GET", subnets_list) + registry.register("/cluster/sdn/vnets/{vnet}/subnets", "POST", subnets_create) + registry.register("/cluster/sdn/vnets/{vnet}/subnets/{subnet}", "GET", subnet_get) + registry.register("/cluster/sdn/vnets/{vnet}/subnets/{subnet}", "PUT", subnet_update) + registry.register("/cluster/sdn/vnets/{vnet}/subnets/{subnet}", "DELETE", subnet_delete) + registry.register("/cluster/sdn/vnets/{vnet}/ips", "POST", ips_create) + registry.register("/cluster/sdn/vnets/{vnet}/ips", "PUT", ips_update) + registry.register("/cluster/sdn/vnets/{vnet}/ips", "DELETE", ips_delete) + registry.register("/cluster/sdn/vnets/{vnet}/firewall", "GET", fw_index) + registry.register("/cluster/sdn/vnets/{vnet}/firewall/options", "GET", fw_options_get) + registry.register("/cluster/sdn/vnets/{vnet}/firewall/options", "PUT", fw_options_put) + registry.register("/cluster/sdn/vnets/{vnet}/firewall/rules", "GET", fw_rules_list) + registry.register("/cluster/sdn/vnets/{vnet}/firewall/rules", "POST", fw_rules_create) + registry.register("/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", "GET", fw_rule_get) + registry.register("/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", "PUT", fw_rule_update) + registry.register("/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", "DELETE", fw_rule_delete) + + registry.register("/cluster/sdn/fabrics", "GET", fabrics_index) + registry.register("/cluster/sdn/fabrics/all", "GET", fabrics_all) + registry.register("/cluster/sdn/fabrics/fabric", "GET", fabric_list) + registry.register("/cluster/sdn/fabrics/fabric", "POST", fabric_create) + registry.register("/cluster/sdn/fabrics/fabric/{id}", "GET", fabric_get) + registry.register("/cluster/sdn/fabrics/fabric/{id}", "PUT", fabric_update) + registry.register("/cluster/sdn/fabrics/fabric/{id}", "DELETE", fabric_delete) + registry.register("/cluster/sdn/fabrics/node", "GET", fabric_nodes_list) + registry.register("/cluster/sdn/fabrics/node/{fabric_id}", "GET", fabric_nodes_list) + registry.register("/cluster/sdn/fabrics/node/{fabric_id}", "POST", fabric_node_create) + registry.register("/cluster/sdn/fabrics/node/{fabric_id}/{node_id}", "GET", fabric_node_get) + registry.register("/cluster/sdn/fabrics/node/{fabric_id}/{node_id}", "PUT", fabric_node_update) + registry.register( + "/cluster/sdn/fabrics/node/{fabric_id}/{node_id}", "DELETE", fabric_node_delete + ) + + registry.register("/cluster/sdn/prefix-lists", "GET", prefix_list) + registry.register("/cluster/sdn/prefix-lists", "POST", prefix_create) + registry.register("/cluster/sdn/prefix-lists/{id}", "GET", prefix_get) + registry.register("/cluster/sdn/prefix-lists/{id}", "PUT", prefix_update) + registry.register("/cluster/sdn/prefix-lists/{id}", "DELETE", prefix_delete) + registry.register("/cluster/sdn/prefix-lists/{id}/entries", "GET", prefix_entries) + registry.register("/cluster/sdn/prefix-lists/{id}/entries", "POST", prefix_entry_create) + registry.register("/cluster/sdn/prefix-lists/{id}/entries/{url_seq}", "GET", prefix_entry_get) + registry.register( + "/cluster/sdn/prefix-lists/{id}/entries/{url_seq}", "PUT", prefix_entry_update + ) + registry.register( + "/cluster/sdn/prefix-lists/{id}/entries/{url_seq}", "DELETE", prefix_entry_delete + ) + + registry.register("/cluster/sdn/route-maps", "GET", route_maps_index) + registry.register("/cluster/sdn/route-maps/entries", "GET", route_entries_list) + registry.register("/cluster/sdn/route-maps/entries", "POST", route_entry_create) + registry.register("/cluster/sdn/route-maps/entries/{route-map-id}", "GET", route_map_entries) + registry.register( + "/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "GET", + route_entry_get, + ) + registry.register( + "/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "PUT", + route_entry_update, + ) + registry.register( + "/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "DELETE", + route_entry_delete, + ) + + registry.register("/nodes/{node}/sdn", "GET", node_sdn_index) + registry.register("/nodes/{node}/sdn/zones", "GET", node_zones) + registry.register("/nodes/{node}/sdn/zones/{zone}", "GET", node_zone) + registry.register("/nodes/{node}/sdn/zones/{zone}/bridges", "GET", node_zone_bridges) + registry.register("/nodes/{node}/sdn/zones/{zone}/content", "GET", node_zone_content) + registry.register("/nodes/{node}/sdn/zones/{zone}/ip-vrf", "GET", node_zone_ip_vrf) + registry.register("/nodes/{node}/sdn/vnets/{vnet}", "GET", node_vnet) + registry.register("/nodes/{node}/sdn/vnets/{vnet}/mac-vrf", "GET", node_vnet_mac_vrf) + registry.register("/nodes/{node}/sdn/fabrics/{fabric}", "GET", node_fabric) + registry.register( + "/nodes/{node}/sdn/fabrics/{fabric}/interfaces", "GET", node_fabric_interfaces + ) + registry.register("/nodes/{node}/sdn/fabrics/{fabric}/neighbors", "GET", node_fabric_neighbors) + registry.register("/nodes/{node}/sdn/fabrics/{fabric}/routes", "GET", node_fabric_routes) diff --git a/app/handlers/storage.py b/app/handlers/storage.py new file mode 100644 index 0000000..e1aa840 --- /dev/null +++ b/app/handlers/storage.py @@ -0,0 +1,576 @@ +"""Storage semantic handlers.""" + +from __future__ import annotations + +import json +from typing import Any + +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.common import database, require_node, state, storage_payload, subdirs, values +from app.simulation.seed import CLUSTER_ID, stable_id + + +def register_storage_handlers(registry: HandlerRegistry) -> None: + async def _storage_row(request: Request, node: str | None, storage_id: str) -> Any: + row = await database(request).pool.fetchrow( + """SELECT s.storage_id, s.storage_type, s.shared, s.capacity_bytes, s.used_bytes, + s.config, n.name AS node_name + FROM storages s + JOIN resources r ON r.id = s.resource_id + JOIN nodes n ON n.id = r.node_id + WHERE s.storage_id=$1 AND ($2::text IS NULL OR n.name=$2)""", + storage_id, + node, + ) + if row is None: + raise ApiError(404, "storage does not exist") + return row + + async def storage_ids(_request: Request, _inputs: dict[str, Any]) -> list[dict[str, str]]: + rows = await database(_request).pool.fetch( + "SELECT DISTINCT storage_id FROM storages ORDER BY storage_id" + ) + return [{"storage": str(row["storage_id"])} for row in rows] + + async def storage_create(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + storage_id = str(payload["storage"]) + storage_type = str(payload.get("type") or "dir") + exists = await database(request).pool.fetchval( + "SELECT EXISTS(SELECT 1 FROM storages WHERE storage_id=$1)", + storage_id, + ) + if exists: + raise ApiError(409, "storage ID already exists") + node = await database(request).pool.fetchrow( + "SELECT id, name FROM nodes ORDER BY name LIMIT 1" + ) + if node is None: + raise ApiError(503, "no nodes available") + resource_id = stable_id(f"storage:{storage_id}") + config = { + key: value + for key, value in payload.items() + if key not in {"storage", "type", "nodes", "delete"} + } + if "content" in payload: + config["content"] = [ + item.strip() for item in str(payload["content"]).split(",") if item.strip() + ] + async with database(request).pool.acquire() as connection: + async with connection.transaction(): + await connection.execute( + """INSERT INTO resources(id, node_id, kind, external_id, state, cluster_id) + VALUES($1, $2, 'storage', $3, $4::jsonb, $5)""", + resource_id, + node["id"], + storage_id, + json.dumps({**config, "status": "available"}, sort_keys=True), + CLUSTER_ID, + ) + await connection.execute( + """INSERT INTO storages( + resource_id, cluster_id, storage_id, storage_type, shared, config + ) VALUES($1, $2, $3, $4, $5, $6::jsonb)""", + resource_id, + CLUSTER_ID, + storage_id, + storage_type, + bool(payload.get("shared", False)), + json.dumps(config, sort_keys=True), + ) + return {"storage": storage_id, "type": storage_type, "config": config} + + async def storage_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + storage_id = str(values(inputs)["storage"]) + row = await _storage_row(request, None, storage_id) + config = state(row["config"]) + return { + "storage": storage_id, + "type": str(row["storage_type"]), + "shared": int(bool(row["shared"])), + **config, + } + + async def storage_update(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + storage_id = str(values(inputs)["storage"]) + row = await database(request).pool.fetchrow( + """SELECT s.resource_id, s.config FROM storages s WHERE s.storage_id=$1""", + storage_id, + ) + if row is None: + raise ApiError(404, "storage does not exist") + current = state(row["config"]) + provided = values(inputs) + updated = { + **current, + **{ + key: value + for key, value in provided.items() + if key not in {"storage", "delete", "digest"} + }, + } + await database(request).pool.execute( + "UPDATE storages SET config=$2::jsonb WHERE storage_id=$1", + storage_id, + json.dumps(updated, sort_keys=True), + ) + return updated + + async def storage_delete(request: Request, inputs: dict[str, Any]) -> None: + storage_id = str(values(inputs)["storage"]) + status = await database(request).pool.execute( + """DELETE FROM resources r USING storages s + WHERE s.resource_id=r.id AND s.storage_id=$1""", + storage_id, + ) + if status != "DELETE 1": + raise ApiError(404, "storage does not exist") + + async def node_storage_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + await require_node(request, node) + rows = await database(request).pool.fetch( + """SELECT s.storage_id, s.storage_type, s.shared, + s.capacity_bytes, s.used_bytes, s.config + FROM storages s + JOIN resources r ON r.id = s.resource_id + JOIN nodes n ON n.id = r.node_id + WHERE n.name=$1 OR s.shared = true + ORDER BY s.storage_id""", + node, + ) + return [storage_payload(row) for row in rows] + + async def node_storage_index(request: Request, inputs: dict[str, Any]) -> list[dict[str, str]]: + node = str(values(inputs)["node"]) + storage_id = str(values(inputs)["storage"]) + await require_node(request, node) + await _storage_row(request, None, storage_id) + return subdirs("content", "status", "upload") + + async def node_storage_status(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(values(inputs)["node"]) + storage_id = str(values(inputs)["storage"]) + await require_node(request, node) + row = await _storage_row(request, None, storage_id) + return storage_payload(row) + + async def node_storage_content( + request: Request, inputs: dict[str, Any] + ) -> list[dict[str, Any]]: + node = str(values(inputs)["node"]) + storage_id = str(values(inputs)["storage"]) + await require_node(request, node) + await _storage_row(request, None, storage_id) + resource_id = await database(request).pool.fetchval( + "SELECT resource_id FROM storages WHERE storage_id=$1", + storage_id, + ) + contents = await database(request).pool.fetch( + """SELECT volume_id, content_type, size_bytes, metadata, created_at + FROM storage_contents WHERE storage_resource_id=$1 ORDER BY created_at DESC""", + resource_id, + ) + backups = await database(request).pool.fetch( + """SELECT b.volume_id, b.size_bytes, b.metadata, b.created_at, r.external_id AS vmid + FROM backups b + LEFT JOIN resources r ON r.id = b.resource_id + WHERE b.storage_resource_id=$1 + ORDER BY b.created_at DESC""", + resource_id, + ) + result: list[dict[str, Any]] = [] + for item in contents: + metadata = state(item["metadata"]) + result.append( + { + "volid": str(item["volume_id"]), + "content": str(item["content_type"]), + "size": int(item["size_bytes"]), + "format": metadata.get("format", "raw"), + "ctime": int(item["created_at"].timestamp()), + } + ) + for item in backups: + metadata = state(item["metadata"]) + result.append( + { + "volid": str(item["volume_id"]), + "content": "backup", + "size": int(item["size_bytes"]), + "format": "vma.zst", + "vmid": int(item["vmid"]) if item["vmid"] is not None else None, + "notes": metadata.get("notes-template"), + "ctime": int(item["created_at"].timestamp()), + } + ) + return result + + async def _content_item( + request: Request, storage_resource_id: object, volume_id: str + ) -> dict[str, Any]: + row = await database(request).pool.fetchrow( + """SELECT volume_id, content_type, size_bytes, metadata, created_at + FROM storage_contents WHERE storage_resource_id=$1 AND volume_id=$2""", + storage_resource_id, + volume_id, + ) + if row is not None: + metadata = state(row["metadata"]) + return { + "volid": str(row["volume_id"]), + "content": str(row["content_type"]), + "size": int(row["size_bytes"]), + "format": metadata.get("format", "raw"), + "ctime": int(row["created_at"].timestamp()), + } + backup = await database(request).pool.fetchrow( + """SELECT b.volume_id, b.size_bytes, b.metadata, b.created_at, r.external_id AS vmid + FROM backups b + LEFT JOIN resources r ON r.id = b.resource_id + WHERE b.storage_resource_id=$1 AND b.volume_id=$2""", + storage_resource_id, + volume_id, + ) + if backup is None: + raise ApiError(404, "volume does not exist") + metadata = state(backup["metadata"]) + return { + "volid": str(backup["volume_id"]), + "content": "backup", + "size": int(backup["size_bytes"]), + "format": "vma.zst", + "vmid": int(backup["vmid"]) if backup["vmid"] is not None else None, + "notes": metadata.get("notes-template"), + "ctime": int(backup["created_at"].timestamp()), + } + + async def node_storage_content_get(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(values(inputs)["node"]) + storage_id = str(values(inputs)["storage"]) + volume_id = str(values(inputs)["volume"]) + await require_node(request, node) + await _storage_row(request, None, storage_id) + resource_id = await database(request).pool.fetchval( + "SELECT resource_id FROM storages WHERE storage_id=$1", + storage_id, + ) + return await _content_item(request, resource_id, volume_id) + + async def node_storage_content_delete(request: Request, inputs: dict[str, Any]) -> None: + node = str(values(inputs)["node"]) + storage_id = str(values(inputs)["storage"]) + volume_id = str(values(inputs)["volume"]) + await require_node(request, node) + await _storage_row(request, None, storage_id) + resource_id = await database(request).pool.fetchval( + "SELECT resource_id FROM storages WHERE storage_id=$1", + storage_id, + ) + status = await database(request).pool.execute( + "DELETE FROM storage_contents WHERE storage_resource_id=$1 AND volume_id=$2", + resource_id, + volume_id, + ) + if status == "DELETE 1": + return + status = await database(request).pool.execute( + "DELETE FROM backups WHERE storage_resource_id=$1 AND volume_id=$2", + resource_id, + volume_id, + ) + if status != "DELETE 1": + raise ApiError(404, "volume does not exist") + + async def node_storage_upload(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + node = str(values(inputs)["node"]) + storage_id = str(values(inputs)["storage"]) + await require_node(request, node) + await _storage_row(request, None, storage_id) + payload = values(inputs) + filename = str(payload.get("filename") or "upload.bin") + content_type = str(payload.get("content") or "iso") + raw_size = payload.get("size") or 0 + try: + size = int(raw_size) + except (TypeError, ValueError) as error: + raise ApiError(400, "invalid size") from error + volume_id = f"{storage_id}:{content_type}/{filename}" + resource_id = await database(request).pool.fetchval( + "SELECT resource_id FROM storages WHERE storage_id=$1", + storage_id, + ) + await database(request).pool.execute( + """INSERT INTO storage_contents( + id, storage_resource_id, volume_id, content_type, size_bytes, metadata + ) VALUES(gen_random_uuid(), $1, $2, $3, $4, $5::jsonb) + ON CONFLICT (storage_resource_id, volume_id) DO UPDATE + SET size_bytes=EXCLUDED.size_bytes, + content_type=EXCLUDED.content_type, + metadata=EXCLUDED.metadata""", + resource_id, + volume_id, + content_type, + size, + json.dumps({"filename": filename, "source": "upload"}, sort_keys=True), + ) + return {"uploadid": volume_id, "filename": filename, "size": size, "volid": volume_id} + + async def node_storage_prunebackups( + request: Request, inputs: dict[str, Any] + ) -> list[dict[str, Any]] | None: + node = str(values(inputs)["node"]) + storage_id = str(values(inputs)["storage"]) + await require_node(request, node) + await _storage_row(request, None, storage_id) + resource_id = await database(request).pool.fetchval( + "SELECT resource_id FROM storages WHERE storage_id=$1", + storage_id, + ) + if request.method == "DELETE": + keep = int(values(inputs).get("keep-last") or values(inputs).get("keep_last") or 1) + await database(request).pool.execute( + """DELETE FROM backups + WHERE storage_resource_id=$1 AND id IN ( + SELECT id FROM backups + WHERE storage_resource_id=$1 + ORDER BY created_at DESC + OFFSET $2 + )""", + resource_id, + keep, + ) + return None + rows = await database(request).pool.fetch( + """SELECT volume_id, size_bytes, created_at FROM backups + WHERE storage_resource_id=$1 ORDER BY created_at DESC""", + resource_id, + ) + return [ + { + "volid": str(row["volume_id"]), + "size": int(row["size_bytes"]), + "ctime": int(row["created_at"].timestamp()), + } + for row in rows + ] + + async def content_copy(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + storage_id = str(payload["storage"]) + volume = str(payload["volume"]) + await require_node(request, node) + await _storage_row(request, None, storage_id) + resource_id = await database(request).pool.fetchval( + "SELECT resource_id FROM storages WHERE storage_id=$1", + storage_id, + ) + row = await database(request).pool.fetchrow( + """SELECT volume_id, content_type, size_bytes, metadata + FROM storage_contents WHERE storage_resource_id=$1 AND volume_id=$2""", + resource_id, + volume, + ) + if row is None: + raise ApiError(404, "volume does not exist") + target = str(payload.get("target") or f"{volume}-copy") + await database(request).pool.execute( + """INSERT INTO storage_contents( + id, storage_resource_id, volume_id, content_type, size_bytes, metadata + ) VALUES(gen_random_uuid(), $1, $2, $3, $4, $5::jsonb) + ON CONFLICT (storage_resource_id, volume_id) DO UPDATE + SET size_bytes=EXCLUDED.size_bytes, metadata=EXCLUDED.metadata""", + resource_id, + target, + row["content_type"], + row["size_bytes"], + json.dumps({**state(row["metadata"]), "copied_from": volume}, sort_keys=True), + ) + return f"UPID:{node}:copy:{target}" + + async def content_update(request: Request, inputs: dict[str, Any]) -> None: + payload = values(inputs) + node = str(payload["node"]) + storage_id = str(payload["storage"]) + volume = str(payload["volume"]) + await require_node(request, node) + resource_id = await database(request).pool.fetchval( + "SELECT resource_id FROM storages WHERE storage_id=$1", + storage_id, + ) + row = await database(request).pool.fetchrow( + """SELECT metadata FROM storage_contents + WHERE storage_resource_id=$1 AND volume_id=$2""", + resource_id, + volume, + ) + if row is None: + raise ApiError(404, "volume does not exist") + meta = state(row["metadata"]) + if "notes" in payload: + meta["notes"] = payload["notes"] + if "protected" in payload: + meta["protected"] = int(bool(payload["protected"])) + await database(request).pool.execute( + """UPDATE storage_contents SET metadata=$3::jsonb + WHERE storage_resource_id=$1 AND volume_id=$2""", + resource_id, + volume, + json.dumps(meta, sort_keys=True), + ) + + async def download_url(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + storage_id = str(payload["storage"]) + await require_node(request, node) + await _storage_row(request, None, storage_id) + filename = str(payload.get("filename") or "download.bin") + content_type = str(payload.get("content") or "iso") + volume_id = f"{storage_id}:{content_type}/{filename}" + resource_id = await database(request).pool.fetchval( + "SELECT resource_id FROM storages WHERE storage_id=$1", + storage_id, + ) + await database(request).pool.execute( + """INSERT INTO storage_contents( + id, storage_resource_id, volume_id, content_type, size_bytes, metadata + ) VALUES(gen_random_uuid(), $1, $2, $3, 0, $4::jsonb) + ON CONFLICT (storage_resource_id, volume_id) DO UPDATE + SET metadata=EXCLUDED.metadata""", + resource_id, + volume_id, + content_type, + json.dumps( + { + "filename": filename, + "url": payload.get("url"), + "source": "download-url", + }, + sort_keys=True, + ), + ) + return f"UPID:{node}:download:{filename}" + + async def oci_pull(request: Request, inputs: dict[str, Any]) -> str: + payload = values(inputs) + node = str(payload["node"]) + storage_id = str(payload["storage"]) + await require_node(request, node) + await _storage_row(request, None, storage_id) + reference = str(payload.get("reference") or "image:latest") + filename = str(payload.get("filename") or reference.replace("/", "_")) + volume_id = f"{storage_id}:import/{filename}" + resource_id = await database(request).pool.fetchval( + "SELECT resource_id FROM storages WHERE storage_id=$1", + storage_id, + ) + await database(request).pool.execute( + """INSERT INTO storage_contents( + id, storage_resource_id, volume_id, content_type, size_bytes, metadata + ) VALUES(gen_random_uuid(), $1, $2, 'import', 0, $3::jsonb) + ON CONFLICT (storage_resource_id, volume_id) DO UPDATE + SET metadata=EXCLUDED.metadata""", + resource_id, + volume_id, + json.dumps({"reference": reference, "source": "oci"}, sort_keys=True), + ) + return f"UPID:{node}:oci-pull:{filename}" + + async def file_restore_list(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + payload = values(inputs) + await require_node(request, str(payload["node"])) + await _storage_row(request, None, str(payload["storage"])) + filepath = str(payload.get("filepath") or "/") + return [{"filepath": filepath.rstrip("/") + "/etc", "type": "d", "text": "etc"}] + + async def file_restore_download(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + await require_node(request, str(payload["node"])) + await _storage_row(request, None, str(payload["storage"])) + return { + "download-url": f"/api2/json/nodes/{payload['node']}/storage/" + f"{payload['storage']}/file-restore/download", + "filepath": payload.get("filepath") or "/", + "volume": payload.get("volume"), + } + + async def storage_identity(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + await require_node(request, str(payload["node"])) + row = await _storage_row(request, None, str(payload["storage"])) + return { + "storage": str(row["storage_id"]), + "type": str(row["storage_type"]), + "fingerprint": f"sim-{row['storage_id']}", + } + + async def import_metadata(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + await require_node(request, str(payload["node"])) + storage_id = str(payload["storage"]) + volume = str(payload["volume"]) + await _storage_row(request, None, storage_id) + return { + "type": "qemu", + "source": volume, + "disks": {"scsi0": f"{storage_id}:0/vm-import.raw"}, + "net0": "virtio,bridge=vmbr0", + } + + async def storage_rrd(request: Request, inputs: dict[str, Any]) -> dict[str, Any]: + payload = values(inputs) + await require_node(request, str(payload["node"])) + storage_id = str(payload["storage"]) + await _storage_row(request, None, storage_id) + return {"filename": f"pve-storage-{storage_id}.rrd"} + + async def storage_rrddata(request: Request, inputs: dict[str, Any]) -> list[dict[str, Any]]: + payload = values(inputs) + await require_node(request, str(payload["node"])) + await _storage_row(request, None, str(payload["storage"])) + return [ + {"time": 1_700_000_000, "used": 10, "total": 100}, + {"time": 1_700_000_060, "used": 12, "total": 100}, + ] + + registry.register("/storage", "GET", storage_ids) + registry.register("/storage", "POST", storage_create) + registry.register("/storage/{storage}", "GET", storage_get) + registry.register("/storage/{storage}", "PUT", storage_update) + registry.register("/storage/{storage}", "DELETE", storage_delete) + registry.register("/nodes/{node}/storage", "GET", node_storage_list) + registry.register("/nodes/{node}/storage/{storage}", "GET", node_storage_index) + registry.register("/nodes/{node}/storage/{storage}/status", "GET", node_storage_status) + registry.register("/nodes/{node}/storage/{storage}/content", "GET", node_storage_content) + registry.register("/nodes/{node}/storage/{storage}/content", "POST", node_storage_upload) + registry.register( + "/nodes/{node}/storage/{storage}/content/{volume}", "GET", node_storage_content_get + ) + registry.register( + "/nodes/{node}/storage/{storage}/content/{volume}", "DELETE", node_storage_content_delete + ) + registry.register("/nodes/{node}/storage/{storage}/upload", "POST", node_storage_upload) + registry.register( + "/nodes/{node}/storage/{storage}/prunebackups", "GET", node_storage_prunebackups + ) + registry.register( + "/nodes/{node}/storage/{storage}/prunebackups", "DELETE", node_storage_prunebackups + ) + registry.register("/nodes/{node}/storage/{storage}/content/{volume}", "POST", content_copy) + registry.register("/nodes/{node}/storage/{storage}/content/{volume}", "PUT", content_update) + registry.register("/nodes/{node}/storage/{storage}/download-url", "POST", download_url) + registry.register("/nodes/{node}/storage/{storage}/oci-registry-pull", "POST", oci_pull) + registry.register("/nodes/{node}/storage/{storage}/file-restore/list", "GET", file_restore_list) + registry.register( + "/nodes/{node}/storage/{storage}/file-restore/download", "GET", file_restore_download + ) + registry.register("/nodes/{node}/storage/{storage}/identity", "GET", storage_identity) + registry.register("/nodes/{node}/storage/{storage}/import-metadata", "GET", import_metadata) + registry.register("/nodes/{node}/storage/{storage}/rrd", "GET", storage_rrd) + registry.register("/nodes/{node}/storage/{storage}/rrddata", "GET", storage_rrddata) diff --git a/app/lifespan.py b/app/lifespan.py new file mode 100644 index 0000000..fbbcff3 --- /dev/null +++ b/app/lifespan.py @@ -0,0 +1,63 @@ +"""Application resource ownership.""" + +from __future__ import annotations + +import asyncio +from collections.abc import AsyncIterator, Callable +from contextlib import AbstractAsyncContextManager, asynccontextmanager +from typing import Protocol + +from fastapi import FastAPI + +from app.config import Settings +from app.db.pool import AsyncpgDatabase, Database + +DatabaseFactory = Callable[[Settings], Database] +Lifespan = Callable[[FastAPI], AbstractAsyncContextManager[None]] + + +class LifespanWorker(Protocol): + async def run(self) -> None: ... + + def stop(self) -> None: ... + + +WorkerFactory = Callable[[Database], LifespanWorker] + + +def create_lifespan( + settings: Settings, + database_factory: DatabaseFactory, + worker_factories: tuple[WorkerFactory, ...] = (), +) -> Lifespan: + """Build a lifespan context so tests can inject a database implementation.""" + + @asynccontextmanager + async def lifespan(app: FastAPI) -> AsyncIterator[None]: + database = database_factory(settings) + await database.connect() + app.state.database = database + try: + from app.vsphere.seed import seed_vsphere_inventory + + await seed_vsphere_inventory(database, force=False) + except Exception: + pass + workers = tuple(factory(database) for factory in worker_factories) + worker_tasks = tuple(asyncio.create_task(worker.run()) for worker in workers) + try: + yield + finally: + for worker in workers: + worker.stop() + if worker_tasks: + await asyncio.gather(*worker_tasks) + await database.close() + + return lifespan + + +def default_database_factory(settings: Settings) -> Database: + """Create the production asyncpg adapter.""" + + return AsyncpgDatabase(settings) diff --git a/app/logging.py b/app/logging.py new file mode 100644 index 0000000..eb87a0a --- /dev/null +++ b/app/logging.py @@ -0,0 +1,40 @@ +"""Structured logging configuration with safe JSON output.""" + +from __future__ import annotations + +import json +import logging +from datetime import UTC, datetime +from typing import Any + + +class JsonFormatter(logging.Formatter): + """Serialize standard records and selected structured attributes as JSON.""" + + _fields = ("request_id", "method", "path", "status", "duration_ms") + + def format(self, record: logging.LogRecord) -> str: + payload: dict[str, Any] = { + "timestamp": datetime.now(UTC).isoformat(), + "level": record.levelname, + "logger": record.name, + "message": record.getMessage(), + } + for field in self._fields: + value = getattr(record, field, None) + if value is not None: + payload[field] = value + if record.exc_info is not None: + payload["exception"] = self.formatException(record.exc_info) + return json.dumps(payload, ensure_ascii=False, separators=(",", ":")) + + +def configure_logging(level: str) -> None: + """Configure the root logger once for the process.""" + + handler = logging.StreamHandler() + handler.setFormatter(JsonFormatter()) + root = logging.getLogger() + root.handlers.clear() + root.addHandler(handler) + root.setLevel(level.upper()) diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..7aa5ff2 --- /dev/null +++ b/app/main.py @@ -0,0 +1,136 @@ +"""FastAPI application factory and ASGI entry point.""" + +from __future__ import annotations + +import asyncio +from typing import cast + +from fastapi import FastAPI + +from app.api.errors import ApiError, api_error_handler, unhandled_exception_handler +from app.api.middleware import RequestContextMiddleware +from app.api.openapi import openapi_tag_metadata +from app.api.registry import HandlerRegistry +from app.config import Settings, get_settings +from app.contracts.model import Snapshot +from app.contracts.runtime import apply_runtime_contract, contract_store_root +from app.db.pool import AsyncpgDatabase, Database +from app.handlers.core import build_core_handlers +from app.lifespan import DatabaseFactory, WorkerFactory, create_lifespan, default_database_factory +from app.logging import configure_logging +from app.observability.health import router as health_router +from app.simulation.clock import AcceleratedClock +from app.tasks.backup import backup_handler +from app.tasks.lxc import lxc_handler +from app.tasks.qemu import qemu_handler +from app.tasks.repository import TaskRepository +from app.tasks.worker import TaskWorker +from app.vsphere.rest import vsphere_rest_router +from app.vsphere.soap.router import router as vsphere_soap_router +from app.web.routes import router as web_router + + +def create_app( + settings: Settings | None = None, + database_factory: DatabaseFactory = default_database_factory, + handlers: HandlerRegistry | None = None, + worker_factories: tuple[WorkerFactory, ...] | None = None, +) -> FastAPI: + """Create an isolated application instance with explicit resource factories.""" + + resolved = settings or get_settings() + configure_logging(resolved.log_level) + resolved_workers = worker_factories + pve_stub = bool(getattr(resolved, "enable_pve_stub", False) and resolved.contract_snapshot) + if resolved_workers is None and pve_stub and handlers is None: + + def task_worker(database: Database) -> TaskWorker: + adapter = cast(AsyncpgDatabase, database) + repository = TaskRepository(adapter.pool) + clock = AcceleratedClock(resolved.simulation_time_scale) + qemu = qemu_handler(repository, clock) + lxc = lxc_handler(repository, clock) + backup = backup_handler(repository, clock) + return TaskWorker( + repository, + "simulator-worker", + { + "qemu-clone": qemu, + "qemu-create": qemu, + "qemu-delete": qemu, + "qemu-reboot": qemu, + "qemu-reset": qemu, + "qemu-resume": qemu, + "qemu-shutdown": qemu, + "qemu-migrate": qemu, + "qemu-move-disk": qemu, + "qemu-snapshot-create": qemu, + "qemu-snapshot-delete": qemu, + "qemu-snapshot-rollback": qemu, + "qemu-start": qemu, + "qemu-stop": qemu, + "qemu-suspend": qemu, + "qemu-update": qemu, + "lxc-clone": lxc, + "lxc-create": lxc, + "lxc-delete": lxc, + "lxc-migrate": lxc, + "lxc-reboot": lxc, + "lxc-resume": lxc, + "lxc-shutdown": lxc, + "lxc-snapshot-create": lxc, + "lxc-snapshot-delete": lxc, + "lxc-snapshot-rollback": lxc, + "lxc-start": lxc, + "lxc-stop": lxc, + "lxc-suspend": lxc, + "vzdump": backup, + "aptupdate": backup, + }, + concurrency=resolved.task_worker_concurrency, + lease_seconds=resolved.task_lease_seconds, + ) + + resolved_workers = (task_worker,) + app = FastAPI( + title=resolved.app_name, + version="0.1.0", + openapi_tags=openapi_tag_metadata(include_pve=pve_stub), + lifespan=create_lifespan(resolved, database_factory, resolved_workers or ()), + ) + app.state.settings = resolved + app.state.contract_swap_lock = asyncio.Lock() + app.state.vsphere_contract_major = 9 + app.state.runtime_source_version = "8.0.2" + app.add_middleware(RequestContextMiddleware, header_name=resolved.request_id_header) + from app.vsphere.rest.version_gate import VsphereVersionGateMiddleware + + app.add_middleware(VsphereVersionGateMiddleware) + app.add_exception_handler(Exception, unhandled_exception_handler) + app.add_exception_handler(ApiError, api_error_handler) + # Native vSphere surface (survives contract hot-swap). + from app.vsphere.soap.pbm import router as vsphere_pbm_router + + app.include_router(vsphere_rest_router) + app.include_router(vsphere_soap_router) + app.include_router(vsphere_pbm_router) + app.include_router(web_router) + app.include_router(health_router) + if pve_stub and resolved.contract_snapshot is not None: + snapshot = Snapshot.model_validate_json(resolved.contract_snapshot.read_bytes()) + resolved_handlers = handlers or build_core_handlers(resolved) + apply_runtime_contract( + app, + snapshot, + handlers=resolved_handlers, + store_root=contract_store_root(resolved), + fallback=resolved.contract_fallback, + settings=resolved, + require_evidence_match=True, + register_admin=True, + ) + + return app + + +app = create_app() diff --git a/app/observability/__init__.py b/app/observability/__init__.py new file mode 100644 index 0000000..6715098 --- /dev/null +++ b/app/observability/__init__.py @@ -0,0 +1 @@ +"""Health, metrics, and tracing adapters.""" diff --git a/app/observability/health.py b/app/observability/health.py new file mode 100644 index 0000000..01115c0 --- /dev/null +++ b/app/observability/health.py @@ -0,0 +1,37 @@ +"""Kubernetes-compatible health endpoints.""" + +from __future__ import annotations + +from typing import Annotated + +from fastapi import APIRouter, Depends, Response, status +from pydantic import BaseModel + +from app.db.pool import Database +from app.dependencies import get_database + +router = APIRouter(prefix="/health", tags=["Simulator"]) + + +class HealthResponse(BaseModel): + status: str + + +@router.get("/live", response_model=HealthResponse) +async def live() -> HealthResponse: + """Report process liveness without checking dependencies.""" + + return HealthResponse(status="ok") + + +@router.get("/ready", response_model=HealthResponse) +async def ready( + response: Response, + database: Annotated[Database, Depends(get_database)], +) -> HealthResponse: + """Report whether the required database dependency is usable.""" + + if await database.is_ready(): + return HealthResponse(status="ok") + response.status_code = status.HTTP_503_SERVICE_UNAVAILABLE + return HealthResponse(status="unavailable") diff --git a/app/security/__init__.py b/app/security/__init__.py new file mode 100644 index 0000000..64959db --- /dev/null +++ b/app/security/__init__.py @@ -0,0 +1 @@ +"""Authentication, secrets, and authorization boundaries.""" diff --git a/app/security/acl.py b/app/security/acl.py new file mode 100644 index 0000000..5b7b128 --- /dev/null +++ b/app/security/acl.py @@ -0,0 +1,92 @@ +"""Capability-driven ACL evaluation with token privilege separation.""" + +from __future__ import annotations + +from dataclasses import dataclass + +from app.contracts.model import Permissions + + +@dataclass(frozen=True, slots=True) +class Realm: + name: str + kind: str + + +@dataclass(frozen=True, slots=True) +class Principal: + name: str + realm: str + + +@dataclass(frozen=True, slots=True) +class Role: + name: str + privileges: frozenset[str] + + +@dataclass(frozen=True, slots=True) +class AclEntry: + principal: str + path: str + privileges: frozenset[str] + propagate: bool = True + + +def _ancestors(path: str) -> tuple[str, ...]: + parts = [part for part in path.split("/") if part] + return tuple(["/"] + ["/" + "/".join(parts[:index]) for index in range(1, len(parts) + 1)]) + + +def effective_privileges( + principal: str, path: str, entries: tuple[AclEntry, ...] +) -> frozenset[str]: + privileges: set[str] = set() + for entry in entries: + if entry.principal != principal or entry.path not in _ancestors(path): + continue + if entry.path == path or entry.propagate: + privileges.update(entry.privileges) + return frozenset(privileges) + + +def authorize( + principal: str, + path: str, + required: frozenset[str], + entries: tuple[AclEntry, ...], + *, + token_privileges: frozenset[str] | None = None, + require_all: bool = True, +) -> bool: + privileges = effective_privileges(principal, path, entries) + if token_privileges is not None: + privileges &= token_privileges + return required <= privileges if require_all else bool(required & privileges) + + +@dataclass(frozen=True, slots=True) +class CapabilityRequirement: + path: str + privileges: frozenset[str] + require_all: bool = True + + +def requirement_from_contract( + permissions: Permissions | None, parameters: dict[str, str] +) -> CapabilityRequirement | None: + if permissions is None or not permissions.expression: + return None + check = permissions.expression.get("check") + if not isinstance(check, list) or len(check) < 3 or check[0] != "perm": + return None + raw_path = str(check[1]) + for name, value in parameters.items(): + raw_path = raw_path.replace(f"{{{name}}}", value).replace(f"<{name}>", value) + raw_privileges = check[2] + if not isinstance(raw_privileges, list): + return None + require_all = not (len(check) >= 4 and check[3] == "any") + return CapabilityRequirement( + raw_path, frozenset(str(item) for item in raw_privileges), require_all + ) diff --git a/app/security/auth.py b/app/security/auth.py new file mode 100644 index 0000000..c5c9aad --- /dev/null +++ b/app/security/auth.py @@ -0,0 +1,136 @@ +"""Password, ticket, CSRF, and API-token primitives.""" + +from __future__ import annotations + +import base64 +import hashlib +import hmac +import json +import re +import secrets +import time +from dataclasses import dataclass + +from starlette.responses import Response + + +class AuthenticationError(ValueError): + pass + + +def _b64(value: bytes) -> str: + return base64.urlsafe_b64encode(value).rstrip(b"=").decode() + + +def _unb64(value: str) -> bytes: + return base64.urlsafe_b64decode(value + "=" * (-len(value) % 4)) + + +def hash_secret(secret: str, *, salt: bytes | None = None) -> str: + actual_salt = salt or secrets.token_bytes(16) + digest = hashlib.scrypt(secret.encode(), salt=actual_salt, n=2**14, r=8, p=1, dklen=32) + return f"scrypt$16384$8$1${_b64(actual_salt)}${_b64(digest)}" + + +def verify_secret(secret: str, encoded: str) -> bool: + try: + algorithm, n, r, p, salt, expected = encoded.split("$") + if algorithm != "scrypt": + return False + actual = hashlib.scrypt( + secret.encode(), salt=_unb64(salt), n=int(n), r=int(r), p=int(p), dklen=32 + ) + return hmac.compare_digest(actual, _unb64(expected)) + except (ValueError, TypeError): + return False + + +@dataclass(frozen=True, slots=True) +class TicketClaims: + principal: str + issued_at: int + expires_at: int + nonce: str + + +def issue_ticket(principal: str, key: bytes, *, now: int | None = None, ttl: int = 7200) -> str: + issued = int(time.time() if now is None else now) + claims = { + "exp": issued + ttl, + "iat": issued, + "nonce": _b64(secrets.token_bytes(12)), + "principal": principal, + } + payload = _b64(json.dumps(claims, sort_keys=True, separators=(",", ":")).encode()) + signature = _b64(hmac.digest(key, payload.encode(), "sha256")) + return f"PVE:{payload}.{signature}" + + +def verify_ticket(ticket: str, key: bytes, *, now: int | None = None) -> TicketClaims: + try: + prefix, signed = ticket.split(":", 1) + payload, signature = signed.split(".", 1) + if prefix != "PVE" or not hmac.compare_digest( + _unb64(signature), hmac.digest(key, payload.encode(), "sha256") + ): + raise AuthenticationError("invalid ticket") + data = json.loads(_unb64(payload)) + claims = TicketClaims( + principal=str(data["principal"]), + issued_at=int(data["iat"]), + expires_at=int(data["exp"]), + nonce=str(data["nonce"]), + ) + except (ValueError, KeyError, json.JSONDecodeError) as error: + raise AuthenticationError("invalid ticket") from error + current = int(time.time() if now is None else now) + if claims.expires_at < current or claims.issued_at > current + 60: + raise AuthenticationError("ticket expired or not yet valid") + return claims + + +def csrf_token(ticket: str, key: bytes) -> str: + return _b64(hmac.digest(key, b"csrf:" + ticket.encode(), "sha256")) + + +def verify_csrf(ticket: str, token: str, key: bytes) -> bool: + return hmac.compare_digest(csrf_token(ticket, key), token) + + +def set_ticket_cookie(response: Response, ticket: str, *, secure: bool = True) -> None: + response.set_cookie( + "PVEAuthCookie", + ticket, + httponly=True, + secure=secure, + samesite="strict", + path="/", + ) + + +@dataclass(frozen=True, slots=True) +class ApiToken: + principal: str + token_id: str + secret: str + + +TOKEN_PATTERN = re.compile(r"^PVEAPIToken=([^!=\s]+![^=\s]+)=([^\s]+)$") + + +def parse_api_token(header: str) -> ApiToken: + match = TOKEN_PATTERN.fullmatch(header) + if match is None: + raise AuthenticationError("invalid API token") + identity, secret = match.groups() + principal, token_id = identity.rsplit("!", 1) + return ApiToken(principal, token_id, secret) + + +SECRET_RE = re.compile(r"(PVEAPIToken=[^=\s]+=)[^\s]+|(password|secret|token)=([^&\s]+)", re.I) + + +def redact_secrets(value: str) -> str: + return SECRET_RE.sub( + lambda match: (match.group(1) or f"{match.group(2)}=") + "[REDACTED]", value + ) diff --git a/app/simulation/__init__.py b/app/simulation/__init__.py new file mode 100644 index 0000000..8026428 --- /dev/null +++ b/app/simulation/__init__.py @@ -0,0 +1 @@ +"""Persistent deterministic simulation services.""" diff --git a/app/simulation/clock.py b/app/simulation/clock.py new file mode 100644 index 0000000..40b2ae4 --- /dev/null +++ b/app/simulation/clock.py @@ -0,0 +1,61 @@ +"""Injectable simulation clocks; task leases deliberately do not use these.""" + +from __future__ import annotations + +import asyncio +from datetime import UTC, datetime, timedelta +from typing import Protocol + + +class Clock(Protocol): + async def now(self) -> datetime: ... + + async def sleep(self, seconds: float) -> None: ... + + +class RealClock: + async def now(self) -> datetime: + return datetime.now(UTC) + + async def sleep(self, seconds: float) -> None: + await asyncio.sleep(seconds) + + +class AcceleratedClock: + def __init__(self, scale: float) -> None: + if scale <= 0: + raise ValueError("clock scale must be positive") + self._scale = scale + + async def now(self) -> datetime: + return datetime.now(UTC) + + async def sleep(self, seconds: float) -> None: + await asyncio.sleep(seconds / self._scale) + + +class ManualClock: + def __init__(self, initial: datetime) -> None: + if initial.tzinfo is None: + raise ValueError("manual clock requires timezone-aware time") + self._now = initial + self._condition = asyncio.Condition() + + async def now(self) -> datetime: + async with self._condition: + return self._now + + async def sleep(self, seconds: float) -> None: + if seconds < 0: + raise ValueError("sleep duration cannot be negative") + async with self._condition: + target = self._now + timedelta(seconds=seconds) + await self._condition.wait_for(lambda: self._now >= target) + + async def advance(self, seconds: float) -> datetime: + if seconds < 0: + raise ValueError("clock cannot move backwards") + async with self._condition: + self._now += timedelta(seconds=seconds) + self._condition.notify_all() + return self._now diff --git a/app/simulation/demo_cluster.py b/app/simulation/demo_cluster.py new file mode 100644 index 0000000..423739c --- /dev/null +++ b/app/simulation/demo_cluster.py @@ -0,0 +1,370 @@ +"""Enterprise-scale demo cluster profile for realistic emulator workloads.""" + +from __future__ import annotations + +import uuid +from collections import defaultdict +from collections.abc import Sequence + +from app.simulation.seed import ( + SeedNode, + SeedProfile, + SeedResource, + SeedTask, + _node, + _resource, + stable_id, +) + +DEMO_NODE_COUNT = 20 +DEMO_QEMU_COUNT = 850 +DEMO_LXC_COUNT = 150 +DEMO_CEPH_OSD_COUNT = 300 +CEPH_TOTAL_BYTES = 5 * 1024**5 +QEMU_VMID_START = 100 +LXC_VMID_START = 10_000 + +QEMU_PREFIXES = ( + "web", + "api", + "db", + "cache", + "mq", + "batch", + "ml", + "monitor", + "log", + "ci", + "k8s", + "vpn", + "ldap", + "git", + "proxy", +) +LXC_PREFIXES = ( + "svc-nginx", + "svc-haproxy", + "svc-dns", + "svc-vault", + "svc-redis", + "mon-agent", + "backup-agent", + "ceph-mgr", + "lb-vip", + "proxy-squid", + "jump-host", + "ntp", + "syslog", + "metrics", + "bastion", +) +TIERS = ("prod", "staging", "dev", "qa", "dr") +POOLS = ( + ("production", 280), + ("staging", 160), + ("development", 130), + ("qa", 100), + ("gpu-workloads", 80), + ("legacy", 100), +) +TASK_TYPES = ( + "vzdump", + "qmstart", + "qmstop", + "qmmigrate", + "qmreboot", + "qmclone", + "aptupdate", + "startall", + "stopall", + "cephosd", + "pct-start", + "pct-stop", +) + + +def _even_node_slots(node_count: int, total: int, *, phase: int = 0) -> tuple[int, ...]: + """Return `total` node indices distributed as evenly as possible.""" + + if total <= 0: + return () + base, remainder = divmod(total, node_count) + slots: list[int] = [] + for node_index in range(node_count): + slots.extend([node_index] * (base + (1 if node_index < remainder else 0))) + if phase: + phase %= len(slots) + slots = slots[phase:] + slots[:phase] + return tuple(slots) + + +def _even_sample(resources: Sequence[SeedResource], count: int) -> list[str]: + """Pick `count` resource IDs spread evenly across the provided sequence.""" + + if count <= 0 or not resources: + return [] + if count >= len(resources): + return [resource.external_id for resource in resources] + step = len(resources) / count + return [resources[int(index * step)].external_id for index in range(count)] + + +def _guest_name(prefixes: tuple[str, ...], index: int) -> str: + prefix = prefixes[index % len(prefixes)] + tier = TIERS[index % len(TIERS)] + return f"{tier}-{prefix}-{index:04d}" + + +def _qemu_state(vmid: int, index: int) -> dict[str, object]: + statuses = ("running", "running", "running", "running", "stopped", "paused") + cpus = (1, 2, 2, 4, 4, 8, 8, 16, 32)[index % 9] + memory_mb = (512, 1024, 2048, 4096, 8192, 16_384, 32_768, 65_536)[index % 8] + pool_name = POOLS[index % len(POOLS)][0] + return { + "name": _guest_name(QEMU_PREFIXES, index), + "status": statuses[index % len(statuses)], + "cpus": cpus, + "cores": cpus, + "memory": memory_mb, + "maxmem": memory_mb, + "pool": pool_name, + "tags": f"{TIERS[index % len(TIERS)]};{pool_name}", + "agent": index % 3 != 0, + "template": index % 97 == 0, + "onboot": index % 5 != 0, + "vmid": vmid, + } + + +def _lxc_state(vmid: int, index: int) -> dict[str, object]: + statuses = ("running", "running", "stopped", "stopped") + memory_mb = (256, 512, 1024, 2048, 4096)[index % 5] + pool_name = POOLS[(index + 2) % len(POOLS)][0] + return { + "name": _guest_name(LXC_PREFIXES, index), + "status": statuses[index % len(statuses)], + "cpus": (1, 1, 2, 2, 4)[index % 5], + "memory": memory_mb, + "maxmem": memory_mb, + "pool": pool_name, + "tags": f"container;{pool_name}", + "unprivileged": index % 4 != 0, + "template": index % 41 == 0, + "vmid": vmid, + } + + +def _demo_task(index: int, node: SeedNode, task_type: str, resource_id: str) -> SeedTask: + return SeedTask( + stable_id(f"demo-task:{index}:{task_type}:{resource_id}"), + f"UPID:{node.name}:{index:07X}:{index:07X}:67{index:06X}:" + f"{task_type}:{resource_id}:root@pam:", + task_type, + {"resource_id": resource_id, "node": node.name, "seeded": True}, + ) + + +def demo_cluster_profile() -> SeedProfile: + nodes = tuple( + _node(f"pve{index:02d}", "offline" if index == 19 else "online") + for index in range(1, DEMO_NODE_COUNT + 1) + ) + node_count = len(nodes) + resources: list[SeedResource] = [] + + qemu_slots = _even_node_slots(node_count, DEMO_QEMU_COUNT, phase=0) + lxc_slots = _even_node_slots(node_count, DEMO_LXC_COUNT, phase=node_count // 2) + osd_slots = _even_node_slots(node_count, DEMO_CEPH_OSD_COUNT, phase=node_count // 4) + + qemu_resources: list[SeedResource] = [] + for offset, node_index in enumerate(qemu_slots): + vmid = QEMU_VMID_START + offset + resource = _resource(nodes[node_index], "qemu", str(vmid), _qemu_state(vmid, offset)) + qemu_resources.append(resource) + resources.append(resource) + + lxc_resources: list[SeedResource] = [] + for offset, node_index in enumerate(lxc_slots): + vmid = LXC_VMID_START + offset + resource = _resource(nodes[node_index], "lxc", str(vmid), _lxc_state(vmid, offset)) + lxc_resources.append(resource) + resources.append(resource) + + guests_by_node: dict[uuid.UUID, list[SeedResource]] = defaultdict(list) + for guest in (*qemu_resources, *lxc_resources): + guests_by_node[guest.node_id].append(guest) + + for node in nodes: + resources.append( + _resource( + node, + "storage", + f"local-{node.name}", + { + "content": ["iso", "vztmpl", "backup"], + "status": "available", + "storage_type": "dir", + }, + ) + ) + resources.append( + _resource( + node, + "storage", + f"local-lvm-{node.name}", + { + "content": ["images", "rootdir"], + "status": "available", + "storage_type": "lvmthin", + "shared": False, + }, + ) + ) + resources.append( + _resource( + node, + "storage", + f"backup-{node.name}", + { + "content": ["backup"], + "status": "available", + "storage_type": "dir", + "shared": False, + "total_bytes": 4 * 1024**4, + "used_bytes": int(2.2 * 1024**4), + }, + ) + ) + if int(node.name[3:]) % 2 == 0: + resources.append( + _resource( + node, + "storage", + f"local-zfs-{node.name}", + { + "content": ["images", "rootdir"], + "status": "available", + "storage_type": "zfspool", + "shared": False, + }, + ) + ) + + used_bytes = int(CEPH_TOTAL_BYTES * 0.62) + resources.append( + _resource( + nodes[0], + "storage", + "ceph-prod", + { + "content": ["images", "rootdir", "backup"], + "shared": True, + "status": "available", + "storage_type": "ceph", + "ceph_pool": "rbd", + "total_bytes": CEPH_TOTAL_BYTES, + "used_bytes": used_bytes, + "osd_count": DEMO_CEPH_OSD_COUNT, + }, + ) + ) + resources.append( + _resource( + nodes[node_count // 2], + "storage", + "nfs-backup", + { + "content": ["backup", "iso"], + "shared": True, + "status": "available", + "storage_type": "nfs", + "total_bytes": 80 * 1024**4, + "used_bytes": 52 * 1024**4, + }, + ) + ) + + for osd_index, node_index in enumerate(osd_slots): + node = nodes[node_index] + osd_id = osd_index + weight = round(0.8 + (osd_index % 17) * 0.05, 2) + size_bytes = CEPH_TOTAL_BYTES // DEMO_CEPH_OSD_COUNT + resources.append( + _resource( + node, + "ceph-osd", + f"osd.{osd_id}", + { + "osd_id": osd_id, + "status": "up" if osd_index != 42 else "down", + "in": osd_index != 42, + "weight": weight, + "size_bytes": size_bytes, + "used_bytes": int(size_bytes * (0.55 + (osd_index % 10) * 0.03)), + "device_class": "ssd" if osd_index % 4 else "hdd", + }, + ) + ) + + qemu_by_node = [ + sorted(guests_by_node[node.id], key=lambda resource: int(resource.external_id)) + for node in nodes + ] + pool_guest_cursor = 0 + for pool_index, (pool_id, member_count) in enumerate(POOLS): + pool_guests: list[SeedResource] = [] + per_node, extra = divmod(member_count, node_count) + for node_index, node_guests in enumerate(qemu_by_node): + take = per_node + (1 if node_index < extra else 0) + start = (pool_guest_cursor + node_index) % len(node_guests) if node_guests else 0 + for offset in range(take): + if not node_guests: + break + pool_guests.append(node_guests[(start + offset) % len(node_guests)]) + pool_guest_cursor += member_count + pool_guests.sort(key=lambda resource: int(resource.external_id)) + resources.append( + _resource( + nodes[pool_index % node_count], + "pool", + pool_id, + { + "members": _even_sample(pool_guests, min(40, len(pool_guests))), + "member_count": len(pool_guests), + "comment": f"Simulated {pool_id} pool", + }, + ) + ) + + ha_guests = [ + qemu_resources[int(index * len(qemu_resources) / min(120, len(qemu_resources)))] + for index in range(min(120, len(qemu_resources))) + ] + for ha_index, guest in enumerate(ha_guests): + node = next(node for node in nodes if node.id == guest.node_id) + resources.append( + _resource( + node, + "ha", + f"vm:{guest.external_id}", + { + "state": "started" if ha_index % 5 else "stopped", + "group": "critical-services", + "max_relocate": 2, + "max_restart": 3, + }, + ) + ) + + tasks: list[SeedTask] = [] + guest_cycle = sorted( + (*qemu_resources, *lxc_resources), + key=lambda resource: (resource.node_id, int(resource.external_id)), + ) + for index in range(1, 251): + guest = guest_cycle[(index - 1) % len(guest_cycle)] + node = next(node for node in nodes if node.id == guest.node_id) + task_type = TASK_TYPES[index % len(TASK_TYPES)] + tasks.append(_demo_task(index, node, task_type, guest.external_id)) + + return SeedProfile("demo-cluster", nodes, tuple(resources), tuple(tasks)) diff --git a/app/simulation/scenarios.py b/app/simulation/scenarios.py new file mode 100644 index 0000000..de54321 --- /dev/null +++ b/app/simulation/scenarios.py @@ -0,0 +1,49 @@ +"""Seeded deterministic fault-rule evaluation.""" + +from __future__ import annotations + +import hashlib +from dataclasses import dataclass + + +@dataclass(frozen=True, slots=True) +class FaultContext: + method: str + path: str + principal: str | None = None + node: str | None = None + vmid: str | None = None + call_number: int = 1 + + +@dataclass(frozen=True, slots=True) +class FaultRule: + kind: str + probability: float = 1.0 + method: str | None = None + path_prefix: str | None = None + principal: str | None = None + node: str | None = None + vmid: str | None = None + call_number: int | None = None + + def __post_init__(self) -> None: + if not 0 <= self.probability <= 1: + raise ValueError("fault probability must be between zero and one") + + +def matches(rule: FaultRule, context: FaultContext, seed: int) -> bool: + filters = ( + (rule.method, context.method), + (rule.principal, context.principal), + (rule.node, context.node), + (rule.vmid, context.vmid), + (rule.call_number, context.call_number), + ) + if any(expected is not None and expected != actual for expected, actual in filters): + return False + if rule.path_prefix is not None and not context.path.startswith(rule.path_prefix): + return False + material = f"{seed}:{rule.kind}:{context.method}:{context.path}:{context.call_number}" + sample = int.from_bytes(hashlib.sha256(material.encode()).digest()[:8], "big") / 2**64 + return sample < rule.probability diff --git a/app/simulation/seed.py b/app/simulation/seed.py new file mode 100644 index 0000000..4b0b49d --- /dev/null +++ b/app/simulation/seed.py @@ -0,0 +1,863 @@ +"""Deterministic idempotent simulation seed profiles.""" + +from __future__ import annotations + +import json +import uuid +from dataclasses import dataclass + +import asyncpg # type: ignore[import-untyped] +from asyncpg import Connection + +from app.security.auth import hash_secret + +NAMESPACE = uuid.UUID("c9040a72-b391-4a7e-9864-3ae46291a531") +CLUSTER_ID = uuid.UUID("dc760c47-d8d7-57e6-9404-f0c6f2395d8f") + + +def default_node_ops_for_seed(node_name: str) -> dict[str, object]: + from app.handlers.nodes import default_node_ops + + ops = default_node_ops() + # Distinct but deterministic bridge addresses per node name. + suffix = (stable_id(f"node-ip:{node_name}").int % 200) + 10 + network = ops.get("network") + if isinstance(network, list): + for item in network: + if not isinstance(item, dict): + continue + if item.get("iface") == "vmbr0": + item["address"] = f"10.0.0.{suffix}/24" + elif item.get("iface") == "vmbr1": + item["address"] = f"10.10.0.{suffix}/24" + return ops + + +@dataclass(frozen=True, slots=True) +class SeedNode: + id: uuid.UUID + name: str + status: str + + +@dataclass(frozen=True, slots=True) +class SeedResource: + id: uuid.UUID + node_id: uuid.UUID + kind: str + external_id: str + state: dict[str, object] + + +@dataclass(frozen=True, slots=True) +class SeedTask: + id: uuid.UUID + upid: str + task_type: str + payload: dict[str, object] + + +@dataclass(frozen=True, slots=True) +class SeedProfile: + name: str + nodes: tuple[SeedNode, ...] + resources: tuple[SeedResource, ...] + tasks: tuple[SeedTask, ...] = () + + def logical_state(self) -> dict[str, object]: + nodes = [{"name": node.name, "status": node.status} for node in self.nodes] + names = {node.id: node.name for node in self.nodes} + resources = [ + { + "kind": resource.kind, + "external_id": resource.external_id, + "node": names[resource.node_id], + "state": resource.state, + } + for resource in self.resources + ] + tasks = [ + {"upid": task.upid, "task_type": task.task_type, "status": "success"} + for task in self.tasks + ] + return {"profile": self.name, "nodes": nodes, "resources": resources, "tasks": tasks} + + +def stable_id(name: str) -> uuid.UUID: + return uuid.uuid5(NAMESPACE, name) + + +def _string_list(state: dict[str, object], key: str) -> tuple[str, ...]: + value = state.get(key, []) + if not isinstance(value, list) or not all(isinstance(item, str) for item in value): + raise ValueError(f"seed state {key} must be a string list") + return tuple(value) + + +def _node(name: str, status: str = "online") -> SeedNode: + return SeedNode(stable_id(f"node:{name}"), name, status) + + +def _resource( + node: SeedNode, kind: str, external_id: str, state: dict[str, object] +) -> SeedResource: + return SeedResource(stable_id(f"{kind}:{external_id}"), node.id, kind, external_id, state) + + +def _completed_task(index: int, task_type: str, resource_id: str) -> SeedTask: + return SeedTask( + stable_id(f"task:{index}:{task_type}:{resource_id}"), + f"UPID:pve01:0000000{index}:0000000{index}:6500000{index}:" + f"{task_type}:{resource_id}:root@pam:", + task_type, + {"resource_id": resource_id, "seeded": True}, + ) + + +def small_profile() -> SeedProfile: + node = _node("pve01") + resources = ( + _resource(node, "qemu", "100", {"name": "demo", "status": "stopped"}), + _resource(node, "qemu", "101", {"name": "worker", "status": "stopped"}), + _resource(node, "lxc", "200", {"name": "service", "status": "stopped"}), + _resource(node, "storage", "local", {"content": ["iso", "backup"], "status": "available"}), + _resource( + node, "storage", "local-lvm", {"content": ["images", "rootdir"], "status": "available"} + ), + ) + tasks = (_completed_task(1, "qmstart", "100"), _completed_task(2, "qmstop", "100")) + return SeedProfile("small", (node,), resources, tasks) + + +def medium_profile() -> SeedProfile: + nodes = tuple(_node(f"pve{index}") for index in range(1, 4)) + resources: list[SeedResource] = [] + for vmid in range(100, 150): + node = nodes[(vmid - 100) % len(nodes)] + resources.append( + _resource(node, "qemu", str(vmid), {"name": f"vm-{vmid}", "status": "stopped"}) + ) + for vmid in range(200, 220): + node = nodes[(vmid - 200) % len(nodes)] + resources.append( + _resource(node, "lxc", str(vmid), {"name": f"ct-{vmid}", "status": "stopped"}) + ) + for node in nodes: + resources.append( + _resource( + node, + "storage", + f"local-{node.name}", + {"content": ["images"], "shared": False, "status": "available"}, + ) + ) + resources.append( + _resource( + nodes[0], + "storage", + "shared", + {"content": ["images", "backup"], "shared": True, "status": "available"}, + ) + ) + resources.append(_resource(nodes[0], "pool", "development", {"members": ["100", "101", "200"]})) + tasks = tuple(_completed_task(index, "qmstart", str(99 + index)) for index in range(1, 11)) + return SeedProfile("medium", nodes, tuple(resources), tasks) + + +def large_profile(*, node_count: int = 10, resource_count: int = 10_000) -> SeedProfile: + if node_count < 1 or resource_count < 1: + raise ValueError("large profile counts must be positive") + nodes = tuple(_node(f"pve{index}") for index in range(1, node_count + 1)) + resources = tuple( + _resource( + nodes[index % node_count], + "qemu" if index % 4 else "lxc", + str(100 + index), + {"name": f"guest-{100 + index}", "status": "stopped"}, + ) + for index in range(resource_count) + ) + return SeedProfile("large", nodes, resources) + + +def ha_demo_profile() -> SeedProfile: + profile = medium_profile() + resources = ( + *profile.resources, + _resource(profile.nodes[0], "ha", "vm:100", {"state": "started", "group": "primary"}), + ) + return SeedProfile("ha-demo", profile.nodes, resources, profile.tasks) + + +def minimal_profile() -> SeedProfile: + node = _node("pve01") + resources = ( + _resource(node, "storage", "local", {"content": ["iso", "backup"], "status": "available"}), + _resource( + node, "storage", "local-lvm", {"content": ["images", "rootdir"], "status": "available"} + ), + ) + return SeedProfile("minimal", (node,), resources) + + +def broken_storage_profile() -> SeedProfile: + profile = small_profile() + resources = tuple( + _resource( + next(node for node in profile.nodes if node.id == resource.node_id), + resource.kind, + resource.external_id, + {**resource.state, "status": "offline", "error": "simulated I/O failure"} + if resource.kind == "storage" and resource.external_id == "local-lvm" + else resource.state, + ) + for resource in profile.resources + ) + return SeedProfile("broken-storage", profile.nodes, resources, profile.tasks) + + +def build_profile( + name: str, *, large_nodes: int = 10, large_resources: int = 10_000 +) -> SeedProfile: + if name == "small": + return small_profile() + if name == "medium": + return medium_profile() + if name == "large": + return large_profile(node_count=large_nodes, resource_count=large_resources) + if name == "ha-demo": + return ha_demo_profile() + if name == "broken-storage": + return broken_storage_profile() + if name == "minimal": + return minimal_profile() + if name == "demo-cluster": + from app.simulation.demo_cluster import demo_cluster_profile + + return demo_cluster_profile() + raise ValueError(f"unknown seed profile: {name}") + + +def _storage_type(resource: SeedResource) -> str: + configured = resource.state.get("storage_type") + if isinstance(configured, str) and configured: + return configured + if resource.external_id.startswith("local"): + if "lvm" in resource.external_id: + return "lvmthin" + if "zfs" in resource.external_id: + return "zfspool" + return "dir" + if resource.external_id.startswith("ceph"): + return "ceph" + if resource.external_id.startswith("nfs"): + return "nfs" + return "dir" + + +def _storage_capacity(resource: SeedResource) -> tuple[int | None, int | None]: + total = resource.state.get("total_bytes", resource.state.get("capacity_bytes")) + used = resource.state.get("used_bytes") + total_bytes = int(total) if isinstance(total, int) else None + used_bytes = int(used) if isinstance(used, int) else None + return total_bytes, used_bytes + + +async def clear_simulation_state(connection: Connection) -> None: + """Remove all mutable simulator state so a seed/reset never fails on leftovers. + + API-created guests, storages, users, groups, roles, ACL/tokens and custom + realms must not block "Remove demo data" / reseed. Builtin auth realms + (`pam`, `pve`, `test`) are kept because principals reference them. + """ + for statement in ( + "DELETE FROM task_logs", + "DELETE FROM task_events", + "DELETE FROM resource_locks", + "DELETE FROM tasks", + "DELETE FROM pool_members", + "DELETE FROM backups", + "DELETE FROM snapshots", + "DELETE FROM storage_contents", + "DELETE FROM vm_disks", + "DELETE FROM vm_network_interfaces", + "DELETE FROM virtual_machines", + "DELETE FROM containers", + "DELETE FROM storages", + "DELETE FROM pools", + "DELETE FROM resources", + "DELETE FROM nodes", + "DELETE FROM openid_pending", + "DELETE FROM tfa_entries", + "DELETE FROM group_acl_entries", + "DELETE FROM identity_group_members", + "DELETE FROM acl_entries", + "DELETE FROM api_tokens", + "DELETE FROM auth_tickets", + "DELETE FROM identity_groups", + "DELETE FROM principals", + "DELETE FROM roles", + "DELETE FROM realms WHERE name NOT IN ('pam', 'pve', 'test')", + "DELETE FROM fault_injections", + "DELETE FROM scenario_rules", + "DELETE FROM audit_events", + ): + await connection.execute(statement) + await connection.execute( + """UPDATE clusters + SET name = 'pve-simulator', + metadata = '{}'::jsonb, + updated_at = now() + WHERE id = $1""", + CLUSTER_ID, + ) + + +async def simulation_state_summary(connection: Connection) -> dict[str, object]: + row = await connection.fetchrow( + """SELECT + c.name AS cluster_name, + COALESCE(c.metadata->>'profile', 'unknown') AS profile, + (SELECT count(*)::int FROM nodes) AS nodes, + (SELECT count(*)::int FROM resources WHERE kind = 'qemu') AS qemu, + (SELECT count(*)::int FROM resources WHERE kind = 'lxc') AS lxc, + (SELECT count(*)::int FROM resources WHERE kind = 'ceph-osd') AS ceph_osds, + (SELECT count(*)::int FROM resources WHERE kind = 'storage') AS storages, + (SELECT count(*)::int FROM backups) AS backups, + (SELECT count(*)::int FROM tasks) AS tasks, + (SELECT count(*)::int FROM task_logs) AS task_logs, + (SELECT count(*)::int FROM snapshots) AS snapshots, + (SELECT count(*)::int FROM principals) AS principals, + COALESCE( + (SELECT sum(capacity_bytes)::bigint FROM storages WHERE storage_type = 'ceph'), + 0 + ) AS ceph_capacity_bytes + FROM clusters c + WHERE c.id = $1""", + CLUSTER_ID, + ) + if row is None: + return {"profile": "unknown", "loaded": False} + payload = dict(row) + payload["loaded"] = payload["profile"] == "demo-cluster" + payload["ceph_capacity_pib"] = round((payload.get("ceph_capacity_bytes") or 0) / 1024**5, 2) + return payload + + +async def apply_seed(connection: Connection, profile: SeedProfile) -> None: + async with connection.transaction(): + await clear_simulation_state(connection) + await connection.execute( + """UPDATE clusters + SET name = $2, + metadata = $3::jsonb, + updated_at = now() + WHERE id = $1""", + CLUSTER_ID, + "prod-pve-cluster" if profile.name == "demo-cluster" else "pve-simulator", + json.dumps( + { + "profile": profile.name, + "nodes": len(profile.nodes), + "resources": len(profile.resources), + }, + sort_keys=True, + ), + ) + await connection.executemany( + "INSERT INTO nodes(id, name, status, metadata) VALUES($1, $2, $3, $4::jsonb)", + [ + ( + node.id, + node.name, + node.status, + json.dumps({"ops": default_node_ops_for_seed(node.name)}, sort_keys=True), + ) + for node in profile.nodes + ], + ) + await connection.executemany( + """INSERT INTO resources(id, node_id, kind, external_id, state) + VALUES($1, $2, $3, $4, $5::jsonb)""", + [ + ( + resource.id, + resource.node_id, + resource.kind, + resource.external_id, + json.dumps(resource.state, sort_keys=True), + ) + for resource in profile.resources + ], + ) + qemu = [resource for resource in profile.resources if resource.kind == "qemu"] + if qemu: + await connection.executemany( + """INSERT INTO virtual_machines(resource_id, cluster_id, vmid, config) + VALUES($1, 'dc760c47-d8d7-57e6-9404-f0c6f2395d8f', $2, $3::jsonb)""", + [ + ( + resource.id, + int(resource.external_id), + json.dumps(resource.state, sort_keys=True), + ) + for resource in qemu + ], + ) + containers = [resource for resource in profile.resources if resource.kind == "lxc"] + if containers: + await connection.executemany( + """INSERT INTO containers(resource_id, cluster_id, vmid, config) + VALUES($1, 'dc760c47-d8d7-57e6-9404-f0c6f2395d8f', $2, $3::jsonb)""", + [ + ( + resource.id, + int(resource.external_id), + json.dumps(resource.state, sort_keys=True), + ) + for resource in containers + ], + ) + storages = [resource for resource in profile.resources if resource.kind == "storage"] + if storages: + await connection.executemany( + """INSERT INTO storages( + resource_id, cluster_id, storage_id, storage_type, shared, + capacity_bytes, used_bytes, config + ) VALUES($1, $2, $3, $4, $5, $6, $7, $8::jsonb)""", + [ + ( + resource.id, + str(CLUSTER_ID), + resource.external_id, + _storage_type(resource), + bool(resource.state.get("shared", False)), + *_storage_capacity(resource), + json.dumps(resource.state, sort_keys=True), + ) + for resource in storages + ], + ) + contents = [ + ( + stable_id(f"content:{resource.external_id}:{content}"), + resource.id, + f"{resource.external_id}:{content}/seeded", + str(content), + ) + for resource in storages + for content in _string_list(resource.state, "content") + ] + if contents: + await connection.executemany( + """INSERT INTO storage_contents( + id, storage_resource_id, volume_id, content_type + ) VALUES($1, $2, $3, $4)""", + contents, + ) + pools = [resource for resource in profile.resources if resource.kind == "pool"] + if pools: + await connection.executemany( + """INSERT INTO pools(id, cluster_id, pool_id, metadata) + VALUES($1, 'dc760c47-d8d7-57e6-9404-f0c6f2395d8f', $2, $3::jsonb)""", + [ + (resource.id, resource.external_id, json.dumps(resource.state, sort_keys=True)) + for resource in pools + ], + ) + members = [ + (pool.id, member.id) + for pool in pools + for external_id in _string_list(pool.state, "members") + for member in profile.resources + if member.external_id == external_id and member.kind in {"qemu", "lxc"} + ] + if members: + await connection.executemany( + "INSERT INTO pool_members(pool_id, resource_id) VALUES($1, $2)", members + ) + if profile.tasks: + await connection.executemany( + """INSERT INTO tasks(id, upid, status, payload, task_type, progress, result) + VALUES($1, $2, 'success', $3::jsonb, $4, 100, '{\"seeded\":true}'::jsonb)""", + [ + (task.id, task.upid, json.dumps(task.payload, sort_keys=True), task.task_type) + for task in profile.tasks + ], + ) + await connection.execute( + """INSERT INTO principals(id, name, password_hash, realm_name) + VALUES($1, 'root@pam', $2, 'pam') + ON CONFLICT (name) DO UPDATE SET password_hash=EXCLUDED.password_hash, + realm_name=EXCLUDED.realm_name""", + stable_id("principal:root@pam"), + hash_secret("secret", salt=b"pve-simulator-v1"), + ) + await connection.execute( + """INSERT INTO api_tokens(principal_id, token_id, secret_hash, privileges) + VALUES($1, 'automation', $2, $3) + ON CONFLICT (principal_id, token_id) DO UPDATE + SET secret_hash=EXCLUDED.secret_hash, privileges=EXCLUDED.privileges""", + stable_id("principal:root@pam"), + hash_secret("automation-secret", salt=b"pve-token-seed-v1"), + ["VM.Audit", "VM.PowerMgmt", "Sys.Audit"], + ) + auditor_id = stable_id("principal:auditor@pve") + await connection.execute( + """INSERT INTO principals(id, name, password_hash, realm_name) + VALUES($1, 'auditor@pve', $2, 'pve') + ON CONFLICT (name) DO UPDATE SET password_hash=EXCLUDED.password_hash, + realm_name=EXCLUDED.realm_name""", + auditor_id, + hash_secret("auditor-secret", salt=b"pve-auditor-v1"), + ) + await connection.execute( + """INSERT INTO roles(name, privileges) + VALUES('PVEAuditor', $1) + ON CONFLICT (name) DO UPDATE SET privileges=EXCLUDED.privileges""", + ["Sys.Audit", "VM.Audit"], + ) + await connection.execute( + "DELETE FROM acl_entries WHERE principal_id=$1 AND role_name='PVEAuditor'", + auditor_id, + ) + auditor_group_id = await connection.fetchval( + """INSERT INTO identity_groups(id, group_id, comment) + VALUES($1, 'auditors', 'Read-only operators') + ON CONFLICT (group_id) DO UPDATE SET comment=EXCLUDED.comment + RETURNING id""", + stable_id("group:auditors"), + ) + await connection.execute( + """INSERT INTO identity_group_members(group_id, principal_id) + VALUES($1, $2) ON CONFLICT DO NOTHING""", + auditor_group_id, + auditor_id, + ) + await connection.execute( + """INSERT INTO group_acl_entries(group_id, role_name, path, propagate) + VALUES($1, 'PVEAuditor', '/', true) + ON CONFLICT (group_id, role_name, path) DO UPDATE + SET propagate=EXCLUDED.propagate""", + auditor_group_id, + ) + await connection.execute( + """INSERT INTO api_tokens(principal_id, token_id, secret_hash, privileges) + VALUES($1, 'readonly', $2, $3) + ON CONFLICT (principal_id, token_id) DO UPDATE + SET secret_hash=EXCLUDED.secret_hash, privileges=EXCLUDED.privileges""", + auditor_id, + hash_secret("readonly-secret", salt=b"pve-readonly-v1"), + ["Sys.Audit", "VM.Audit"], + ) + for username, role_name, privileges, acl_path, token_id, token_secret in ( + ( + "operator@pve", + "PVEVMOperator", + ["VM.Audit", "VM.PowerMgmt"], + "/vms", + "operator", + "operator-secret", + ), + ( + "storage@pve", + "PVEStorageUser", + ["Datastore.Audit", "Datastore.AllocateSpace"], + "/storage", + "storage", + "storage-secret", + ), + ): + principal_id = stable_id(f"principal:{username}") + await connection.execute( + """INSERT INTO principals(id, name, password_hash, realm_name) + VALUES($1, $2, $3, 'pve') + ON CONFLICT (name) DO UPDATE SET password_hash=EXCLUDED.password_hash, + realm_name=EXCLUDED.realm_name""", + principal_id, + username, + hash_secret(f"{username}-password", salt=f"seed:{username}".encode()), + ) + await connection.execute( + """INSERT INTO roles(name, privileges) VALUES($1, $2) + ON CONFLICT (name) DO UPDATE SET privileges=EXCLUDED.privileges""", + role_name, + privileges, + ) + await connection.execute( + """INSERT INTO acl_entries(principal_id, role_name, path, propagate) + VALUES($1, $2, $3, true) + ON CONFLICT (principal_id, role_name, path) DO UPDATE + SET propagate=EXCLUDED.propagate""", + principal_id, + role_name, + acl_path, + ) + await connection.execute( + """INSERT INTO api_tokens(principal_id, token_id, secret_hash, privileges) + VALUES($1, $2, $3, $4) + ON CONFLICT (principal_id, token_id) DO UPDATE + SET secret_hash=EXCLUDED.secret_hash, privileges=EXCLUDED.privileges, + privilege_separation=true""", + principal_id, + token_id, + hash_secret(token_secret, salt=f"token:{username}".encode()), + privileges, + ) + if profile.name == "demo-cluster": + await _apply_demo_cluster_extras(connection, profile) + + +async def _apply_demo_cluster_extras(connection: Connection, profile: SeedProfile) -> None: + names = {node.id: node.name for node in profile.nodes} + guests = [resource for resource in profile.resources if resource.kind in {"qemu", "lxc"}] + + disks: list[tuple[uuid.UUID, uuid.UUID, str, str, int, str]] = [] + for index, resource in enumerate(guests): + node_name = names[resource.node_id] + disk_count = 1 + (index % 3) + for disk_index in range(disk_count): + device = "rootfs" if resource.kind == "lxc" and disk_index == 0 else f"scsi{disk_index}" + storage_id = "ceph-prod" if (index + disk_index) % 4 == 0 else f"local-lvm-{node_name}" + size_bytes = (20 + (index % 9) * 10 + disk_index * 15) * 1024**3 + disks.append( + ( + stable_id(f"disk:{resource.external_id}:{device}"), + resource.id, + device, + storage_id, + size_bytes, + json.dumps({"format": "raw" if disk_index else "qcow2"}, sort_keys=True), + ) + ) + if disks: + await connection.executemany( + """INSERT INTO vm_disks(id, resource_id, device, storage_id, size_bytes, metadata) + VALUES($1, $2, $3, $4, $5, $6::jsonb)""", + disks, + ) + + interfaces: list[tuple[uuid.UUID, uuid.UUID, str, str]] = [] + for index, resource in enumerate(guests): + interfaces.append( + ( + stable_id(f"net:{resource.external_id}:net0"), + resource.id, + "net0", + json.dumps( + { + "bridge": "vmbr0", + "firewall": index % 7 != 0, + "tag": (index % 12) * 10 or None, + }, + sort_keys=True, + ), + ) + ) + if index % 5 == 0: + interfaces.append( + ( + stable_id(f"net:{resource.external_id}:net1"), + resource.id, + "net1", + json.dumps({"bridge": "vmbr1", "firewall": True}, sort_keys=True), + ) + ) + if interfaces: + await connection.executemany( + """INSERT INTO vm_network_interfaces(id, resource_id, device, config) + VALUES($1, $2, $3, $4::jsonb)""", + interfaces, + ) + + snapshots: list[tuple[uuid.UUID, uuid.UUID, str, str | None, str, str]] = [] + for index, resource in enumerate(guests): + if index % 7 != 0: + continue + for snap_index in range(1 + (index % 3)): + snap_name = f"snap-{snap_index:02d}" + snapshots.append( + ( + stable_id(f"snapshot:{resource.external_id}:{snap_name}"), + resource.id, + snap_name, + None if snap_index == 0 else f"snap-{snap_index - 1:02d}", + f"Automated snapshot #{snap_index}", + json.dumps({"vmstate": index % 2 == 0}, sort_keys=True), + ) + ) + if snapshots: + await connection.executemany( + """INSERT INTO snapshots(id, resource_id, name, parent_name, description, state) + VALUES($1, $2, $3, $4, $5, $6::jsonb)""", + snapshots, + ) + + storage_rows = await connection.fetch( + """SELECT s.resource_id, s.storage_id, n.name AS node_name + FROM storages s + JOIN resources r ON r.id = s.resource_id + JOIN nodes n ON n.id = r.node_id + WHERE s.storage_id LIKE 'backup-%' OR s.storage_id IN ('ceph-prod', 'nfs-backup')""" + ) + storage_by_id = {row["storage_id"]: row["resource_id"] for row in storage_rows} + storage_by_node = { + str(row["node_name"]): row["resource_id"] + for row in storage_rows + if str(row["storage_id"]).startswith("backup-") + } + fallback_backup = storage_by_id.get("nfs-backup") or storage_by_id.get("ceph-prod") + if fallback_backup is not None: + backups: list[tuple[uuid.UUID, uuid.UUID | None, uuid.UUID, str, int, str]] = [] + qemu_guests = [resource for resource in guests if resource.kind == "qemu"] + for index, resource in enumerate(qemu_guests): + node_name = names[resource.node_id] + backup_storage = storage_by_node.get(node_name, fallback_backup) + volume_id = f"backup/vzdump-qemu-{resource.external_id}-2026_07_15-{index:04d}.vma.zst" + backups.append( + ( + stable_id(f"backup:{resource.external_id}:{index}"), + resource.id, + backup_storage, + volume_id, + (8 + (index % 40)) * 1024**3, + json.dumps( + { + "mode": "snapshot" if index % 3 else "suspend", + "notes-template": "Daily backup", + "node": node_name, + }, + sort_keys=True, + ), + ) + ) + if backups: + await connection.executemany( + """INSERT INTO backups( + id, resource_id, storage_resource_id, volume_id, size_bytes, metadata + ) VALUES($1, $2, $3, $4, $5, $6::jsonb)""", + backups, + ) + + guest_list = sorted( + guests, key=lambda resource: (names[resource.node_id], resource.external_id) + ) + extra_tasks: list[tuple[uuid.UUID, str, str, str, str]] = [] + for index in range(251, 321): + guest = guest_list[(index - 251) % len(guest_list)] + node_name = names[guest.node_id] + node = next(node for node in profile.nodes if node.name == node_name) + task_type = ("vzdump", "qmmigrate", "qmstart", "cephosd")[index % 4] + status = "running" if index % 17 == 0 else "error" if index % 23 == 0 else "success" + extra_tasks.append( + ( + stable_id(f"demo-task-extra:{index}"), + f"UPID:{node.name}:{index:07X}:{index:07X}:68{index:06X}:" + f"{task_type}:{guest.external_id}:operator@pve:", + status, + json.dumps( + {"resource_id": guest.external_id, "node": node.name}, + sort_keys=True, + ), + task_type, + ) + ) + if extra_tasks: + await connection.executemany( + """INSERT INTO tasks(id, upid, status, payload, task_type, progress, result, error) + VALUES($1, $2, $3, $4::jsonb, $5, + CASE WHEN $3 = 'success' THEN 100 WHEN $3 = 'running' THEN 45 ELSE 0 END, + CASE WHEN $3 = 'success' THEN '{\"seeded\":true}'::jsonb ELSE NULL END, + CASE WHEN $3 = 'error' THEN 'simulated backup failure' ELSE NULL END)""", + extra_tasks, + ) + + task_rows = await connection.fetch( + "SELECT id, task_type, payload FROM tasks ORDER BY upid LIMIT 180" + ) + logs: list[tuple[uuid.UUID, str]] = [] + for task in task_rows: + payload = task["payload"] + if isinstance(payload, dict): + resource_id = payload.get("resource_id", "unknown") + node_label = payload.get("node", "pve01") + else: + resource_id = "unknown" + node_label = "unknown" + messages: tuple[str, ...] = ( + f"starting task {task['task_type']} on {node_label}", + f"processing guest {resource_id}", + f"task {task['task_type']} finished successfully", + ) + if task["task_type"] == "vzdump": + messages = ( + f"INFO: starting backup of VM {resource_id} on {node_label}", + f"INFO: snapshot create VM {resource_id}", + f"INFO: archive file size: {(8 + hash(str(task['id'])) % 40)}GB", + "INFO: Backup finished successfully", + ) + logs.extend((task["id"], message) for message in messages) + if logs: + await connection.executemany( + "INSERT INTO task_logs(task_id, message) VALUES($1, $2)", + logs, + ) + + demo_users = ( + ("admin@pve", "PVEAdmin", ["/"], ["Sys.Modify", "Sys.Audit", "Datastore.Allocate"]), + ("devops@pve", "PVEAdmin", ["/vms"], ["Sys.Audit", "VM.Allocate", "VM.PowerMgmt"]), + ( + "backup-operator@pve", + "PVEDatastoreAdmin", + ["/storage"], + ["Datastore.Allocate", "Datastore.Audit"], + ), + ("ceph-monitor@pve", "PVEAuditor", ["/"], ["Sys.Audit", "Datastore.Audit"]), + ("junior@pve", "PVEAuditor", ["/vms"], ["Sys.Audit", "VM.Audit"]), + ("security@pve", "PVEAuditor", ["/access"], ["Sys.Audit", "User.Modify"]), + ) + for username, role_name, acl_paths, privileges in demo_users: + principal_id = stable_id(f"principal:{username}") + await connection.execute( + """INSERT INTO principals(id, name, password_hash, realm_name) + VALUES($1, $2, $3, 'pve') + ON CONFLICT (name) DO UPDATE SET password_hash=EXCLUDED.password_hash, + realm_name=EXCLUDED.realm_name""", + principal_id, + username, + hash_secret(f"{username}-password", salt=f"seed:{username}".encode()), + ) + await connection.execute( + """INSERT INTO roles(name, privileges) VALUES($1, $2) + ON CONFLICT (name) DO UPDATE SET privileges=EXCLUDED.privileges""", + role_name, + privileges, + ) + for acl_path in acl_paths: + await connection.execute( + """INSERT INTO acl_entries(principal_id, role_name, path, propagate) + VALUES($1, $2, $3, true) + ON CONFLICT (principal_id, role_name, path) DO UPDATE + SET propagate=EXCLUDED.propagate""", + principal_id, + role_name, + acl_path, + ) + + +async def seed_url( + database_url: str, + profile_name: str = "small", + *, + large_nodes: int = 10, + large_resources: int = 10_000, +) -> dict[str, object]: + connection = await asyncpg.connect(database_url) + try: + profile = build_profile( + profile_name, large_nodes=large_nodes, large_resources=large_resources + ) + await apply_seed(connection, profile) + return profile.logical_state() + finally: + await connection.close() diff --git a/app/simulation/seed_cli.py b/app/simulation/seed_cli.py new file mode 100644 index 0000000..1a8a9aa --- /dev/null +++ b/app/simulation/seed_cli.py @@ -0,0 +1,44 @@ +"""Apply a deterministic simulation seed.""" + +import asyncio +import json +import os + +from app.config import get_settings +from app.db.pool import AsyncpgDatabase +from app.vsphere.seed import seed_vsphere_inventory + + +async def run() -> None: + settings = get_settings() + enable_pve = os.getenv("ENABLE_PVE_STUB", "false").lower() in {"1", "true", "yes"} + proxmox_stub: dict | None = None + if enable_pve: + from app.simulation.seed import seed_url + + proxmox_stub = await seed_url( + settings.database_url.get_secret_value(), + os.getenv("SEED_PROFILE", "small"), + large_nodes=int(os.getenv("SEED_LARGE_NODES", "10")), + large_resources=int(os.getenv("SEED_LARGE_RESOURCES", "10000")), + ) + database = AsyncpgDatabase(settings) + await database.connect() + try: + vsphere = await seed_vsphere_inventory( + database, + force=True, + profile=os.getenv("SEED_VSPHERE_PROFILE", "large"), + large_hosts=int(os.getenv("SEED_VSPHERE_LARGE_HOSTS", "10")), + large_vms=int(os.getenv("SEED_VSPHERE_LARGE_VMS", "1000")), + ) + finally: + await database.close() + payload = {"vsphere": vsphere} + if proxmox_stub is not None: + payload["proxmox_stub"] = proxmox_stub + print(json.dumps(payload, sort_keys=True)) + + +if __name__ == "__main__": + asyncio.run(run()) diff --git a/app/simulation/transitions.py b/app/simulation/transitions.py new file mode 100644 index 0000000..59a213d --- /dev/null +++ b/app/simulation/transitions.py @@ -0,0 +1,67 @@ +"""Explicit virtual-machine state machine.""" + +from __future__ import annotations + +from dataclasses import dataclass +from enum import StrEnum + +from app.simulation.clock import Clock + + +class VmState(StrEnum): + STOPPED = "stopped" + STARTING = "starting" + RUNNING = "running" + PAUSING = "pausing" + PAUSED = "paused" + RESUMING = "resuming" + STOPPING = "stopping" + MIGRATING = "migrating" + SNAPSHOTTING = "snapshotting" + BACKING_UP = "backing_up" + ERROR = "error" + + +class InvalidTransitionError(ValueError): + pass + + +TRANSITIONS: dict[tuple[VmState, str], tuple[VmState, VmState]] = { + (VmState.STOPPED, "start"): (VmState.STARTING, VmState.RUNNING), + (VmState.RUNNING, "stop"): (VmState.STOPPING, VmState.STOPPED), + (VmState.RUNNING, "shutdown"): (VmState.STOPPING, VmState.STOPPED), + (VmState.RUNNING, "reboot"): (VmState.STOPPING, VmState.RUNNING), + (VmState.RUNNING, "reset"): (VmState.STOPPING, VmState.RUNNING), + (VmState.RUNNING, "suspend"): (VmState.PAUSING, VmState.PAUSED), + (VmState.RUNNING, "pause"): (VmState.PAUSING, VmState.PAUSED), + (VmState.PAUSED, "resume"): (VmState.RESUMING, VmState.RUNNING), + (VmState.RUNNING, "migrate"): (VmState.MIGRATING, VmState.RUNNING), + (VmState.STOPPED, "migrate"): (VmState.MIGRATING, VmState.STOPPED), + (VmState.RUNNING, "snapshot"): (VmState.SNAPSHOTTING, VmState.RUNNING), + (VmState.STOPPED, "snapshot"): (VmState.SNAPSHOTTING, VmState.STOPPED), + (VmState.RUNNING, "backup"): (VmState.BACKING_UP, VmState.RUNNING), + (VmState.STOPPED, "backup"): (VmState.BACKING_UP, VmState.STOPPED), +} + + +@dataclass(frozen=True, slots=True) +class Transition: + operation: str + before: VmState + intermediate: VmState + after: VmState + + +def plan_transition(state: VmState, operation: str) -> Transition: + states = TRANSITIONS.get((state, operation)) + if states is None: + raise InvalidTransitionError(f"cannot {operation} VM while it is {state}") + return Transition(operation, state, states[0], states[1]) + + +async def execute_transition( + state: VmState, operation: str, clock: Clock, duration_seconds: float +) -> tuple[VmState, VmState]: + transition = plan_transition(state, operation) + await clock.sleep(duration_seconds) + return transition.intermediate, transition.after diff --git a/app/surface_probe.py b/app/surface_probe.py new file mode 100644 index 0000000..fc479b5 --- /dev/null +++ b/app/surface_probe.py @@ -0,0 +1,282 @@ +"""Probe every declared contract method across majors 6-9. + +Order: GET, then PUT, then POST, then DELETE. Critical buckets +(``unimplemented_501``, ``unsupported_message``, ``server_5xx``, +``exception``) must stay empty — this module backs the CI surface gate. +""" + +from __future__ import annotations + +import asyncio +import json +import os +import re +import sys +from collections import Counter, defaultdict +from pathlib import Path +from typing import Any +from urllib.parse import quote + +import asyncpg # type: ignore[import-untyped] +from httpx import ASGITransport, AsyncClient +from pydantic import SecretStr + +from app.config import Settings +from app.contracts.examples import path_param_example, schema_example +from app.contracts.model import Method, Snapshot +from app.db.migrations import migrate +from app.db.pool import AsyncpgDatabase +from app.main import create_app +from app.simulation.seed import apply_seed, small_profile +from app.web.contract_catalog import get_major_releases + +_BUNDLED_9 = Path( + "contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/snapshot.json" +) +_EVIDENCE_9 = Path("evidence/pve-9.2.3.json") +_PATH_RE = re.compile(r"\{([^{}]+)\}") +_FORBIDDEN = re.compile( + r"not supported in the emulator|not implemented in the simulator|" + r"handler pending for this contract method|is not supported in the (emulator|simulator)", + re.I, +) +_EXTRA_PATH: dict[str, object] = { + "groupid": "admins", + "roleid": "Administrator", + "zone": "localnet", + "vnet": "vnet0", + "subnet": "10.0.0.0-24", + "controller": "evpn1", + "dns": "dns1", + "ipam": "pve", + "flag": "noout", + "osdid": "0", + "monid": "0", + "id": "example", + "cputype": "custom1", + "pci-id-or-mapping": "0000:00:1f.0", + "rule": "rule1", + "sid": "vm:100", + "pos": "0", + "cidr": "10.0.0.0/24", + "tokenid": "automation", + "fabric_id": "fab1", + "node_id": "pve01", + "url_seq": "1", + "route-map-id": "rm1", + "order": "10", + "userid": "root@pam", + "realm": "pam", + "name": "example", + "plugin": "example", + "target": "example", +} + + +def _path_value(name: str) -> str: + value = path_param_example(name) + if value is None: + value = _EXTRA_PATH.get(name, "example") + return str(value) + + +def render_path(template: str) -> str: + def replace(match: re.Match[str]) -> str: + return quote(str(_path_value(match.group(1))), safe="@._-") + + return _PATH_RE.sub(replace, template) + + +def body_for(method: Method, path_template: str) -> dict[str, Any]: + path_names = set(_PATH_RE.findall(path_template)) + payload: dict[str, Any] = {} + for parameter in method.parameters: + if parameter.name in path_names: + continue + if parameter.definition.optional: + continue + payload[parameter.name] = schema_example(parameter.definition, name=parameter.name) + return payload + + +def classify(status: int, text: str) -> str: + if _FORBIDDEN.search(text or ""): + return "unsupported_message" + if status == 501: + return "unimplemented_501" + if 200 <= status < 300: + return "success_2xx" + if status in {401, 403}: + return "auth_401_403" + if status in {400, 404, 405, 409, 412, 422, 423}: + return "client_4xx" + if status >= 500: + return "server_5xx" + return f"other_{status}" + + +async def prepare_db(url: str) -> None: + connection = await asyncpg.connect(url) + try: + await migrate(connection) + await apply_seed(connection, small_profile()) + finally: + await connection.close() + + +async def login(client: AsyncClient) -> str: + response = await client.post( + "/api2/json/access/ticket", + content="username=root%40pam&password=secret", + headers={"content-type": "application/x-www-form-urlencoded"}, + ) + response.raise_for_status() + data = response.json()["data"] + client.cookies.set("PVEAuthCookie", data["ticket"]) + return str(data["CSRFPreventionToken"]) + + +async def probe_major( + client: AsyncClient, + csrf: str, + major: int, + snapshot: Snapshot, +) -> dict[str, Any]: + apply = await client.post("/ui/api/contract/apply", params={"major": major}) + apply.raise_for_status() + applied = apply.json() + report = (await client.get("/admin/compatibility")).json() + + by_verb: dict[str, Counter[str]] = defaultdict(Counter) + failures: list[dict[str, Any]] = [] + samples_ok: dict[str, int] = Counter() + + methods = [(path.path, method) for path in snapshot.paths for method in path.methods] + order = {"GET": 0, "PUT": 1, "POST": 2, "DELETE": 3} + methods.sort(key=lambda item: (order.get(item[1].verb.upper(), 9), item[0])) + + for path_template, method in methods: + verb = method.verb.upper() + url = f"/api2/json{render_path(path_template)}" + headers = {"CSRFPreventionToken": csrf} if verb != "GET" else {} + body = body_for(method, path_template) if verb in {"PUT", "POST"} else None + try: + if verb == "GET": + response = await client.get(url, headers=headers) + elif verb == "PUT": + response = await client.put(url, data=body or {}, headers=headers) + elif verb == "POST": + response = await client.post(url, data=body or {}, headers=headers) + elif verb == "DELETE": + response = await client.delete(url, headers=headers) + else: + continue + except Exception as exc: + by_verb[verb]["exception"] += 1 + failures.append( + { + "verb": verb, + "path": path_template, + "error": str(exc)[:200], + "bucket": "exception", + } + ) + continue + + text = response.text + bucket = classify(response.status_code, text) + by_verb[verb][bucket] += 1 + samples_ok[verb] += int(bucket == "success_2xx") + if bucket in {"unimplemented_501", "unsupported_message", "server_5xx", "exception"}: + failures.append( + { + "verb": verb, + "path": path_template, + "status": response.status_code, + "bucket": bucket, + "body": text[:240], + } + ) + + levels = report.get("levels") or {} + dims = report.get("dimensions") or {} + return { + "major": major, + "version": snapshot.source_version, + "apply": applied, + "declared": report.get("total_declared"), + "implemented": (levels.get("implemented") or {}).get("count"), + "verified": (levels.get("verified") or {}).get("count"), + "dimensions_min": min((item.get("count") or 0) for item in dims.values()) if dims else 0, + "by_verb": {verb: dict(counter) for verb, counter in by_verb.items()}, + "success_by_verb": dict(samples_ok), + "failure_count": len(failures), + "failures": failures[:40], + } + + +async def run_probe(*, database_url: str | None = None) -> list[dict[str, Any]]: + """Run the full surface probe and return per-major result dicts.""" + + url = database_url or os.environ.get("TEST_DATABASE_URL") or os.environ.get("DATABASE_URL") + if not url: + raise RuntimeError("TEST_DATABASE_URL / DATABASE_URL required") + await prepare_db(url) + settings = Settings( + database_url=SecretStr(url), + contract_snapshot=_BUNDLED_9, + compatibility_evidence=_EVIDENCE_9, + ticket_signing_key=SecretStr("development-only-signing-key-change-me"), + ) + app = create_app(settings=settings, database_factory=lambda s: AsyncpgDatabase(s)) + + releases = {release.major: release for release in get_major_releases()} + results: list[dict[str, Any]] = [] + async with app.router.lifespan_context(app): + async with AsyncClient( + transport=ASGITransport(app=app), + base_url="http://test", + timeout=30.0, + ) as client: + csrf = await login(client) + for major in (6, 7, 8, 9): + release = releases[major] + if release.bundled_revision is None: + raise RuntimeError(f"missing bundled revision for major {major}") + snapshot = Snapshot.model_validate_json( + (Path("contracts") / release.bundled_revision / "snapshot.json").read_bytes() + ) + # Keep a single DB seed for the whole run to avoid deadlocks with + # the live app pool during DELETE FROM cascades. + results.append(await probe_major(client, csrf, major, snapshot)) + return results + + +async def main() -> int: + try: + results = await run_probe() + except RuntimeError as error: + print(str(error), file=sys.stderr) + return 2 + out = Path("evidence/_api_surface_probe.json") + out.parent.mkdir(parents=True, exist_ok=True) + out.write_text(json.dumps(results, indent=2, ensure_ascii=False), encoding="utf-8") + print(json.dumps({"ok": True, "report": str(out), "majors": len(results)})) + for item in results: + print( + f"PVE {item['version']}: declared={item['declared']} " + f"impl={item['implemented']} ver={item['verified']} " + f"fail={item['failure_count']}" + ) + for verb in ("GET", "PUT", "POST", "DELETE"): + buckets = item["by_verb"].get(verb) or {} + if not buckets: + continue + total = sum(buckets.values()) + print(f" {verb}: total={total} {buckets}") + critical = sum(int(item["failure_count"]) for item in results) + return 1 if critical else 0 + + +if __name__ == "__main__": + raise SystemExit(asyncio.run(main())) diff --git a/app/tasks/__init__.py b/app/tasks/__init__.py new file mode 100644 index 0000000..6d311f0 --- /dev/null +++ b/app/tasks/__init__.py @@ -0,0 +1 @@ +"""Durable asynchronous task engine.""" diff --git a/app/tasks/backup.py b/app/tasks/backup.py new file mode 100644 index 0000000..7c481de --- /dev/null +++ b/app/tasks/backup.py @@ -0,0 +1,86 @@ +"""Worker semantics for backup/vzdump tasks.""" + +from __future__ import annotations + +import json +from typing import Any + +from app.simulation.clock import Clock +from app.simulation.seed import stable_id +from app.tasks.repository import Task, TaskRepository +from app.tasks.worker import TaskHandler + + +def backup_handler(repository: TaskRepository, clock: Clock) -> TaskHandler: + async def execute(task: Task) -> dict[str, Any]: + if task.task_type == "aptupdate": + node = str(task.payload.get("node", "unknown")) + await repository.append_log(task.id, f"starting apt update on {node}") + await clock.sleep(1.0) + async with repository.pool.acquire() as connection: + metadata = await connection.fetchval( + "SELECT metadata FROM nodes WHERE name=$1", + node, + ) + if metadata is not None: + payload = json.loads(metadata) if isinstance(metadata, str) else dict(metadata) + ops = payload.setdefault("ops", {}) + apt = ops.setdefault("apt", {}) + packages = list(apt.get("packages") or []) + for package in packages: + if isinstance(package, dict) and package.get("Status") == "upgradable": + package["Status"] = "installed" + if package.get("Version"): + package["OldVersion"] = package["Version"] + apt["packages"] = packages + apt["update"] = {"status": "stopped", "exitstatus": "OK"} + payload["ops"] = ops + await connection.execute( + "UPDATE nodes SET metadata=$2::jsonb, updated_at=now() WHERE name=$1", + node, + json.dumps(payload, sort_keys=True), + ) + await repository.append_log(task.id, "apt update finished") + return {"status": "OK"} + + node = str(task.payload["node"]) + vmids = [str(item) for item in task.payload.get("vmids", [])] + storage_id = str(task.payload.get("storage") or "nfs-backup") + await repository.append_log(task.id, f"starting vzdump on {node} for {len(vmids)} guests") + async with repository.pool.acquire() as connection: + storage_resource_id = await connection.fetchval( + "SELECT resource_id FROM storages WHERE storage_id=$1", + storage_id, + ) + if storage_resource_id is None: + raise ValueError(f"storage {storage_id} does not exist") + created = 0 + for index, vmid in enumerate(vmids): + resource_id = await connection.fetchval( + """SELECT r.id FROM resources r JOIN nodes n ON n.id=r.node_id + WHERE n.name=$1 AND r.kind='qemu' AND r.external_id=$2""", + node, + vmid, + ) + volume_id = f"backup/vzdump-qemu-{vmid}-{task.id.hex[:8]}-{index:04d}.vma.zst" + await connection.execute( + """INSERT INTO backups( + id, resource_id, storage_resource_id, volume_id, size_bytes, metadata + ) VALUES($1, $2, $3, $4, $5, $6::jsonb) + ON CONFLICT (storage_resource_id, volume_id) DO NOTHING""", + stable_id(f"backup-task:{task.id}:{vmid}"), + resource_id, + storage_resource_id, + volume_id, + (8 + index) * 1024**3, + json.dumps( + {"mode": task.payload.get("mode", "snapshot"), "type": "vzdump"}, + sort_keys=True, + ), + ) + created += 1 + await repository.append_log(task.id, f"backup archive created: {volume_id}") + await repository.append_log(task.id, f"vzdump finished ({created} archives)") + return {"created": created} + + return execute diff --git a/app/tasks/lxc.py b/app/tasks/lxc.py new file mode 100644 index 0000000..9c0e35f --- /dev/null +++ b/app/tasks/lxc.py @@ -0,0 +1,245 @@ +"""Worker semantics for asynchronous LXC transitions.""" + +from __future__ import annotations + +import json +import uuid +from collections.abc import Mapping +from typing import Any, cast + +from app.simulation.clock import Clock +from app.simulation.transitions import VmState, plan_transition +from app.tasks.repository import Task, TaskRepository +from app.tasks.worker import TaskHandler + + +def lxc_handler(repository: TaskRepository, clock: Clock) -> TaskHandler: + async def execute(task: Task) -> dict[str, Any]: + operation = task.task_type.removeprefix("lxc-") + if operation == "create": + return await _create(repository, task, clock) + if operation == "clone": + return await _clone(repository, task) + resource_id = uuid.UUID(str(task.payload["resource_id"])) + if operation == "delete": + return await _delete(repository, task, resource_id) + if operation.startswith("snapshot-"): + return await _snapshot( + repository, task, resource_id, operation.removeprefix("snapshot-") + ) + if operation == "migrate" or operation == "remote-migrate": + return await _migrate(repository, task, resource_id, clock) + async with repository.pool.acquire() as connection: + row = await connection.fetchrow("SELECT state FROM resources WHERE id=$1", resource_id) + if row is None: + raise ValueError("resource disappeared") + state = _object(row["state"]) + transition = plan_transition(VmState(str(state["status"])), operation) + state["status"] = transition.intermediate + await connection.execute( + "UPDATE resources SET state=$2::jsonb WHERE id=$1", + resource_id, + json.dumps(state), + ) + await repository.append_log(task.id, f"container {operation} started") + await clock.sleep(1.0) + async with repository.pool.acquire() as connection: + state["status"] = transition.after + await connection.execute( + "UPDATE resources SET state=$2::jsonb WHERE id=$1", + resource_id, + json.dumps(state), + ) + await repository.append_log(task.id, f"container {operation} completed") + return {"status": str(transition.after)} + + return execute + + +async def _create(repository: TaskRepository, task: Task, clock: Clock) -> dict[str, Any]: + node, vmid = str(task.payload["node"]), int(task.payload["vmid"]) + config = dict(task.payload.get("config", {})) + start = bool(task.payload.get("start", False)) + resource_id = uuid.uuid4() + status = "running" if start else "stopped" + state = {"status": status, **config} + async with repository.pool.acquire() as connection: + async with connection.transaction(): + node_row = await connection.fetchrow( + "SELECT id, cluster_id FROM nodes WHERE name=$1", node + ) + if node_row is None: + raise ValueError("node disappeared") + await connection.execute( + """INSERT INTO resources( + id, node_id, cluster_id, kind, external_id, state, metadata + ) VALUES($1, $2, $3, 'lxc', $4, $5::jsonb, '{}'::jsonb)""", + resource_id, + node_row["id"], + node_row["cluster_id"], + str(vmid), + json.dumps(state, sort_keys=True), + ) + await connection.execute( + """INSERT INTO containers(resource_id, cluster_id, vmid, config) + VALUES($1, $2, $3, $4::jsonb)""", + resource_id, + node_row["cluster_id"], + vmid, + json.dumps(config, sort_keys=True), + ) + if start: + await clock.sleep(0.5) + await repository.append_log(task.id, f"container {vmid} created") + return {"vmid": vmid, "status": status} + + +async def _delete(repository: TaskRepository, task: Task, resource_id: uuid.UUID) -> dict[str, Any]: + async with repository.pool.acquire() as connection: + status = await connection.execute("DELETE FROM resources WHERE id=$1", resource_id) + if status != "DELETE 1": + raise ValueError("resource disappeared") + await repository.append_log(task.id, "container deleted") + return {"deleted": True} + + +async def _snapshot( + repository: TaskRepository, + task: Task, + resource_id: uuid.UUID, + operation: str, +) -> dict[str, Any]: + name = str(task.payload["snapname"]) + async with repository.pool.acquire() as connection: + async with connection.transaction(): + if operation == "create": + row = await connection.fetchrow( + """SELECT r.state, c.config FROM resources r + JOIN containers c ON c.resource_id=r.id WHERE r.id=$1""", + resource_id, + ) + if row is None: + raise ValueError("resource disappeared") + captured = { + "resource_state": _object(row["state"]), + "config": _object(row["config"]), + } + await connection.execute( + """INSERT INTO snapshots(id, resource_id, name, description, state) + VALUES($1, $2, $3, $4, $5::jsonb)""", + uuid.uuid4(), + resource_id, + name, + str(task.payload.get("description", "")), + json.dumps(captured, sort_keys=True), + ) + elif operation == "delete": + status = await connection.execute( + "DELETE FROM snapshots WHERE resource_id=$1 AND name=$2", + resource_id, + name, + ) + if status != "DELETE 1": + raise ValueError("snapshot disappeared") + elif operation == "rollback": + row = await connection.fetchrow( + "SELECT state FROM snapshots WHERE resource_id=$1 AND name=$2", + resource_id, + name, + ) + if row is None: + raise ValueError("snapshot disappeared") + captured = _object(row["state"]) + state = dict(cast(Mapping[str, Any], captured["resource_state"])) + await connection.execute( + """UPDATE resources SET state=$2::jsonb, version=version+1, + updated_at=now() WHERE id=$1""", + resource_id, + json.dumps(state, sort_keys=True), + ) + await connection.execute( + "UPDATE containers SET config=$2::jsonb WHERE resource_id=$1", + resource_id, + json.dumps(captured["config"], sort_keys=True), + ) + else: + raise ValueError(f"unsupported snapshot operation: {operation}") + await repository.append_log(task.id, f"snapshot {name} {operation} completed") + return {"snapshot": name, "operation": operation} + + +async def _clone(repository: TaskRepository, task: Task) -> dict[str, Any]: + source_id = uuid.UUID(str(task.payload["source_resource_id"])) + target_id = uuid.uuid4() + node, vmid = str(task.payload["node"]), int(task.payload["vmid"]) + async with repository.pool.acquire() as connection: + async with connection.transaction(): + source = await connection.fetchrow( + """SELECT r.state, c.config FROM resources r + JOIN containers c ON c.resource_id=r.id WHERE r.id=$1""", + source_id, + ) + target = await connection.fetchrow( + "SELECT id, cluster_id FROM nodes WHERE name=$1", node + ) + if source is None or target is None: + raise ValueError("clone source or target disappeared") + config = _object(source["config"]) + if task.payload.get("name") is not None: + config["hostname"] = task.payload["name"] + state = {**_object(source["state"]), **config, "status": "stopped"} + await connection.execute( + """INSERT INTO resources(id,node_id,cluster_id,kind,external_id,state,metadata) + VALUES($1,$2,$3,'lxc',$4,$5::jsonb,'{}'::jsonb)""", + target_id, + target["id"], + target["cluster_id"], + str(vmid), + json.dumps(state), + ) + await connection.execute( + """INSERT INTO containers(resource_id,cluster_id,vmid,config) + VALUES($1,$2,$3,$4::jsonb)""", + target_id, + target["cluster_id"], + vmid, + json.dumps(config), + ) + await repository.append_log(task.id, f"container cloned to {vmid}") + return {"vmid": vmid, "node": node} + + +async def _migrate( + repository: TaskRepository, task: Task, resource_id: uuid.UUID, clock: Clock +) -> dict[str, Any]: + target = str(task.payload["target"]) + async with repository.pool.acquire() as connection: + row = await connection.fetchrow("SELECT state FROM resources WHERE id=$1", resource_id) + if row is None: + raise ValueError("resource disappeared") + state = _object(row["state"]) + transition = plan_transition(VmState(str(state["status"])), "migrate") + state["status"] = transition.intermediate + await connection.execute( + "UPDATE resources SET state=$2::jsonb WHERE id=$1", resource_id, json.dumps(state) + ) + await repository.append_log(task.id, f"migration to {target} started") + await clock.sleep(1.0) + async with repository.pool.acquire() as connection: + node = await connection.fetchrow("SELECT id FROM nodes WHERE name=$1", target) + if node is None: + raise ValueError("target node disappeared") + state["status"] = transition.after + await connection.execute( + """UPDATE resources SET node_id=$2,state=$3::jsonb,version=version+1, + updated_at=now() WHERE id=$1""", + resource_id, + node["id"], + json.dumps(state), + ) + await repository.append_log(task.id, f"migration to {target} completed") + return {"node": target, "status": str(transition.after)} + + +def _object(value: object) -> dict[str, Any]: + return json.loads(value) if isinstance(value, str) else dict(cast(Mapping[str, Any], value)) diff --git a/app/tasks/qemu.py b/app/tasks/qemu.py new file mode 100644 index 0000000..3d7b5db --- /dev/null +++ b/app/tasks/qemu.py @@ -0,0 +1,328 @@ +"""Worker semantics for asynchronous QEMU transitions.""" + +from __future__ import annotations + +import json +import uuid +from collections.abc import Mapping +from typing import Any, cast + +from app.simulation.clock import Clock +from app.simulation.transitions import VmState, plan_transition +from app.tasks.repository import Task, TaskRepository +from app.tasks.worker import TaskHandler + + +def qemu_handler(repository: TaskRepository, clock: Clock) -> TaskHandler: + async def execute(task: Task) -> dict[str, Any]: + operation = task.task_type.removeprefix("qemu-") + if operation == "create": + return await _create(repository, task) + if operation == "clone": + return await _clone(repository, task) + resource_id = uuid.UUID(str(task.payload["resource_id"])) + if operation == "update": + return await _update(repository, task, resource_id) + if operation == "delete": + return await _delete(repository, task, resource_id) + if operation.startswith("snapshot-"): + return await _snapshot( + repository, task, resource_id, operation.removeprefix("snapshot-") + ) + if operation == "migrate" or operation == "remote-migrate": + return await _migrate(repository, task, resource_id, clock) + if operation == "move-disk": + return await _move_disk(repository, task, resource_id) + async with repository.pool.acquire() as connection: + row = await connection.fetchrow("SELECT state FROM resources WHERE id=$1", resource_id) + if row is None: + raise ValueError("resource disappeared") + raw = row["state"] + state = json.loads(raw) if isinstance(raw, str) else dict(raw) + transition = plan_transition(VmState(str(state["status"])), operation) + state["status"] = transition.intermediate + await connection.execute( + "UPDATE resources SET state=$2::jsonb WHERE id=$1", + resource_id, + json.dumps(state), + ) + await repository.append_log(task.id, f"VM {operation} started") + await clock.sleep(1.0) + async with repository.pool.acquire() as connection: + state["status"] = transition.after + await connection.execute( + "UPDATE resources SET state=$2::jsonb WHERE id=$1", + resource_id, + json.dumps(state), + ) + await repository.append_log(task.id, f"VM {operation} completed") + return {"status": str(transition.after)} + + return execute + + +async def _create(repository: TaskRepository, task: Task) -> dict[str, Any]: + node, vmid = str(task.payload["node"]), int(task.payload["vmid"]) + config = dict(task.payload.get("config", {})) + resource_id = uuid.uuid4() + state = {"status": "stopped", **config} + async with repository.pool.acquire() as connection: + async with connection.transaction(): + node_row = await connection.fetchrow( + "SELECT id, cluster_id FROM nodes WHERE name=$1", node + ) + if node_row is None: + raise ValueError("node disappeared") + await connection.execute( + """INSERT INTO resources( + id, node_id, cluster_id, kind, external_id, state, metadata + ) VALUES($1, $2, $3, 'qemu', $4, $5::jsonb, '{}'::jsonb)""", + resource_id, + node_row["id"], + node_row["cluster_id"], + str(vmid), + json.dumps(state, sort_keys=True), + ) + await connection.execute( + """INSERT INTO virtual_machines(resource_id, cluster_id, vmid, config) + VALUES($1, $2, $3, $4::jsonb)""", + resource_id, + node_row["cluster_id"], + vmid, + json.dumps(config, sort_keys=True), + ) + await repository.append_log(task.id, f"VM {vmid} created") + return {"vmid": vmid, "status": "stopped"} + + +async def _update(repository: TaskRepository, task: Task, resource_id: uuid.UUID) -> dict[str, Any]: + changes = dict(task.payload.get("changes", {})) + delete_keys = tuple(str(task.payload.get("delete", "")).split(",")) + async with repository.pool.acquire() as connection: + async with connection.transaction(): + row = await connection.fetchrow( + """SELECT r.state, v.config FROM resources r + JOIN virtual_machines v ON v.resource_id=r.id WHERE r.id=$1""", + resource_id, + ) + if row is None: + raise ValueError("resource disappeared") + state = _object(row["state"]) + config = _object(row["config"]) + config.update(changes) + for key in delete_keys: + if key: + config.pop(key, None) + state.pop(key, None) + state.update(changes) + await connection.execute( + """UPDATE resources SET state=$2::jsonb, version=version+1, + updated_at=now() WHERE id=$1""", + resource_id, + json.dumps(state, sort_keys=True), + ) + await connection.execute( + "UPDATE virtual_machines SET config=$2::jsonb WHERE resource_id=$1", + resource_id, + json.dumps(config, sort_keys=True), + ) + await repository.append_log(task.id, "VM configuration updated") + return {"updated": sorted(changes), "deleted": sorted(key for key in delete_keys if key)} + + +async def _delete(repository: TaskRepository, task: Task, resource_id: uuid.UUID) -> dict[str, Any]: + async with repository.pool.acquire() as connection: + status = await connection.execute("DELETE FROM resources WHERE id=$1", resource_id) + if status != "DELETE 1": + raise ValueError("resource disappeared") + await repository.append_log(task.id, "VM deleted") + return {"deleted": True} + + +async def _snapshot( + repository: TaskRepository, + task: Task, + resource_id: uuid.UUID, + operation: str, +) -> dict[str, Any]: + name = str(task.payload["snapname"]) + async with repository.pool.acquire() as connection: + async with connection.transaction(): + if operation == "create": + row = await connection.fetchrow( + """SELECT r.state, v.config FROM resources r + JOIN virtual_machines v ON v.resource_id=r.id WHERE r.id=$1""", + resource_id, + ) + if row is None: + raise ValueError("resource disappeared") + captured = { + "resource_state": _object(row["state"]), + "config": _object(row["config"]), + "vmstate": bool(task.payload.get("vmstate", False)), + } + await connection.execute( + """INSERT INTO snapshots(id, resource_id, name, description, state) + VALUES($1, $2, $3, $4, $5::jsonb)""", + uuid.uuid4(), + resource_id, + name, + str(task.payload.get("description", "")), + json.dumps(captured, sort_keys=True), + ) + elif operation == "delete": + status = await connection.execute( + "DELETE FROM snapshots WHERE resource_id=$1 AND name=$2", + resource_id, + name, + ) + if status != "DELETE 1": + raise ValueError("snapshot disappeared") + elif operation == "rollback": + row = await connection.fetchrow( + "SELECT state FROM snapshots WHERE resource_id=$1 AND name=$2", + resource_id, + name, + ) + if row is None: + raise ValueError("snapshot disappeared") + captured = _object(row["state"]) + state = dict(cast(Mapping[str, Any], captured["resource_state"])) + if bool(task.payload.get("start", False)): + state["status"] = "running" + await connection.execute( + """UPDATE resources SET state=$2::jsonb, version=version+1, + updated_at=now() WHERE id=$1""", + resource_id, + json.dumps(state, sort_keys=True), + ) + await connection.execute( + "UPDATE virtual_machines SET config=$2::jsonb WHERE resource_id=$1", + resource_id, + json.dumps(captured["config"], sort_keys=True), + ) + else: + raise ValueError(f"unsupported snapshot operation: {operation}") + await repository.append_log(task.id, f"snapshot {name} {operation} completed") + return {"snapshot": name, "operation": operation} + + +async def _clone(repository: TaskRepository, task: Task) -> dict[str, Any]: + source_id = uuid.UUID(str(task.payload["source_resource_id"])) + target_id = uuid.uuid4() + node, vmid = str(task.payload["node"]), int(task.payload["vmid"]) + async with repository.pool.acquire() as connection: + async with connection.transaction(): + source = await connection.fetchrow( + """SELECT r.state, v.config FROM resources r + JOIN virtual_machines v ON v.resource_id=r.id WHERE r.id=$1""", + source_id, + ) + target = await connection.fetchrow( + "SELECT id, cluster_id FROM nodes WHERE name=$1", node + ) + if source is None or target is None: + raise ValueError("clone source or target disappeared") + config = _object(source["config"]) + if task.payload.get("name") is not None: + config["name"] = task.payload["name"] + state = {**_object(source["state"]), **config, "status": "stopped"} + await connection.execute( + """INSERT INTO resources(id,node_id,cluster_id,kind,external_id,state,metadata) + VALUES($1,$2,$3,'qemu',$4,$5::jsonb,'{}'::jsonb)""", + target_id, + target["id"], + target["cluster_id"], + str(vmid), + json.dumps(state), + ) + await connection.execute( + """INSERT INTO virtual_machines(resource_id,cluster_id,vmid,config) + VALUES($1,$2,$3,$4::jsonb)""", + target_id, + target["cluster_id"], + vmid, + json.dumps(config), + ) + await repository.append_log(task.id, f"VM cloned to {vmid}") + return {"vmid": vmid, "node": node} + + +async def _migrate( + repository: TaskRepository, task: Task, resource_id: uuid.UUID, clock: Clock +) -> dict[str, Any]: + target = str(task.payload["target"]) + async with repository.pool.acquire() as connection: + row = await connection.fetchrow("SELECT state FROM resources WHERE id=$1", resource_id) + if row is None: + raise ValueError("resource disappeared") + state = _object(row["state"]) + transition = plan_transition(VmState(str(state["status"])), "migrate") + state["status"] = transition.intermediate + await connection.execute( + "UPDATE resources SET state=$2::jsonb WHERE id=$1", resource_id, json.dumps(state) + ) + await repository.append_log(task.id, f"migration to {target} started") + await clock.sleep(1.0) + async with repository.pool.acquire() as connection: + node = await connection.fetchrow("SELECT id FROM nodes WHERE name=$1", target) + if node is None: + raise ValueError("target node disappeared") + state["status"] = transition.after + await connection.execute( + """UPDATE resources SET node_id=$2,state=$3::jsonb,version=version+1, + updated_at=now() WHERE id=$1""", + resource_id, + node["id"], + json.dumps(state), + ) + await repository.append_log(task.id, f"migration to {target} completed") + return {"node": target, "status": str(transition.after)} + + +async def _move_disk( + repository: TaskRepository, task: Task, resource_id: uuid.UUID +) -> dict[str, Any]: + disk = str(task.payload["disk"]) + target_disk = str(task.payload["target_disk"]) + storage = str(task.payload["storage"]) + async with repository.pool.acquire() as connection: + async with connection.transaction(): + row = await connection.fetchrow( + "SELECT config FROM virtual_machines WHERE resource_id=$1", resource_id + ) + if row is None: + raise ValueError("resource disappeared") + config = _object(row["config"]) + if disk not in config: + raise ValueError("disk disappeared") + original = str(config[disk]) + suffix = original.split(":", 1)[1] if ":" in original else original + config[target_disk] = f"{storage}:{suffix}" + if bool(task.payload.get("delete", True)) and target_disk != disk: + config.pop(disk, None) + await connection.execute( + "UPDATE virtual_machines SET config=$2::jsonb WHERE resource_id=$1", + resource_id, + json.dumps(config, sort_keys=True), + ) + await connection.execute( + """UPDATE resources SET state=state || $2::jsonb, version=version+1, + updated_at=now() WHERE id=$1""", + resource_id, + json.dumps({target_disk: config[target_disk]}, sort_keys=True), + ) + await connection.execute( + """UPDATE vm_disks SET device=$2,storage_id=$3 + WHERE resource_id=$1 AND device=$4""", + resource_id, + target_disk, + storage, + disk, + ) + await repository.append_log(task.id, f"disk {disk} moved to {storage}") + return {"disk": target_disk, "storage": storage} + + +def _object(value: object) -> dict[str, Any]: + return json.loads(value) if isinstance(value, str) else dict(cast(Mapping[str, Any], value)) diff --git a/app/tasks/repository.py b/app/tasks/repository.py new file mode 100644 index 0000000..3a4c0e6 --- /dev/null +++ b/app/tasks/repository.py @@ -0,0 +1,197 @@ +"""PostgreSQL repository for durable leased tasks.""" + +from __future__ import annotations + +import json +import uuid +from dataclasses import dataclass +from typing import Any + +import asyncpg # type: ignore[import-untyped] # noqa: F401 +from asyncpg import Pool, Record + +from app.db.primitives import ConflictError, require_affected, transaction + + +@dataclass(frozen=True, slots=True) +class Task: + id: uuid.UUID + upid: str + task_type: str + status: str + payload: dict[str, Any] + progress: int + cancel_requested: bool + attempt: int + + +def _task(row: Record) -> Task: + return Task( + id=row["id"], + upid=str(row["upid"]), + task_type=str(row["task_type"]), + status=str(row["status"]), + payload=json.loads(row["payload"]) + if isinstance(row["payload"], str) + else dict(row["payload"]), + progress=int(row["progress"]), + cancel_requested=bool(row["cancel_requested"]), + attempt=int(row["attempt"]), + ) + + +@dataclass(frozen=True, slots=True) +class TaskRepository: + pool: Pool + + async def create( + self, + *, + upid: str, + task_type: str, + payload: dict[str, Any], + resource_key: str | None = None, + idempotency_key: str | None = None, + ) -> Task: + task_id = uuid.uuid4() + async with transaction(self.pool) as connection: + if idempotency_key is not None: + existing = await connection.fetchrow( + "SELECT * FROM tasks WHERE idempotency_key=$1", idempotency_key + ) + if existing is not None: + return _task(existing) + row = await connection.fetchrow( + """INSERT INTO tasks(id, upid, task_type, status, payload, idempotency_key) + VALUES($1,$2,$3,'queued',$4::jsonb,$5) RETURNING *""", + task_id, + upid, + task_type, + json.dumps(payload), + idempotency_key, + ) + if resource_key is not None: + try: + await connection.execute( + "INSERT INTO resource_locks(resource_key, task_id) VALUES($1,$2)", + resource_key, + task_id, + ) + except Exception as error: + raise ConflictError(f"resource is locked: {resource_key}") from error + await connection.execute( + "INSERT INTO task_events(task_id, kind) VALUES($1,'created')", task_id + ) + if row is None: + raise RuntimeError("task insert returned no row") + return _task(row) + + async def claim(self, worker_id: str, lease_seconds: float) -> Task | None: + async with transaction(self.pool) as connection: + row = await connection.fetchrow( + """WITH candidate AS ( + SELECT id FROM tasks + WHERE status='queued' OR (status='running' AND lease_expires_at < now()) + ORDER BY created_at FOR UPDATE SKIP LOCKED LIMIT 1 + ) UPDATE tasks SET status='running', worker_id=$1, + lease_expires_at=now() + $2 * interval '1 second', attempt=attempt+1, + updated_at=now() + WHERE id=(SELECT id FROM candidate) RETURNING *""", + worker_id, + lease_seconds, + ) + if row is None: + return None + await connection.execute( + "INSERT INTO task_events(task_id, kind, data) VALUES($1,'claimed',$2::jsonb)", + row["id"], + json.dumps({"worker": worker_id}), + ) + return _task(row) + + async def heartbeat(self, task_id: uuid.UUID, worker_id: str, lease_seconds: float) -> None: + status = await self.pool.execute( + """UPDATE tasks SET lease_expires_at=now()+$3*interval '1 second', updated_at=now() + WHERE id=$1 AND worker_id=$2 AND status='running'""", + task_id, + worker_id, + lease_seconds, + ) + require_affected(status) + + async def progress(self, task_id: uuid.UUID, worker_id: str, value: int) -> None: + status = await self.pool.execute( + """UPDATE tasks SET progress=$3, updated_at=now() + WHERE id=$1 AND worker_id=$2 AND status='running'""", + task_id, + worker_id, + value, + ) + require_affected(status) + + async def append_log(self, task_id: uuid.UUID, message: str) -> None: + await self.pool.execute( + "INSERT INTO task_logs(task_id, message) VALUES($1,$2)", task_id, message + ) + + async def request_cancel(self, task_id: uuid.UUID) -> None: + status = await self.pool.execute( + """UPDATE tasks SET cancel_requested=true, updated_at=now() + WHERE id=$1 AND status IN ('queued','running')""", + task_id, + ) + require_affected(status) + + async def finish( + self, + task_id: uuid.UUID, + worker_id: str, + *, + status: str, + result: dict[str, Any] | None = None, + error: str | None = None, + ) -> None: + if status not in {"success", "error", "cancelled"}: + raise ValueError("invalid terminal task status") + async with transaction(self.pool) as connection: + command = await connection.execute( + """UPDATE tasks SET status=$3, result=$4::jsonb, error=$5, + progress=CASE WHEN $3='success' THEN 100 ELSE progress END, + lease_expires_at=NULL, updated_at=now() + WHERE id=$1 AND worker_id=$2 AND status='running'""", + task_id, + worker_id, + status, + json.dumps(result) if result is not None else None, + error, + ) + require_affected(command) + await connection.execute("DELETE FROM resource_locks WHERE task_id=$1", task_id) + await connection.execute( + "INSERT INTO task_events(task_id, kind, data) VALUES($1,$2,$3::jsonb)", + task_id, + status, + json.dumps({"error": error} if error else {}), + ) + + async def get(self, task_id: uuid.UUID) -> Task | None: + row = await self.pool.fetchrow("SELECT * FROM tasks WHERE id=$1", task_id) + return _task(row) if row is not None else None + + async def get_by_upid(self, upid: str) -> Task | None: + row = await self.pool.fetchrow("SELECT * FROM tasks WHERE upid=$1", upid) + return _task(row) if row is not None else None + + async def list_for_node(self, node: str) -> tuple[Task, ...]: + rows = await self.pool.fetch( + """SELECT * FROM tasks WHERE payload->>'node'=$1 + ORDER BY created_at DESC LIMIT 1000""", + node, + ) + return tuple(_task(row) for row in rows) + + async def logs(self, task_id: uuid.UUID) -> tuple[str, ...]: + rows = await self.pool.fetch( + "SELECT message FROM task_logs WHERE task_id=$1 ORDER BY sequence", task_id + ) + return tuple(str(row["message"]) for row in rows) diff --git a/app/tasks/upid.py b/app/tasks/upid.py new file mode 100644 index 0000000..521785e --- /dev/null +++ b/app/tasks/upid.py @@ -0,0 +1,75 @@ +"""Proxmox-compatible unique process/task identifiers.""" + +from __future__ import annotations + +import re +import secrets +import time +from dataclasses import dataclass + +UPID_RE = re.compile( + r"^UPID:(?P[A-Za-z0-9][A-Za-z0-9_-]*):" + r"(?P[0-9A-Fa-f]{8}):(?P[0-9A-Fa-f]{8}):" + r"(?P[0-9A-Fa-f]{8}):(?P[A-Za-z0-9_-]+):" + r"(?P[^:]*):(?P[^:]+):$" +) + + +@dataclass(frozen=True, slots=True) +class Upid: + node: str + pid: int + process_start: int + start_time: int + task_type: str + task_id: str + user: str + + def __post_init__(self) -> None: + for name, value in ( + ("pid", self.pid), + ("process_start", self.process_start), + ("start_time", self.start_time), + ): + if not 0 <= value <= 0xFFFFFFFF: + raise ValueError(f"{name} is outside the 32-bit UPID range") + if not self.node or ":" in self.node or not self.task_type or ":" in self.task_type: + raise ValueError("invalid UPID node or task type") + if ":" in self.task_id or not self.user or ":" in self.user: + raise ValueError("invalid UPID task id or user") + + def __str__(self) -> str: + return ( + f"UPID:{self.node}:{self.pid:08X}:{self.process_start:08X}:" + f"{self.start_time:08X}:{self.task_type}:{self.task_id}:{self.user}:" + ) + + @classmethod + def parse(cls, value: str) -> Upid: + match = UPID_RE.fullmatch(value) + if match is None: + raise ValueError("invalid UPID") + values = match.groupdict() + return cls( + node=values["node"], + pid=int(values["pid"], 16), + process_start=int(values["pstart"], 16), + start_time=int(values["start"], 16), + task_type=values["type"], + task_id=values["task_id"], + user=values["user"], + ) + + @classmethod + def allocate(cls, node: str, task_type: str, task_id: str, user: str) -> Upid: + """Build a collision-resistant UPID for a new task.""" + + return cls( + node=node, + pid=secrets.randbits(32), + process_start=secrets.randbits(32), + start_time=int(time.time()) & 0xFFFFFFFF, + task_type=task_type, + task_id=str(task_id), + user=user, + ) diff --git a/app/tasks/worker.py b/app/tasks/worker.py new file mode 100644 index 0000000..2e8c7f9 --- /dev/null +++ b/app/tasks/worker.py @@ -0,0 +1,99 @@ +"""Bounded durable task worker with cooperative cancellation.""" + +from __future__ import annotations + +import asyncio +import logging +from collections.abc import Awaitable, Callable +from dataclasses import dataclass, field +from typing import Any + +from app.tasks.repository import Task, TaskRepository + +TaskHandler = Callable[[Task], Awaitable[dict[str, Any] | None]] +logger = logging.getLogger(__name__) + + +@dataclass(slots=True) +class TaskWorker: + repository: TaskRepository + worker_id: str + handlers: dict[str, TaskHandler] + concurrency: int = 2 + lease_seconds: float = 30.0 + poll_seconds: float = 0.1 + _running: set[asyncio.Task[None]] = field(default_factory=set, init=False) + _stopping: asyncio.Event = field(default_factory=asyncio.Event, init=False) + + async def run(self) -> None: + self._stopping.clear() + try: + while not self._stopping.is_set(): + self._reap() + if len(self._running) >= self.concurrency: + await asyncio.sleep(self.poll_seconds) + continue + try: + task = await self.repository.claim(self.worker_id, self.lease_seconds) + except asyncio.CancelledError: + raise + except Exception: + logger.exception("task claim failed; polling will retry") + await asyncio.sleep(self.poll_seconds) + continue + if task is None: + await asyncio.sleep(self.poll_seconds) + continue + execution = asyncio.create_task(self._execute(task)) + self._running.add(execution) + finally: + if self._running: + await asyncio.gather(*self._running, return_exceptions=True) + self._running.clear() + + def stop(self) -> None: + self._stopping.set() + + def _reap(self) -> None: + self._running = {task for task in self._running if not task.done()} + + async def _execute(self, task: Task) -> None: + handler = self.handlers.get(task.task_type) + if handler is None: + await self.repository.finish( + task.id, self.worker_id, status="error", error="unsupported task type" + ) + return + try: + current = await self.repository.get(task.id) + if current is not None and current.cancel_requested: + await self.repository.finish(task.id, self.worker_id, status="cancelled") + return + execution: asyncio.Future[dict[str, Any] | None] = asyncio.ensure_future(handler(task)) + heartbeat = asyncio.create_task(self._heartbeat(task)) + try: + while not execution.done(): + await asyncio.sleep(self.poll_seconds) + current = await self.repository.get(task.id) + if current is not None and current.cancel_requested: + execution.cancel() + await asyncio.gather(execution, return_exceptions=True) + await self.repository.finish(task.id, self.worker_id, status="cancelled") + return + result = await execution + finally: + heartbeat.cancel() + await asyncio.gather(heartbeat, return_exceptions=True) + await self.repository.finish(task.id, self.worker_id, status="success", result=result) + except asyncio.CancelledError: + raise + except Exception as error: # task failures are persisted, not leaked + await self.repository.finish( + task.id, self.worker_id, status="error", error=type(error).__name__ + ) + + async def _heartbeat(self, task: Task) -> None: + interval = max(self.lease_seconds / 3, 0.01) + while True: + await asyncio.sleep(interval) + await self.repository.heartbeat(task.id, self.worker_id, self.lease_seconds) diff --git a/app/vsphere/__init__.py b/app/vsphere/__init__.py new file mode 100644 index 0000000..7331729 --- /dev/null +++ b/app/vsphere/__init__.py @@ -0,0 +1 @@ +"""Native vSphere REST + SOAP simulation surface.""" diff --git a/app/vsphere/contracts/__init__.py b/app/vsphere/contracts/__init__.py new file mode 100644 index 0000000..9bd299c --- /dev/null +++ b/app/vsphere/contracts/__init__.py @@ -0,0 +1 @@ +"""Versioned vSphere REST coverage catalogs for the lab console.""" diff --git a/app/vsphere/contracts/catalog.py b/app/vsphere/contracts/catalog.py new file mode 100644 index 0000000..7317a72 --- /dev/null +++ b/app/vsphere/contracts/catalog.py @@ -0,0 +1,304 @@ +"""Native vSphere API catalog (replaces Proxmox stub catalog in the console).""" + +from __future__ import annotations + +import re +from typing import Any + +from app.vsphere.contracts.matrix import ( + VERSIONS, + catalog_entries_for_major, + is_implemented_for_major, + load_bundle, +) + +_PATH_PARAM = re.compile(r"\{([^{}/]+)\}") + +_PATH_EXAMPLES: dict[str, str] = { + "vm": "vm-111", + "host": "host-11", + "datastore": "datastore-31", + "task": "task-1", + "snapshot": "snapshot-1", + "category_id": "urn:vmomi:InventoryServiceCategory:demo:GLOBAL", + "tag_id": "urn:vmomi:InventoryServiceTag:demo:GLOBAL", + "item_id": "item-demo", + "folder": "group-v23", + "datacenter": "datacenter-21", + "cluster": "domain-c21", + "resource_pool": "resgroup-22", + "permission_id": "1", + "policy": "policy-default", +} + +# Common query/body fields for lab Params drawer (not a full OpenAPI schema). +_QUERY_FIELDS: dict[tuple[str, str], list[dict[str, Any]]] = { + ("GET", "/api/vcenter/vm"): [ + { + "name": "names", + "type": "array", + "optional": True, + "example": "app-0011", + "description": "Filter by VM name", + }, + { + "name": "hosts", + "type": "array", + "optional": True, + "example": "host-11", + "description": "Filter by host", + }, + { + "name": "power_states", + "type": "array", + "optional": True, + "example": "POWERED_ON", + "description": "Filter by power state", + }, + ], + ("POST", "/api/vcenter/vm/{vm}/power"): [ + { + "name": "action", + "type": "string", + "optional": False, + "example": "start", + "description": "start|stop|reset|suspend", + "enum": ["start", "stop", "reset", "suspend"], + }, + ], + ("POST", "/api/vcenter/folder/{folder}"): [ + { + "name": "action", + "type": "string", + "optional": False, + "example": "rename", + "description": "rename|move", + }, + ], + ("POST", "/api/vcenter/host/{host}/maintenance"): [ + { + "name": "action", + "type": "string", + "optional": False, + "example": "enter", + "description": "enter|exit", + }, + ], +} + +_BODY_FIELDS: dict[tuple[str, str], list[dict[str, Any]]] = { + ("POST", "/api/vcenter/vm"): [ + {"name": "name", "type": "string", "optional": False, "example": "lab-vm"}, + { + "name": "placement", + "type": "object", + "optional": True, + "example": '{"folder":"group-v23","host":"host-11","datastore":"datastore-31"}', + }, + {"name": "cpu_count", "type": "integer", "optional": True, "example": "2"}, + {"name": "memory_size_MiB", "type": "integer", "optional": True, "example": "2048"}, + ], + ("POST", "/api/vcenter/datacenter"): [ + {"name": "name", "type": "string", "optional": False, "example": "Datacenter-2"}, + {"name": "folder", "type": "string", "optional": True, "example": "group-d1"}, + ], + ("POST", "/api/vcenter/cluster"): [ + {"name": "name", "type": "string", "optional": False, "example": "Cluster-2"}, + {"name": "folder", "type": "string", "optional": True, "example": "group-h23"}, + ], + ("POST", "/api/vcenter/folder"): [ + {"name": "name", "type": "string", "optional": False, "example": "workloads"}, + {"name": "parent", "type": "string", "optional": True, "example": "group-v23"}, + {"name": "type", "type": "string", "optional": True, "example": "VIRTUAL_MACHINE"}, + ], + ("POST", "/api/cis/tagging/category"): [ + { + "name": "create_spec", + "type": "object", + "optional": False, + "example": '{"name":"env","description":"lab","cardinality":"MULTIPLE","associable_types":[]}', + }, + ], + ("POST", "/api/cis/tagging/tag"): [ + { + "name": "create_spec", + "type": "object", + "optional": False, + "example": '{"name":"prod","category_id":"…"}', + }, + ], + ("POST", "/api/content/local-library"): [ + { + "name": "create_spec", + "type": "object", + "optional": False, + "example": '{"name":"Templates"}', + }, + ], +} + + +def list_vsphere_majors(*, runtime_version: str | None) -> dict[str, Any]: + return { + "runtime_version": runtime_version or VERSIONS[9]["version"], + "plane": "vsphere-rest", + "majors": [ + { + "major": major, + "series": meta["series"], + "latest_version": meta["version"], + "artifact_url": f"stub://vmware/vsphere-{meta['version']}/api-contract", + "bundled": True, + } + for major, meta in VERSIONS.items() + ], + } + + +def vsphere_catalog_payload(major: int) -> dict[str, Any]: + meta = VERSIONS.get(major) or VERSIONS[9] + bundle = load_bundle(major) + entries = catalog_entries_for_major(major) + grouped: dict[str, dict[str, dict[str, Any]]] = {} + for entry in entries: + path = entry["path"] + parts = [p for p in path.split("/") if p] + tag = "/".join(parts[:3]) if len(parts) >= 3 else path + by_path = grouped.setdefault(tag, {}) + path_entry = by_path.setdefault(path, {"path": path, "methods": []}) + path_entry["methods"].append( + { + "verb": entry["verb"], + "name": f"{entry['verb'].lower()}_{parts[-1] if parts else 'root'}", + "description": f"{entry['status']} {entry['verb']} {path}", + "protected": True, + "implemented": entry["status"] in {"implemented", "stub"}, + } + ) + categories = [ + { + "tag": tag, + "paths": sorted(by_path.values(), key=lambda item: item["path"]), + } + for tag, by_path in sorted(grouped.items()) + ] + return { + "major": major, + "series": meta["series"], + "source_version": meta["version"], + "latest_version": meta["version"], + "artifact_url": f"stub://vmware/vsphere-{meta['version']}/api-contract", + "bundled": True, + "path_count": sum(len(cat["paths"]) for cat in categories), + "method_count": len(entries), + "categories": categories, + "plane": "vsphere-rest", + "contract_kind": bundle.get("kind", "stub-openapi-matrix"), + } + + +def _field( + name: str, + *, + type_name: str = "string", + optional: bool = False, + example: Any = None, + description: str | None = None, + enum: list[str] | None = None, +) -> dict[str, Any]: + return { + "name": name, + "type": type_name, + "description": description, + "optional": optional, + "enum": enum or [], + "example": example if example is not None else name, + } + + +def _path_fields(path: str) -> list[dict[str, Any]]: + fields = [] + for name in _PATH_PARAM.findall(path): + fields.append( + _field( + name, + optional=False, + example=_PATH_EXAMPLES.get(name, name), + description=f"Path parameter {{{name}}}", + ) + ) + return fields + + +def _body_example_from_fields(fields: list[dict[str, Any]]) -> dict[str, Any]: + body: dict[str, Any] = {} + for field in fields: + if field.get("optional"): + continue + example = field.get("example") + if isinstance(example, str) and example.startswith("{"): + try: + import json + + body[field["name"]] = json.loads(example) + continue + except Exception: + body[field["name"]] = example + continue + body[field["name"]] = example + return body + + +def vsphere_method_payload( + *, + major: int, + path: str, + verb: str, + runtime_version: str | None, +) -> dict[str, Any]: + meta = VERSIONS.get(major) or VERSIONS[9] + upper = verb.upper() + path_fields = _path_fields(path) + key = (upper, path) + query_or_body = _QUERY_FIELDS.get(key, []) + body_fields = list(_BODY_FIELDS.get(key, [])) + # Query-style action fields appear as body_fields in the Params UI (same editor). + for item in query_or_body: + body_fields.append( + _field( + str(item["name"]), + type_name=str(item.get("type") or "string"), + optional=bool(item.get("optional", True)), + example=item.get("example"), + description=item.get("description"), + enum=list(item.get("enum") or []), + ) + ) + # Generic POST with {path params} but no body schema → offer empty object note via name. + if upper in {"POST", "PATCH", "PUT"} and not body_fields and "{" not in path: + body_fields.append( + _field( + "name", + optional=True, + example="example", + description="Primary name field when required by create APIs", + ) + ) + resolved = path + for field in path_fields: + resolved = resolved.replace(f"{{{field['name']}}}", str(field["example"])) + return { + "major": major, + "path": path, + "verb": upper, + "name": path.strip("/").replace("/", "_"), + "description": f"{upper} {path}", + "resolved_path": resolved, + "path_fields": path_fields, + "body_fields": body_fields, + "indexed_fields": [], + "body_example": _body_example_from_fields(body_fields), + "implemented": is_implemented_for_major(upper, path, major), + "runtime_version": runtime_version or meta["version"], + "source_version": meta["version"], + } diff --git a/app/vsphere/contracts/compatibility.py b/app/vsphere/contracts/compatibility.py new file mode 100644 index 0000000..29a534d --- /dev/null +++ b/app/vsphere/contracts/compatibility.py @@ -0,0 +1,148 @@ +"""Compatibility / Implementation-coverage payload for the lab UI.""" + +from __future__ import annotations + +from collections import Counter +from pathlib import Path +from typing import Any + +from app.vsphere.contracts.matrix import VERSIONS, catalog_entries_for_major +from app.vsphere.rest.coverage import catalog_entries + +_EVIDENCE_ROOT = Path(__file__).resolve().parents[3] / "evidence" + + +def _level(count: int, total: int) -> dict[str, Any]: + total = max(total, 1) + return {"count": count, "score": round(count / total, 4)} + + +def vsphere_compatibility_payload( + major: int, + *, + runtime_version: str | None = None, +) -> dict[str, Any]: + """Shape expected by lab UI ``updateCatalogCoverage`` / compatibility help panel.""" + + meta = VERSIONS.get(major) or VERSIONS[9] + universe = catalog_entries() + active = catalog_entries_for_major(major) + declared = len(universe) + implemented = len(active) + unsupported = max(declared - implemented, 0) + by_verb = Counter(e["verb"] for e in active) + universe_by_verb = Counter(e["verb"] for e in universe) + + # Surface matrix treats every registered route as exercised for the active floor. + observed = implemented + verified = implemented + + dimensions = { + "route_method": _level(implemented, declared), + "get": _level(by_verb.get("GET", 0), max(universe_by_verb.get("GET", 0), 1)), + "post": _level(by_verb.get("POST", 0), max(universe_by_verb.get("POST", 0), 1)), + "patch": _level(by_verb.get("PATCH", 0), max(universe_by_verb.get("PATCH", 0), 1)), + "delete": _level(by_verb.get("DELETE", 0), max(universe_by_verb.get("DELETE", 0), 1)), + "auth_session": _level( + sum(1 for e in active if e["path"] in {"/api/session", "/rest/com/vmware/cis/session"}), + 6, + ), + "inventory": _level( + sum(1 for e in active if "/api/vcenter/" in e["path"]), + max(sum(1 for e in universe if "/api/vcenter/" in e["path"]), 1), + ), + "legacy_rest": _level( + sum(1 for e in active if e["path"].startswith("/rest/")), + max(sum(1 for e in universe if e["path"].startswith("/rest/")), 1), + ), + } + + evidence_path = _EVIDENCE_ROOT / f"vsphere-{meta['version']}.json" + evidence_summary: dict[str, Any] = {} + if evidence_path.is_file(): + try: + import json + + evidence_summary = ( + json.loads(evidence_path.read_text(encoding="utf-8")).get("summary") or {} + ) + except Exception: + evidence_summary = {} + + active_keys = {(a["verb"], a["path"]) for a in active} + gated_entries = [ + f"{e['verb']} {e['path']}" for e in universe if (e["verb"], e["path"]) not in active_keys + ] + return { + "major": major, + "series": meta["series"], + "source_version": meta["version"], + "catalog_version": meta["version"], + "runtime_version": runtime_version or meta["version"], + "plane": "vsphere-rest", + "evidence_scope": "vsphere-registry", + "total_declared": declared, + "levels": { + "declared": _level(declared, declared), + # Prefer "gated" in the help UI; keep schema_only as an alias for older clients. + "gated": _level(unsupported, declared), + "schema_only": _level(unsupported, declared), + "implemented": _level(implemented, declared), + "observed": _level(observed, declared), + "verified": _level(verified, declared), + }, + "dimensions": dimensions, + "classifications": { + "available": [f"{e['verb']} {e['path']}" for e in active], + "fully_compatible": [f"{e['verb']} {e['path']}" for e in active], + "partially_compatible": [], + "incompatible": [], + "regressions": [], + "unsupported": gated_entries, + "gated_501": gated_entries, + }, + "summary": { + "methods": declared, + "implemented": implemented, + "unsupported_in_version": unsupported, + "coverage": round(implemented / max(declared, 1), 4), + "by_verb": dict(sorted(by_verb.items())), + "universe_by_verb": dict(sorted(universe_by_verb.items())), + **{k: v for k, v in evidence_summary.items() if k.startswith("probed")}, + }, + "entries": active, + } + + +def evidence_ledger(major: int) -> dict[str, Any]: + """Compact on-disk ledger written by ``scripts/write_vsphere_evidence.py``.""" + + from datetime import UTC, datetime + + payload = vsphere_compatibility_payload(major) + meta = VERSIONS[major] + return { + "product": "vmware-api-simulator", + "api_version": meta["version"], + "major": major, + "series": meta["series"], + "plane": "vsphere-rest", + "generated_at": datetime.now(UTC).replace(microsecond=0).isoformat().replace("+00:00", "Z"), + "notes": ( + "Ledger derived from app/vsphere/rest/coverage.py + PATH_FLOOR. " + "implemented_methods = available at this major; " + "universe_methods = full simulator registry." + ), + "summary": { + "implemented_methods": payload["summary"]["implemented"], + "universe_methods": payload["summary"]["methods"], + "unsupported_in_version": payload["summary"]["unsupported_in_version"], + "coverage": payload["summary"]["coverage"], + "by_verb": payload["summary"]["by_verb"], + "status": "partial-clone" + if payload["summary"]["coverage"] < 1 + else "registry-complete", + }, + "levels": payload["levels"], + "dimensions": payload["dimensions"], + } diff --git a/app/vsphere/contracts/matrix.py b/app/vsphere/contracts/matrix.py new file mode 100644 index 0000000..f1b2a29 --- /dev/null +++ b/app/vsphere/contracts/matrix.py @@ -0,0 +1,244 @@ +"""Per-major vSphere REST availability matrix (stub OpenAPI stand-in).""" + +from __future__ import annotations + +import json +import re +from functools import lru_cache +from pathlib import Path +from typing import Any + +from app.vsphere.rest.coverage import ACTIVE_STATUSES, IMPLEMENTED + +# Integer majors mirror the console hot-swap ids (6-9). +VERSIONS: dict[int, dict[str, str]] = { + 6: {"series": "vSphere 7.0", "version": "7.0.0"}, + 7: {"series": "vSphere 7.0 U3", "version": "7.0.3"}, + 8: {"series": "vSphere 8.0", "version": "8.0.0"}, + 9: {"series": "vSphere 8.0 U2", "version": "8.0.2"}, +} + +# Minimum major at which a registered path is considered implemented. +# Anything absent defaults to major 9 (latest) so new paths stay opt-in until catalogued. +_DEFAULT_FLOOR = 9 + +PATH_FLOOR: dict[tuple[str, str], int] = { + # Always-on core (7.0+) + ("POST", "/api/session"): 6, + ("DELETE", "/api/session"): 6, + ("GET", "/api/session"): 6, + ("POST", "/rest/com/vmware/cis/session"): 6, + ("GET", "/rest/com/vmware/cis/session"): 6, + ("DELETE", "/rest/com/vmware/cis/session"): 6, + ("GET", "/api/appliance/system/version"): 6, + ("GET", "/api/vcenter/vm"): 6, + ("POST", "/api/vcenter/vm"): 6, + ("GET", "/api/vcenter/vm/{vm}"): 6, + ("DELETE", "/api/vcenter/vm/{vm}"): 6, + ("POST", "/api/vcenter/vm/{vm}/power"): 6, + ("GET", "/api/vcenter/vm/{vm}/guest/identity"): 6, + ("GET", "/api/vcenter/host"): 6, + ("GET", "/api/vcenter/host/{host}"): 6, + ("GET", "/api/vcenter/datastore"): 6, + ("GET", "/api/vcenter/datastore/{datastore}"): 6, + ("GET", "/api/vcenter/network"): 6, + ("GET", "/api/vcenter/datacenter"): 6, + ("GET", "/api/vcenter/cluster"): 6, + ("GET", "/api/vcenter/folder"): 6, + ("GET", "/api/vcenter/resource-pool"): 6, + # 7.0 U3 depth + ("GET", "/api/cis/tasks"): 7, + ("GET", "/api/cis/tasks/{task}"): 7, + ("GET", "/api/vcenter/vm/{vm}/tools"): 7, + ("GET", "/api/vcenter/vm/{vm}/hardware"): 7, + ("GET", "/api/vcenter/vm/{vm}/hardware/cpu"): 7, + ("PATCH", "/api/vcenter/vm/{vm}/hardware/cpu"): 7, + ("GET", "/api/vcenter/vm/{vm}/hardware/memory"): 7, + ("PATCH", "/api/vcenter/vm/{vm}/hardware/memory"): 7, + ("GET", "/api/vcenter/vm/{vm}/hardware/disk"): 7, + ("POST", "/api/vcenter/vm/{vm}/hardware/disk"): 7, + ("GET", "/api/vcenter/vm/{vm}/hardware/ethernet"): 7, + ("POST", "/api/vcenter/vm/{vm}/hardware/ethernet"): 7, + ("GET", "/api/vcenter/vm/{vm}/hardware/boot"): 7, + ("GET", "/api/vcenter/vm/{vm}/snapshots"): 7, + ("POST", "/api/vcenter/vm/{vm}/snapshots"): 7, + ("DELETE", "/api/vcenter/vm/{vm}/snapshots/{snapshot}"): 7, + ("POST", "/api/vcenter/vm/{vm}/snapshots/{snapshot}"): 7, + ("POST", "/api/vcenter/vm/{vm}/clone"): 7, + ("POST", "/api/vcenter/vm/{vm}/relocate"): 7, + ("POST", "/api/vcenter/host/{host}/maintenance"): 7, + ("GET", "/api/vcenter/datastore/{datastore}/files"): 7, + ("POST", "/api/vcenter/datastore/{datastore}/files"): 7, + ("POST", "/api/vcenter/datacenter"): 7, + ("DELETE", "/api/vcenter/datacenter/{datacenter}"): 7, + ("POST", "/api/vcenter/cluster"): 7, + ("DELETE", "/api/vcenter/cluster/{cluster}"): 7, + ("POST", "/api/vcenter/folder"): 7, + ("POST", "/api/vcenter/folder/{folder}"): 7, + ("DELETE", "/api/vcenter/folder/{folder}"): 7, + ("POST", "/api/vcenter/resource-pool"): 7, + ("DELETE", "/api/vcenter/resource-pool/{resource_pool}"): 7, + ("GET", "/api/cis/tagging/category"): 7, + ("POST", "/api/cis/tagging/category"): 7, + ("GET", "/api/cis/tagging/category/{category_id}"): 7, + ("DELETE", "/api/cis/tagging/category/{category_id}"): 7, + ("GET", "/api/cis/tagging/tag"): 7, + ("POST", "/api/cis/tagging/tag"): 7, + ("GET", "/api/cis/tagging/tag/{tag_id}"): 7, + ("DELETE", "/api/cis/tagging/tag/{tag_id}"): 7, + ("POST", "/api/cis/tagging/tag-association"): 7, + # 8.0 platform services + ("GET", "/api/appliance/health/system"): 8, + ("GET", "/api/appliance/networking"): 8, + ("GET", "/api/appliance/timesync"): 8, + ("GET", "/api/vcenter/network/dvs"): 8, + ("POST", "/api/vcenter/network/dvs"): 8, + ("POST", "/api/vcenter/network/dvpg"): 8, + ("GET", "/api/content/library"): 8, + ("POST", "/api/content/local-library"): 8, + ("GET", "/api/content/library/item"): 8, + ("POST", "/api/content/library/item"): 8, + ("POST", "/api/vcenter/ovf/library-item/{item_id}"): 8, + ("GET", "/api/vcenter/storage/policies"): 8, + ("GET", "/api/vcenter/storage/policies/{policy}/vm"): 8, + ("GET", "/api/vcenter/privilege"): 8, + ("GET", "/api/vcenter/authorization/roles"): 8, + ("GET", "/api/vcenter/authorization/permissions"): 8, + ("POST", "/api/vcenter/authorization/permissions"): 8, + ("DELETE", "/api/vcenter/authorization/permissions/{permission_id}"): 8, + ("GET", "/api/vcenter/identity/providers"): 8, + ("GET", "/api/vcenter/certificate-management/vcenter/tls"): 9, + ("GET", "/api/vcenter/vm/{vm}/guest/networking"): 7, + ("GET", "/api/vcenter/vm/{vm}/guest/power"): 7, + ("POST", "/api/vcenter/vm/{vm}/guest/power"): 7, + ("POST", "/api/vcenter/vm/{vm}/tools"): 7, + ("POST", "/api/vcenter/vm/{vm}/console/tickets"): 8, + ("POST", "/api/vcenter/vm/{vm}/guest/customization"): 8, + ("POST", "/api/vcenter/vm/{vm}"): 7, + ("GET", "/api/vcenter/host/{host}/storage/storage-device"): 8, + ("GET", "/api/vcenter/host/{host}/networking"): 8, + ("GET", "/api/vcenter/folder/{folder}/children"): 7, + ("GET", "/api/vapi/metadata/metamodel/service"): 8, + ("GET", "/api/vapi/metadata/authentication/component"): 8, + ("GET", "/api/vcenter/activity-history"): 8, + ("GET", "/rest/vcenter/vm"): 6, + ("GET", "/rest/vcenter/vm/{vm}"): 6, + ("POST", "/rest/vcenter/vm/{vm}/power"): 6, + ("GET", "/rest/vcenter/host"): 6, + ("GET", "/rest/vcenter/datastore"): 6, + ("GET", "/rest/vcenter/network"): 6, + ("GET", "/rest/vcenter/datacenter"): 6, + ("GET", "/rest/vcenter/cluster"): 6, + ("GET", "/rest/appliance/system/version"): 6, +} + + +def floor_for(verb: str, path: str) -> int: + return PATH_FLOOR.get((verb.upper(), path), _DEFAULT_FLOOR) + + +def methods_for_major(major: int) -> dict[tuple[str, str], str]: + active = major if major in VERSIONS else 9 + return { + key: status for key, status in IMPLEMENTED.items() if floor_for(key[0], key[1]) <= active + } + + +def catalog_entries_for_major(major: int) -> list[dict[str, str]]: + return [ + {"verb": verb, "path": path, "status": status} + for (verb, path), status in sorted(methods_for_major(major).items()) + ] + + +def is_implemented_for_major(verb: str, path: str, major: int) -> bool: + return methods_for_major(major).get((verb.upper(), path)) in ACTIVE_STATUSES + + +@lru_cache(maxsize=1) +def _compiled_routes() -> list[tuple[str, re.Pattern[str], str, int, int]]: + compiled: list[tuple[str, re.Pattern[str], str, int, int]] = [] + for verb, path in IMPLEMENTED: + pattern = "^" + re.sub(r"\{[^/]+\}", r"[^/]+", path) + "$" + parts = [part for part in path.split("/") if part] + static = sum(1 for part in parts if not (part.startswith("{") and part.endswith("}"))) + compiled.append((verb, re.compile(pattern), path, static, len(path))) + # Prefer more literal segments so /library/item beats /library/{library_id}. + compiled.sort(key=lambda item: (item[0], -item[3], -item[4], item[2])) + return compiled + + +def resolve_template(verb: str, request_path: str) -> str | None: + method = verb.upper() + for route_verb, pattern, template, _static, _length in _compiled_routes(): + if route_verb == method and pattern.match(request_path): + return template + return None + + +def available_for_request(verb: str, request_path: str, major: int) -> bool | None: + """True = allowed, False = known but wrong version, None = not in registry. + + Lab policy: every registered Automation API method is always served with real + (DB-backed) handlers/stubs regardless of the hot-swapped catalog major. + Catalog browse still uses ``methods_for_major`` / PATH_FLOOR for history. + """ + + del major # major retained for call-site compatibility; gating is catalog-only + template = resolve_template(verb, request_path) + if template is None: + return None + return True + + +def bundle_payload(major: int) -> dict[str, Any]: + meta = VERSIONS.get(major) or VERSIONS[9] + entries = catalog_entries_for_major(major) + return { + "product": "vmware-api-simulator", + "plane": "vsphere-rest", + "major": major, + "series": meta["series"], + "version": meta["version"], + "kind": "stub-openapi-matrix", + "notes": ( + "Stub contract derived from app/vsphere/rest/coverage.py + PATH_FLOOR. " + "Not a Broadcom OpenAPI dump; used for catalog browse and hot-swap gating." + ), + "method_count": len(entries), + "methods": entries, + } + + +def bundles_root() -> Path: + return Path(__file__).resolve().parents[3] / "contracts" / "vsphere" + + +def write_bundles(root: Path | None = None) -> list[Path]: + base = root or bundles_root() + written: list[Path] = [] + for major in sorted(VERSIONS): + meta = VERSIONS[major] + directory = base / meta["version"] + directory.mkdir(parents=True, exist_ok=True) + payload = bundle_payload(major) + path = directory / "manifest.json" + path.write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8") + written.append(path) + (base / "README.md").write_text( + "# vSphere stub contracts\n\n" + "Versioned JSON matrices generated from `app/vsphere/contracts/matrix.py`.\n" + "Hot-swap (`POST /ui/api/contract/apply?major=N`) switches the catalog major " + "for UI browse/evidence. Runtime always serves the full registered surface " + "(no HTTP 501 version gate on known paths).\n", + encoding="utf-8", + ) + return written + + +def load_bundle(major: int) -> dict[str, Any]: + meta = VERSIONS.get(major) or VERSIONS[9] + path = bundles_root() / meta["version"] / "manifest.json" + if path.is_file(): + return json.loads(path.read_text(encoding="utf-8")) + return bundle_payload(major) diff --git a/app/vsphere/domain/__init__.py b/app/vsphere/domain/__init__.py new file mode 100644 index 0000000..603dd1a --- /dev/null +++ b/app/vsphere/domain/__init__.py @@ -0,0 +1 @@ +"""Shared business operations for REST and SOAP surfaces.""" diff --git a/app/vsphere/domain/api_state.py b/app/vsphere/domain/api_state.py new file mode 100644 index 0000000..c974798 --- /dev/null +++ b/app/vsphere/domain/api_state.py @@ -0,0 +1,763 @@ +"""DB-backed Automation API surface state (keyed by verb + path template).""" + +from __future__ import annotations + +import json +import secrets +from typing import Any + +from app.db.pool import Database +from app.vsphere import inventory + +_STATE_SQL = """ +INSERT INTO vsphere_api_state (state_key, verb, path_template, payload, seed_payload, updated_at) +VALUES ($1, $2, $3, $4::jsonb, $4::jsonb, now()) +ON CONFLICT (state_key) DO UPDATE +SET payload = EXCLUDED.payload, updated_at = now() +""" + +_SEED_STATE_SQL = """ +INSERT INTO vsphere_api_state (state_key, verb, path_template, payload, seed_payload, updated_at) +VALUES ($1, $2, $3, $4::jsonb, $4::jsonb, now()) +ON CONFLICT (state_key) DO UPDATE +SET payload = EXCLUDED.payload, + seed_payload = EXCLUDED.seed_payload, + updated_at = now() +""" + + +def state_key(verb: str, path_template: str) -> str: + return f"{verb.upper()} {path_template}" + + +def _pool(database: Database) -> Any: + return database.pool # type: ignore[attr-defined] + + +def _decode_json(value: Any) -> Any: + """asyncpg may return jsonb as str depending on codec configuration.""" + + current = value + while isinstance(current, str): + try: + current = json.loads(current) + except json.JSONDecodeError: + break + return current + + +def is_empty_payload(payload: Any) -> bool: + if payload is None or payload == "" or payload == {} or payload == []: + return True + if isinstance(payload, dict): + for key in ("data", "value", "messages", "items", "results"): + if key in payload and payload[key] in ([], None, {}): + return True + return False + + +async def get_payload(database: Database, verb: str, path_template: str) -> Any | None: + pool = _pool(database) + async with pool.acquire() as conn: + row = await conn.fetchrow( + "SELECT payload FROM vsphere_api_state WHERE state_key = $1", + state_key(verb, path_template), + ) + if row is None: + return None + return _decode_json(row["payload"]) + + +async def get_payload_or_seed(database: Database, verb: str, path_template: str) -> Any | None: + """Return runtime payload, restoring seed_payload from DB when missing/empty.""" + + payload = await get_payload(database, verb, path_template) + if not is_empty_payload(payload): + return payload + restored = await restore_seed_payload(database, verb, path_template) + if restored is not None: + return restored + return payload + + +async def put_payload(database: Database, verb: str, path_template: str, payload: Any) -> None: + """Update runtime payload; preserves existing seed_payload baseline when present.""" + + pool = _pool(database) + async with pool.acquire() as conn: + await conn.execute( + _STATE_SQL, + state_key(verb, path_template), + verb.upper(), + path_template, + json.dumps(payload), + ) + + +async def put_seed_payload(database: Database, verb: str, path_template: str, payload: Any) -> None: + """Write both runtime payload and immutable seed baseline (used only by seed).""" + + pool = _pool(database) + async with pool.acquire() as conn: + await conn.execute( + _SEED_STATE_SQL, + state_key(verb, path_template), + verb.upper(), + path_template, + json.dumps(payload), + ) + + +async def restore_seed_payload(database: Database, verb: str, path_template: str) -> Any | None: + """Restore payload from DB seed_payload baseline (no Python templates).""" + + pool = _pool(database) + key = state_key(verb, path_template) + async with pool.acquire() as conn: + row = await conn.fetchrow( + "SELECT seed_payload FROM vsphere_api_state WHERE state_key = $1", + key, + ) + if row is None or row["seed_payload"] is None: + return None + payload = _decode_json(row["seed_payload"]) + await conn.execute( + """ + UPDATE vsphere_api_state + SET payload = seed_payload, updated_at = now() + WHERE state_key = $1 + """, + key, + ) + return payload + + +async def delete_payload(database: Database, verb: str, path_template: str) -> bool: + """Remove a leaf resource document; collection roots use restore_seed_payload instead.""" + + pool = _pool(database) + async with pool.acquire() as conn: + result = await conn.execute( + "DELETE FROM vsphere_api_state WHERE state_key = $1", + state_key(verb, path_template), + ) + return result.endswith("1") + + +async def list_collection(database: Database, path_template: str) -> list[Any]: + """Return GET payload for a collection path; always a list.""" + + payload = await get_payload(database, "GET", path_template) + if isinstance(payload, list): + return payload + if payload is None: + return [] + return [payload] + + +def _lab_row(leaf: str, path: str, **extra: Any) -> dict[str, Any]: + return { + "id": f"{leaf}-lab-1", + "name": f"{leaf}-lab-1", + "status": "ENABLED", + "path": path, + **extra, + } + + +def ensure_nonempty(payload: Any, path: str) -> Any: + """Guarantee lab payloads are never empty lists/objects/null (incl. nested data).""" + + if payload is None or payload == "" or payload == {} or payload == []: + return default_for_get_path(path) + if isinstance(payload, dict) and len(payload) == 0: + return default_for_get_path(path) + if isinstance(payload, list) and len(payload) == 0: + return default_for_get_path(path) + if isinstance(payload, dict): + # Fill known nested empties that clients treat as "no data". + out = dict(payload) + changed = False + for key in ("data", "value", "messages", "items", "results"): + if key in out and out[key] in ([], None, {}): + filled = default_for_get_path(path) + if ( + key == "messages" + and isinstance(filled, dict) + and isinstance(filled.get("messages"), list) + ): + out[key] = filled["messages"] + elif isinstance(filled, list): + out[key] = filled + elif key in {"data", "value"}: + # Prefer wrapping a realistic list when the key is a collection. + out[key] = filled + if out[key] in ([], None, {}): + out[key] = [{"id": "lab-1", "name": "lab", "path": path}] + else: + out[key] = [{"id": "lab-ok", "default_message": "Healthy", "args": []}] + changed = True + if changed: + return out + return payload + + +def default_for_get_path(path: str) -> Any: + """Realistic lab defaults — never returns empty list/object/null.""" + + leaf = path.rstrip("/").rsplit("/", 1)[-1] + if leaf.startswith("{") and leaf.endswith("}"): + name = leaf[1:-1] + return { + "id": f"lab-{name}", + "name": f"lab-{name}", + "path": path, + "status": "ENABLED", + } + + if "/appliance/access/ssh" in path: + return {"enabled": True} + if "/appliance/access/dcui" in path: + return {"enabled": True} + if "/appliance/access/consolecli" in path: + return {"enabled": True} + if "/appliance/access/shell" in path: + return {"enabled": True, "timeout": 300} + if path.endswith("/dns/hostname"): + return {"name": "vcenter.lab.local"} + if path.endswith("/dns/servers"): + return {"mode": "DHCP", "servers": ["8.8.8.8", "1.1.1.1"]} + if path.endswith("/dns/domains"): + return ["lab.local", "vsphere.local"] + if "/appliance/timesync" in path: + return {"mode": "NTP", "servers": ["time.lab.local"]} + if "/appliance/networking" in path: + return { + "hostname": "vcenter.lab.local", + "node_name": "vcenter.lab.local", + "default_gateway": "192.168.1.1", + "dns": {"mode": "DHCP", "servers": ["8.8.8.8"], "domains": ["lab.local"]}, + "interfaces": [ + {"name": "nic0", "status": "up", "ipv4": {"address": "192.168.1.50", "prefix": 24}} + ], + } + if "/appliance/health" in path: + return {"status": "green", "messages": [{"id": "ok", "default_message": "Healthy"}]} + if "/appliance/update" in path: + return {"state": "UP_TO_DATE", "version": "8.0.2"} + if "/appliance/recovery" in path: + return {"status": "IDLE", "parts": [{"part": "VCSA", "status": "OK"}]} + if "/appliance/system/storage" in path: + return [{"disk": "sda", "capacity": 100000000000, "used": 40000000000}] + if "/appliance/system/time" in path: + return {"seconds_since_epoch": 1767225600, "datetime": "2026-01-01T00:00:00.000Z"} + if "/certificate-management" in path: + return { + "cert": "-----BEGIN CERTIFICATE-----\nMIIBstub\n-----END CERTIFICATE-----", + "valid_from": "2026-01-01T00:00:00.000Z", + "valid_to": "2028-01-01T00:00:00.000Z", + } + if "/identity/providers" in path: + return [{"provider": "vsphere.local", "name": "vsphere.local", "type_id": "LocalOS"}] + if "/crypto-manager" in path or "/crypto/" in path: + return [{"provider": "native-kms", "type": "NATIVE", "status": "READY"}] + if "/activity-history" in path: + return [ + { + "activity": "activity-lab-1", + "description": "Seed inventory", + "status": "SUCCEEDED", + "start_time": "2026-01-01T00:00:00.000Z", + "user": "administrator@vsphere.local", + } + ] + if "/namespace-management/virtual-machine-classes" in path: + return [ + { + "id": "best-effort-small", + "cpu_count": 2, + "memory_mb": 2048, + "description": "Lab small class", + }, + { + "id": "guaranteed-large", + "cpu_count": 8, + "memory_mb": 16384, + "description": "Lab large class", + }, + ] + if "/namespace-management/supervisors" in path or "/namespaces/" in path: + if "{" in path: + return { + "supervisor": "supervisor-1", + "name": "supervisor-lab", + "config_status": "RUNNING", + "kubernetes_status": "READY", + } + return [ + { + "supervisor": "supervisor-1", + "name": "supervisor-lab", + "config_status": "RUNNING", + "kubernetes_status": "READY", + } + ] + if "/namespace-management" in path: + return [ + { + "cluster": "domain-c21", + "cluster_name": "Cluster", + "config_status": "RUNNING", + "kubernetes_status": "READY", + } + ] + if "/esx/settings" in path: + if "{" in path and not path.endswith("}"): + return { + "status": "COMPLIANT", + "software_info": { + "base_image": {"version": "8.0.2-0.0"}, + "components": [{"name": "VMware-VMTools", "version": "12.0"}], + }, + } + return [{"cluster": "domain-c21", "status": "COMPLIANT", "commit": "commit-lab-1"}] + if "/trusted-infrastructure" in path or "/trustedinfrastructure" in path: + return [{"cluster": "domain-c21", "state": "ENABLED", "attestation": "READY"}] + if "/services/service" in path or path.endswith("/services"): + return [ + {"service": "vsphere-ui", "state": "STARTED", "description": "vSphere Client"}, + {"service": "vpxd", "state": "STARTED", "description": "vCenter Server"}, + {"service": "vapi-endpoint", "state": "STARTED", "description": "vAPI Endpoint"}, + ] + if "/storage/policies" in path: + return [ + { + "policy": "policy-default", + "name": "vSAN Default Storage Policy", + "description": "Lab default", + }, + {"policy": "policy-thin", "name": "Thin provision", "description": "Thin disks"}, + ] + if "/guest/customization-specs" in path or "/guest/customization" in path: + return [ + {"name": "linux-lab", "description": "Linux cloud-init lab spec", "os_type": "LINUX"} + ] + if "/vcha" in path: + return {"mode": "DISABLED", "cluster_mode": "DISABLED"} + if "/content/registries/health" in path: + return [{"registry": "harbor-lab-1", "status": "HEALTHY", "details": "ok"}] + if "/content/registries/harbor" in path: + return [{"registry": "harbor-lab-1", "name": "harbor-lab", "version": "2.9"}] + if "/content/security-policies" in path: + return [{"policy": "sec-policy-lab-1", "name": "Default security", "status": "ENABLED"}] + if "/content/trusted-certificates" in path: + return [ + { + "certificate": "cert-lab-1", + "name": "lab-ca", + "valid_to": "2028-01-01T00:00:00.000Z", + } + ] + if path.endswith("/content/type") or path.endswith("/content/types"): + return [ + {"type": "ovf", "description": "OVF template"}, + {"type": "iso", "description": "ISO image"}, + {"type": "vm-template", "description": "VM template"}, + ] + if path.rstrip("/") == "/api/content/library": + return ["lib-local-1", "lib-published-1"] + if path.rstrip("/") == "/api/content/library/item": + return ["item-ubuntu", "item-centos"] + if "/content/" in path: + if "download-session" in path or "update-session" in path: + if path.endswith("/file"): + return [ + { + "name": "descriptor.ovf", + "size": 256, + "status": "READY", + "download_endpoint": { + "uri": "/api/content/library/item/download-session/session-lab-1/file/descriptor.ovf" + }, + } + ] + return { + "id": "session-lab-1", + "library_item_id": "item-ubuntu", + "state": "ACTIVE", + "name": "lab-session", + } + if leaf in {"file", "changes", "storage"}: + return [ + { + "name": "descriptor.ovf", + "size": 4096, + "checksum_info": {"algorithm": "SHA256", "checksum": "lab"}, + "storage_uris": ["ds:///vmfs/volumes/datastore-31/content/descriptor.ovf"], + "version": "1", + "cached": True, + } + ] + if leaf in {"item", "library", "local-library", "subscribed-library"}: + return [_lab_row(leaf, path, type="LOCAL")] + return [_lab_row(leaf or "content", path)] + if "/cis/tagging/category" in path and "{" not in path: + return ["cat-lab-1", "urn:vmomi:InventoryServiceCategory:environment:GLOBAL"] + if "/cis/tagging/tag" in path and "{" not in path and "association" not in path: + return ["tag-lab-1", "urn:vmomi:InventoryServiceTag:prod:GLOBAL"] + if "/cis/tagging" in path: + return [_lab_row("tagging", path, category_id="cat-lab-1")] + if "/vcenter/vm/" in path and "/hardware/adapter/nvme" in path: + return [{"adapter": "19000", "bus": 0, "pci_slot_number": 160}] + if "/vcenter/vm/" in path and "/hardware/adapter/sata" in path: + return [{"adapter": "15000", "bus": 0, "pci_slot_number": 33}] + if "/vcenter/vm/" in path and "/hardware/parallel" in path: + return [{"port": "10000", "yield_on_poll": True}] + if "/vcenter/vm/" in path and "/hardware/" in path: + return [_lab_row(leaf or "device", path, key="2000")] + if "/vcenter/vm/" in path and "/guest/" in path: + return { + "family": "LINUX", + "full_name": {"name": "Ubuntu Linux (64-bit)"}, + "host_name": "lab-guest", + "ip_address": "192.168.1.100", + } + if "/vcenter/host/" in path: + return {"connection_state": "CONNECTED", "power_state": "POWERED_ON", "status": "green"} + # VM power state is served by GET /api/vcenter/vm/{vm}/power (live inventory). + if "/stats/" in path or "/metrics" in path: + return { + "interval": "PT5M", + "data_points": [{"time": "2026-01-01T00:00:00.000Z", "value": 1.0}], + } + if "/vapi/metadata/authentication" in path: + return [ + "com.vmware.cis.session", + "com.vmware.vcenter", + "com.vmware.appliance", + "com.vmware.content", + ] + if "/vapi/metadata" in path: + return [ + "com.vmware.vcenter", + "com.vmware.appliance", + "com.vmware.cis", + "com.vmware.content", + ] + + if any(token in leaf for token in ("list",)) or ( + "{" not in path and leaf not in {"version", "system", "networking", "timesync"} + ): + if path.count("{") == 0 and leaf not in { + "ssh", + "dcui", + "shell", + "consolecli", + "timesync", + "version", + "networking", + "system", + "tls", + "evc-mode", + "hostname", + "servers", + "domains", + }: + return [_lab_row(leaf, path)] + return { + "id": f"lab-{leaf}", + "name": f"lab-{leaf}", + "status": "ENABLED", + "path": path, + "value": True, + } + + +async def seed_api_surface(database: Database) -> dict[str, int]: + """Populate vsphere_api_state for every GET route in the Broadcom universe + lab extras. + + Templates in ``default_for_get_path`` are used ONLY here at seed time — request handlers + must read ``vsphere_api_state`` / domain tables without inventing payloads. + """ + + from app.vsphere.rest.coverage import IMPLEMENTED + from app.vsphere.security.authz import PRIVILEGES, ROLE_PRIVILEGES + + hosts = await inventory.list_objects(database, type_name="HostSystem") + clusters = await inventory.list_objects(database, type_name="ClusterComputeResource") + vms = await inventory.list_objects(database, type_name="VirtualMachine") + datastores = await inventory.list_objects(database, type_name="Datastore") + + host_ids = [h.moid for h in hosts] or ["host-11"] + cluster_ids = [c.moid for c in clusters] or ["domain-c21"] + vm_ids = [v.moid for v in vms[:50]] or ["vm-101"] + ds_ids = [d.moid for d in datastores] or ["datastore-31"] + + # Inventory-derived collections overwrite generic defaults. + extras: dict[tuple[str, str], Any] = { + ("GET", "/api/vcenter/privilege"): [ + {"id": key, "name": name, "description": name} + for key, name in sorted(PRIVILEGES.items()) + ], + ("GET", "/api/vcenter/authorization/roles"): [ + {"role": role, "privileges": sorted(privs)} + for role, privs in sorted(ROLE_PRIVILEGES.items()) + ], + ("GET", "/api/appliance/health/system"): { + "status": "green", + "value": "green", + "messages": [{"id": "ok", "default_message": "Healthy", "args": []}], + }, + ("GET", "/api/appliance/system/version"): { + "version": "8.0.2", + "product": "VMware vCenter Server", + "type": "vCenter Server", + "build": "simulator", + "install_time": "2026-01-01T00:00:00.000Z", + "releasedate": "2026-01-01", + "summary": "VMware API Simulator", + }, + ("GET", "/api/vcenter/certificate-management/vcenter/tls-csr"): { + "csr": "-----BEGIN CERTIFICATE REQUEST-----\nMIIBLabCSR\n-----END CERTIFICATE REQUEST-----", + "status": "AVAILABLE", + "subject_dn": "CN=vcenter.lab.local", + }, + ("GET", "/api/vcenter/certificate-management/vcenter/trusted-root-chains"): [ + { + "chain": "chain-lab-1", + "cert_chain": ["-----BEGIN CERTIFICATE-----\nMIIBRoot\n-----END CERTIFICATE-----"], + "thumbprint": "AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD", + } + ], + ("GET", "/api/vapi/metadata/metamodel/service"): [ + "com.vmware.vcenter.vm", + "com.vmware.vcenter.host", + "com.vmware.cis.tagging.category", + "com.vmware.cis.tagging.tag", + "com.vmware.content.library", + ], + ("GET", "/api/vapi/metadata/authentication/component"): [ + "com.vmware.cis.session", + "com.vmware.vcenter", + "com.vmware.appliance", + "com.vmware.content", + ], + ("GET", "/api/vcenter/activity-history"): [ + { + "activity": "activity-lab-1", + "description": "Seed inventory", + "status": "SUCCEEDED", + "start_time": "2026-01-01T00:00:00.000Z", + "user": "administrator@vsphere.local", + }, + { + "activity": "activity-lab-2", + "description": "Appliance networking update", + "status": "SUCCEEDED", + "start_time": "2026-01-01T00:05:00.000Z", + "user": "administrator@vsphere.local", + }, + ], + ("GET", "/api/vcenter/services"): [ + {"service": "vsphere-ui", "state": "STARTED"}, + {"service": "vpxd", "state": "STARTED"}, + {"service": "vapi-endpoint", "state": "STARTED"}, + {"service": "rhttpproxy", "state": "STARTED"}, + ], + ("GET", "/api/vcenter/namespace-management/clusters"): [ + { + "cluster": cid, + "cluster_name": "Cluster", + "config_status": "RUNNING", + "kubernetes_status": "READY", + } + for cid in cluster_ids + ], + ("GET", "/api/vcenter/namespace-management/supervisors/{supervisor}/summary"): { + "supervisor": "supervisor-1", + "name": "supervisor-lab", + "config_status": "RUNNING", + "kubernetes_status": "READY", + "status": "ENABLED", + "clusters": cluster_ids, + }, + ("GET", "/api/vcenter/namespace-management/supervisor-services"): [ + {"supervisor_service": "service-lab-1", "name": "demo-operator", "state": "ACTIVATED"} + ], + ("GET", "/api/esx/settings/clusters/{cluster}/software"): { + "base_image": {"version": "8.0.2-0.0"}, + "components": {}, + "commit": "commit-lab-1", + "status": "COMPLIANT", + "clusters": cluster_ids, + }, + ("GET", "/api/esx/settings/hosts/{host}/software"): { + "base_image": {"version": "8.0.2-0.0"}, + "status": "COMPLIANT", + "hosts": host_ids[:20], + }, + ("GET", "/api/vcenter/crypto-manager/kms/providers"): [ + {"provider": "native-kms", "type": "NATIVE", "status": "READY", "health": "OK"} + ], + ("GET", "/api/vcenter/trusted-infrastructure/trust-authority-clusters"): [ + {"cluster": cid, "state": "ENABLED"} for cid in cluster_ids + ], + ("GET", "/api/vcenter/storage/policies"): [ + {"policy": "policy-default", "name": "vSAN Default Storage Policy"}, + {"policy": "policy-thin", "name": "Thin provision"}, + ], + ("GET", "/api/vcenter/guest/customization-specs"): [ + {"name": "linux-lab", "description": "Linux lab", "os_type": "LINUX"}, + {"name": "windows-lab", "description": "Windows lab", "os_type": "WINDOWS"}, + ], + ("GET", "/api/appliance/access/ssh"): {"enabled": True}, + ("GET", "/api/appliance/access/dcui"): {"enabled": True}, + ("GET", "/api/appliance/access/shell"): {"enabled": True, "timeout": 300}, + ("GET", "/api/appliance/access/consolecli"): {"enabled": True}, + ("GET", "/api/appliance/services"): [ + {"service": "vsphere-ui", "state": "STARTED", "description": "vSphere Client"}, + {"service": "vpxd", "state": "STARTED", "description": "vCenter Server"}, + {"service": "vapi-endpoint", "state": "STARTED", "description": "vAPI Endpoint"}, + ], + ("GET", "/api/vcenter/identity/providers"): [ + {"provider": "vsphere.local", "name": "vsphere.local", "type_id": "LocalOS"} + ], + ("GET", "/api/vcenter/certificate-management/vcenter/tls"): { + "cert": "-----BEGIN CERTIFICATE-----\nMIIBlab\n-----END CERTIFICATE-----", + "valid_from": "2026-01-01T00:00:00.000Z", + "valid_to": "2028-01-01T00:00:00.000Z", + "subject_dn": "CN=vcenter.lab.local", + }, + } + # Drop Nones + extras = {k: v for k, v in extras.items() if v is not None} + + inserted = 0 + pool = _pool(database) + async with pool.acquire() as conn: + await conn.execute("DELETE FROM vsphere_api_state") + batch: list[tuple[str, str, str, str]] = [] + seen: set[str] = set() + for (verb, path), _status in IMPLEMENTED.items(): + if verb != "GET" or not path.startswith("/api/"): + continue + payload = extras.get((verb, path)) + if payload is None: + payload = default_for_get_path(path) + payload = ensure_nonempty(payload, path) + if path in { + "/api/vcenter/namespace-management/clusters", + "/api/vcenter/namespace-management/clusters/{cluster}", + }: + payload = [ + { + "cluster": cid, + "cluster_name": "Cluster", + "config_status": "RUNNING", + "status": "COMPLIANT", + "kubernetes_status": "READY", + } + for cid in cluster_ids + ] + if path in { + "/api/esx/settings/clusters/{cluster}/software", + "/api/esx/settings/clusters/software", + }: + payload = { + "base_image": {"version": "8.0.2-0.0"}, + "components": {}, + "commit": "commit-lab-1", + "status": "COMPLIANT", + "clusters": cluster_ids, + } + if path == "/api/vcenter/namespace-management/supervisors/{supervisor}/summary": + payload = { + "supervisor": "supervisor-1", + "name": "supervisor-lab", + "config_status": "RUNNING", + "kubernetes_status": "READY", + "status": "ENABLED", + "clusters": cluster_ids, + } + key = state_key(verb, path) + batch.append((key, verb, path, json.dumps(payload))) + seen.add(key) + inserted += 1 + + for (verb, path), payload in extras.items(): + key = state_key(verb, path) + if key in seen: + continue + batch.append((key, verb, path, json.dumps(payload))) + seen.add(key) + inserted += 1 + + # Template hardware fallbacks (live inventory overrides when VM exists). + hardware_seed = { + "/api/vcenter/vm/{vm}/hardware/cdrom": [ + { + "cdrom": "3000", + "label": "CD/DVD drive 1", + "state": "CONNECTED", + "backing": {"type": "ISO_FILE", "iso_file": "[datastore1] ISO/ubuntu.iso"}, + } + ], + "/api/vcenter/vm/{vm}/hardware/floppy": [{"floppy": "8000", "state": "NOT_CONNECTED"}], + "/api/vcenter/vm/{vm}/hardware/serial": [{"port": "9000", "yield_on_poll": True}], + "/api/vcenter/vm/{vm}/hardware/adapter/scsi": [ + {"adapter": "1000", "type": "LSILOGIC", "sharing": "NONE", "pci_slot_number": 16} + ], + "/api/vcenter/vm/{vm}/hardware/adapter/sata": [ + {"adapter": "15000", "bus": 0, "pci_slot_number": 33} + ], + "/api/vcenter/vm/{vm}/hardware/adapter/nvme": [ + {"adapter": "19000", "bus": 0, "pci_slot_number": 160} + ], + "/api/vcenter/vm/{vm}/hardware/parallel": [{"port": "10000", "yield_on_poll": True}], + "/api/vcenter/vm/{vm}/hardware/boot": { + "type": "BIOS", + "delay": 0, + "retry": False, + "retry_delay": 10000, + "enter_setup_mode": False, + }, + "/api/vcenter/vm/{vm}/hardware/boot/device": [ + {"type": "CDROM"}, + {"type": "DISK"}, + {"type": "ETHERNET"}, + ], + "/api/vcenter/vm/{vm}/guest/local-filesystem": { + "filesystems": {"/": {"capacity": 21474836480, "free_space": 10737418240}} + }, + "/api/vcenter/host/{host}/storage/storage-device": [ + { + "device": "naa.lab1", + "display_name": "Local Disk", + "capacity": 1099511627776, + "ssd": False, + } + ], + "/api/vcenter/host/{host}/networking": { + "dns": {"servers": ["8.8.8.8"], "domains": ["lab.local"]}, + "routing": {"default_gateway": "192.168.1.1"}, + }, + "/api/vcenter/storage/policies/{policy}/vm": [ + {"vm": vid, "vm_home": True, "disks": []} for vid in vm_ids[:10] + ], + } + for path, payload in hardware_seed.items(): + key = state_key("GET", path) + if key in seen: + continue + batch.append((key, "GET", path, json.dumps(payload))) + seen.add(key) + inserted += 1 + + await conn.executemany(_SEED_STATE_SQL, batch) + + _ = ds_ids + return {"api_state_rows": inserted, "hosts": len(host_ids), "vms_sampled": len(vm_ids)} + + +async def new_id(prefix: str = "id") -> str: + return f"{prefix}-{secrets.token_hex(4)}" diff --git a/app/vsphere/domain/appliance.py b/app/vsphere/domain/appliance.py new file mode 100644 index 0000000..3969575 --- /dev/null +++ b/app/vsphere/domain/appliance.py @@ -0,0 +1,164 @@ +"""Mutable vCenter appliance networking / timesync state (lab persistence).""" + +from __future__ import annotations + +from typing import Any + +from app.db.pool import Database +from app.vsphere.domain import api_state +from app.vsphere.errors import invalid_argument + +_NETWORKING_KEY = "/api/appliance/networking" +_TIMESYNC_KEY = "/api/appliance/timesync" + +_DEFAULT_NETWORKING: dict[str, Any] = { + "hostname": "vcenter.lab.local", + "node_name": "vcenter.lab.local", + "default_gateway": "192.168.1.1", + "dns": { + "mode": "DHCP", + "servers": ["8.8.8.8", "1.1.1.1"], + "domains": ["lab.local"], + }, + "interfaces": [ + { + "name": "nic0", + "status": "up", + "mac": "00:50:56:aa:bb:cc", + "ipv4": {"address": "192.168.1.50", "prefix": 24, "configurable": True}, + } + ], + "proxy": {"enabled": False, "server": "", "port": 0, "username": ""}, + "no_proxy": ["localhost", "127.0.0.1", ".lab.local"], +} + +_DEFAULT_TIMESYNC: dict[str, Any] = { + "mode": "NTP", + "servers": ["time.lab.local"], + "current_time": "2026-01-01T00:00:00.000Z", +} + + +def _merge_networking(payload: Any) -> dict[str, Any]: + """Overlay stored fields onto the full lab default shape.""" + + base = dict(_DEFAULT_NETWORKING) + if not isinstance(payload, dict): + return base + merged = {**base, **payload} + dns_base = dict(_DEFAULT_NETWORKING["dns"]) + dns_stored = payload.get("dns") if isinstance(payload.get("dns"), dict) else {} + merged["dns"] = {**dns_base, **dns_stored} + if not merged.get("interfaces"): + merged["interfaces"] = list(_DEFAULT_NETWORKING["interfaces"]) + return merged + + +async def get_networking(database: Database) -> dict[str, Any]: + payload = await api_state.get_payload_or_seed(database, "GET", _NETWORKING_KEY) + if not isinstance(payload, dict): + return {} + dns = payload.get("dns") if isinstance(payload.get("dns"), dict) else {} + if not list(dns.get("domains") or []) or not list(dns.get("servers") or []): + restored = await api_state.restore_seed_payload(database, "GET", _NETWORKING_KEY) + if isinstance(restored, dict): + await save_networking(database, restored) + return restored + return payload + + +async def save_networking(database: Database, networking: dict[str, Any]) -> None: + await api_state.put_payload(database, "GET", _NETWORKING_KEY, networking) + # Keep Automation API GET mirrors in sync for stub/matrix probes. + hostname = str(networking.get("hostname") or "vcenter.lab.local") + dns = networking.get("dns") or {} + await api_state.put_payload( + database, "GET", "/api/appliance/networking/dns/hostname", {"name": hostname} + ) + await api_state.put_payload( + database, + "GET", + "/api/appliance/networking/dns/servers", + {"mode": dns.get("mode") or "DHCP", "servers": list(dns.get("servers") or [])}, + ) + await api_state.put_payload( + database, + "GET", + "/api/appliance/networking/dns/domains", + list(dns.get("domains") or []), + ) + + +async def set_hostname(database: Database, name: str) -> str: + hostname = name.strip() + if not hostname: + raise invalid_argument("name is required") + networking = await get_networking(database) + networking["hostname"] = hostname + networking["node_name"] = hostname + await save_networking(database, networking) + return hostname + + +async def get_hostname(database: Database) -> str: + networking = await get_networking(database) + return str(networking.get("hostname") or "vcenter.lab.local") + + +async def set_dns_servers( + database: Database, + *, + mode: str | None = None, + servers: list[str] | None = None, +) -> dict[str, Any]: + networking = await get_networking(database) + dns = dict(networking.get("dns") or {}) + if mode is not None: + dns["mode"] = mode + if servers is not None: + dns["servers"] = [str(s) for s in servers] + networking["dns"] = dns + await save_networking(database, networking) + return {"mode": dns.get("mode") or "DHCP", "servers": list(dns.get("servers") or [])} + + +async def set_dns_domains(database: Database, domains: list[str]) -> list[str]: + networking = await get_networking(database) + dns = dict(networking.get("dns") or {}) + dns["domains"] = [str(d) for d in domains] + networking["dns"] = dns + await save_networking(database, networking) + return list(dns["domains"]) + + +async def get_timesync(database: Database) -> dict[str, Any]: + payload = await api_state.get_payload_or_seed(database, "GET", _TIMESYNC_KEY) + return payload if isinstance(payload, dict) else {} + + +async def seed_appliance_state(database: Database) -> None: + """Write appliance networking/timesync seed baselines into vsphere_api_state.""" + + networking = dict(_DEFAULT_NETWORKING) + await api_state.put_seed_payload(database, "GET", _NETWORKING_KEY, networking) + await api_state.put_seed_payload(database, "GET", _TIMESYNC_KEY, dict(_DEFAULT_TIMESYNC)) + await save_networking(database, networking) + dns = networking.get("dns") or {} + await api_state.put_seed_payload( + database, + "GET", + "/api/appliance/networking/dns/hostname", + {"name": networking["hostname"]}, + ) + await api_state.put_seed_payload( + database, + "GET", + "/api/appliance/networking/dns/servers", + {"mode": dns.get("mode") or "DHCP", "servers": list(dns.get("servers") or [])}, + ) + await api_state.put_seed_payload( + database, + "GET", + "/api/appliance/networking/dns/domains", + list(dns.get("domains") or []), + ) diff --git a/app/vsphere/domain/content.py b/app/vsphere/domain/content.py new file mode 100644 index 0000000..fa72a7a --- /dev/null +++ b/app/vsphere/domain/content.py @@ -0,0 +1,632 @@ +"""Content library + datastore file metadata.""" + +from __future__ import annotations + +import secrets +from typing import Any + +from asyncpg.exceptions import UniqueViolationError # type: ignore[import-untyped] + +from app.db.pool import Database +from app.vsphere import inventory +from app.vsphere.domain import tagging +from app.vsphere.domain import tasks as task_store +from app.vsphere.errors import already_exists, invalid_argument, not_found + + +def _pool(database: Database) -> Any: + return database.pool # type: ignore[attr-defined] + + +async def create_library( + database: Database, + *, + name: str, + description: str = "", + library_id: str | None = None, +) -> str: + if not name.strip(): + raise invalid_argument("name is required") + lib_id = library_id or f"lib-{secrets.token_hex(6)}" + pool = _pool(database) + try: + async with pool.acquire() as conn: + await conn.execute( + """ + INSERT INTO vsphere_libraries (id, name, description, type, props) + VALUES ($1, $2, $3, 'LOCAL', '{}'::jsonb) + ON CONFLICT (id) DO NOTHING + """, + lib_id, + name, + description, + ) + # Id already present (seed ensure) — treat as success. + exists = await conn.fetchval("SELECT 1 FROM vsphere_libraries WHERE id = $1", lib_id) + if exists: + return lib_id + except UniqueViolationError as error: + # Name collision with a different id: keep requesting id with a unique name. + if library_id: + pool = _pool(database) + async with pool.acquire() as conn: + await conn.execute( + """ + INSERT INTO vsphere_libraries (id, name, description, type, props) + VALUES ($1, $2, $3, 'LOCAL', '{}'::jsonb) + ON CONFLICT (id) DO NOTHING + """, + lib_id, + f"{name} ({lib_id})", + description, + ) + return lib_id + raise already_exists(f"Library {name} already exists") from error + return lib_id + + +async def list_libraries(database: Database) -> list[dict[str, Any]]: + pool = _pool(database) + async with pool.acquire() as conn: + rows = await conn.fetch("SELECT * FROM vsphere_libraries ORDER BY name") + return [ + { + "id": row["id"], + "name": row["name"], + "description": row["description"], + "type": row["type"], + } + for row in rows + ] + + +async def create_library_item( + database: Database, + *, + library_id: str, + name: str, + item_type: str = "ovf", + description: str = "", + item_id: str | None = None, +) -> str: + pool = _pool(database) + async with pool.acquire() as conn: + exists = await conn.fetchval("SELECT 1 FROM vsphere_libraries WHERE id = $1", library_id) + if not exists: + raise not_found(f"Library {library_id} not found") + resolved_id = item_id or f"item-{secrets.token_hex(6)}" + try: + await conn.execute( + """ + INSERT INTO vsphere_library_items (id, library_id, name, type, description) + VALUES ($1, $2, $3, $4, $5) + ON CONFLICT (id) DO NOTHING + """, + resolved_id, + library_id, + name, + item_type, + description, + ) + except UniqueViolationError: + # (library_id, name) taken — keep stable id with a unique name for seed. + if item_id: + await conn.execute( + """ + INSERT INTO vsphere_library_items (id, library_id, name, type, description) + VALUES ($1, $2, $3, $4, $5) + ON CONFLICT (id) DO NOTHING + """, + resolved_id, + library_id, + f"{name}-{resolved_id}", + item_type, + description, + ) + else: + raise + return resolved_id + + +async def list_library_items(database: Database, library_id: str) -> list[dict[str, Any]]: + pool = _pool(database) + async with pool.acquire() as conn: + exists = await conn.fetchval("SELECT 1 FROM vsphere_libraries WHERE id = $1", library_id) + if not exists: + raise not_found(f"Library {library_id} not found") + rows = await conn.fetch( + "SELECT * FROM vsphere_library_items WHERE library_id = $1 ORDER BY name", + library_id, + ) + return [ + { + "id": row["id"], + "library_id": row["library_id"], + "name": row["name"], + "type": row["type"], + "description": row["description"], + } + for row in rows + ] + + +_LAB_SESSION_ID = "session-lab-1" +_LAB_ITEM_ID = "item-ubuntu" + + +async def clear_transfer_sessions(database: Database) -> None: + """Drop durable transfer sessions (used by inventory reseed).""" + + pool = _pool(database) + async with pool.acquire() as conn: + await conn.execute( + """ + DO $$ BEGIN + IF to_regclass('public.vsphere_transfer_sessions') IS NOT NULL THEN + DELETE FROM vsphere_transfer_sessions; + END IF; + END $$; + """ + ) + + +def _decode_files(value: Any) -> dict[str, Any]: + import json + + current = value + while isinstance(current, str): + current = json.loads(current) + if isinstance(current, dict): + return current + return {} + + +async def _upsert_session( + database: Database, + *, + session_id: str, + kind: str, + library_item_id: str, + state: str, + files: dict[str, Any], +) -> None: + import json + + pool = _pool(database) + async with pool.acquire() as conn: + await conn.execute( + """ + INSERT INTO vsphere_transfer_sessions (id, kind, library_item_id, state, files, updated_at) + VALUES ($1, $2, $3, $4, $5::jsonb, now()) + ON CONFLICT (id, kind) DO UPDATE SET + library_item_id = EXCLUDED.library_item_id, + state = EXCLUDED.state, + files = EXCLUDED.files, + updated_at = now() + """, + session_id, + kind, + library_item_id, + state, + json.dumps(files), + ) + + +async def _get_session_row( + database: Database, session_id: str, kind: str | None = None +) -> dict[str, Any] | None: + pool = _pool(database) + async with pool.acquire() as conn: + if kind: + row = await conn.fetchrow( + "SELECT * FROM vsphere_transfer_sessions WHERE id = $1 AND kind = $2", + session_id, + kind, + ) + else: + row = await conn.fetchrow( + "SELECT * FROM vsphere_transfer_sessions WHERE id = $1", + session_id, + ) + if row is None: + return None + return { + "id": row["id"], + "kind": row["kind"], + "library_item_id": row["library_item_id"], + "state": row["state"], + "files": _decode_files(row["files"]), + } + + +async def create_update_session( + database: Database, + *, + library_item_id: str, + session_id: str | None = None, +) -> str: + pool = _pool(database) + async with pool.acquire() as conn: + exists = await conn.fetchval( + "SELECT 1 FROM vsphere_library_items WHERE id = $1", library_item_id + ) + if not exists: + raise not_found(f"Library item {library_item_id} not found") + resolved = session_id or f"update-session-{secrets.token_hex(6)}" + files = { + "upload.bin": { + "name": "upload.bin", + "source_type": "PUSH", + "size": 1024, + "status": "READY", + "upload_endpoint": { + "uri": f"/api/content/library/item/update-session/{resolved}/file/upload.bin", + }, + } + } + await _upsert_session( + database, + session_id=resolved, + kind="update", + library_item_id=library_item_id, + state="ACTIVE", + files=files, + ) + return resolved + + +async def add_update_session_file( + database: Database, + session_id: str, + *, + name: str, + source_type: str = "PUSH", + size: int = 0, + content: str = "", +) -> dict[str, Any]: + session = await _get_session_row(database, session_id, "update") + if session is None: + raise not_found(f"Update session {session_id} not found") + file_info = { + "name": name, + "source_type": source_type, + "size": size or len(content.encode("utf-8")), + "status": "READY", + "upload_endpoint": { + "uri": f"/api/content/library/item/update-session/{session_id}/file/{name}", + }, + "content": content, + } + files = dict(session["files"]) + files[name] = file_info + await _upsert_session( + database, + session_id=session_id, + kind="update", + library_item_id=session["library_item_id"], + state=session["state"], + files=files, + ) + return { + "name": name, + "source_type": source_type, + "size": file_info["size"], + "status": "READY", + "upload_endpoint": file_info["upload_endpoint"], + } + + +async def complete_update_session(database: Database, session_id: str) -> None: + session = await _get_session_row(database, session_id, "update") + if session is None: + raise not_found(f"Update session {session_id} not found") + await _upsert_session( + database, + session_id=session_id, + kind="update", + library_item_id=session["library_item_id"], + state="DONE", + files=session["files"], + ) + + +async def get_update_session(database: Database, session_id: str) -> dict[str, Any]: + session = await _get_session_row(database, session_id, "update") + if session is None: + raise not_found(f"Update session {session_id} not found") + return { + "id": session["id"], + "library_item_id": session["library_item_id"], + "state": session["state"], + "client_progress": 100 if session["state"] == "DONE" else 50, + } + + +async def create_download_session( + database: Database, + *, + library_item_id: str, + session_id: str | None = None, +) -> str: + pool = _pool(database) + async with pool.acquire() as conn: + exists = await conn.fetchval( + "SELECT 1 FROM vsphere_library_items WHERE id = $1", library_item_id + ) + if not exists: + raise not_found(f"Library item {library_item_id} not found") + resolved = session_id or f"download-session-{secrets.token_hex(6)}" + files = { + "descriptor.ovf": { + "name": "descriptor.ovf", + "size": 256, + "status": "READY", + "download_endpoint": { + "uri": f"/api/content/library/item/download-session/{resolved}/file/descriptor.ovf", + }, + } + } + await _upsert_session( + database, + session_id=resolved, + kind="download", + library_item_id=library_item_id, + state="ACTIVE", + files=files, + ) + return resolved + + +async def get_download_session(database: Database, session_id: str) -> dict[str, Any]: + session = await _get_session_row(database, session_id, "download") + if session is None: + raise not_found(f"Download session {session_id} not found") + return { + "id": session["id"], + "library_item_id": session["library_item_id"], + "state": session["state"], + } + + +async def list_download_session_files(database: Database, session_id: str) -> list[dict[str, Any]]: + session = await _get_session_row(database, session_id, "download") + if session is None: + raise not_found(f"Download session {session_id} not found") + return [ + { + "name": f["name"], + "size": f["size"], + "status": f["status"], + "download_endpoint": f["download_endpoint"], + } + for f in session["files"].values() + ] + + +async def deploy_ovf_from_library( + database: Database, + *, + item_id: str, + name: str, + folder: str = "group-v23", + host: str = "host-11", + datastore: str = "datastore-31", +) -> tuple[str, str]: + pool = _pool(database) + async with pool.acquire() as conn: + row = await conn.fetchrow("SELECT * FROM vsphere_library_items WHERE id = $1", item_id) + if row is None: + raise not_found(f"Library item {item_id} not found") + moid = await inventory.next_moid(database, "vm") + await inventory.upsert_object( + database, + moid=moid, + type_name="VirtualMachine", + name=name, + parent_moid=folder, + props={ + "power_state": "POWERED_OFF", + "cpu_count": 2, + "memory_size_mib": 2048, + "guest_OS": "OTHER_GUEST_64", + "hardware_version": "VMX_19", + "host": host, + "datastore": datastore, + "networks": ["network-41"], + "identity": {"name": name}, + "deployed_from_library_item": item_id, + "nics": [], + "disks": [ + { + "key": "2000", + "value": {"label": "Hard disk 1", "capacity": 21474836480, "type": "SCSI"}, + } + ], + }, + ) + task_id = await task_store.create_task( + database, + description=f"Deploy OVF item {item_id} as {moid}", + service="com.vmware.vcenter.ovf", + operation="deploy", + result={"vm": moid}, + ) + return moid, task_id + + +async def list_datastore_files(database: Database, datastore: str) -> list[dict[str, Any]]: + obj = await inventory.get_object(database, datastore) + if obj is None or obj.type != "Datastore": + raise not_found(f"Datastore {datastore} not found") + pool = _pool(database) + async with pool.acquire() as conn: + rows = await conn.fetch( + """ + SELECT path, size, type FROM vsphere_datastore_files + WHERE datastore_moid = $1 ORDER BY path + """, + datastore, + ) + return [{"path": row["path"], "size": row["size"], "type": row["type"]} for row in rows] + + +async def put_datastore_file( + database: Database, + datastore: str, + path: str, + *, + size: int = 0, + file_type: str = "FILE", +) -> None: + obj = await inventory.get_object(database, datastore) + if obj is None or obj.type != "Datastore": + raise not_found(f"Datastore {datastore} not found") + pool = _pool(database) + async with pool.acquire() as conn: + await conn.execute( + """ + INSERT INTO vsphere_datastore_files (datastore_moid, path, size, type) + VALUES ($1, $2, $3, $4) + ON CONFLICT (datastore_moid, path) DO UPDATE SET size = EXCLUDED.size, type = EXCLUDED.type + """, + datastore, + path, + size, + file_type, + ) + + +async def seed_platform_extras(database: Database) -> None: + """Idempotent demo libraries/tags/files/sessions when platform tables exist. + + Always ensures stable lab IDs so probes and clients hit non-empty GETs: + ``lib-local-1``, ``item-ubuntu``, ``cat-lab-1``, ``tag-lab-1``, ``session-lab-1``, … + """ + + from app.vsphere.domain import tasks as task_store + + # Ensure lab libraries/items even when older random-id rows already exist. + lib = await create_library( + database, + name="Local Content", + description="Lab library", + library_id="lib-local-1", + ) + await create_library_item( + database, + library_id=lib, + name="ubuntu-22.04", + item_type="ovf", + description="Ubuntu template OVF", + item_id="item-ubuntu", + ) + await create_library_item( + database, + library_id=lib, + name="centos-stream-9", + item_type="ovf", + description="CentOS Stream OVF", + item_id="item-centos", + ) + pub = await create_library( + database, + name="Published Templates", + description="Published lab library", + library_id="lib-published-1", + ) + await create_library_item( + database, + library_id=pub, + name="golden-image", + item_type="ovf", + description="Golden image OVF", + item_id="item-golden", + ) + + env = await tagging.create_category( + database, + name="Environment", + description="Environment tags", + associable_types=["VirtualMachine", "HostSystem"], + category_id="urn:vmomi:InventoryServiceCategory:environment:GLOBAL", + ) + owner = await tagging.create_category( + database, + name="Owner", + description="Team ownership", + associable_types=["VirtualMachine"], + category_id="urn:vmomi:InventoryServiceCategory:owner:GLOBAL", + ) + prod = await tagging.create_tag( + database, + category_id=env, + name="prod", + tag_id="urn:vmomi:InventoryServiceTag:prod:GLOBAL", + ) + await tagging.create_tag( + database, + category_id=env, + name="staging", + tag_id="urn:vmomi:InventoryServiceTag:staging:GLOBAL", + ) + await tagging.create_tag( + database, + category_id=owner, + name="platform", + tag_id="urn:vmomi:InventoryServiceTag:platform:GLOBAL", + ) + await tagging.create_category( + database, + name="Lab", + description="Probe alias category", + associable_types=["VirtualMachine"], + category_id="cat-lab-1", + ) + await tagging.create_tag( + database, + category_id="cat-lab-1", + name="lab", + tag_id="tag-lab-1", + ) + await tagging.attach_tag(database, prod, "VirtualMachine", "vm-101") + await tagging.attach_tag(database, prod, "VirtualMachine", "vm-102") + await tagging.attach_tag(database, "tag-lab-1", "VirtualMachine", "vm-101") + + await put_datastore_file( + database, "datastore-31", "[datastore1] ISO/ubuntu.iso", size=900000000 + ) + await put_datastore_file( + database, "datastore-31", "[datastore1] ISO/vmware-tools.iso", size=120000000 + ) + await put_datastore_file(database, "datastore-31", "[datastore1] web-01/web-01.vmx", size=4096) + await put_datastore_file( + database, "datastore-31", "[datastore1] web-01/web-01.vmdk", size=42949672960 + ) + + item_id = _LAB_ITEM_ID + pool = _pool(database) + async with pool.acquire() as conn: + has_item = await conn.fetchval("SELECT 1 FROM vsphere_library_items WHERE id = $1", item_id) + if has_item: + await create_download_session(database, library_item_id=item_id, session_id=_LAB_SESSION_ID) + await create_update_session(database, library_item_id=item_id, session_id=_LAB_SESSION_ID) + + # Lab snapshots so GET /snapshots is DB-backed (no create-on-read). + from app.vsphere.domain import vm_ops + + for vm_moid in ("vm-101", "vm-102"): + snaps = await vm_ops.list_snapshots(database, vm_moid) + if not snaps: + await vm_ops.create_snapshot( + database, vm_moid, name="initial", description="Lab default snapshot" + ) + + await task_store.create_task( + database, + description="Lab inventory seed", + service="com.vmware.vcenter", + operation="seed", + status="SUCCEEDED", + result={"seeded": True, "profile": "lab"}, + task_id="task-1", + ) diff --git a/app/vsphere/domain/inventory_ops.py b/app/vsphere/domain/inventory_ops.py new file mode 100644 index 0000000..3b61fa1 --- /dev/null +++ b/app/vsphere/domain/inventory_ops.py @@ -0,0 +1,225 @@ +"""CRUD for folders, datacenters, clusters, resource pools, hosts, DVS.""" + +from __future__ import annotations + +from typing import Any + +from app.db.pool import Database +from app.vsphere import inventory +from app.vsphere.errors import invalid_argument, not_found + + +async def create_folder( + database: Database, + *, + name: str, + parent: str, + folder_type: str = "VIRTUAL_MACHINE", +) -> str: + parent_obj = await inventory.get_object(database, parent) + if parent_obj is None: + raise not_found(f"Parent {parent} not found") + moid = await inventory.next_moid(database, "group") + # next_moid with group- may not work well; use folder- style + import secrets + + moid = f"group-{secrets.token_hex(3)}" + await inventory.upsert_object( + database, + moid=moid, + type_name="Folder", + name=name, + parent_moid=parent, + props={"folder_type": folder_type}, + ) + return moid + + +async def create_datacenter(database: Database, *, name: str, folder: str = "group-d1") -> str: + import secrets + + moid = f"datacenter-{secrets.randbelow(900) + 100}" + host_folder = f"group-h{secrets.randbelow(90) + 10}" + vm_folder = f"group-v{secrets.randbelow(90) + 10}" + ds_folder = f"group-s{secrets.randbelow(90) + 10}" + net_folder = f"group-n{secrets.randbelow(90) + 10}" + await inventory.upsert_object( + database, + moid=moid, + type_name="Datacenter", + name=name, + parent_moid=folder, + props={ + "datastore_folder": ds_folder, + "host_folder": host_folder, + "vm_folder": vm_folder, + "network_folder": net_folder, + }, + ) + for child_moid, child_name, ftype in ( + (host_folder, "host", "HOST"), + (vm_folder, "vm", "VIRTUAL_MACHINE"), + (ds_folder, "datastore", "DATASTORE"), + (net_folder, "network", "NETWORK"), + ): + await inventory.upsert_object( + database, + moid=child_moid, + type_name="Folder", + name=child_name, + parent_moid=moid, + props={"folder_type": ftype}, + ) + return moid + + +async def create_cluster( + database: Database, + *, + name: str, + folder: str = "group-h23", + drs_enabled: bool = True, + ha_enabled: bool = True, +) -> str: + import secrets + + moid = f"domain-c{secrets.randbelow(900) + 100}" + rp = f"resgroup-{secrets.randbelow(900) + 100}" + await inventory.upsert_object( + database, + moid=moid, + type_name="ClusterComputeResource", + name=name, + parent_moid=folder, + props={"drs_enabled": drs_enabled, "ha_enabled": ha_enabled, "resource_pool": rp}, + ) + await inventory.upsert_object( + database, + moid=rp, + type_name="ResourcePool", + name="Resources", + parent_moid=moid, + props={"cpu_limit_mhz": -1, "memory_limit_mib": -1}, + ) + return moid + + +async def create_resource_pool( + database: Database, + *, + name: str, + parent: str, +) -> str: + parent_obj = await inventory.get_object(database, parent) + if parent_obj is None: + raise not_found(f"Parent {parent} not found") + import secrets + + moid = f"resgroup-{secrets.randbelow(900) + 100}" + await inventory.upsert_object( + database, + moid=moid, + type_name="ResourcePool", + name=name, + parent_moid=parent, + props={"cpu_limit_mhz": -1, "memory_limit_mib": -1}, + ) + return moid + + +async def rename_object(database: Database, moid: str, name: str) -> None: + obj = await inventory.get_object(database, moid) + if obj is None: + raise not_found(f"Object {moid} not found") + await inventory.upsert_object( + database, + moid=obj.moid, + type_name=obj.type, + name=name, + parent_moid=obj.parent_moid, + props=obj.props, + ) + + +async def move_object(database: Database, moid: str, parent: str) -> None: + obj = await inventory.get_object(database, moid) + if obj is None: + raise not_found(f"Object {moid} not found") + parent_obj = await inventory.get_object(database, parent) + if parent_obj is None: + raise not_found(f"Parent {parent} not found") + await inventory.upsert_object( + database, + moid=obj.moid, + type_name=obj.type, + name=obj.name, + parent_moid=parent, + props=obj.props, + ) + + +async def delete_managed(database: Database, moid: str) -> None: + obj = await inventory.get_object(database, moid) + if obj is None: + raise not_found(f"Object {moid} not found") + children = [ + child for child in await inventory.list_objects(database) if child.parent_moid == moid + ] + if children: + raise invalid_argument(f"Object {moid} still has children") + await inventory.delete_object(database, moid) + + +async def set_host_maintenance(database: Database, host: str, enabled: bool) -> dict[str, Any]: + obj = await inventory.get_object(database, host) + if obj is None or obj.type != "HostSystem": + raise not_found(f"Host {host} not found") + props = dict(obj.props) + props["connection_state"] = "CONNECTED" + props["maintenance_mode"] = enabled + await inventory.update_props(database, host, props) + return {"host": host, "maintenance_mode": enabled} + + +async def create_dvs( + database: Database, + *, + name: str, + folder: str = "group-n23", +) -> str: + import secrets + + moid = f"dvs-{secrets.randbelow(900) + 100}" + await inventory.upsert_object( + database, + moid=moid, + type_name="VmwareDistributedVirtualSwitch", + name=name, + parent_moid=folder, + props={"version": "8.0.0", "num_ports": 128}, + ) + return moid + + +async def create_dvpg( + database: Database, + *, + name: str, + dvs: str, + vlan_id: int = 0, +) -> str: + parent = await inventory.get_object(database, dvs) + if parent is None: + raise not_found(f"DVS {dvs} not found") + import secrets + + moid = f"dvportgroup-{secrets.randbelow(900) + 100}" + await inventory.upsert_object( + database, + moid=moid, + type_name="DistributedVirtualPortgroup", + name=name, + parent_moid=dvs, + props={"type": "DISTRIBUTED_PORTGROUP", "vlan_id": vlan_id, "dvs": dvs}, + ) + return moid diff --git a/app/vsphere/domain/platform_surface.py b/app/vsphere/domain/platform_surface.py new file mode 100644 index 0000000..335b7d9 --- /dev/null +++ b/app/vsphere/domain/platform_surface.py @@ -0,0 +1,434 @@ +"""Lab-grade NSX / WCP / vSAN / identity / VECS / NFC state (DB-backed).""" + +from __future__ import annotations + +import json +import secrets +from typing import Any + +from app.db.pool import Database +from app.vsphere import inventory +from app.vsphere.domain import api_state + +_IDENTITY = "/api/vcenter/identity/providers" + + +def default_identity_providers() -> list[dict[str, Any]]: + return [ + { + "provider": "vsphere.local", + "name": "vsphere.local", + "type_id": "LocalOS", + "domain_names": ["vsphere.local"], + "is_default": True, + }, + { + "provider": "oidc-lab", + "name": "Lab OIDC", + "type_id": "Oidc", + "issuer_uri": "https://idp.lab.local/realms/vsphere", + "client_id": "vcenter-lab", + "is_default": False, + }, + { + "provider": "saml-lab", + "name": "Lab SAML", + "type_id": "Saml", + "idp_entity_id": "https://idp.lab.local/saml", + "sso_service_url": "https://idp.lab.local/saml/sso", + "is_default": False, + }, + ] + + +def default_nsx_surface() -> dict[str, Any]: + return { + ("GET", "/api/vcenter/namespace-management/nsx-tier0-gateway"): [ + { + "gateway": "nsx-tier0-1", + "name": "tier0-lab", + "path": "/infra/tier-0s/tier0-lab", + "status": "UP", + } + ], + ("GET", "/api/vcenter/namespace-management/networks/{network}/nsx/projects"): [ + { + "project": "nsx-project-1", + "name": "default", + "path": "/orgs/default/projects/default", + "status": "READY", + } + ], + ("GET", "/api/vcenter/namespace-management/networks/{network}/nsx/edges"): [ + { + "edge": "nsx-edge-1", + "name": "edge-lab-1", + "path": "/infra/sites/default/enforcement-points/default/edge-clusters/edge-1", + "status": "UP", + } + ], + ( + "GET", + "/api/vcenter/namespace-management/networks/{network}/nsx/distributed-switches", + ): [ + { + "distributed_switch": "nsx-dvs-1", + "name": "NSX-DVS", + "path": "/infra/sites/default/enforcement-points/default/transport-zones/tz-1", + "status": "UP", + } + ], + ("GET", "/api/vcenter/namespace-management/networks/{network}/nsx/vpcs"): [ + { + "vpc": "vpc-lab-1", + "name": "vpc-lab", + "path": "/orgs/default/projects/default/vpcs/vpc-lab", + "status": "READY", + } + ], + ( + "GET", + "/api/vcenter/namespace-management/networks/{network}/nsx/vpc-connectivity-profiles", + ): [ + { + "profile": "vpc-profile-1", + "name": "default-connectivity", + "status": "READY", + } + ], + ( + "GET", + "/api/vcenter/namespaces/{namespace}/networks/{network}/nsx/subnets", + ): [ + { + "subnet": "subnet-lab-1", + "name": "workload", + "cidr": "10.244.0.0/24", + "status": "READY", + } + ], + } + + +def default_wcp_surface() -> dict[str, Any]: + return { + ("GET", "/api/vcenter/namespace-management/networks"): [ + { + "network": "network-41", + "name": "VM Network", + "mode": "NSXT_VPC", + "status": "READY", + } + ], + ("GET", "/api/vcenter/namespaces"): [ + { + "namespace": "ns-lab-1", + "name": "ns-lab-1", + "cluster": "domain-c21", + "config_status": "RUNNING", + "stats": {"cpu_used": 2, "memory_used_mib": 4096}, + } + ], + ("GET", "/api/vcenter/namespace-management/virtual-machine-classes"): [ + { + "id": "best-effort-small", + "cpu_count": 2, + "memory_mb": 2048, + "description": "Lab small class", + }, + { + "id": "guaranteed-large", + "cpu_count": 8, + "memory_mb": 16384, + "description": "Lab large class", + }, + ], + ("GET", "/api/vcenter/namespace-management/clusters/{cluster}/nsm"): { + "cluster": "domain-c21", + "config_status": "RUNNING", + "kubernetes_status": "READY", + "network_provider": "NSXT_CONTAINER_PLUGIN", + }, + ( + "GET", + "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/providers", + ): [ + { + "provider": "oidc-supervisor", + "name": "Supervisor OIDC", + "issuer": "https://idp.lab.local/realms/supervisor", + "type": "OIDC", + "status": "READY", + } + ], + ("GET", "/api/vcenter/namespace-management/infrastructure-policies"): [ + { + "policy": "infra-policy-lab-1", + "name": "default-infra", + "status": "ENABLED", + } + ], + } + + +def default_vsan_surface() -> dict[str, Any]: + return { + ("GET", "/api/vcenter/storage/policies"): [ + { + "policy": "policy-default", + "name": "vSAN Default Storage Policy", + "description": "Lab vSAN default", + "policy_type": "VSAN", + }, + { + "policy": "policy-thin", + "name": "Thin provision", + "description": "Thin disks", + "policy_type": "VVOL", + }, + { + "policy": "policy-vsan-raid1", + "name": "vSAN RAID1", + "description": "Failures to tolerate = 1", + "policy_type": "VSAN", + }, + ], + ("GET", "/api/vcenter/storage/policies/{policy}"): { + "policy": "policy-default", + "name": "vSAN Default Storage Policy", + "description": "Lab vSAN default", + "policy_type": "VSAN", + "constraints": [{"property_name": "hostFailuresToTolerate", "value": 1}], + }, + } + + +def default_vecs_surface() -> dict[str, Any]: + return { + ("GET", "/api/vcenter/certificate-management/vcenter/tls-csr"): { + "csr": "-----BEGIN CERTIFICATE REQUEST-----\nMIIBLabCSR\n-----END CERTIFICATE REQUEST-----", + "status": "AVAILABLE", + "subject_dn": "CN=vcenter.lab.local", + }, + ("GET", "/api/vcenter/certificate-management/vcenter/signing-certificate"): { + "cert": "-----BEGIN CERTIFICATE-----\nMIIBSigning\n-----END CERTIFICATE-----", + "valid_from": "2026-01-01T00:00:00.000Z", + "valid_to": "2030-01-01T00:00:00.000Z", + "subject_dn": "CN=CA,DC=vsphere,DC=local", + }, + ("GET", "/api/vcenter/certificate-management/vcenter/trusted-root-chains"): [ + { + "chain": "chain-lab-1", + "cert_chain": ["-----BEGIN CERTIFICATE-----\nMIIBRoot\n-----END CERTIFICATE-----"], + "thumbprint": "AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD", + } + ], + ( + "GET", + "/api/vcenter/namespace-management/supervisors/{supervisor}/certificates", + ): [ + { + "certificate": "supervisor-tls", + "status": "VALID", + "valid_to": "2028-01-01T00:00:00.000Z", + } + ], + ( + "GET", + "/api/vcenter/namespace-management/supervisors/{supervisor}/signing-requests", + ): [ + { + "request": "csr-supervisor-1", + "status": "PENDING", + "csr": "-----BEGIN CERTIFICATE REQUEST-----\nMIIBSupCSR\n-----END CERTIFICATE REQUEST-----", + } + ], + } + + +async def seed_platform_surface(database: Database) -> dict[str, int]: + """Overlay rich lab payloads for previously shallow product areas (seed-time only).""" + + rows = 0 + providers = default_identity_providers() + await api_state.put_seed_payload(database, "GET", _IDENTITY, providers) + rows += 1 + + for mapping in ( + default_nsx_surface(), + default_wcp_surface(), + default_vsan_surface(), + default_vecs_surface(), + ): + for (verb, path), payload in mapping.items(): + await api_state.put_seed_payload(database, verb, path, payload) + rows += 1 + return {"platform_surface_rows": rows} + + +async def list_identity_providers(database: Database) -> list[dict[str, Any]]: + payload = await api_state.get_payload_or_seed(database, "GET", _IDENTITY) + if not isinstance(payload, list) or not payload: + return [] + if not any(str(item.get("provider")) == "vsphere.local" for item in payload): + restored = await api_state.restore_seed_payload(database, "GET", _IDENTITY) + if isinstance(restored, list) and restored: + return restored + return payload + + +async def get_identity_provider(database: Database, provider: str) -> dict[str, Any] | None: + for item in await list_identity_providers(database): + if provider in { + str(item.get("provider")), + str(item.get("name")), + str(item.get("id")), + }: + return item + return None + + +async def upsert_identity_provider(database: Database, body: dict[str, Any]) -> dict[str, Any]: + providers = await list_identity_providers(database) + provider_id = str(body.get("provider") or body.get("name") or f"idp-{secrets.token_hex(3)}") + entry = { + "provider": provider_id, + "name": str(body.get("name") or provider_id), + "type_id": str(body.get("type_id") or body.get("type") or "Oidc"), + "is_default": bool(body.get("is_default", False)), + **{ + k: v + for k, v in body.items() + if k not in {"provider", "name", "type_id", "type", "is_default"} + }, + } + out: list[dict[str, Any]] = [] + replaced = False + for item in providers: + if str(item.get("provider")) == provider_id: + out.append({**item, **entry}) + replaced = True + else: + out.append(item) + if not replaced: + out.append(entry) + await api_state.put_payload(database, "GET", _IDENTITY, out) + return entry + + +async def delete_identity_provider(database: Database, provider: str) -> bool: + providers = await list_identity_providers(database) + filtered = [p for p in providers if str(p.get("provider")) != provider] + if len(filtered) == len(providers): + return False + # Soft-delete lab baseline: restore seed document so GET stays non-empty. + await api_state.restore_seed_payload(database, "GET", _IDENTITY) + return True + + +def _decode_payload(value: Any) -> dict[str, Any]: + current = value + while isinstance(current, str): + current = json.loads(current) + return current if isinstance(current, dict) else {} + + +async def _save_nfc_lease(database: Database, lease_id: str, info: dict[str, Any]) -> None: + pool = database.pool # type: ignore[attr-defined] + async with pool.acquire() as conn: + await conn.execute( + """ + INSERT INTO vsphere_nfc_leases (id, vm_moid, state, payload, updated_at) + VALUES ($1, $2, $3, $4::jsonb, now()) + ON CONFLICT (id) DO UPDATE SET + vm_moid = EXCLUDED.vm_moid, + state = EXCLUDED.state, + payload = EXCLUDED.payload, + updated_at = now() + """, + lease_id, + str(info.get("entity") or ""), + str(info.get("state") or "ready"), + json.dumps(info), + ) + await inventory.upsert_object( + database, + moid=lease_id, + type_name="HttpNfcLease", + name=lease_id, + parent_moid=None, + props=info, + ) + + +async def create_nfc_lease( + database: Database, + *, + vm: str, + files: list[str] | None = None, +) -> dict[str, Any]: + lease_id = f"lease-{secrets.token_hex(6)}" + file_list = files or [f"{vm}.vmdk", f"{vm}.nvram"] + info = { + "lease": lease_id, + "state": "ready", + "entity": vm, + "initializeProgress": 100, + "transferProgress": 0, + "info": { + "deviceUrl": [ + { + "key": f"disk-{index}", + "importKey": name, + "url": f"https://localhost/nfc/{lease_id}/files/{name}", + "sslThumbprint": "https://example.invalid/thumbprint", + } + for index, name in enumerate(file_list) + ] + }, + "files": {name: {"uploaded": False, "size": 0} for name in file_list}, + } + await _save_nfc_lease(database, lease_id, info) + return info + + +async def get_nfc_lease(database: Database, lease_id: str) -> dict[str, Any] | None: + pool = database.pool # type: ignore[attr-defined] + async with pool.acquire() as conn: + row = await conn.fetchrow( + "SELECT payload FROM vsphere_nfc_leases WHERE id = $1", + lease_id, + ) + if row is None: + return None + return _decode_payload(row["payload"]) + + +async def complete_nfc_lease(database: Database, lease_id: str) -> dict[str, Any] | None: + lease = await get_nfc_lease(database, lease_id) + if lease is None: + return None + lease["state"] = "done" + lease["transferProgress"] = 100 + await _save_nfc_lease(database, lease_id, lease) + return lease + + +async def upload_nfc_file( + database: Database, + lease_id: str, + filename: str, + size: int, +) -> dict[str, Any] | None: + lease = await get_nfc_lease(database, lease_id) + if lease is None: + return None + files = lease.setdefault("files", {}) + files[filename] = {"uploaded": True, "size": size} + uploaded = sum(1 for meta in files.values() if meta.get("uploaded")) + total = max(len(files), 1) + lease["transferProgress"] = int(100 * uploaded / total) + if uploaded >= total: + lease["state"] = "done" + await _save_nfc_lease(database, lease_id, lease) + return lease diff --git a/app/vsphere/domain/tagging.py b/app/vsphere/domain/tagging.py new file mode 100644 index 0000000..b94d64b --- /dev/null +++ b/app/vsphere/domain/tagging.py @@ -0,0 +1,321 @@ +"""CIS tagging store.""" + +from __future__ import annotations + +import secrets +from typing import Any + +from app.db.pool import Database +from app.vsphere.errors import already_exists, not_found + + +def _pool(database: Database) -> Any: + return database.pool # type: ignore[attr-defined] + + +async def create_category( + database: Database, + *, + name: str, + description: str = "", + cardinality: str = "MULTIPLE", + associable_types: list[str] | None = None, + category_id: str | None = None, +) -> str: + cat_id = category_id or f"urn:vmomi:InventoryServiceCategory:{secrets.token_hex(8)}:GLOBAL" + types = associable_types or [] + pool = _pool(database) + async with pool.acquire() as conn: + existing = await conn.fetchval("SELECT 1 FROM vsphere_tag_categories WHERE id = $1", cat_id) + if existing: + return cat_id + try: + await conn.execute( + """ + INSERT INTO vsphere_tag_categories (id, name, description, cardinality, associable_types) + VALUES ($1, $2, $3, $4, $5) + """, + cat_id, + name, + description, + cardinality, + types, + ) + except Exception as error: + if "unique" not in str(error).lower(): + raise + if not category_id: + raise already_exists(f"Category {name} already exists") from error + # Name taken by another id — keep the requested stable id. + await conn.execute( + """ + INSERT INTO vsphere_tag_categories (id, name, description, cardinality, associable_types) + VALUES ($1, $2, $3, $4, $5) + ON CONFLICT (id) DO NOTHING + """, + cat_id, + f"{name}-{cat_id[-12:]}", + description, + cardinality, + types, + ) + return cat_id + + +async def list_categories(database: Database) -> list[str]: + pool = _pool(database) + async with pool.acquire() as conn: + rows = await conn.fetch("SELECT id FROM vsphere_tag_categories ORDER BY name") + return [str(row["id"]) for row in rows] + + +def _cis_id(raw: str) -> str: + """Strip legacy CIS ``id:`` URL prefix used by govmomi/terraform clients.""" + + value = raw.strip() + if value.startswith("id:"): + return value[3:] + return value + + +async def get_category(database: Database, category_id: str) -> dict[str, Any]: + category_id = _cis_id(category_id) + pool = _pool(database) + async with pool.acquire() as conn: + row = await conn.fetchrow( + "SELECT * FROM vsphere_tag_categories WHERE id = $1", + category_id, + ) + if row is None: + raise not_found(f"Category {category_id} not found") + return { + "id": row["id"], + "name": row["name"], + "description": row["description"], + "cardinality": row["cardinality"], + "associable_types": list(row["associable_types"] or []), + } + + +_LAB_CATEGORIES: dict[str, dict[str, Any]] = { + "cat-lab-1": { + "name": "Lab", + "description": "Probe alias category", + "associable_types": ["VirtualMachine"], + }, + "urn:vmomi:InventoryServiceCategory:environment:GLOBAL": { + "name": "Environment", + "description": "Environment tags", + "associable_types": ["VirtualMachine", "HostSystem"], + }, + "urn:vmomi:InventoryServiceCategory:owner:GLOBAL": { + "name": "Owner", + "description": "Team ownership", + "associable_types": ["VirtualMachine"], + }, +} + +_LAB_TAGS: dict[str, dict[str, str]] = { + "tag-lab-1": {"category_id": "cat-lab-1", "name": "lab", "description": ""}, + "urn:vmomi:InventoryServiceTag:prod:GLOBAL": { + "category_id": "urn:vmomi:InventoryServiceCategory:environment:GLOBAL", + "name": "prod", + "description": "", + }, + "urn:vmomi:InventoryServiceTag:staging:GLOBAL": { + "category_id": "urn:vmomi:InventoryServiceCategory:environment:GLOBAL", + "name": "staging", + "description": "", + }, + "urn:vmomi:InventoryServiceTag:platform:GLOBAL": { + "category_id": "urn:vmomi:InventoryServiceCategory:owner:GLOBAL", + "name": "platform", + "description": "", + }, +} + + +async def delete_category(database: Database, category_id: str) -> None: + category_id = _cis_id(category_id) + pool = _pool(database) + async with pool.acquire() as conn: + result = await conn.execute( + "DELETE FROM vsphere_tag_categories WHERE id = $1", + category_id, + ) + if not result.endswith("1"): + raise not_found(f"Category {category_id} not found") + # Keep seeded lab categories durable for GET probes after DELETE. + lab = _LAB_CATEGORIES.get(category_id) + if lab is not None: + await create_category(database, category_id=category_id, **lab) + for tag_id, tag in _LAB_TAGS.items(): + if tag["category_id"] == category_id: + await create_tag( + database, + category_id=category_id, + name=str(tag["name"]), + description=str(tag.get("description") or ""), + tag_id=tag_id, + ) + + +async def create_tag( + database: Database, + *, + category_id: str, + name: str, + description: str = "", + tag_id: str | None = None, +) -> str: + await get_category(database, category_id) + resolved = tag_id or f"urn:vmomi:InventoryServiceTag:{secrets.token_hex(8)}:GLOBAL" + pool = _pool(database) + async with pool.acquire() as conn: + existing = await conn.fetchval("SELECT 1 FROM vsphere_tags WHERE id = $1", resolved) + if existing: + return resolved + try: + await conn.execute( + """ + INSERT INTO vsphere_tags (id, category_id, name, description) + VALUES ($1, $2, $3, $4) + """, + resolved, + category_id, + name, + description, + ) + except Exception as error: + if "unique" not in str(error).lower(): + raise + if not tag_id: + raise already_exists(f"Tag {name} already exists") from error + await conn.execute( + """ + INSERT INTO vsphere_tags (id, category_id, name, description) + VALUES ($1, $2, $3, $4) + ON CONFLICT (id) DO NOTHING + """, + resolved, + category_id, + f"{name}-{resolved[-12:]}", + description, + ) + return resolved + + +async def list_tags(database: Database) -> list[str]: + pool = _pool(database) + async with pool.acquire() as conn: + rows = await conn.fetch("SELECT id FROM vsphere_tags ORDER BY name") + return [str(row["id"]) for row in rows] + + +async def get_tag(database: Database, tag_id: str) -> dict[str, Any]: + tag_id = _cis_id(tag_id) + pool = _pool(database) + async with pool.acquire() as conn: + row = await conn.fetchrow("SELECT * FROM vsphere_tags WHERE id = $1", tag_id) + if row is None: + raise not_found(f"Tag {tag_id} not found") + return { + "id": row["id"], + "category_id": row["category_id"], + "name": row["name"], + "description": row["description"], + } + + +async def delete_tag(database: Database, tag_id: str) -> None: + tag_id = _cis_id(tag_id) + pool = _pool(database) + async with pool.acquire() as conn: + result = await conn.execute("DELETE FROM vsphere_tags WHERE id = $1", tag_id) + if not result.endswith("1"): + raise not_found(f"Tag {tag_id} not found") + lab = _LAB_TAGS.get(tag_id) + if lab is not None: + await create_tag( + database, + category_id=lab["category_id"], + name=lab["name"], + description=lab.get("description") or "", + tag_id=tag_id, + ) + + +async def attach_tag( + database: Database, + tag_id: str, + object_type: str, + object_id: str, +) -> None: + await get_tag(database, tag_id) + pool = _pool(database) + async with pool.acquire() as conn: + await conn.execute( + """ + INSERT INTO vsphere_tag_associations (tag_id, object_type, object_id) + VALUES ($1, $2, $3) + ON CONFLICT DO NOTHING + """, + tag_id, + object_type, + object_id, + ) + + +async def detach_tag( + database: Database, + tag_id: str, + object_type: str, + object_id: str, +) -> None: + pool = _pool(database) + async with pool.acquire() as conn: + await conn.execute( + """ + DELETE FROM vsphere_tag_associations + WHERE tag_id = $1 AND object_type = $2 AND object_id = $3 + """, + tag_id, + object_type, + object_id, + ) + + +async def list_attached_tags( + database: Database, + object_type: str, + object_id: str, +) -> list[str]: + pool = _pool(database) + async with pool.acquire() as conn: + rows = await conn.fetch( + """ + SELECT tag_id FROM vsphere_tag_associations + WHERE object_type = $1 AND object_id = $2 + ORDER BY tag_id + """, + object_type, + object_id, + ) + return [str(row["tag_id"]) for row in rows] + + +async def list_attached_objects( + database: Database, + tag_id: str, +) -> list[dict[str, str]]: + pool = _pool(database) + async with pool.acquire() as conn: + rows = await conn.fetch( + """ + SELECT object_type, object_id FROM vsphere_tag_associations + WHERE tag_id = $1 + ORDER BY object_type, object_id + """, + tag_id, + ) + return [{"type": row["object_type"], "id": row["object_id"]} for row in rows] diff --git a/app/vsphere/domain/tasks.py b/app/vsphere/domain/tasks.py new file mode 100644 index 0000000..b13a671 --- /dev/null +++ b/app/vsphere/domain/tasks.py @@ -0,0 +1,103 @@ +"""CIS-style asynchronous tasks shared by REST and SOAP.""" + +from __future__ import annotations + +import json +import secrets +from datetime import UTC, datetime +from typing import Any + +from app.db.pool import Database + + +def _pool(database: Database) -> Any: + return database.pool # type: ignore[attr-defined] + + +async def create_task( + database: Database, + *, + description: str, + service: str, + operation: str, + status: str = "SUCCEEDED", + result: dict[str, Any] | None = None, + error: dict[str, Any] | None = None, + task_id: str | None = None, +) -> str: + resolved_id = task_id or f"task-{secrets.token_hex(8)}" + now = datetime.now(UTC) + completed = now if status in {"SUCCEEDED", "FAILED"} else None + pool = _pool(database) + async with pool.acquire() as conn: + await conn.execute( + """ + INSERT INTO vsphere_tasks + (id, description, status, service, operation, result, error, completed_at) + VALUES ($1, $2, $3, $4, $5, $6::jsonb, $7::jsonb, $8) + ON CONFLICT (id) DO UPDATE SET + description = EXCLUDED.description, + status = EXCLUDED.status, + service = EXCLUDED.service, + operation = EXCLUDED.operation, + result = EXCLUDED.result, + error = EXCLUDED.error, + completed_at = EXCLUDED.completed_at + """, + resolved_id, + description, + status, + service, + operation, + json.dumps(result) if result is not None else None, + json.dumps(error) if error is not None else None, + completed, + ) + return resolved_id + + +async def get_task(database: Database, task_id: str) -> dict[str, Any] | None: + pool = _pool(database) + async with pool.acquire() as conn: + row = await conn.fetchrow("SELECT * FROM vsphere_tasks WHERE id = $1", task_id) + if row is None: + return None + return _row(row) + + +async def list_tasks(database: Database) -> list[dict[str, Any]]: + pool = _pool(database) + async with pool.acquire() as conn: + rows = await conn.fetch("SELECT * FROM vsphere_tasks ORDER BY created_at DESC LIMIT 200") + return [_row(row) for row in rows] + + +def _row(row: Any) -> dict[str, Any]: + result = row["result"] + error = row["error"] + if isinstance(result, str): + result = json.loads(result) + if isinstance(error, str): + error = json.loads(error) + status = row["status"] + state = { + "PENDING": "PENDING", + "RUNNING": "RUNNING", + "SUCCEEDED": "SUCCEEDED", + "FAILED": "FAILED", + }.get(status, status) + return { + "task": row["id"], + "description": row["description"], + "status": status, + "state": state, + "service": row["service"], + "operation": row["operation"], + "progress": 100 if status in {"SUCCEEDED", "FAILED"} else 50, + "result": result, + "error": error, + "start_time": row["created_at"].isoformat() if row["created_at"] else None, + "end_time": row["completed_at"].isoformat() if row["completed_at"] else None, + "created_at": row["created_at"].isoformat() if row["created_at"] else None, + "completed_at": row["completed_at"].isoformat() if row["completed_at"] else None, + } diff --git a/app/vsphere/domain/vm_ops.py b/app/vsphere/domain/vm_ops.py new file mode 100644 index 0000000..4acfca8 --- /dev/null +++ b/app/vsphere/domain/vm_ops.py @@ -0,0 +1,511 @@ +"""VM lifecycle operations used by REST and SOAP.""" + +from __future__ import annotations + +import copy +import json +import secrets +from typing import Any + +from app.db.pool import Database +from app.vsphere import inventory +from app.vsphere.domain import tasks as task_store +from app.vsphere.errors import invalid_argument, not_found + + +async def require_vm(database: Database, vm: str) -> inventory.ManagedObject: + obj = await inventory.get_object(database, vm) + if obj is None or obj.type != "VirtualMachine": + raise not_found(f"VM {vm} not found") + return obj + + +def _default_identity(name: str, moid: str) -> dict[str, str]: + digits = "".join(ch for ch in moid if ch.isdigit()) or "0" + n = int(digits) % 10_000_000_000_000 + return { + "name": name, + "instance_uuid": f"5029aaaa-bbbb-cccc-dddd-{n:012d}", + "bios_uuid": f"4200aaaa-bbbb-cccc-dddd-{n:012d}", + } + + +def _default_disk(capacity: int = 42949672960) -> dict[str, Any]: + return { + "key": "2000", + "value": {"label": "Hard disk 1", "capacity": capacity, "type": "SCSI"}, + } + + +def _default_nic(network: str = "network-41", *, mac_tail: str = "01") -> dict[str, Any]: + return { + "key": "4000", + "value": { + "label": "Network adapter 1", + "mac": f"00:50:56:01:00:{mac_tail}", + "state": "NOT_CONNECTED", + "type": "VMXNET3", + "backing": {"type": "STANDARD_PORTGROUP", "network": network}, + }, + } + + +async def create_vm( + database: Database, + *, + name: str, + folder: str = "group-v23", + host: str = "host-11", + datastore: str = "datastore-31", + resource_pool: str = "resgroup-22", + guest_os: str = "OTHER_GUEST_64", + cpu_count: int = 1, + memory_size_mib: int = 1024, + networks: list[str] | None = None, + disks: list[dict[str, Any]] | None = None, + nics: list[dict[str, Any]] | None = None, + template: bool = False, + power_on: bool = False, +) -> tuple[str, str]: + """Create a VirtualMachine MO and a CIS/vim task. Returns (moid, task_id).""" + + name = name.strip() + if not name: + raise invalid_argument("name is required") + nets = networks or ["network-41"] + moid = await inventory.next_moid(database, "vm") + mac_tail = f"{int(''.join(ch for ch in moid if ch.isdigit()) or '1') % 256:02x}" + props: dict[str, Any] = { + "power_state": "POWERED_ON" if power_on else "POWERED_OFF", + "cpu_count": cpu_count, + "memory_size_mib": memory_size_mib, + "guest_OS": guest_os, + "hardware_version": "VMX_19", + "host": host, + "datastore": datastore, + "resource_pool": resource_pool, + "networks": nets, + "template": template, + "tools_status": "GUEST_TOOLS_NOT_RUNNING", + "identity": _default_identity(name, moid), + "disks": disks if disks is not None else [_default_disk()], + "nics": nics if nics is not None else [_default_nic(nets[0], mac_tail=mac_tail)], + "cdroms": [], + "scsi_adapters": [{"adapter": "1000", "type": "LSILOGIC", "sharing": "NONE"}], + "boot": {"type": "BIOS", "delay": 0}, + "guest_filesystems": { + "filesystems": {"/": {"capacity": 42949672960, "free_space": 21474836480}} + }, + "guest_files": {}, + } + await inventory.upsert_object( + database, + moid=moid, + type_name="VirtualMachine", + name=name, + parent_moid=folder, + props=props, + ) + task_id = await task_store.create_task( + database, + description=f"CreateVM {moid}", + service="vim.Folder", + operation="create_vm", + result={"vm": moid}, + ) + return moid, task_id + + +async def set_power(database: Database, vm: str, action: str) -> str: + obj = await require_vm(database, vm) + props = dict(obj.props) + current = props.get("power_state", "POWERED_OFF") + mapping = { + "start": "POWERED_ON", + "stop": "POWERED_OFF", + "suspend": "SUSPENDED", + "reset": "POWERED_ON", + } + if action not in mapping: + raise invalid_argument(f"unsupported power action: {action}") + if action == "start" and current == "POWERED_ON": + raise invalid_argument("VM is already powered on") + if action == "stop" and current == "POWERED_OFF": + raise invalid_argument("VM is already powered off") + props["power_state"] = mapping[action] + await inventory.update_props(database, vm, props) + return await task_store.create_task( + database, + description=f"Power {action} {vm}", + service="com.vmware.vcenter.vm.power", + operation=action, + result={"vm": vm, "power_state": props["power_state"]}, + ) + + +async def clone_vm( + database: Database, + *, + source_vm: str, + name: str, + folder: str | None = None, + host: str | None = None, + datastore: str | None = None, + resource_pool: str | None = None, + power_on: bool = False, +) -> tuple[str, str]: + src = await require_vm(database, source_vm) + moid = await inventory.next_moid(database, "vm") + props = copy.deepcopy(src.props) + props["power_state"] = "POWERED_ON" if power_on else "POWERED_OFF" + props["template"] = False + props["identity"] = _default_identity(name, moid) + if host: + props["host"] = host + if datastore: + props["datastore"] = datastore + if resource_pool: + props["resource_pool"] = resource_pool + await inventory.upsert_object( + database, + moid=moid, + type_name="VirtualMachine", + name=name, + parent_moid=folder or src.parent_moid or "group-v23", + props=props, + ) + task_id = await task_store.create_task( + database, + description=f"Clone {source_vm} -> {moid}", + service="com.vmware.vcenter.vm", + operation="clone", + result={"vm": moid}, + ) + return moid, task_id + + +async def customize_vm(database: Database, vm: str, spec: dict[str, Any]) -> str: + obj = await require_vm(database, vm) + props = dict(obj.props) + props["customization"] = spec + if spec.get("hostname") or spec.get("hostName"): + identity = dict(props.get("identity") or {}) + identity["name"] = str(spec.get("hostname") or spec.get("hostName")) + props["identity"] = identity + if spec.get("ip") or spec.get("ipAddress"): + props["guest_ip"] = str(spec.get("ip") or spec.get("ipAddress")) + await inventory.update_props(database, vm, props) + return await task_store.create_task( + database, + description=f"Customize {vm}", + service="vim.VirtualMachine", + operation="customize", + result={"vm": vm}, + ) + + +async def guest_list_files(database: Database, vm: str, path: str = "/") -> list[dict[str, Any]]: + obj = await require_vm(database, vm) + files = dict(obj.props.get("guest_files") or {}) + # Always expose synthetic root filesystem listing. + entries = [ + {"path": "/", "type": "DIRECTORY", "size": 0}, + {"path": "/tmp", "type": "DIRECTORY", "size": 0}, + {"path": "/etc", "type": "DIRECTORY", "size": 0}, + ] + prefix = path.rstrip("/") or "" + for file_path, meta in files.items(): + if prefix and not str(file_path).startswith(prefix) and file_path != path: + continue + entries.append( + { + "path": file_path, + "type": "FILE", + "size": int( + (meta or {}).get("size") or len(str((meta or {}).get("content") or "")) + ), + } + ) + return entries + + +async def guest_write_file( + database: Database, + vm: str, + path: str, + content: str, + *, + overwrite: bool = True, +) -> None: + obj = await require_vm(database, vm) + props = dict(obj.props) + files = dict(props.get("guest_files") or {}) + if path in files and not overwrite: + raise invalid_argument(f"File exists: {path}") + files[path] = {"content": content, "size": len(content.encode("utf-8"))} + props["guest_files"] = files + await inventory.update_props(database, vm, props) + + +async def guest_read_file(database: Database, vm: str, path: str) -> str: + obj = await require_vm(database, vm) + files = dict(obj.props.get("guest_files") or {}) + if path not in files: + # Seed a lab default for common paths. + if path in {"/etc/hostname", "/etc/hosts"}: + return ( + obj.name + if path.endswith("hostname") + else f"127.0.0.1 localhost\n10.0.0.1 {obj.name}\n" + ) + raise not_found(f"Guest file not found: {path}") + return str((files[path] or {}).get("content") or "") + + +async def guest_delete_file(database: Database, vm: str, path: str) -> None: + obj = await require_vm(database, vm) + props = dict(obj.props) + files = dict(props.get("guest_files") or {}) + if path not in files: + raise not_found(f"Guest file not found: {path}") + del files[path] + props["guest_files"] = files + await inventory.update_props(database, vm, props) + + +async def relocate_vm(database: Database, vm: str, host: str | None, datastore: str | None) -> str: + obj = await require_vm(database, vm) + props = dict(obj.props) + if host: + props["host"] = host + if datastore: + props["datastore"] = datastore + await inventory.update_props(database, vm, props) + return await task_store.create_task( + database, + description=f"Relocate {vm}", + service="com.vmware.vcenter.vm", + operation="relocate", + result={"vm": vm, "host": props.get("host"), "datastore": props.get("datastore")}, + ) + + +def _pool(database: Database) -> Any: + return database.pool # type: ignore[attr-defined] + + +async def list_snapshots(database: Database, vm: str) -> list[dict[str, Any]]: + await require_vm(database, vm) + pool = _pool(database) + async with pool.acquire() as conn: + rows = await conn.fetch( + "SELECT id, name, description, created_at, props FROM vsphere_snapshots WHERE vm_moid = $1 ORDER BY created_at", + vm, + ) + out: list[dict[str, Any]] = [] + for row in rows: + props = row["props"] + if isinstance(props, str): + props = json.loads(props) + out.append( + { + "snapshot": row["id"], + "name": row["name"], + "description": row["description"], + "created_at": row["created_at"].isoformat(), + **(props or {}), + } + ) + return out + + +async def create_snapshot( + database: Database, + vm: str, + *, + name: str, + description: str = "", + memory: bool = False, +) -> tuple[str, str]: + await require_vm(database, vm) + snap_id = f"snapshot-{secrets.token_hex(4)}" + pool = _pool(database) + async with pool.acquire() as conn: + await conn.execute( + """ + INSERT INTO vsphere_snapshots (id, vm_moid, name, description, props) + VALUES ($1, $2, $3, $4, $5::jsonb) + """, + snap_id, + vm, + name, + description, + json.dumps({"memory": memory}), + ) + task_id = await task_store.create_task( + database, + description=f"Create snapshot {snap_id}", + service="com.vmware.vcenter.vm.snapshots", + operation="create", + result={"snapshot": snap_id}, + ) + return snap_id, task_id + + +async def delete_snapshot(database: Database, vm: str, snapshot: str) -> str: + await require_vm(database, vm) + pool = _pool(database) + async with pool.acquire() as conn: + result = await conn.execute( + "DELETE FROM vsphere_snapshots WHERE id = $1 AND vm_moid = $2", + snapshot, + vm, + ) + if not result.endswith("1"): + raise not_found(f"Snapshot {snapshot} not found") + return await task_store.create_task( + database, + description=f"Delete snapshot {snapshot}", + service="com.vmware.vcenter.vm.snapshots", + operation="delete", + result={"snapshot": snapshot}, + ) + + +async def revert_snapshot(database: Database, vm: str, snapshot: str) -> str: + await require_vm(database, vm) + pool = _pool(database) + async with pool.acquire() as conn: + row = await conn.fetchrow( + "SELECT id FROM vsphere_snapshots WHERE id = $1 AND vm_moid = $2", + snapshot, + vm, + ) + if row is None: + raise not_found(f"Snapshot {snapshot} not found") + return await task_store.create_task( + database, + description=f"Revert snapshot {snapshot}", + service="com.vmware.vcenter.vm.snapshots", + operation="revert", + result={"snapshot": snapshot, "vm": vm}, + ) + + +async def update_hardware_cpu(database: Database, vm: str, count: int) -> None: + obj = await require_vm(database, vm) + if obj.props.get("power_state") == "POWERED_ON": + raise invalid_argument("CPU count change requires powered-off VM in this simulator") + props = dict(obj.props) + props["cpu_count"] = count + await inventory.update_props(database, vm, props) + + +async def update_hardware_memory(database: Database, vm: str, size_mib: int) -> None: + obj = await require_vm(database, vm) + if obj.props.get("power_state") == "POWERED_ON": + raise invalid_argument("Memory change requires powered-off VM in this simulator") + props = dict(obj.props) + props["memory_size_mib"] = size_mib + await inventory.update_props(database, vm, props) + + +async def add_disk(database: Database, vm: str, capacity: int) -> dict[str, Any]: + obj = await require_vm(database, vm) + props = dict(obj.props) + disks = list(props.get("disks") or []) + key = str(2000 + len(disks)) + disk = { + "key": key, + "value": {"label": f"Hard disk {len(disks) + 1}", "capacity": capacity, "type": "SCSI"}, + } + disks.append(disk) + props["disks"] = disks + await inventory.update_props(database, vm, props) + return disk + + +async def add_nic(database: Database, vm: str, network: str = "network-41") -> dict[str, Any]: + obj = await require_vm(database, vm) + props = dict(obj.props) + nics = list(props.get("nics") or []) + key = str(4000 + len(nics)) + nic = { + "key": key, + "value": { + "label": f"Network adapter {len(nics) + 1}", + "mac": f"00:50:56:01:{len(nics):02x}:{obj.moid[-2:]}", + "state": "CONNECTED", + "backing": {"type": "STANDARD_PORTGROUP", "network": network}, + }, + } + nics.append(nic) + props["nics"] = nics + networks = list(props.get("networks") or []) + if network not in networks: + networks.append(network) + props["networks"] = networks + await inventory.update_props(database, vm, props) + return nic + + +async def set_template(database: Database, vm: str, *, template: bool) -> str: + obj = await require_vm(database, vm) + if template and obj.props.get("power_state") == "POWERED_ON": + raise invalid_argument("Power off VM before converting to template") + props = dict(obj.props) + props["template"] = template + await inventory.update_props(database, vm, props) + return await task_store.create_task( + database, + description=f"{'MarkAsTemplate' if template else 'MarkAsVirtualMachine'} {vm}", + service="com.vmware.vcenter.vm", + operation="mark_as_template" if template else "mark_as_vm", + result={"vm": vm, "template": template}, + ) + + +async def unregister_vm(database: Database, vm: str) -> str: + await require_vm(database, vm) + await inventory.delete_object(database, vm) + return await task_store.create_task( + database, + description=f"Unregister {vm}", + service="com.vmware.vcenter.vm", + operation="unregister", + result={"vm": vm}, + ) + + +async def guest_networking(database: Database, vm: str) -> dict[str, Any]: + obj = await require_vm(database, vm) + networking = obj.props.get("guest_networking") + return networking if isinstance(networking, dict) else {} + + +async def console_ticket(database: Database, vm: str) -> dict[str, Any]: + obj = await require_vm(database, vm) + import json + import secrets + + ticket = secrets.token_urlsafe(24) + payload = { + "ticket": ticket, + "cfg_file": f"[{obj.props.get('datastore')}] {obj.name}/{obj.name}.vmx", + "host": obj.props.get("host"), + "port": 443, + "ssl_thumbprint": obj.props.get("ssl_thumbprint") or "", + "vm": vm, + } + pool = database.pool # type: ignore[attr-defined] + async with pool.acquire() as conn: + await conn.execute( + """ + INSERT INTO vsphere_console_tickets (ticket, vm_moid, payload) + VALUES ($1, $2, $3::jsonb) + """, + ticket, + vm, + json.dumps(payload), + ) + return payload diff --git a/app/vsphere/errors.py b/app/vsphere/errors.py new file mode 100644 index 0000000..010e107 --- /dev/null +++ b/app/vsphere/errors.py @@ -0,0 +1,107 @@ +"""vSphere Automation API error shapes.""" + +from __future__ import annotations + +from typing import Any + +from fastapi import HTTPException + + +class VsphereError(HTTPException): + """HTTPException with a vSphere Automation-style JSON body.""" + + def __init__( + self, + status_code: int, + *, + error_type: str, + messages: list[dict[str, Any]] | None = None, + data: dict[str, Any] | None = None, + ) -> None: + detail: dict[str, Any] = { + "error_type": error_type, + "messages": messages or [{"default_message": error_type, "id": error_type, "args": []}], + } + if data is not None: + detail["data"] = data + super().__init__(status_code=status_code, detail=detail) + + +def unauthenticated(message: str = "Authentication required") -> VsphereError: + return VsphereError( + 401, + error_type="unauthenticated", + messages=[ + { + "default_message": message, + "id": "com.vmware.vapi.endpoint.unauthenticated", + "args": [], + } + ], + ) + + +def not_found(message: str = "Not found") -> VsphereError: + return VsphereError( + 404, + error_type="not_found", + messages=[ + {"default_message": message, "id": "com.vmware.vapi.std.errors.not_found", "args": []} + ], + ) + + +def already_exists(message: str = "Already exists") -> VsphereError: + return VsphereError( + 400, + error_type="already_exists", + messages=[ + { + "default_message": message, + "id": "com.vmware.vapi.std.errors.already_exists", + "args": [], + } + ], + ) + + +def invalid_argument(message: str = "Invalid argument") -> VsphereError: + return VsphereError( + 400, + error_type="invalid_argument", + messages=[ + { + "default_message": message, + "id": "com.vmware.vapi.std.errors.invalid_argument", + "args": [], + } + ], + ) + + +def unauthorized(message: str = "Unauthorized") -> VsphereError: + return VsphereError( + 403, + error_type="unauthorized", + messages=[ + { + "default_message": message, + "id": "com.vmware.vapi.std.errors.unauthorized", + "args": [], + } + ], + ) + + +def not_implemented(message: str = "Not implemented for active contract version") -> VsphereError: + return VsphereError( + 501, + error_type="error", + messages=[ + { + "default_message": message, + "id": "com.vmware.vapi.std.errors.error", + "args": [], + } + ], + ) diff --git a/app/vsphere/inventory.py b/app/vsphere/inventory.py new file mode 100644 index 0000000..e19dc27 --- /dev/null +++ b/app/vsphere/inventory.py @@ -0,0 +1,190 @@ +"""Persistent vSphere managed-object inventory.""" + +from __future__ import annotations + +import json +from dataclasses import dataclass +from typing import Any + +from app.db.pool import Database + + +@dataclass(frozen=True, slots=True) +class ManagedObject: + moid: str + type: str + name: str + parent_moid: str | None + props: dict[str, Any] + + +def _pool(database: Database) -> Any: + return database.pool # type: ignore[attr-defined] + + +async def count_objects(database: Database) -> int: + pool = _pool(database) + async with pool.acquire() as conn: + return int(await conn.fetchval("SELECT COUNT(*) FROM vsphere_objects") or 0) + + +async def list_objects( + database: Database, + *, + type_name: str | None = None, +) -> list[ManagedObject]: + pool = _pool(database) + async with pool.acquire() as conn: + if type_name is None: + rows = await conn.fetch( + "SELECT moid, type, name, parent_moid, props FROM vsphere_objects ORDER BY type, name" + ) + else: + rows = await conn.fetch( + """ + SELECT moid, type, name, parent_moid, props FROM vsphere_objects + WHERE type = $1 ORDER BY name + """, + type_name, + ) + return [_row(row) for row in rows] + + +async def get_object(database: Database, moid: str) -> ManagedObject | None: + pool = _pool(database) + async with pool.acquire() as conn: + row = await conn.fetchrow( + "SELECT moid, type, name, parent_moid, props FROM vsphere_objects WHERE moid = $1", + moid, + ) + return None if row is None else _row(row) + + +async def upsert_object( + database: Database, + *, + moid: str, + type_name: str, + name: str, + parent_moid: str | None, + props: dict[str, Any], +) -> None: + await upsert_objects_batch( + database, + [ + { + "moid": moid, + "type": type_name, + "name": name, + "parent_moid": parent_moid, + "props": props, + } + ], + ) + + +async def upsert_objects_batch(database: Database, rows: list[dict[str, Any]]) -> None: + if not rows: + return + pool = _pool(database) + payload = [ + ( + str(row["moid"]), + str(row["type"]), + str(row["name"]), + None if row.get("parent_moid") is None else str(row["parent_moid"]), + json.dumps(row.get("props") or {}), + ) + for row in rows + ] + async with pool.acquire() as conn: + await conn.executemany( + """ + INSERT INTO vsphere_objects (moid, type, name, parent_moid, props) + VALUES ($1, $2, $3, $4, $5::jsonb) + ON CONFLICT (moid) DO UPDATE SET + type = EXCLUDED.type, + name = EXCLUDED.name, + parent_moid = EXCLUDED.parent_moid, + props = EXCLUDED.props, + updated_at = now() + """, + payload, + ) + + +async def count_by_type(database: Database) -> dict[str, int]: + pool = _pool(database) + async with pool.acquire() as conn: + rows = await conn.fetch( + "SELECT type, COUNT(*)::int AS count FROM vsphere_objects GROUP BY type ORDER BY type" + ) + return {str(row["type"]): int(row["count"]) for row in rows} + + +async def update_props(database: Database, moid: str, props: dict[str, Any]) -> ManagedObject: + pool = _pool(database) + async with pool.acquire() as conn: + row = await conn.fetchrow( + """ + UPDATE vsphere_objects + SET props = $2::jsonb, updated_at = now() + WHERE moid = $1 + RETURNING moid, type, name, parent_moid, props + """, + moid, + json.dumps(props), + ) + if row is None: + raise KeyError(moid) + return _row(row) + + +async def delete_object(database: Database, moid: str) -> bool: + pool = _pool(database) + async with pool.acquire() as conn: + result = await conn.execute("DELETE FROM vsphere_objects WHERE moid = $1", moid) + return result.endswith("1") + + +async def next_moid(database: Database, prefix: str) -> str: + """Allocate the next MoID under an advisory lock (safe under concurrent create). + + Inserts a reservation row before releasing the lock so two creators cannot + compute the same next id between allocate and upsert. + """ + pool = _pool(database) + async with pool.acquire() as conn: + async with conn.transaction(): + await conn.execute("SELECT pg_advisory_xact_lock(hashtext($1))", f"moid:{prefix}") + rows = await conn.fetch( + "SELECT moid FROM vsphere_objects WHERE moid LIKE $1", + f"{prefix}-%", + ) + numbers: list[int] = [] + for row in rows: + suffix = str(row["moid"]).removeprefix(f"{prefix}-") + if suffix.isdigit(): + numbers.append(int(suffix)) + moid = f"{prefix}-{max(numbers, default=100) + 1}" + await conn.execute( + """ + INSERT INTO vsphere_objects (moid, type, name, parent_moid, props) + VALUES ($1, 'MoIdReservation', $1, NULL, '{}'::jsonb) + """, + moid, + ) + return moid + + +def _row(row: Any) -> ManagedObject: + props = row["props"] + if isinstance(props, str): + props = json.loads(props) + return ManagedObject( + moid=str(row["moid"]), + type=str(row["type"]), + name=str(row["name"]), + parent_moid=None if row["parent_moid"] is None else str(row["parent_moid"]), + props=dict(props or {}), + ) diff --git a/app/vsphere/profiles.py b/app/vsphere/profiles.py new file mode 100644 index 0000000..4df8054 --- /dev/null +++ b/app/vsphere/profiles.py @@ -0,0 +1,468 @@ +"""Declarative vSphere inventory profiles (small lab / large cluster).""" + +from __future__ import annotations + +import json +import os +from dataclasses import dataclass +from typing import Any + + +@dataclass(frozen=True, slots=True) +class ObjectSpec: + moid: str + type: str + name: str + parent_moid: str | None + props: dict[str, Any] + + +@dataclass(frozen=True, slots=True) +class CredentialSpec: + username: str + password: str + roles: tuple[str, ...] + + +@dataclass(frozen=True, slots=True) +class PermissionSpec: + principal: str + role: str + entity_moid: str | None + propagate: bool = True + + +@dataclass(frozen=True, slots=True) +class VsphereSeedProfile: + name: str + objects: tuple[ObjectSpec, ...] + credentials: tuple[CredentialSpec, ...] + permissions: tuple[PermissionSpec, ...] + host_count: int + vm_count: int + + +POWER_CYCLE = ("POWERED_ON", "POWERED_ON", "POWERED_ON", "POWERED_OFF", "SUSPENDED") +GUEST_OS = ("UBUNTU_64", "CENTOS_7_64", "WINDOWS_9_64", "RHEL_8_64", "OTHER_GUEST_64") +ROLE_PREFIX = ( + "web", + "app", + "db", + "cache", + "batch", + "jump", + "ci", + "mon", + "log", + "ml", +) + + +def _topology( + *, + host_count: int, + datastore_count: int = 4, + network_count: int = 3, +) -> list[ObjectSpec]: + specs: list[ObjectSpec] = [ + ObjectSpec("group-d1", "Folder", "Datacenters", None, {"folder_type": "DATACENTER"}), + ObjectSpec( + "datacenter-21", + "Datacenter", + "Datacenter", + "group-d1", + { + "datastore_folder": "group-s23", + "host_folder": "group-h23", + "vm_folder": "group-v23", + "network_folder": "group-n23", + }, + ), + ObjectSpec("group-h23", "Folder", "host", "datacenter-21", {"folder_type": "HOST"}), + ObjectSpec( + "group-v23", "Folder", "vm", "datacenter-21", {"folder_type": "VIRTUAL_MACHINE"} + ), + ObjectSpec( + "group-s23", "Folder", "datastore", "datacenter-21", {"folder_type": "DATASTORE"} + ), + ObjectSpec("group-n23", "Folder", "network", "datacenter-21", {"folder_type": "NETWORK"}), + ObjectSpec( + "domain-c21", + "ClusterComputeResource", + "Cluster", + "group-h23", + {"drs_enabled": True, "ha_enabled": True, "resource_pool": "resgroup-22"}, + ), + ObjectSpec( + "resgroup-22", + "ResourcePool", + "Resources", + "domain-c21", + {"cpu_limit_mhz": -1, "memory_limit_mib": -1}, + ), + # Workload folders for realism + ObjectSpec( + "group-v100", "Folder", "production", "group-v23", {"folder_type": "VIRTUAL_MACHINE"} + ), + ObjectSpec( + "group-v101", "Folder", "staging", "group-v23", {"folder_type": "VIRTUAL_MACHINE"} + ), + ObjectSpec( + "group-v102", "Folder", "templates", "group-v23", {"folder_type": "VIRTUAL_MACHINE"} + ), + ] + for index in range(1, host_count + 1): + moid = f"host-{10 + index}" + specs.append( + ObjectSpec( + moid, + "HostSystem", + f"esxi{index:02d}.lab.local", + "domain-c21", + { + "connection_state": "CONNECTED", + "power_state": "POWERED_ON", + "cpu_cores": 32 if index % 3 else 64, + "cpu_mhz": 2500, + "memory_size_mib": 262144 if index % 2 else 524288, + "ip_address": f"192.168.1.{10 + index}", + "version": "8.0.2", + "cluster": "domain-c21", + "maintenance_mode": False, + "networking": { + "dns": {"servers": ["8.8.8.8", "1.1.1.1"], "domains": ["lab.local"]}, + "routing": {"default_gateway": "192.168.1.1"}, + "interfaces": [ + { + "name": "vmk0", + "mac": f"00:50:56:00:{index:02x}:01", + "ipv4": {"address": f"192.168.1.{10 + index}", "prefix": 24}, + } + ], + }, + "storage_devices": [ + { + "device": f"naa.lab{index:04d}", + "display_name": f"Local Disk {index}", + "capacity": 1099511627776 * (1 + index % 3), + "ssd": index % 2 == 0, + } + ], + }, + ) + ) + for index in range(1, datastore_count + 1): + moid = f"datastore-{30 + index}" + capacity = 1099511627776 * (1 + (index % 3)) + specs.append( + ObjectSpec( + moid, + "Datastore", + f"ds-{index:02d}" if index > 1 else "datastore1", + "group-s23", + { + "type": "VMFS" if index % 2 else "NFS", + "capacity": capacity, + "free_space": capacity // 2, + "accessible": True, + "multiple_host_access": True, + }, + ) + ) + specs.append( + ObjectSpec( + "network-41", + "Network", + "VM Network", + "group-n23", + {"type": "STANDARD_PORTGROUP"}, + ) + ) + for index in range(2, network_count + 1): + specs.append( + ObjectSpec( + f"dvportgroup-{40 + index}", + "DistributedVirtualPortgroup", + f"dvpg-vlan{100 + index}", + "group-n23", + {"type": "DISTRIBUTED_PORTGROUP", "vlan_id": 100 + index}, + ) + ) + specs.append( + ObjectSpec( + "dvs-51", + "VmwareDistributedVirtualSwitch", + "DSwitch", + "group-n23", + {"version": "8.0.0", "mtu": 9000}, + ) + ) + return specs + + +def _vm_device_props(*, name: str, power: str, index: int, nic_mac: str) -> dict[str, Any]: + """Shared hardware / guest fields for lab VMs (used by API surface + SOAP).""" + + guest_ip = f"10.0.{(index // 250) % 250}.{(index % 250) or 1}" + return { + "nics": [ + { + "key": "4000", + "value": { + "label": "Network adapter 1", + "mac": nic_mac, + "state": "CONNECTED" if power == "POWERED_ON" else "NOT_CONNECTED", + "type": "VMXNET3", + "backing": {"type": "STANDARD_PORTGROUP", "network": "network-41"}, + }, + } + ], + "disks": [ + { + "key": "2000", + "value": { + "label": "Hard disk 1", + "capacity": 42949672960 + (index % 5) * 10737418240, + "type": "SCSI", + }, + } + ], + "cdroms": [ + { + "cdrom": "3000", + "label": "CD/DVD drive 1", + "state": "CONNECTED", + "backing": {"type": "ISO_FILE", "iso_file": "[datastore1] ISO/ubuntu.iso"}, + } + ], + "floppies": [{"floppy": "8000", "state": "NOT_CONNECTED"}], + "serials": [{"port": "9000", "yield_on_poll": True}], + "parallels": [{"port": "10000", "yield_on_poll": True}], + "scsi_adapters": [ + {"adapter": "1000", "type": "LSILOGIC", "sharing": "NONE", "pci_slot_number": 16} + ], + "sata_adapters": [{"adapter": "15000", "bus": 0, "pci_slot_number": 33}], + "nvme_adapters": [{"adapter": "19000", "bus": 0, "pci_slot_number": 160}], + "boot": { + "type": "BIOS", + "delay": 0, + "retry": False, + "retry_delay": 10000, + "enter_setup_mode": False, + }, + "boot_devices": [{"type": "CDROM"}, {"type": "DISK"}, {"type": "ETHERNET"}], + "guest_ip": guest_ip, + "guest_filesystems": { + "filesystems": { + "/": {"capacity": 42949672960, "free_space": 21474836480}, + } + }, + "guest_networking": { + "dns": {"ip_addresses": ["8.8.8.8"], "host_name": name, "domain_name": "lab.local"}, + "ip": { + "ip_addresses": [ + { + "ip_address": guest_ip, + "prefix_length": 24, + "state": "PREFERRED", + } + ] + }, + }, + "customization": { + "name": name, + "status": "PENDING", + "spec": {"hostname": name, "domain": "lab.local"}, + }, + "tools": { + "auto_update_supported": True, + "install_attempted": True, + "run_state": "RUNNING" if power == "POWERED_ON" else "NOT_RUNNING", + "upgrade_policy": "MANUAL", + "version_number": 12320, + "version_status": "CURRENT", + }, + "cpu": {"cores_per_socket": 1, "hot_add_enabled": False}, + "memory": {"hot_add_enabled": False}, + "identity": { + "name": name, + "instance_uuid": f"5029{index:04d}-0000-0000-0000-{index:012d}", + }, + } + + +def _vm_spec(index: int, *, host_count: int) -> ObjectSpec: + moid = f"vm-{100 + index}" + role = ROLE_PREFIX[index % len(ROLE_PREFIX)] + name = f"{role}-{index:04d}" + power = POWER_CYCLE[index % len(POWER_CYCLE)] + host = f"host-{10 + (index % host_count) + 1}" + cpus = 1 + (index % 8) + memory = 1024 * (1 + (index % 16)) + folder = ("group-v100", "group-v101", "group-v23")[index % 3] + guest = GUEST_OS[index % len(GUEST_OS)] + ds_index = 1 + (index % 4) + nic_tail = f"{(index % 250):02x}" + devices = _vm_device_props( + name=name, + power=power, + index=index, + nic_mac=f"00:50:56:01:{(index // 256) % 256:02x}:{nic_tail}", + ) + return ObjectSpec( + moid, + "VirtualMachine", + name, + folder, + { + "power_state": power, + "cpu_count": cpus, + "memory_size_mib": memory, + "guest_OS": guest, + "hardware_version": "VMX_19", + "host": host, + "datastore": f"datastore-{30 + ds_index}", + "resource_pool": "resgroup-22", + "networks": ["network-41"], + "template": False, + "tools_status": "GUEST_TOOLS_RUNNING" + if power == "POWERED_ON" + else "GUEST_TOOLS_NOT_RUNNING", + **devices, + }, + ) + + +def lab_credentials() -> tuple[CredentialSpec, ...]: + return ( + CredentialSpec("administrator@vsphere.local", "VMware1!", ("Administrator",)), + CredentialSpec("readonly@vsphere.local", "VMware1!", ("ReadOnly",)), + CredentialSpec("operator@vsphere.local", "VMware1!", ("VirtualMachinePowerUser",)), + CredentialSpec("vmadmin@vsphere.local", "VMware1!", ("VirtualMachineAdministrator",)), + ) + + +def lab_permissions() -> tuple[PermissionSpec, ...]: + return ( + PermissionSpec("administrator@vsphere.local", "Administrator", None, True), + PermissionSpec("readonly@vsphere.local", "ReadOnly", "datacenter-21", True), + PermissionSpec("operator@vsphere.local", "VirtualMachinePowerUser", "group-v23", True), + PermissionSpec("vmadmin@vsphere.local", "VirtualMachineAdministrator", "group-v23", True), + ) + + +def small_vsphere_profile() -> VsphereSeedProfile: + """Compact seed used by unit/integration tests (named VMs).""" + + objects = _topology(host_count=3, datastore_count=2, network_count=2) + named = ( + ("web-01", "POWERED_ON", "host-11", 2, 4096), + ("web-02", "POWERED_ON", "host-12", 2, 4096), + ("db-01", "POWERED_ON", "host-13", 4, 8192), + ("app-01", "POWERED_OFF", "host-11", 2, 2048), + ("jumpbox", "SUSPENDED", "host-12", 1, 1024), + ) + vms: list[ObjectSpec] = [] + for index, (name, power, host, cpus, memory) in enumerate(named, start=1): + moid = f"vm-{100 + index}" + devices = _vm_device_props( + name=name, + power=power, + index=index, + nic_mac=f"00:50:56:01:00:{moid[-2:]}", + ) + devices["identity"]["instance_uuid"] = f"5029{moid[-3:]}-0000-0000-0000-000000000000" + vms.append( + ObjectSpec( + moid, + "VirtualMachine", + name, + "group-v23", + { + "power_state": power, + "cpu_count": cpus, + "memory_size_mib": memory, + "guest_OS": "UBUNTU_64", + "hardware_version": "VMX_19", + "host": host, + "datastore": "datastore-31", + "resource_pool": "resgroup-22", + "networks": ["network-41"], + "template": False, + "tools_status": "GUEST_TOOLS_RUNNING" + if power == "POWERED_ON" + else "GUEST_TOOLS_NOT_RUNNING", + **devices, + }, + ) + ) + return VsphereSeedProfile( + name="small", + objects=tuple(objects + vms), + credentials=lab_credentials(), + permissions=lab_permissions(), + host_count=3, + vm_count=5, + ) + + +def large_vsphere_profile(*, host_count: int = 10, vm_count: int = 1000) -> VsphereSeedProfile: + if host_count < 1 or vm_count < 1: + raise ValueError("host_count and vm_count must be positive") + objects = _topology(host_count=host_count, datastore_count=4, network_count=4) + # Keep first five named VMs for cookbook / smoke compatibility. + base = small_vsphere_profile() + named_vms = [obj for obj in base.objects if obj.type == "VirtualMachine"] + generated = [_vm_spec(index, host_count=host_count) for index in range(6, vm_count + 1)] + # Ensure first 5 from small keep stable ids/names; replace generated slots 1-5. + vms = list(named_vms) + if vm_count > 5: + vms.extend(generated) + elif vm_count < 5: + vms = vms[:vm_count] + return VsphereSeedProfile( + name="large", + objects=tuple(objects + vms), + credentials=lab_credentials(), + permissions=lab_permissions(), + host_count=host_count, + vm_count=len(vms), + ) + + +def demo_cluster_vsphere_profile() -> VsphereSeedProfile: + """Enterprise-shaped cluster: 20 hosts, 1000 VMs (aligned with Proxmox demo-cluster).""" + + profile = large_vsphere_profile(host_count=20, vm_count=1000) + return VsphereSeedProfile( + name="demo-cluster", + objects=profile.objects, + credentials=profile.credentials, + permissions=profile.permissions, + host_count=profile.host_count, + vm_count=profile.vm_count, + ) + + +def build_vsphere_profile( + name: str | None = None, + *, + large_hosts: int | None = None, + large_vms: int | None = None, +) -> VsphereSeedProfile: + profile_name = (name or os.getenv("SEED_VSPHERE_PROFILE") or "large").strip().lower() + hosts = ( + large_hosts if large_hosts is not None else int(os.getenv("SEED_VSPHERE_LARGE_HOSTS", "10")) + ) + vms = large_vms if large_vms is not None else int(os.getenv("SEED_VSPHERE_LARGE_VMS", "1000")) + if profile_name.lower() in {"small", "minimal"}: + return small_vsphere_profile() + if profile_name in {"demo-cluster", "demo", "enterprise"}: + return demo_cluster_vsphere_profile() + if profile_name == "large": + return large_vsphere_profile(host_count=hosts, vm_count=vms) + raise ValueError(f"unknown vSphere seed profile: {profile_name}") + + +def props_json(props: dict[str, Any]) -> str: + return json.dumps(props) diff --git a/app/vsphere/rest/__init__.py b/app/vsphere/rest/__init__.py new file mode 100644 index 0000000..9c4a9a9 --- /dev/null +++ b/app/vsphere/rest/__init__.py @@ -0,0 +1,46 @@ +"""vSphere Automation REST routers. + +Package init stays free of FastAPI so probes (e.g. pulumi-tests) can import +``app.vsphere.rest.coverage`` / matrix helpers without the full app stack. +``vsphere_rest_router`` is assembled lazily on first access. +""" + +from __future__ import annotations + +from typing import Any + +__all__ = ["vsphere_rest_router"] + + +def __getattr__(name: str) -> Any: + if name == "vsphere_rest_router": + from fastapi import APIRouter + + from app.vsphere.rest.appliance_ext import router as appliance_ext_router + from app.vsphere.rest.content_rest import router as content_router + from app.vsphere.rest.inventory_ext import router as inventory_ext_router + from app.vsphere.rest.legacy import router as legacy_router + from app.vsphere.rest.nfc_rest import router as nfc_router + from app.vsphere.rest.platform_rest import router as platform_router + from app.vsphere.rest.router import router as core_router + from app.vsphere.rest.stub_surface import router as stub_surface_router + from app.vsphere.rest.tagging_rest import router as tagging_router + from app.vsphere.rest.tasks import router as tasks_router + from app.vsphere.rest.vm_ext import router as vm_ext_router + + vsphere_rest_router = APIRouter() + vsphere_rest_router.include_router(core_router) + vsphere_rest_router.include_router(tasks_router) + vsphere_rest_router.include_router(vm_ext_router) + vsphere_rest_router.include_router(inventory_ext_router) + vsphere_rest_router.include_router(tagging_router) + vsphere_rest_router.include_router(content_router) + vsphere_rest_router.include_router(appliance_ext_router) + vsphere_rest_router.include_router(platform_router) + vsphere_rest_router.include_router(nfc_router) + vsphere_rest_router.include_router(legacy_router) + # Broadcom universe per-path stubs — must stay last so deep handlers win. + vsphere_rest_router.include_router(stub_surface_router) + globals()["vsphere_rest_router"] = vsphere_rest_router + return vsphere_rest_router + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/app/vsphere/rest/appliance_ext.py b/app/vsphere/rest/appliance_ext.py new file mode 100644 index 0000000..4136bbb --- /dev/null +++ b/app/vsphere/rest/appliance_ext.py @@ -0,0 +1,123 @@ +"""Appliance health / networking / timesync — mutable lab state.""" + +from __future__ import annotations + +from typing import Any + +from fastapi import APIRouter, Depends + +from app.db.pool import Database +from app.dependencies import get_database +from app.vsphere.domain import appliance +from app.vsphere.errors import invalid_argument +from app.vsphere.security.authz import require_admin, require_read +from app.vsphere.security.session import SessionInfo + +router = APIRouter(tags=["vSphere Appliance"]) + + +@router.get("/api/appliance/health/system") +async def health_system( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + from app.vsphere.domain import api_state + + payload = await api_state.get_payload(database, "GET", "/api/appliance/health/system") + return payload if isinstance(payload, dict) else {"status": "unknown", "messages": []} + + +@router.get("/api/appliance/networking") +async def networking( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return await appliance.get_networking(database) + + +@router.get("/api/appliance/networking/dns/hostname") +async def get_dns_hostname( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, str]: + return {"name": await appliance.get_hostname(database)} + + +@router.put("/api/appliance/networking/dns/hostname") +@router.post("/api/appliance/networking/dns/hostname") +async def set_dns_hostname( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_admin), +) -> dict[str, str]: + name = str(body.get("name") or body.get("hostname") or "").strip() + if not name: + raise invalid_argument("name is required") + hostname = await appliance.set_hostname(database, name) + return {"name": hostname} + + +@router.get("/api/appliance/networking/dns/servers") +async def get_dns_servers( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + networking_state = await appliance.get_networking(database) + dns = networking_state.get("dns") or {} + return {"mode": dns.get("mode"), "servers": list(dns.get("servers") or [])} + + +@router.put("/api/appliance/networking/dns/servers") +@router.post("/api/appliance/networking/dns/servers") +async def set_dns_servers( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_admin), +) -> dict[str, Any]: + mode = body.get("mode") + servers = body.get("servers") + if servers is None and body.get("server"): + servers = [body["server"]] + return await appliance.set_dns_servers( + database, + mode=str(mode) if mode is not None else None, + servers=[str(s) for s in servers] if isinstance(servers, list) else None, + ) + + +@router.get("/api/appliance/networking/dns/domains") +async def get_dns_domains( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[str]: + networking_state = await appliance.get_networking(database) + dns = networking_state.get("dns") or {} + return list(dns.get("domains") or []) + + +@router.put("/api/appliance/networking/dns/domains") +@router.post("/api/appliance/networking/dns/domains") +async def set_dns_domains( + body: dict[str, Any] | list[Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_admin), +) -> list[str]: + if isinstance(body, list): + domains = [str(d) for d in body] + else: + domains = [str(d) for d in (body.get("domains") or body.get("domain") or [])] + if isinstance(body.get("domain"), str): + domains = [str(body["domain"])] + if not domains: + from app.vsphere.errors import invalid_argument + + raise invalid_argument("domains is required") + return await appliance.set_dns_domains(database, domains) + + +@router.get("/api/appliance/timesync") +async def timesync( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return await appliance.get_timesync(database) diff --git a/app/vsphere/rest/content_rest.py b/app/vsphere/rest/content_rest.py new file mode 100644 index 0000000..b895fbd --- /dev/null +++ b/app/vsphere/rest/content_rest.py @@ -0,0 +1,191 @@ +"""Content library, OVF deploy, storage policies, privileges.""" + +from __future__ import annotations + +from typing import Any + +from fastapi import APIRouter, Depends, Query + +from app.db.pool import Database +from app.dependencies import get_database +from app.vsphere.domain import api_state, content +from app.vsphere.security.authz import require_privilege, require_read +from app.vsphere.security.session import SessionInfo + +router = APIRouter(tags=["vSphere Content"]) + + +@router.get("/api/content/library") +async def list_libraries( + database: Database = Depends(get_database), _: SessionInfo = Depends(require_read) +) -> list[str]: + return [item["id"] for item in await content.list_libraries(database)] + + +@router.post("/api/content/local-library") +async def create_library( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("ContentLibrary.CreateLocalLibrary")), +) -> str: + from app.vsphere.errors import invalid_argument + + spec = body.get("create_spec") or body + name = spec.get("name") if isinstance(spec, dict) else None + if not name: + raise invalid_argument("create_spec.name is required") + return await content.create_library( + database, name=str(name), description=str(spec.get("description") or "") + ) + + +@router.get("/api/content/library/item") +async def list_items( + library_id: str = Query(...), + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[str]: + return [item["id"] for item in await content.list_library_items(database, library_id)] + + +@router.post("/api/content/library/item") +async def create_item( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("ContentLibrary.AddLibraryItem")), +) -> str: + from app.vsphere.errors import invalid_argument + + spec = body.get("create_spec") or body + if not isinstance(spec, dict): + raise invalid_argument("create_spec is required") + library_id = spec.get("library_id") + name = spec.get("name") + if not library_id: + raise invalid_argument("create_spec.library_id is required") + if not name: + raise invalid_argument("create_spec.name is required") + return await content.create_library_item( + database, + library_id=str(library_id), + name=str(name), + item_type=str(spec.get("type") or "ovf"), + description=str(spec.get("description") or ""), + ) + + +@router.post("/api/vcenter/ovf/library-item/{item_id}") +async def deploy_ovf( + item_id: str, + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Provisioning.DeployTemplate")), +) -> dict[str, Any]: + target = body.get("target") or {} + deployment = body.get("deployment_spec") or body + moid, task_id = await content.deploy_ovf_from_library( + database, + item_id=item_id, + name=str(deployment.get("name") or f"ovf-{item_id[-6:]}"), + folder=str(target.get("folder") or "group-v23"), + host=str(target.get("host") or "host-11"), + datastore=str(target.get("datastore") or "datastore-31"), + ) + return {"resource_id": {"id": moid, "type": "VirtualMachine"}, "task": task_id} + + +@router.post("/api/content/library/item/update-session") +async def create_update_session( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("ContentLibrary.AddLibraryItem")), +) -> str: + create_spec = body.get("create_spec") or body + library_item_id = str(create_spec.get("library_item_id") or create_spec.get("item_id") or "") + if not library_item_id: + from app.vsphere.errors import invalid_argument + + raise invalid_argument("create_spec.library_item_id is required") + return await content.create_update_session(database, library_item_id=library_item_id) + + +@router.get("/api/content/library/item/update-session/{session_id}") +async def get_update_session( + session_id: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return await content.get_update_session(database, session_id) + + +@router.post("/api/content/library/item/update-session/{session_id}/file") +async def add_update_session_file( + session_id: str, + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("ContentLibrary.AddLibraryItem")), +) -> dict[str, Any]: + file_spec = body.get("file_spec") or body + return await content.add_update_session_file( + database, + session_id, + name=str(file_spec.get("name") or "upload.bin"), + source_type=str(file_spec.get("source_type") or "PUSH"), + size=int(file_spec.get("size") or 0), + content=str(file_spec.get("content") or ""), + ) + + +@router.post("/api/content/library/item/update-session/{session_id}") +async def complete_update_session( + session_id: str, + action: str = Query("complete"), + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("ContentLibrary.AddLibraryItem")), +) -> None: + del action + await content.complete_update_session(database, session_id) + + +@router.post("/api/content/library/item/download-session") +async def create_download_session( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> str: + create_spec = body.get("create_spec") or body + library_item_id = str(create_spec.get("library_item_id") or create_spec.get("item_id") or "") + if not library_item_id: + from app.vsphere.errors import invalid_argument + + raise invalid_argument("create_spec.library_item_id is required") + return await content.create_download_session(database, library_item_id=library_item_id) + + +@router.get("/api/content/library/item/download-session/{session_id}") +async def get_download_session( + session_id: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return await content.get_download_session(database, session_id) + + +@router.get("/api/content/library/item/download-session/{session_id}/file") +async def list_download_session_files( + session_id: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + return await content.list_download_session_files(database, session_id) + + +@router.get("/api/vcenter/storage/policies") +async def storage_policies( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + payload = await api_state.get_payload(database, "GET", "/api/vcenter/storage/policies") + if isinstance(payload, list): + return payload + return [] diff --git a/app/vsphere/rest/coverage.py b/app/vsphere/rest/coverage.py new file mode 100644 index 0000000..1739988 --- /dev/null +++ b/app/vsphere/rest/coverage.py @@ -0,0 +1,222 @@ +"""Implemented REST path registry for UI catalog and surface probes. + +CORE_* entries are deep lab handlers. Broadcom Automation API routes from +``universe.json`` (generated from the public operations index) fill the rest as +thin stubs — each ``(verb, path)`` is registered separately in ``stub_surface``. +""" + +from __future__ import annotations + +import json +from functools import lru_cache +from pathlib import Path + +ACTIVE_STATUSES = frozenset({"implemented", "stub"}) + +# verb + path template → status (deep handlers) +CORE_IMPLEMENTED: dict[tuple[str, str], str] = { + ("POST", "/api/session"): "implemented", + ("DELETE", "/api/session"): "implemented", + ("GET", "/api/session"): "implemented", + ("POST", "/rest/com/vmware/cis/session"): "implemented", + ("GET", "/rest/com/vmware/cis/session"): "implemented", + ("DELETE", "/rest/com/vmware/cis/session"): "implemented", + ("GET", "/api/cis/tasks"): "implemented", + ("GET", "/api/cis/tasks/{task}"): "implemented", + ("GET", "/api/appliance/system/version"): "implemented", + ("GET", "/api/appliance/health/system"): "implemented", + ("GET", "/api/appliance/networking"): "implemented", + ("GET", "/api/appliance/networking/dns/hostname"): "implemented", + ("PUT", "/api/appliance/networking/dns/hostname"): "implemented", + ("POST", "/api/appliance/networking/dns/hostname"): "implemented", + ("GET", "/api/appliance/networking/dns/servers"): "implemented", + ("PUT", "/api/appliance/networking/dns/servers"): "implemented", + ("POST", "/api/appliance/networking/dns/servers"): "implemented", + ("GET", "/api/appliance/networking/dns/domains"): "implemented", + ("PUT", "/api/appliance/networking/dns/domains"): "implemented", + ("POST", "/api/appliance/networking/dns/domains"): "implemented", + ("GET", "/api/appliance/timesync"): "implemented", + ("GET", "/api/vcenter/vm"): "implemented", + ("POST", "/api/vcenter/vm"): "implemented", + ("GET", "/api/vcenter/vm/{vm}"): "implemented", + ("DELETE", "/api/vcenter/vm/{vm}"): "implemented", + ("GET", "/api/vcenter/vm/{vm}/power"): "implemented", + ("POST", "/api/vcenter/vm/{vm}/power"): "implemented", + ("GET", "/api/vcenter/vm/{vm}/guest/identity"): "implemented", + ("GET", "/api/vcenter/vm/{vm}/guest/local-filesystem"): "implemented", + ("GET", "/api/vcenter/vm/{vm}/guest/filesystem"): "implemented", + ("PUT", "/api/vcenter/vm/{vm}/guest/filesystem"): "implemented", + ("DELETE", "/api/vcenter/vm/{vm}/guest/filesystem"): "implemented", + ("GET", "/api/vcenter/vm/{vm}/guest/filesystem/files"): "implemented", + ("GET", "/api/vcenter/vm/{vm}/tools"): "implemented", + ("GET", "/api/vcenter/vm/{vm}/hardware"): "implemented", + ("GET", "/api/vcenter/vm/{vm}/hardware/cpu"): "implemented", + ("PATCH", "/api/vcenter/vm/{vm}/hardware/cpu"): "implemented", + ("GET", "/api/vcenter/vm/{vm}/hardware/memory"): "implemented", + ("PATCH", "/api/vcenter/vm/{vm}/hardware/memory"): "implemented", + ("GET", "/api/vcenter/vm/{vm}/hardware/disk"): "implemented", + ("POST", "/api/vcenter/vm/{vm}/hardware/disk"): "implemented", + ("GET", "/api/vcenter/vm/{vm}/hardware/ethernet"): "implemented", + ("POST", "/api/vcenter/vm/{vm}/hardware/ethernet"): "implemented", + ("GET", "/api/vcenter/vm/{vm}/hardware/boot"): "implemented", + ("GET", "/api/vcenter/vm/{vm}/snapshots"): "implemented", + ("POST", "/api/vcenter/vm/{vm}/snapshots"): "implemented", + ("DELETE", "/api/vcenter/vm/{vm}/snapshots/{snapshot}"): "implemented", + ("POST", "/api/vcenter/vm/{vm}/snapshots/{snapshot}"): "implemented", + ("POST", "/api/vcenter/vm/{vm}/clone"): "implemented", + ("POST", "/api/vcenter/vm/{vm}/relocate"): "implemented", + ("GET", "/api/vcenter/host"): "implemented", + ("GET", "/api/vcenter/host/{host}"): "implemented", + ("POST", "/api/vcenter/host/{host}/maintenance"): "implemented", + ("GET", "/api/vcenter/datastore"): "implemented", + ("GET", "/api/vcenter/datastore/{datastore}"): "implemented", + ("GET", "/api/vcenter/datastore/{datastore}/files"): "implemented", + ("POST", "/api/vcenter/datastore/{datastore}/files"): "implemented", + ("GET", "/api/vcenter/network"): "implemented", + ("GET", "/api/vcenter/datacenter"): "implemented", + ("POST", "/api/vcenter/datacenter"): "implemented", + ("DELETE", "/api/vcenter/datacenter/{datacenter}"): "implemented", + ("GET", "/api/vcenter/cluster"): "implemented", + ("POST", "/api/vcenter/cluster"): "implemented", + ("DELETE", "/api/vcenter/cluster/{cluster}"): "implemented", + ("GET", "/api/vcenter/folder"): "implemented", + ("POST", "/api/vcenter/folder"): "implemented", + ("POST", "/api/vcenter/folder/{folder}"): "implemented", + ("DELETE", "/api/vcenter/folder/{folder}"): "implemented", + ("GET", "/api/vcenter/resource-pool"): "implemented", + ("POST", "/api/vcenter/resource-pool"): "implemented", + ("DELETE", "/api/vcenter/resource-pool/{resource_pool}"): "implemented", + ("GET", "/api/vcenter/network/dvs"): "implemented", + ("POST", "/api/vcenter/network/dvs"): "implemented", + ("POST", "/api/vcenter/network/dvpg"): "implemented", + ("GET", "/api/cis/tagging/category"): "implemented", + ("POST", "/api/cis/tagging/category"): "implemented", + ("GET", "/api/cis/tagging/category/{category_id}"): "implemented", + ("DELETE", "/api/cis/tagging/category/{category_id}"): "implemented", + ("GET", "/api/cis/tagging/tag"): "implemented", + ("POST", "/api/cis/tagging/tag"): "implemented", + ("GET", "/api/cis/tagging/tag/{tag_id}"): "implemented", + ("DELETE", "/api/cis/tagging/tag/{tag_id}"): "implemented", + ("POST", "/api/cis/tagging/tag-association"): "implemented", + ("GET", "/api/content/library"): "implemented", + ("POST", "/api/content/local-library"): "implemented", + ("GET", "/api/content/library/item"): "implemented", + ("POST", "/api/content/library/item"): "implemented", + ("POST", "/api/content/library/item/update-session"): "implemented", + ("GET", "/api/content/library/item/update-session/{session_id}"): "implemented", + ("POST", "/api/content/library/item/update-session/{session_id}"): "implemented", + ("POST", "/api/content/library/item/update-session/{session_id}/file"): "implemented", + ("POST", "/api/content/library/item/download-session"): "implemented", + ("GET", "/api/content/library/item/download-session/{session_id}"): "implemented", + ("GET", "/api/content/library/item/download-session/{session_id}/file"): "implemented", + ("POST", "/api/vcenter/ovf/library-item/{item_id}"): "implemented", + ("GET", "/api/vcenter/storage/policies"): "implemented", + ("GET", "/api/vcenter/storage/policies/{policy}/vm"): "implemented", + ("GET", "/api/vcenter/privilege"): "implemented", + ("GET", "/api/vcenter/authorization/roles"): "implemented", + ("GET", "/api/vcenter/authorization/permissions"): "implemented", + ("POST", "/api/vcenter/authorization/permissions"): "implemented", + ("DELETE", "/api/vcenter/authorization/permissions/{permission_id}"): "implemented", + ("GET", "/api/vcenter/namespaces"): "implemented", + ("GET", "/api/vcenter/namespace-management/nsx-tier0-gateway"): "implemented", + ("GET", "/api/vcenter/namespace-management/networks"): "implemented", + ("GET", "/api/vcenter/namespace-management/virtual-machine-classes"): "implemented", + ("GET", "/api/vcenter/identity/providers"): "implemented", + ("POST", "/api/vcenter/identity/providers"): "implemented", + ("GET", "/api/vcenter/identity/providers/{provider}"): "implemented", + ("PUT", "/api/vcenter/identity/providers/{provider}"): "implemented", + ("PATCH", "/api/vcenter/identity/providers/{provider}"): "implemented", + ("DELETE", "/api/vcenter/identity/providers/{provider}"): "implemented", + ("GET", "/api/vcenter/certificate-management/vcenter/tls-csr"): "implemented", + ("POST", "/api/vcenter/certificate-management/vcenter/tls-csr"): "implemented", + ("GET", "/api/vcenter/certificate-management/vcenter/trusted-root-chains"): "implemented", + ("GET", "/api/vcenter/vm/{vm}/guest/customization"): "implemented", + ("GET", "/api/vcenter/certificate-management/vcenter/tls"): "implemented", + ("GET", "/api/vcenter/vm/{vm}/guest/networking"): "implemented", + ("GET", "/api/vcenter/vm/{vm}/guest/power"): "implemented", + ("POST", "/api/vcenter/vm/{vm}/guest/power"): "implemented", + ("POST", "/api/vcenter/vm/{vm}/tools"): "implemented", + ("POST", "/api/vcenter/vm/{vm}/console/tickets"): "implemented", + ("POST", "/api/vcenter/vm/{vm}/guest/customization"): "implemented", + ("POST", "/api/vcenter/vm/{vm}"): "implemented", + ("GET", "/api/vcenter/host/{host}/storage/storage-device"): "implemented", + ("GET", "/api/vcenter/host/{host}/networking"): "implemented", + ("GET", "/api/vcenter/folder/{folder}/children"): "implemented", + ("GET", "/api/vapi/metadata/metamodel/service"): "implemented", + ("GET", "/api/vapi/metadata/authentication/component"): "implemented", + ("GET", "/api/vcenter/activity-history"): "implemented", + ("GET", "/rest/vcenter/vm"): "implemented", + ("GET", "/rest/vcenter/vm/{vm}"): "implemented", + ("POST", "/rest/vcenter/vm/{vm}/power"): "implemented", + ("GET", "/rest/vcenter/host"): "implemented", + ("GET", "/rest/vcenter/datastore"): "implemented", + ("GET", "/rest/vcenter/network"): "implemented", + ("GET", "/rest/vcenter/datacenter"): "implemented", + ("GET", "/rest/vcenter/cluster"): "implemented", + ("GET", "/rest/appliance/system/version"): "implemented", +} + + +@lru_cache(maxsize=1) +def _universe_routes() -> dict[tuple[str, str], str]: + path = Path(__file__).with_name("universe.json") + if not path.is_file(): + return {} + payload = json.loads(path.read_text(encoding="utf-8")) + out: dict[tuple[str, str], str] = {} + for entry in payload.get("methods") or []: + verb = str(entry.get("verb", "")).upper() + route = str(entry.get("path", "")) + if verb and route: + out[(verb, route)] = "stub" + return out + + +def _merged() -> dict[tuple[str, str], str]: + merged = dict(_universe_routes()) + merged.update(CORE_IMPLEMENTED) + return merged + + +IMPLEMENTED: dict[tuple[str, str], str] = _merged() + + +def reload_coverage() -> dict[tuple[str, str], str]: + """Reload universe.json (tests / generator).""" + + _universe_routes.cache_clear() + IMPLEMENTED.clear() + IMPLEMENTED.update(_merged()) + from contextlib import suppress + + with suppress(Exception): + from app.vsphere.contracts.matrix import _compiled_routes + + _compiled_routes.cache_clear() + return IMPLEMENTED + + +def catalog_entries() -> list[dict[str, str]]: + return [ + {"verb": verb, "path": path, "status": status} + for (verb, path), status in sorted(IMPLEMENTED.items()) + ] + + +def is_implemented(verb: str, path: str) -> bool: + return IMPLEMENTED.get((verb.upper(), path)) in ACTIVE_STATUSES + + +def universe_stats() -> dict[str, int | str]: + path = Path(__file__).with_name("universe.json") + if not path.is_file(): + return {"broadcom_operations": 0, "unique_routes": 0} + payload = json.loads(path.read_text(encoding="utf-8")) + return { + "source_label": str(payload.get("source_label") or ""), + "broadcom_operations": int(payload.get("broadcom_operations") or 0), + "unique_routes": int(payload.get("unique_routes") or 0), + "registry_methods": len(IMPLEMENTED), + "core_methods": len(CORE_IMPLEMENTED), + "stub_methods": sum(1 for status in IMPLEMENTED.values() if status == "stub"), + } diff --git a/app/vsphere/rest/inventory_ext.py b/app/vsphere/rest/inventory_ext.py new file mode 100644 index 0000000..62cf7d2 --- /dev/null +++ b/app/vsphere/rest/inventory_ext.py @@ -0,0 +1,213 @@ +"""Inventory CRUD, host maintenance, datastore files, DVS.""" + +from __future__ import annotations + +from typing import Any + +from fastapi import APIRouter, Depends, Query, Response + +from app.db.pool import Database +from app.dependencies import get_database +from app.vsphere import inventory +from app.vsphere.domain import content, inventory_ops +from app.vsphere.errors import invalid_argument +from app.vsphere.security.authz import require_privilege, require_read +from app.vsphere.security.session import SessionInfo + +router = APIRouter(tags=["vSphere Inventory Ext"]) + + +def _require_name(body: dict[str, Any]) -> str: + name = body.get("name") + if not name: + raise invalid_argument("name is required") + return str(name) + + +@router.post("/api/vcenter/datacenter") +async def create_dc( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("Datacenter.Create")), +) -> str: + return await inventory_ops.create_datacenter( + database, name=_require_name(body), folder=str(body.get("folder") or "group-d1") + ) + + +@router.delete("/api/vcenter/datacenter/{datacenter}") +async def delete_dc( + datacenter: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("Datacenter.Delete")), +) -> Response: + await inventory_ops.delete_managed(database, datacenter) + return Response(status_code=204) + + +@router.post("/api/vcenter/cluster") +async def create_cluster( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("Cluster.Create")), +) -> str: + return await inventory_ops.create_cluster( + database, + name=_require_name(body), + folder=str(body.get("folder") or "group-h23"), + drs_enabled=bool((body.get("drs") or {}).get("enabled", True)), + ha_enabled=bool((body.get("ha") or {}).get("enabled", True)), + ) + + +@router.delete("/api/vcenter/cluster/{cluster}") +async def delete_cluster( + cluster: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("Cluster.Delete")), +) -> Response: + await inventory_ops.delete_managed(database, cluster) + return Response(status_code=204) + + +@router.post("/api/vcenter/folder") +async def create_folder( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("Folder.Create")), +) -> str: + return await inventory_ops.create_folder( + database, + name=_require_name(body), + parent=str(body.get("parent") or body.get("folder") or "group-v23"), + folder_type=str(body.get("type") or "VIRTUAL_MACHINE"), + ) + + +@router.post("/api/vcenter/folder/{folder}") +async def folder_action( + folder: str, + action: str = Query(...), + body: dict[str, Any] | None = None, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("Folder.Rename")), +) -> Response: + body = body or {} + if action == "rename": + await inventory_ops.rename_object(database, folder, _require_name(body)) + elif action == "move": + parent = body.get("parent") + if not parent: + raise invalid_argument("parent is required") + await inventory_ops.move_object(database, folder, str(parent)) + else: + raise invalid_argument(f"unsupported action {action}") + return Response(status_code=204) + + +@router.delete("/api/vcenter/folder/{folder}") +async def delete_folder( + folder: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("Folder.Delete")), +) -> Response: + await inventory_ops.delete_managed(database, folder) + return Response(status_code=204) + + +@router.post("/api/vcenter/resource-pool") +async def create_rp( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("Resource.CreatePool")), +) -> str: + return await inventory_ops.create_resource_pool( + database, name=_require_name(body), parent=str(body.get("parent") or "resgroup-22") + ) + + +@router.delete("/api/vcenter/resource-pool/{resource_pool}") +async def delete_rp( + resource_pool: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("Resource.DeletePool")), +) -> Response: + await inventory_ops.delete_managed(database, resource_pool) + return Response(status_code=204) + + +@router.post("/api/vcenter/host/{host}/maintenance") +async def host_maintenance( + host: str, + action: str = Query(...), + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("Host.Config.Maintenance")), +) -> dict[str, Any]: + if action not in {"enter", "exit"}: + raise invalid_argument("action must be enter|exit") + return await inventory_ops.set_host_maintenance(database, host, enabled=(action == "enter")) + + +@router.get("/api/vcenter/datastore/{datastore}/files") +async def ds_files( + datastore: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + return await content.list_datastore_files(database, datastore) + + +@router.post("/api/vcenter/datastore/{datastore}/files") +async def ds_put_file( + datastore: str, + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("Datastore.FileManagement")), +) -> Response: + path = body.get("path") + if not path: + raise invalid_argument("path is required") + await content.put_datastore_file( + database, + datastore, + str(path), + size=int(body.get("size") or 0), + file_type=str(body.get("type") or "FILE"), + ) + return Response(status_code=204) + + +@router.get("/api/vcenter/network/dvs") +async def list_dvs( + database: Database = Depends(get_database), _: SessionInfo = Depends(require_read) +) -> list[dict[str, Any]]: + objects = await inventory.list_objects(database, type_name="VmwareDistributedVirtualSwitch") + return [{"dvs": o.moid, "name": o.name} for o in objects] + + +@router.post("/api/vcenter/network/dvs") +async def create_dvs( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("Network.Assign")), +) -> str: + return await inventory_ops.create_dvs( + database, name=_require_name(body), folder=str(body.get("folder") or "group-n23") + ) + + +@router.post("/api/vcenter/network/dvpg") +async def create_dvpg( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("Network.Assign")), +) -> str: + dvs = body.get("dvs") + if not dvs: + raise invalid_argument("dvs is required") + return await inventory_ops.create_dvpg( + database, + name=_require_name(body), + dvs=str(dvs), + vlan_id=int(body.get("vlan_id") or 0), + ) diff --git a/app/vsphere/rest/legacy.py b/app/vsphere/rest/legacy.py new file mode 100644 index 0000000..e0debc8 --- /dev/null +++ b/app/vsphere/rest/legacy.py @@ -0,0 +1,223 @@ +"""Legacy `/rest/...` JSON wrappers mirroring Automation API `/api` paths.""" + +from __future__ import annotations + +from typing import Any + +from fastapi import APIRouter, Depends, Query, Request, Response + +from app.db.pool import Database +from app.dependencies import get_database +from app.vsphere.domain import vm_ops +from app.vsphere.errors import invalid_argument +from app.vsphere.rest import router as core +from app.vsphere.rest import tagging_rest +from app.vsphere.security.authz import require_privilege, require_read +from app.vsphere.security.session import SessionInfo + +router = APIRouter(tags=["vSphere Legacy REST"]) + + +def _value(payload: Any) -> dict[str, Any]: + return {"value": payload} + + +@router.get("/rest/vcenter/vm") +async def rest_list_vms( + database: Database = Depends(get_database), + session: SessionInfo = Depends(require_read), + names: list[str] | None = Query(default=None), + power_states: list[str] | None = Query(default=None), + hosts: list[str] | None = Query(default=None), + folders: list[str] | None = Query(default=None), + limit: int | None = Query(default=None, ge=1, le=5000), + cursor: int = Query(default=0, ge=0), +) -> dict[str, Any]: + payload = await core.list_vms( + database=database, + _=session, + names=names, + power_states=power_states, + hosts=hosts, + folders=folders, + datacenters=None, + clusters=None, + resource_pools=None, + limit=limit, + cursor=cursor, + ) + return _value(payload) + + +@router.get("/rest/vcenter/vm/{vm}") +async def rest_get_vm( + vm: str, + database: Database = Depends(get_database), + session: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return _value(await core.get_vm(vm=vm, database=database, _=session)) + + +@router.get("/rest/vcenter/host") +async def rest_list_hosts( + database: Database = Depends(get_database), + session: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return _value(await core.list_hosts(database=database, _=session)) + + +@router.get("/rest/vcenter/datastore") +async def rest_list_datastores( + database: Database = Depends(get_database), + session: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return _value(await core.list_datastores(database=database, _=session)) + + +@router.get("/rest/vcenter/network") +async def rest_list_networks( + database: Database = Depends(get_database), + session: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return _value(await core.list_networks(database=database, _=session)) + + +@router.get("/rest/vcenter/datacenter") +async def rest_list_datacenters( + database: Database = Depends(get_database), + session: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return _value(await core.list_datacenters(database=database, _=session)) + + +@router.get("/rest/vcenter/cluster") +async def rest_list_clusters( + database: Database = Depends(get_database), + session: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return _value(await core.list_clusters(database=database, _=session)) + + +@router.get("/rest/appliance/system/version") +async def rest_appliance_version( + request: Request, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return _value(await core.appliance_version(request=request, database=database)) + + +@router.post("/rest/vcenter/vm/{vm}/power") +async def rest_power_vm( + vm: str, + action: str = Query(...), + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Interact.PowerOn")), +) -> dict[str, Any]: + task_id = await vm_ops.set_power(database, vm, action.lower()) + return _value({"task": task_id}) + + +# --- CIS tagging (govmomi / terraform-provider-vsphere / pulumi-vsphere) --- + + +@router.get("/rest/com/vmware/cis/tagging/category") +async def rest_list_categories( + database: Database = Depends(get_database), + session: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return _value(await tagging_rest.list_categories(database=database, _=session)) + + +@router.post("/rest/com/vmware/cis/tagging/category") +async def rest_category_action( + body: dict[str, Any] | None = None, + action: str | None = Query(default=None, alias="~action"), + database: Database = Depends(get_database), + session: SessionInfo = Depends(require_privilege("InventoryService.Tagging.CreateCategory")), +) -> Any: + payload = body or {} + act = (action or "create").lower() + if act == "create": + return _value( + await tagging_rest.create_category(body=payload, database=database, _=session) + ) + raise invalid_argument(f"unsupported ~action {act}") + + +@router.get("/rest/com/vmware/cis/tagging/category/{category_id}") +async def rest_get_category( + category_id: str, + database: Database = Depends(get_database), + session: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return _value( + await tagging_rest.get_category(category_id=category_id, database=database, _=session) + ) + + +@router.delete("/rest/com/vmware/cis/tagging/category/{category_id}") +async def rest_delete_category( + category_id: str, + database: Database = Depends(get_database), + session: SessionInfo = Depends(require_privilege("InventoryService.Tagging.CreateCategory")), +) -> Response: + return await tagging_rest.delete_category(category_id=category_id, database=database, _=session) + + +@router.get("/rest/com/vmware/cis/tagging/tag") +async def rest_list_tags( + database: Database = Depends(get_database), + session: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return _value(await tagging_rest.list_tags(database=database, _=session)) + + +@router.post("/rest/com/vmware/cis/tagging/tag") +async def rest_tag_action( + body: dict[str, Any] | None = None, + action: str | None = Query(default=None, alias="~action"), + database: Database = Depends(get_database), + session: SessionInfo = Depends(require_privilege("InventoryService.Tagging.CreateTag")), +) -> Any: + payload = body or {} + act = (action or "create").lower() + if act == "create": + return _value(await tagging_rest.create_tag(body=payload, database=database, _=session)) + raise invalid_argument(f"unsupported ~action {act}") + + +@router.get("/rest/com/vmware/cis/tagging/tag/{tag_id}") +async def rest_get_tag( + tag_id: str, + database: Database = Depends(get_database), + session: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return _value(await tagging_rest.get_tag(tag_id=tag_id, database=database, _=session)) + + +@router.delete("/rest/com/vmware/cis/tagging/tag/{tag_id}") +async def rest_delete_tag( + tag_id: str, + database: Database = Depends(get_database), + session: SessionInfo = Depends(require_privilege("InventoryService.Tagging.CreateTag")), +) -> Response: + return await tagging_rest.delete_tag(tag_id=tag_id, database=database, _=session) + + +@router.post("/rest/com/vmware/cis/tagging/tag-association") +async def rest_tag_association( + body: dict[str, Any] | None = None, + action: str | None = Query(default=None, alias="~action"), + database: Database = Depends(get_database), + session: SessionInfo = Depends(require_privilege("InventoryService.Tagging.AttachTag")), +) -> Any: + """govmomi/terraform use ``?~action=`` instead of JSON ``action``.""" + + payload = dict(body or {}) + if action and "action" not in payload: + payload["action"] = action + result = await tagging_rest.tag_association(body=payload, database=database, _=session) + if isinstance(result, Response): + return result + return _value(result) diff --git a/app/vsphere/rest/mappers.py b/app/vsphere/rest/mappers.py new file mode 100644 index 0000000..8475b8c --- /dev/null +++ b/app/vsphere/rest/mappers.py @@ -0,0 +1,122 @@ +"""Map inventory rows to vSphere Automation REST JSON shapes.""" + +from __future__ import annotations + +from typing import Any + +from app.vsphere.inventory import ManagedObject + + +def vm_summary(obj: ManagedObject) -> dict[str, Any]: + props = obj.props + return { + "vm": obj.moid, + "name": obj.name, + "power_state": props.get("power_state", "POWERED_OFF"), + "cpu_count": props.get("cpu_count"), + "memory_size_MiB": props.get("memory_size_mib"), + } + + +def vm_info(obj: ManagedObject) -> dict[str, Any]: + props = obj.props + cpu = dict(props.get("cpu") or {}) + return { + "guest_OS": props.get("guest_OS"), + "name": obj.name, + "identity": props.get("identity"), + "power_state": props.get("power_state"), + "hardware": { + "version": props.get("hardware_version"), + "cpu": { + "count": props.get("cpu_count"), + "cores_per_socket": cpu.get("cores_per_socket"), + }, + "memory": {"size_MiB": props.get("memory_size_mib")}, + }, + "nics": props.get("nics") or [], + "disks": props.get("disks") or [], + "boot": props.get("boot") or {}, + } + + +def host_summary(obj: ManagedObject) -> dict[str, Any]: + props = obj.props + return { + "host": obj.moid, + "name": obj.name, + "connection_state": props.get("connection_state", "CONNECTED"), + "power_state": props.get("power_state", "POWERED_ON"), + } + + +def host_info(obj: ManagedObject) -> dict[str, Any]: + props = obj.props + return { + "name": obj.name, + "connection_state": props.get("connection_state", "CONNECTED"), + "power_state": props.get("power_state", "POWERED_ON"), + "cpu": { + "count": props.get("cpu_cores", 1), + "mhz": props.get("cpu_mhz", 2000), + }, + "memory": {"size_MiB": props.get("memory_size_mib", 8192)}, + } + + +def datastore_summary(obj: ManagedObject) -> dict[str, Any]: + props = obj.props + return { + "datastore": obj.moid, + "name": obj.name, + "type": props.get("type", "VMFS"), + "free_space": props.get("free_space", 0), + "capacity": props.get("capacity", 0), + } + + +def network_summary(obj: ManagedObject) -> dict[str, Any]: + props = obj.props + return { + "network": obj.moid, + "name": obj.name, + "type": props.get("type", "STANDARD_PORTGROUP"), + } + + +def datacenter_summary(obj: ManagedObject) -> dict[str, Any]: + props = obj.props + return { + "datacenter": obj.moid, + "name": obj.name, + "datastore_folder": props.get("datastore_folder"), + "host_folder": props.get("host_folder"), + "network_folder": props.get("network_folder"), + "vm_folder": props.get("vm_folder"), + } + + +def cluster_summary(obj: ManagedObject) -> dict[str, Any]: + props = obj.props + return { + "cluster": obj.moid, + "name": obj.name, + "drs_enabled": props.get("drs_enabled", False), + "ha_enabled": props.get("ha_enabled", False), + } + + +def folder_summary(obj: ManagedObject) -> dict[str, Any]: + props = obj.props + return { + "folder": obj.moid, + "name": obj.name, + "type": props.get("folder_type", "VIRTUAL_MACHINE"), + } + + +def resource_pool_summary(obj: ManagedObject) -> dict[str, Any]: + return { + "resource_pool": obj.moid, + "name": obj.name, + } diff --git a/app/vsphere/rest/nfc_rest.py b/app/vsphere/rest/nfc_rest.py new file mode 100644 index 0000000..4593075 --- /dev/null +++ b/app/vsphere/rest/nfc_rest.py @@ -0,0 +1,80 @@ +"""HttpNfcLease-compatible upload endpoints for OVF/VMDK lab transfers.""" + +from __future__ import annotations + +from typing import Any + +from fastapi import APIRouter, Depends, Request, Response +from fastapi.responses import JSONResponse + +from app.db.pool import Database +from app.dependencies import get_database +from app.vsphere.domain import platform_surface +from app.vsphere.errors import not_found +from app.vsphere.security.authz import require_privilege, require_read +from app.vsphere.security.session import SessionInfo + +router = APIRouter(tags=["vSphere NFC"]) + + +@router.get("/nfc/{lease_id}") +async def nfc_lease_status( + lease_id: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + lease = await platform_surface.get_nfc_lease(database, lease_id) + if lease is None: + raise not_found(f"NFC lease {lease_id} not found") + return lease + + +@router.post("/nfc/{lease_id}/complete") +async def nfc_lease_complete( + lease_id: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Provisioning.DeployTemplate")), +) -> dict[str, Any]: + lease = await platform_surface.complete_nfc_lease(database, lease_id) + if lease is None: + raise not_found(f"NFC lease {lease_id} not found") + return lease + + +@router.put("/nfc/{lease_id}/files/{filename:path}") +@router.post("/nfc/{lease_id}/files/{filename:path}") +async def nfc_upload_file( + lease_id: str, + filename: str, + request: Request, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Provisioning.DeployTemplate")), +) -> JSONResponse: + body = await request.body() + lease = await platform_surface.upload_nfc_file(database, lease_id, filename, len(body)) + if lease is None: + raise not_found(f"NFC lease {lease_id} not found") + return JSONResponse( + content={ + "lease": lease_id, + "filename": filename, + "bytes": len(body), + "state": lease.get("state"), + "transferProgress": lease.get("transferProgress"), + }, + status_code=200, + ) + + +@router.get("/nfc/{lease_id}/files/{filename:path}") +async def nfc_download_file( + lease_id: str, + filename: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> Response: + lease = await platform_surface.get_nfc_lease(database, lease_id) + if lease is None: + raise not_found(f"NFC lease {lease_id} not found") + content = f"# lab nfc placeholder for {filename} on {lease_id}\n".encode() + return Response(content=content, media_type="application/octet-stream") diff --git a/app/vsphere/rest/platform_rest.py b/app/vsphere/rest/platform_rest.py new file mode 100644 index 0000000..c9c0e25 --- /dev/null +++ b/app/vsphere/rest/platform_rest.py @@ -0,0 +1,531 @@ +"""Permissions, identity, guest extras, host detail, console tickets.""" + +from __future__ import annotations + +from typing import Any + +from fastapi import APIRouter, Depends, Query, Response + +from app.db.pool import Database +from app.dependencies import get_database +from app.vsphere import inventory +from app.vsphere.domain import vm_ops +from app.vsphere.errors import invalid_argument, not_found +from app.vsphere.security.authz import require_admin, require_privilege, require_read +from app.vsphere.security.session import SessionInfo + +router = APIRouter(tags=["vSphere Platform"]) + + +@router.get("/api/vcenter/privilege") +async def list_privileges( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, str]]: + from app.vsphere.domain import api_state + + payload = await api_state.get_payload(database, "GET", "/api/vcenter/privilege") + return payload if isinstance(payload, list) else [] + + +@router.get("/api/vcenter/authorization/roles") +async def list_roles( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + from app.vsphere.domain import api_state + + payload = await api_state.get_payload(database, "GET", "/api/vcenter/authorization/roles") + return payload if isinstance(payload, list) else [] + + +@router.get("/api/vcenter/authorization/permissions") +async def list_permissions( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + pool = database.pool # type: ignore[attr-defined] + async with pool.acquire() as conn: + rows = await conn.fetch( + "SELECT id, principal, role, entity_moid, propagate FROM vsphere_permissions ORDER BY id" + ) + return [ + { + "id": row["id"], + "principal": row["principal"], + "role": row["role"], + "entity": row["entity_moid"], + "propagate": row["propagate"], + } + for row in rows + ] + + +@router.post("/api/vcenter/authorization/permissions") +async def create_permission( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_admin), +) -> dict[str, Any]: + principal = str(body.get("principal") or "").strip() + role = str(body.get("role") or "").strip() + if not principal or not role: + raise invalid_argument("principal and role are required") + entity = body.get("entity") or body.get("entity_moid") + propagate = bool(body.get("propagate", True)) + pool = database.pool # type: ignore[attr-defined] + async with pool.acquire() as conn: + row = await conn.fetchrow( + """ + INSERT INTO vsphere_permissions (principal, role, entity_moid, propagate) + VALUES ($1, $2, $3, $4) + RETURNING id + """, + principal, + role, + None if entity in (None, "", "null") else str(entity), + propagate, + ) + return {"id": row["id"]} + + +@router.delete("/api/vcenter/authorization/permissions/{permission_id}") +async def delete_permission( + permission_id: int, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_admin), +) -> Response: + pool = database.pool # type: ignore[attr-defined] + async with pool.acquire() as conn: + result = await conn.execute( + "DELETE FROM vsphere_permissions WHERE id = $1", + permission_id, + ) + if not result.endswith("1"): + raise not_found(f"Permission {permission_id} not found") + return Response(status_code=204) + + +@router.get("/api/vcenter/namespaces") +async def list_namespaces( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + from app.vsphere.domain import api_state + + payload = await api_state.get_payload(database, "GET", "/api/vcenter/namespaces") + return payload if isinstance(payload, list) else [] + + +@router.get("/api/vcenter/namespace-management/nsx-tier0-gateway") +async def nsx_tier0_gateway( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + from app.vsphere.domain import api_state + + path = "/api/vcenter/namespace-management/nsx-tier0-gateway" + payload = await api_state.get_payload(database, "GET", path) + return payload if isinstance(payload, list) else [] + + +@router.get("/api/vcenter/namespace-management/networks") +async def wcp_networks( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + from app.vsphere.domain import api_state + + path = "/api/vcenter/namespace-management/networks" + payload = await api_state.get_payload(database, "GET", path) + return payload if isinstance(payload, list) else [] + + +@router.get("/api/vcenter/namespace-management/virtual-machine-classes") +async def vm_classes( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + from app.vsphere.domain import api_state + + path = "/api/vcenter/namespace-management/virtual-machine-classes" + payload = await api_state.get_payload(database, "GET", path) + return payload if isinstance(payload, list) else [] + + +@router.get("/api/vcenter/identity/providers") +async def identity_providers( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + from app.vsphere.domain import platform_surface + + return await platform_surface.list_identity_providers(database) + + +@router.post("/api/vcenter/identity/providers") +async def create_identity_provider( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_admin), +) -> dict[str, Any]: + from app.vsphere.domain import platform_surface + + return await platform_surface.upsert_identity_provider(database, body) + + +@router.get("/api/vcenter/identity/providers/{provider}") +async def get_identity_provider( + provider: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + from app.vsphere.domain import platform_surface + + item = await platform_surface.get_identity_provider(database, provider) + if item is not None: + return item + raise not_found(f"Identity provider {provider} not found") + + +@router.patch("/api/vcenter/identity/providers/{provider}") +@router.put("/api/vcenter/identity/providers/{provider}") +async def update_identity_provider( + provider: str, + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_admin), +) -> dict[str, Any]: + from app.vsphere.domain import platform_surface + + payload = {**body, "provider": provider} + return await platform_surface.upsert_identity_provider(database, payload) + + +@router.delete("/api/vcenter/identity/providers/{provider}") +async def delete_identity_provider( + provider: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_admin), +) -> Response: + from app.vsphere.domain import platform_surface + + if not await platform_surface.delete_identity_provider(database, provider): + raise not_found(f"Identity provider {provider} not found") + return Response(status_code=204) + + +@router.get("/api/vcenter/certificate-management/vcenter/tls") +async def machine_tls( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + from app.vsphere.domain import api_state + + payload = await api_state.get_payload( + database, "GET", "/api/vcenter/certificate-management/vcenter/tls" + ) + return payload if isinstance(payload, dict) else {} + + +@router.get("/api/vcenter/certificate-management/vcenter/tls-csr") +async def machine_tls_csr_get( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + from app.vsphere.domain import api_state + + payload = await api_state.get_payload( + database, "GET", "/api/vcenter/certificate-management/vcenter/tls-csr" + ) + return payload if isinstance(payload, dict) else {} + + +@router.post("/api/vcenter/certificate-management/vcenter/tls-csr") +async def machine_tls_csr_create( + body: dict[str, Any] | None = None, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_admin), +) -> dict[str, Any]: + from app.vsphere.domain import api_state + + del body + payload = await api_state.get_payload( + database, "GET", "/api/vcenter/certificate-management/vcenter/tls-csr" + ) + return payload if isinstance(payload, dict) else {} + + +@router.get("/api/vcenter/certificate-management/vcenter/trusted-root-chains") +async def trusted_root_chains( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + from app.vsphere.domain import api_state + + payload = await api_state.get_payload( + database, "GET", "/api/vcenter/certificate-management/vcenter/trusted-root-chains" + ) + return payload if isinstance(payload, list) else [] + + +@router.get("/api/vcenter/vm/{vm}/guest/customization") +async def guest_customization_get( + vm: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + obj = await vm_ops.require_vm(database, vm) + customization = obj.props.get("customization") + return customization if isinstance(customization, dict) else {} + + +@router.get("/api/vcenter/vm/{vm}/guest/networking") +async def guest_networking( + vm: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return await vm_ops.guest_networking(database, vm) + + +@router.get("/api/vcenter/vm/{vm}/guest/power") +async def guest_power_get( + vm: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, str]: + obj = await vm_ops.require_vm(database, vm) + state = str(obj.props.get("power_state") or "POWERED_OFF") + return {"state": "RUNNING" if state == "POWERED_ON" else "NOT_RUNNING"} + + +@router.post("/api/vcenter/vm/{vm}/guest/power") +async def guest_power_post( + vm: str, + action: str = Query(...), + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Interact.PowerOn")), +) -> Response: + mapping = {"reboot": "reset", "shutdown": "stop", "standby": "suspend"} + await vm_ops.set_power(database, vm, mapping.get(action, action)) + return Response(status_code=204) + + +@router.post("/api/vcenter/vm/{vm}/tools") +async def tools_upgrade( + vm: str, + action: str = Query("upgrade"), + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Interact.DeviceConnection")), +) -> dict[str, str]: + del action + await vm_ops.require_vm(database, vm) + from app.vsphere.domain import tasks as task_store + + task_id = await task_store.create_task( + database, + description=f"Upgrade tools {vm}", + service="com.vmware.vcenter.vm.tools", + operation="upgrade", + result={"vm": vm}, + ) + return {"task": task_id} + + +@router.post("/api/vcenter/vm/{vm}/console/tickets") +async def console_tickets( + vm: str, + body: dict[str, Any] | None = None, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Interact.ConsoleInteract")), +) -> dict[str, Any]: + del body + return await vm_ops.console_ticket(database, vm) + + +@router.post("/api/vcenter/vm/{vm}/guest/customization") +async def guest_customization( + vm: str, + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Config.Rename")), +) -> dict[str, str]: + obj = await vm_ops.require_vm(database, vm) + props = dict(obj.props) + props["customization"] = body + await inventory.update_props(database, vm, props) + from app.vsphere.domain import tasks as task_store + + task_id = await task_store.create_task( + database, + description=f"Customize {vm}", + service="com.vmware.vcenter.vm.guest.customization", + operation="set", + result={"vm": vm}, + ) + return {"task": task_id} + + +@router.get("/api/vcenter/vm/{vm}/guest/local-filesystem") +async def guest_local_filesystem( + vm: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + obj = await vm_ops.require_vm(database, vm) + filesystems = obj.props.get("guest_filesystems") + return filesystems if isinstance(filesystems, dict) else {} + + +@router.get("/api/vcenter/vm/{vm}/guest/filesystem") +async def guest_filesystem_get( + vm: str, + path: str = Query("/"), + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + if path in {"/", "/tmp", "/etc"}: + entries = await vm_ops.guest_list_files(database, vm, path) + return {"path": path, "type": "DIRECTORY", "files": entries} + content = await vm_ops.guest_read_file(database, vm, path) + return {"path": path, "type": "FILE", "content": content, "size": len(content.encode("utf-8"))} + + +@router.put("/api/vcenter/vm/{vm}/guest/filesystem") +async def guest_filesystem_put( + vm: str, + body: dict[str, Any], + path: str = Query(...), + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Interact.DeviceConnection")), +) -> Response: + content = str(body.get("content") or "") + await vm_ops.guest_write_file(database, vm, path, content, overwrite=True) + return Response(status_code=204) + + +@router.delete("/api/vcenter/vm/{vm}/guest/filesystem") +async def guest_filesystem_delete( + vm: str, + path: str = Query(...), + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Interact.DeviceConnection")), +) -> Response: + await vm_ops.guest_delete_file(database, vm, path) + return Response(status_code=204) + + +@router.get("/api/vcenter/vm/{vm}/guest/filesystem/files") +async def guest_filesystem_list( + vm: str, + path: str = Query("/"), + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + return await vm_ops.guest_list_files(database, vm, path) + + +@router.post("/api/vcenter/vm/{vm}") +async def vm_action( + vm: str, + action: str = Query(...), + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Provisioning.MarkAsTemplate")), +) -> dict[str, str]: + if action == "mark-as-template": + task_id = await vm_ops.set_template(database, vm, template=True) + elif action in {"mark-as-vm", "mark-as-virtual-machine"}: + task_id = await vm_ops.set_template(database, vm, template=False) + elif action == "unregister": + task_id = await vm_ops.unregister_vm(database, vm) + else: + raise invalid_argument(f"unsupported action {action}") + return {"task": task_id} + + +@router.get("/api/vcenter/host/{host}/storage/storage-device") +async def host_storage( + host: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + obj = await inventory.get_object(database, host) + if obj is None or obj.type != "HostSystem": + raise not_found(f"Host {host} not found") + devices = obj.props.get("storage_devices") + return list(devices) if isinstance(devices, list) else [] + + +@router.get("/api/vcenter/host/{host}/networking") +async def host_networking( + host: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + obj = await inventory.get_object(database, host) + if obj is None or obj.type != "HostSystem": + raise not_found(f"Host {host} not found") + networking = obj.props.get("networking") + return networking if isinstance(networking, dict) else {} + + +@router.get("/api/vcenter/folder/{folder}/children") +async def folder_children( + folder: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, str]]: + parent = await inventory.get_object(database, folder) + if parent is None: + raise not_found(f"Folder {folder} not found") + children = [obj for obj in await inventory.list_objects(database) if obj.parent_moid == folder] + return [{"moid": c.moid, "type": c.type, "name": c.name} for c in children] + + +@router.get("/api/vcenter/storage/policies/{policy}/vm") +async def policy_vms( + policy: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[str]: + objects = await inventory.list_objects(database, type_name="VirtualMachine") + if policy in {"policy-default", "default"}: + return [obj.moid for obj in objects] + # Named non-default policies attach to every 10th VM for lab demos. + return [obj.moid for i, obj in enumerate(objects) if i % 10 == 0] + + +@router.get("/api/vapi/metadata/metamodel/service") +async def metamodel_services( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[str]: + from app.vsphere.domain import api_state + + payload = await api_state.get_payload(database, "GET", "/api/vapi/metadata/metamodel/service") + return payload if isinstance(payload, list) else [] + + +@router.get("/api/vapi/metadata/authentication/component") +async def authentication_components( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[str]: + from app.vsphere.domain import api_state + + payload = await api_state.get_payload( + database, "GET", "/api/vapi/metadata/authentication/component" + ) + return payload if isinstance(payload, list) else [] + + +@router.get("/api/vcenter/activity-history") +async def activity_history( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + from app.vsphere.domain import api_state + + payload = await api_state.get_payload(database, "GET", "/api/vcenter/activity-history") + return payload if isinstance(payload, list) else [] diff --git a/app/vsphere/rest/router.py b/app/vsphere/rest/router.py new file mode 100644 index 0000000..f7ab6ed --- /dev/null +++ b/app/vsphere/rest/router.py @@ -0,0 +1,450 @@ +"""vSphere Automation REST API (/api + legacy /rest).""" + +from __future__ import annotations + +from typing import Any + +from fastapi import APIRouter, Depends, Query, Request, Response +from fastapi.responses import JSONResponse +from fastapi.security import HTTPBasicCredentials + +from app.db.pool import Database +from app.dependencies import get_database +from app.vsphere import inventory +from app.vsphere.domain import vm_ops +from app.vsphere.errors import invalid_argument, not_found, unauthenticated +from app.vsphere.rest import mappers +from app.vsphere.security.authz import require_privilege, require_read +from app.vsphere.security.session import ( + SESSION_HEADER, + SessionInfo, + create_session, + delete_session, + ensure_default_credentials, + optional_basic, + require_session, + verify_password, +) + +router = APIRouter(tags=["vSphere REST"]) + + +def _session_json(session_id: str, *, legacy: bool = False) -> JSONResponse: + # Modern /api/session returns a JSON string; legacy /rest returns {value: ...}. + body: Any = {"value": session_id} if legacy else session_id + return JSONResponse(content=body, status_code=201 if not legacy else 200) + + +def _attach_session_cookie(response: Response, session_id: str) -> None: + response.headers[SESSION_HEADER] = session_id + response.set_cookie( + key=SESSION_HEADER, + value=session_id, + httponly=False, + samesite="strict", + path="/", + max_age=(2 * 60 * 60), + ) + + +@router.post("/api/session") +async def create_api_session( + request: Request, + database: Database = Depends(get_database), + credentials: HTTPBasicCredentials | None = Depends(optional_basic), +) -> Response: + await ensure_default_credentials(database) + username, password = await _credentials_from_request(request, credentials) + if not await verify_password(database, username, password): + raise unauthenticated("Invalid credentials") + session_id = await create_session(database, username) + response = _session_json(session_id) + _attach_session_cookie(response, session_id) + return response + + +@router.delete("/api/session") +async def delete_api_session( + session: SessionInfo = Depends(require_session), + database: Database = Depends(get_database), +) -> Response: + await delete_session(database, session.id) + response = Response(status_code=204) + response.delete_cookie(SESSION_HEADER, path="/") + return response + + +@router.get("/api/session") +async def get_api_session(session: SessionInfo = Depends(require_session)) -> Response: + # vSphere Automation: validate session with HTTP 200 and empty body. + # Lab helpers expose identity via optional headers for the web console. + response = Response(status_code=200) + response.headers["x-vmware-session-user"] = session.username + response.headers["x-vmware-session-roles"] = ",".join(session.roles) + return response + + +@router.post("/rest/com/vmware/cis/session") +async def create_legacy_session( + request: Request, + database: Database = Depends(get_database), + credentials: HTTPBasicCredentials | None = Depends(optional_basic), +) -> Response: + await ensure_default_credentials(database) + username, password = await _credentials_from_request(request, credentials) + if not await verify_password(database, username, password): + raise unauthenticated("Invalid credentials") + session_id = await create_session(database, username) + response = _session_json(session_id, legacy=True) + _attach_session_cookie(response, session_id) + return response + + +@router.get("/rest/com/vmware/cis/session") +async def get_legacy_session(session: SessionInfo = Depends(require_session)) -> dict[str, str]: + return {"value": session.id} + + +@router.delete("/rest/com/vmware/cis/session") +async def delete_legacy_session( + session: SessionInfo = Depends(require_session), + database: Database = Depends(get_database), +) -> dict[str, Any]: + await delete_session(database, session.id) + return {"value": None} + + +@router.get("/api/appliance/system/version") +async def appliance_version( + request: Request, + database: Database = Depends(get_database), +) -> dict[str, Any]: + """Lab-friendly: version is readable without a session (real vCenter varies).""" + + from app.vsphere.domain import api_state + + payload = await api_state.get_payload(database, "GET", "/api/appliance/system/version") + if isinstance(payload, dict) and payload: + # Overlay active runtime major when contract apply changed it. + major = getattr(request.app.state, "runtime_source_version", None) + if major: + out = dict(payload) + out["version"] = str(major) + return out + return payload + return {} + + +@router.get("/api/vcenter/vm") +async def list_vms( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), + names: list[str] | None = Query(default=None), + power_states: list[str] | None = Query(default=None), + hosts: list[str] | None = Query(default=None), + folders: list[str] | None = Query(default=None), + datacenters: list[str] | None = Query(default=None), + clusters: list[str] | None = Query(default=None), + resource_pools: list[str] | None = Query(default=None), + limit: int | None = Query(default=None, ge=1, le=5000), + cursor: int = Query(default=0, ge=0), +) -> list[dict[str, Any]]: + objects = await inventory.list_objects(database, type_name="VirtualMachine") + result_objs = objects + if names: + wanted = set(names) + result_objs = [obj for obj in result_objs if obj.name in wanted] + if power_states: + wanted_states = set(power_states) + result_objs = [obj for obj in result_objs if obj.props.get("power_state") in wanted_states] + if hosts: + host_set = set(hosts) + result_objs = [obj for obj in result_objs if obj.props.get("host") in host_set] + if folders: + folder_set = set(folders) + result_objs = [obj for obj in result_objs if obj.parent_moid in folder_set] + if resource_pools: + rp_set = set(resource_pools) + result_objs = [obj for obj in result_objs if obj.props.get("resource_pool") in rp_set] + if clusters or datacenters: + all_objects = {obj.moid: obj for obj in await inventory.list_objects(database)} + if clusters: + cluster_set = set(clusters) + result_objs = [ + obj + for obj in result_objs + if all_objects.get(str(obj.props.get("host") or ""), None) + and all_objects[str(obj.props.get("host"))].parent_moid in cluster_set + ] + if datacenters: + dc_set = set(datacenters) + filtered = [] + for obj in result_objs: + parent = all_objects.get(obj.parent_moid or "") + grand = ( + all_objects.get(parent.parent_moid) if parent and parent.parent_moid else None + ) + if (parent and parent.moid in dc_set) or (grand and grand.moid in dc_set): + filtered.append(obj) + result_objs = filtered + if limit is not None: + result_objs = result_objs[cursor : cursor + limit] + elif cursor: + result_objs = result_objs[cursor:] + return [mappers.vm_summary(obj) for obj in result_objs] + + +@router.get("/api/vcenter/vm/{vm}") +async def get_vm( + vm: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + obj = await inventory.get_object(database, vm) + if obj is None or obj.type != "VirtualMachine": + raise not_found(f"VM {vm} not found") + return mappers.vm_info(obj) + + +@router.post("/api/vcenter/vm") +async def create_vm( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Inventory.Create")), +) -> str: + name = str(body.get("name") or "").strip() + if not name: + raise invalid_argument("name is required") + guest = body.get("guest_OS") or body.get("guest_os") or "OTHER_GUEST_64" + placement = body.get("placement") or {} + folder = placement.get("folder") or "group-v23" + host = placement.get("host") or "host-11" + datastore = placement.get("datastore") or "datastore-31" + pool = placement.get("resource_pool") or placement.get("cluster") or "resgroup-22" + cpu = int((body.get("cpu") or {}).get("count") or body.get("cpu_count") or 1) + memory = int((body.get("memory") or {}).get("size_MiB") or body.get("memory_size_MiB") or 1024) + disks_spec = body.get("disks") or body.get("disk") + nics_spec = body.get("nics") or body.get("ethernet") + networks = body.get("networks") or ["network-41"] + disks = None + if isinstance(disks_spec, list) and disks_spec: + disks = [] + for idx, disk in enumerate(disks_spec): + value = disk.get("new_vmdk") or disk.get("value") or disk + capacity = int(value.get("capacity") or value.get("capacity_bytes") or 42949672960) + disks.append( + { + "key": str(2000 + idx), + "value": { + "label": f"Hard disk {idx + 1}", + "capacity": capacity, + "type": "SCSI", + }, + } + ) + nics = None + if isinstance(nics_spec, list) and nics_spec: + nics = [] + for idx, nic in enumerate(nics_spec): + value = nic.get("value") or nic + backing = value.get("backing") or {} + network = str(backing.get("network") or (networks[0] if networks else "network-41")) + nics.append( + { + "key": str(4000 + idx), + "value": { + "label": f"Network adapter {idx + 1}", + "mac": value.get("mac_address") or f"00:50:56:01:00:{idx:02x}", + "state": "NOT_CONNECTED", + "type": value.get("type") or "VMXNET3", + "backing": {"type": "STANDARD_PORTGROUP", "network": network}, + }, + } + ) + if network not in networks: + networks.append(network) + moid, _task = await vm_ops.create_vm( + database, + name=name, + folder=str(folder), + host=str(host), + datastore=str(datastore), + resource_pool=str(pool), + guest_os=str(guest), + cpu_count=cpu, + memory_size_mib=memory, + networks=[str(n) for n in networks], + disks=disks, + nics=nics, + ) + return moid + + +@router.delete("/api/vcenter/vm/{vm}") +async def delete_vm( + vm: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Inventory.Delete")), +) -> Response: + obj = await inventory.get_object(database, vm) + if obj is None or obj.type != "VirtualMachine": + raise not_found(f"VM {vm} not found") + if obj.props.get("power_state") == "POWERED_ON": + raise invalid_argument("VM must be powered off before delete") + await inventory.delete_object(database, vm) + return Response(status_code=204) + + +@router.get("/api/vcenter/vm/{vm}/power") +async def get_vm_power( + vm: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, str]: + obj = await inventory.get_object(database, vm) + if obj is None or obj.type != "VirtualMachine": + raise not_found(f"VM {vm} not found") + state = str(obj.props.get("power_state") or "POWERED_OFF") + return {"state": state} + + +@router.post("/api/vcenter/vm/{vm}/power") +async def power_vm( + vm: str, + action: str = Query(...), + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Interact.PowerOn")), +) -> dict[str, str]: + task_id = await vm_ops.set_power(database, vm, action.lower()) + return {"task": task_id} + + +@router.get("/api/vcenter/host") +async def list_hosts( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + objects = await inventory.list_objects(database, type_name="HostSystem") + return [mappers.host_summary(obj) for obj in objects] + + +@router.get("/api/vcenter/host/{host}") +async def get_host( + host: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + obj = await inventory.get_object(database, host) + if obj is None or obj.type != "HostSystem": + raise not_found(f"Host {host} not found") + return mappers.host_info(obj) + + +@router.get("/api/vcenter/datastore") +async def list_datastores( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + objects = await inventory.list_objects(database, type_name="Datastore") + return [mappers.datastore_summary(obj) for obj in objects] + + +@router.get("/api/vcenter/datastore/{datastore}") +async def get_datastore( + datastore: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + obj = await inventory.get_object(database, datastore) + if obj is None or obj.type != "Datastore": + raise not_found(f"Datastore {datastore} not found") + props = obj.props + return { + "name": obj.name, + "type": props.get("type", "VMFS"), + "accessible": props.get("accessible", True), + "free_space": props.get("free_space", 0), + "capacity": props.get("capacity", 0), + "multiple_host_access": props.get("multiple_host_access", True), + } + + +@router.get("/api/vcenter/network") +async def list_networks( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + networks = await inventory.list_objects(database, type_name="Network") + dvpg = await inventory.list_objects(database, type_name="DistributedVirtualPortgroup") + return [mappers.network_summary(obj) for obj in (*networks, *dvpg)] + + +@router.get("/api/vcenter/datacenter") +async def list_datacenters( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + objects = await inventory.list_objects(database, type_name="Datacenter") + return [mappers.datacenter_summary(obj) for obj in objects] + + +@router.get("/api/vcenter/cluster") +async def list_clusters( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + objects = await inventory.list_objects(database, type_name="ClusterComputeResource") + return [mappers.cluster_summary(obj) for obj in objects] + + +@router.get("/api/vcenter/folder") +async def list_folders( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + objects = await inventory.list_objects(database, type_name="Folder") + return [mappers.folder_summary(obj) for obj in objects] + + +@router.get("/api/vcenter/resource-pool") +async def list_resource_pools( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + objects = await inventory.list_objects(database, type_name="ResourcePool") + return [mappers.resource_pool_summary(obj) for obj in objects] + + +@router.get("/api/vcenter/vm/{vm}/guest/identity") +async def vm_guest_identity( + vm: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + obj = await inventory.get_object(database, vm) + if obj is None or obj.type != "VirtualMachine": + raise not_found(f"VM {vm} not found") + return { + "name": obj.name, + "family": "LINUX", + "full_name": {"default_message": obj.props.get("guest_OS", "OTHER")}, + "ip_address": "10.0.0." + obj.moid.split("-")[-1], + "host_name": obj.name, + } + + +async def _credentials_from_request( + request: Request, + credentials: HTTPBasicCredentials | None, +) -> tuple[str, str]: + if credentials is not None: + return credentials.username, credentials.password + # Some clients post JSON credentials (lab convenience). + if request.headers.get("content-type", "").startswith("application/json"): + try: + payload = await request.json() + except Exception: + payload = {} + if isinstance(payload, dict) and payload.get("user_name") and payload.get("password"): + return str(payload["user_name"]), str(payload["password"]) + raise unauthenticated("Basic authentication required") diff --git a/app/vsphere/rest/stub_surface.py b/app/vsphere/rest/stub_surface.py new file mode 100644 index 0000000..22b9c6e --- /dev/null +++ b/app/vsphere/rest/stub_surface.py @@ -0,0 +1,349 @@ +"""DB-backed per-path routes for Broadcom Automation API stubs without deep handlers. + +Each ``(verb, path)`` from the universe registry is registered with +``APIRouter.add_api_route`` (same idea as Proxmox ``register_contract_routes``), +instead of a single ``/api/{full_path:path}`` catch-all. +""" + +from __future__ import annotations + +import re +from collections.abc import Awaitable, Callable +from typing import Any + +from fastapi import APIRouter, Depends, Request, Response +from fastapi.responses import JSONResponse + +from app.db.pool import Database +from app.dependencies import get_database +from app.vsphere import inventory +from app.vsphere.domain import api_state, tagging +from app.vsphere.domain import content as content_domain +from app.vsphere.errors import not_found +from app.vsphere.rest.coverage import IMPLEMENTED +from app.vsphere.security.authz import require_read +from app.vsphere.security.session import SessionInfo + +router = APIRouter(tags=["vSphere REST surface"]) + +_PARAM_RE = re.compile(r"\{([A-Za-z0-9_]+)\}") + + +def _extract_params(template: str, concrete: str) -> dict[str, str]: + pattern = "^" + _PARAM_RE.sub(r"([^/]+)", template) + "$" + match = re.match(pattern, concrete) + if not match: + return {} + names = _PARAM_RE.findall(template) + return {name: match.group(index + 1) for index, name in enumerate(names)} + + +async def _live_get(database: Database, template: str, concrete: str) -> Any | None: + """Return inventory/platform-backed payloads when possible.""" + + params = _extract_params(template, concrete) + + if template == "/api/cis/tagging/category": + return await tagging.list_categories(database) + if template == "/api/cis/tagging/tag": + return await tagging.list_tags(database) + if template == "/api/content/library": + return await content_domain.list_libraries(database) + if template == "/api/content/library/item": + libs = await content_domain.list_libraries(database) + items: list[dict[str, Any]] = [] + for lib in libs: + items.extend(await content_domain.list_library_items(database, lib["id"])) + return items + if template == "/api/content/local-library": + libs = await content_domain.list_libraries(database) + return [lib for lib in libs if lib.get("type") == "LOCAL"] + + vm = params.get("vm") + if vm and "/hardware/" in template: + obj = await inventory.get_object(database, vm) + if obj is None: + raise not_found(f"VM {vm} not found") + props = obj.props or {} + + def _live_list(key: str) -> list[Any] | None: + value = props.get(key) + if isinstance(value, list) and value: + return list(value) + return None + + # Prefer non-empty inventory props; otherwise fall through to vsphere_api_state. + if template.endswith("/hardware/cdrom"): + return _live_list("cdroms") + if template.endswith("/hardware/floppy"): + return _live_list("floppies") + if template.endswith("/hardware/serial"): + return _live_list("serials") + if template.endswith("/hardware/parallel"): + return _live_list("parallels") + if template.endswith("/hardware/adapter/scsi"): + return _live_list("scsi_adapters") + if template.endswith("/hardware/adapter/sata"): + return _live_list("sata_adapters") + if template.endswith("/hardware/adapter/nvme"): + return _live_list("nvme_adapters") + if template.endswith("/hardware/boot") and isinstance(props.get("boot"), dict): + return props["boot"] + if template.endswith("/hardware/boot/device"): + return _live_list("boot_devices") + if template.endswith("/hardware/disk"): + return _live_list("disks") or list(props.get("disks") or []) + if template.endswith("/hardware/ethernet"): + return _live_list("nics") or list(props.get("nics") or []) + if "/hardware/disk/" in template and template.endswith("}"): + disk_id = params.get("disk") + for disk in props.get("disks") or []: + if str(disk.get("key") or disk.get("disk")) == str(disk_id): + return disk + if "/hardware/ethernet/" in template and template.endswith("}"): + nic_id = params.get("nic") + for nic in props.get("nics") or []: + if str(nic.get("key") or nic.get("nic")) == str(nic_id): + return nic + + if vm and "/guest/" in template: + obj = await inventory.get_object(database, vm) + if obj is None: + raise not_found(f"VM {vm} not found") + props = obj.props or {} + if template.endswith("/guest/local-filesystem"): + if "guest_filesystems" in props: + return props["guest_filesystems"] + return None + identity = props.get("identity") or {} + if identity or props.get("guest_OS") or props.get("guest_ip"): + return { + "name": identity.get("name") or obj.name, + "family": "LINUX" + if "WIN" not in str(props.get("guest_OS", "")).upper() + else "WINDOWS", + "full_name": {"name": props.get("guest_OS") or obj.name}, + "host_name": identity.get("name") or obj.name, + "ip_address": props.get("guest_ip"), + } + return None + + host = params.get("host") + if host and template.endswith("/networking"): + obj = await inventory.get_object(database, host) + if obj is None: + raise not_found(f"Host {host} not found") + networking = (obj.props or {}).get("networking") + return networking if networking is not None else None + if host and "storage-device" in template: + obj = await inventory.get_object(database, host) + if obj is None: + raise not_found(f"Host {host} not found") + devices = (obj.props or {}).get("storage_devices") + return devices if devices is not None else None + + return None + + +async def _mutate_vm_hardware( + database: Database, + template: str, + concrete: str, + verb: str, + body: dict[str, Any], +) -> Any | None: + params = _extract_params(template, concrete) + vm = params.get("vm") + if not vm or "/hardware/" not in template: + return False + obj = await inventory.get_object(database, vm) + if obj is None: + raise not_found(f"VM {vm} not found") + props = dict(obj.props or {}) + + if verb == "POST" and template.endswith("/hardware/cdrom"): + items = list(props.get("cdroms") or []) + key = str(3000 + len(items)) + items.append( + {"cdrom": key, "label": f"CD/DVD drive {len(items) + 1}", "state": "CONNECTED", **body} + ) + props["cdroms"] = items + await inventory.upsert_object( + database, + moid=vm, + type_name=obj.type, + name=obj.name, + parent_moid=obj.parent_moid, + props=props, + ) + return key + if verb in {"PUT", "PATCH"} and template.endswith("/hardware/boot"): + props["boot"] = {**(props.get("boot") or {}), **body} + await inventory.upsert_object( + database, + moid=vm, + type_name=obj.type, + name=obj.name, + parent_moid=obj.parent_moid, + props=props, + ) + return None + if verb == "DELETE" and "/hardware/cdrom/" in template: + cdrom = params.get("cdrom") + props["cdroms"] = [ + c for c in (props.get("cdroms") or []) if str(c.get("cdrom")) != str(cdrom) + ] + await inventory.upsert_object( + database, + moid=vm, + type_name=obj.type, + name=obj.name, + parent_moid=obj.parent_moid, + props=props, + ) + return None + return False # not handled specialized; fall through to api_state + + +async def _dispatch( + template: str, + verb: str, + request: Request, + database: Database, +) -> Response: + concrete = request.url.path + method = verb.upper() + raw_body: Any = {} + if method in {"POST", "PUT", "PATCH"}: + try: + raw_body = await request.json() + except Exception: + raw_body = {} + if not isinstance(raw_body, dict): + raw_body = {"value": raw_body} + + if method == "GET": + live = await _live_get(database, template, concrete) + if live is not None and not api_state.is_empty_payload(live): + return JSONResponse(content=live, status_code=200) + stored = await api_state.get_payload_or_seed(database, "GET", template) + if stored is None or api_state.is_empty_payload(stored): + return JSONResponse(content={"path": template, "status": "NOT_SEEDED"}, status_code=404) + return JSONResponse(content=stored, status_code=200) + + hw = await _mutate_vm_hardware(database, template, concrete, method, raw_body) + if hw is not False: + if isinstance(hw, str): + return JSONResponse(content=hw, status_code=201) + return Response(status_code=204) + + if method in {"PUT", "PATCH"}: + existing = await api_state.get_payload(database, "GET", template) + if isinstance(existing, dict) and isinstance(raw_body, dict): + merged = {**existing, **raw_body} + elif isinstance(raw_body, dict) and raw_body: + merged = raw_body + elif existing is not None: + merged = existing + else: + merged = {} + await api_state.put_payload(database, "GET", template, merged) + return JSONResponse(content=merged, status_code=200) + + if method == "DELETE": + # Soft-delete: restore seed_payload from DB so lab GETs never go empty/404. + await api_state.restore_seed_payload(database, "GET", template) + if template.endswith("}"): + parent = template.rsplit("/", 1)[0] + if parent: + await api_state.restore_seed_payload(database, "GET", parent) + return Response(status_code=204) + + # POST create / action + action = request.query_params.get("action") + if action: + await api_state.put_payload( + database, + "GET", + template, + { + "last_action": action, + "accepted": True, + "path": template, + **({} if not raw_body else {"spec": raw_body}), + }, + ) + if action.endswith("Task") or "task" in action.lower(): + from app.vsphere.domain import tasks as task_store + + task_id = await task_store.create_task( + database, + description=f"{action} {template}", + service="com.vmware.vapi", + operation=action, + status="SUCCEEDED", + result={"path": template, "action": action}, + ) + return JSONResponse(content=task_id, status_code=200) + return JSONResponse(content={"status": "SUCCESS", "action": action}, status_code=200) + + new_id = await api_state.new_id(template.rstrip("/").rsplit("/", 1)[-1].strip("{}") or "id") + collection_payload = await api_state.get_payload(database, "GET", template) + created = {"id": new_id, "name": raw_body.get("name") or new_id, **raw_body} + if isinstance(collection_payload, list): + collection_payload = [*collection_payload, created] + await api_state.put_payload(database, "GET", template, collection_payload) + else: + await api_state.put_payload( + database, "GET", f"{template}/{{{template.rsplit('/', 1)[-1]}}}", created + ) + await api_state.put_payload(database, "GET", template, created) + return JSONResponse(content=new_id, status_code=201) + + +def _endpoint( + template: str, + verb: str, +) -> Callable[..., Awaitable[Response]]: + async def dispatch( + request: Request, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), + ) -> Response: + return await _dispatch(template, verb, request, database) + + dispatch.__name__ = f"vsphere_stub_{verb}_{template.replace('/', '_').strip('_')}" + dispatch.__qualname__ = dispatch.__name__ + return dispatch + + +def register_stub_routes( + target: APIRouter | None = None, + *, + implemented: dict[tuple[str, str], str] | None = None, +) -> int: + """Register one FastAPI route per stub ``(verb, path)`` from the coverage registry. + + Deep ``CORE_IMPLEMENTED`` handlers are skipped so they keep winning on their + dedicated routers. Returns the number of routes added. + """ + + api = target if target is not None else router + registry = implemented if implemented is not None else IMPLEMENTED + added = 0 + for (verb, path), status in sorted(registry.items(), key=lambda item: (item[0][1], item[0][0])): + if status != "stub": + continue + api.add_api_route( + path, + _endpoint(path, verb), + methods=[verb], + name=f"vsphere-stub:{verb}:{path}", + include_in_schema=True, + openapi_extra={"x-vmware-implementation": "stub"}, + ) + added += 1 + return added + + +register_stub_routes() diff --git a/app/vsphere/rest/tagging_rest.py b/app/vsphere/rest/tagging_rest.py new file mode 100644 index 0000000..3263cda --- /dev/null +++ b/app/vsphere/rest/tagging_rest.py @@ -0,0 +1,140 @@ +"""CIS tagging REST.""" + +from __future__ import annotations + +from typing import Any + +from fastapi import APIRouter, Depends, Response + +from app.db.pool import Database +from app.dependencies import get_database +from app.vsphere.domain import tagging +from app.vsphere.errors import invalid_argument +from app.vsphere.security.authz import require_privilege, require_read +from app.vsphere.security.session import SessionInfo + +router = APIRouter(tags=["vSphere Tagging"]) + + +@router.get("/api/cis/tagging/category") +async def list_categories( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[str]: + return await tagging.list_categories(database) + + +@router.post("/api/cis/tagging/category") +async def create_category( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("InventoryService.Tagging.CreateCategory")), +) -> str: + spec = body.get("create_spec") if isinstance(body.get("create_spec"), dict) else body + name = spec.get("name") if isinstance(spec, dict) else None + if not name: + raise invalid_argument("create_spec.name is required") + return await tagging.create_category( + database, + name=str(name), + description=str(spec.get("description") or ""), + cardinality=str(spec.get("cardinality") or "MULTIPLE"), + associable_types=list(spec.get("associable_types") or []), + ) + + +@router.get("/api/cis/tagging/category/{category_id}") +async def get_category( + category_id: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return await tagging.get_category(database, category_id) + + +@router.delete("/api/cis/tagging/category/{category_id}") +async def delete_category( + category_id: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("InventoryService.Tagging.CreateCategory")), +) -> Response: + await tagging.delete_category(database, category_id) + return Response(status_code=204) + + +@router.get("/api/cis/tagging/tag") +async def list_tags( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[str]: + return await tagging.list_tags(database) + + +@router.post("/api/cis/tagging/tag") +async def create_tag( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("InventoryService.Tagging.CreateTag")), +) -> str: + spec = body.get("create_spec") if isinstance(body.get("create_spec"), dict) else body + if not isinstance(spec, dict): + raise invalid_argument("create_spec is required") + category_id = spec.get("category_id") + name = spec.get("name") + if not category_id: + raise invalid_argument("create_spec.category_id is required") + if not name: + raise invalid_argument("create_spec.name is required") + return await tagging.create_tag( + database, + category_id=str(category_id), + name=str(name), + description=str(spec.get("description") or ""), + ) + + +@router.get("/api/cis/tagging/tag/{tag_id}") +async def get_tag( + tag_id: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + return await tagging.get_tag(database, tag_id) + + +@router.delete("/api/cis/tagging/tag/{tag_id}") +async def delete_tag( + tag_id: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("InventoryService.Tagging.CreateTag")), +) -> Response: + await tagging.delete_tag(database, tag_id) + return Response(status_code=204) + + +@router.post("/api/cis/tagging/tag-association") +async def tag_association( + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("InventoryService.Tagging.AttachTag")), +) -> Any: + action = str(body.get("action") or "attach") + tag_id = body.get("tag_id") + obj = body.get("object_id") or body.get("object") or {} + object_type = str(obj.get("type") or body.get("type") or "VirtualMachine") + object_id = str(obj.get("id") or body.get("id") or "") + if action == "list-attached-tags": + if not object_id: + raise invalid_argument("object_id.id is required") + return await tagging.list_attached_tags(database, object_type, object_id) + if not tag_id: + raise invalid_argument("tag_id is required") + if not object_id: + raise invalid_argument("object_id.id is required") + if action == "attach": + await tagging.attach_tag(database, str(tag_id), object_type, object_id) + return Response(status_code=204) + if action == "detach": + await tagging.detach_tag(database, str(tag_id), object_type, object_id) + return Response(status_code=204) + raise invalid_argument(f"unsupported action {action}") diff --git a/app/vsphere/rest/tasks.py b/app/vsphere/rest/tasks.py new file mode 100644 index 0000000..7cff350 --- /dev/null +++ b/app/vsphere/rest/tasks.py @@ -0,0 +1,47 @@ +"""CIS tasks REST.""" + +from __future__ import annotations + +from typing import Any + +from fastapi import APIRouter, Depends + +from app.db.pool import Database +from app.dependencies import get_database +from app.vsphere.domain import tasks as task_store +from app.vsphere.errors import not_found +from app.vsphere.security.authz import require_read +from app.vsphere.security.session import SessionInfo + +router = APIRouter(tags=["vSphere Tasks"]) + + +@router.get("/api/cis/tasks") +async def list_tasks( + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> list[dict[str, Any]]: + tasks = await task_store.list_tasks(database) + if tasks: + return tasks + # Fresh lab DB — ensure callers always see at least one completed task. + await task_store.create_task( + database, + description="Lab inventory seed", + service="com.vmware.vcenter", + operation="seed", + result={"status": "SUCCEEDED"}, + ) + return await task_store.list_tasks(database) + + +@router.get("/api/cis/tasks/{task}") +async def get_task( + task: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_read), +) -> dict[str, Any]: + payload = await task_store.get_task(database, task) + if payload is None: + raise not_found(f"Task {task} not found") + return payload diff --git a/app/vsphere/rest/universe.json b/app/vsphere/rest/universe.json new file mode 100644 index 0000000..f20570b --- /dev/null +++ b/app/vsphere/rest/universe.json @@ -0,0 +1,7282 @@ +{ + "source": "https://developer.broadcom.com/xapis/vsphere-automation-api/latest/operation-index/", + "source_label": "vSphere Automation API 9.1 (Latest) operations index", + "source_file": "contracts/vsphere/broadcom-9.1-operations-index.txt", + "broadcom_operations": 1348, + "broadcom_by_verb": { + "GET": 628, + "PUT": 93, + "PATCH": 91, + "DELETE": 114, + "POST": 422 + }, + "unique_routes": 1037, + "unique_by_verb": { + "GET": 528, + "PUT": 93, + "PATCH": 87, + "POST": 218, + "DELETE": 111 + }, + "methods": [ + { + "verb": "GET", + "path": "/api/appliance/access/consolecli", + "service": "Appliance Access Consolecli", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/access/consolecli", + "service": "Appliance Access Consolecli", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/access/dcui", + "service": "Appliance Access Dcui", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/access/dcui", + "service": "Appliance Access Dcui", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/access/shell", + "service": "Appliance Access Shell", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/access/shell", + "service": "Appliance Access Shell", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/access/ssh", + "service": "Appliance Access Ssh", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/access/ssh", + "service": "Appliance Access Ssh", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/cores", + "service": "Appliance Cores", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health", + "service": "Appliance Health", + "sample_action": "messages", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health-check-settings", + "service": "Appliance HealthCheckSettings", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/appliance/health-check-settings", + "service": "Appliance HealthCheckSettings", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/applmgmt", + "service": "Appliance Health Applmgmt", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/database", + "service": "Appliance Health Database", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/databasestorage", + "service": "Appliance Health Databasestorage", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/load", + "service": "Appliance Health Load", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/mem", + "service": "Appliance Health Mem", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/softwarepackages", + "service": "Appliance Health Softwarepackages", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/storage", + "service": "Appliance Health Storage", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/swap", + "service": "Appliance Health Swap", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/system", + "service": "Appliance Health System", + "sample_action": "lastcheck", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/infraprofile/configs", + "service": "Appliance Infraprofile Configs", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/infraprofile/configs", + "service": "Appliance Infraprofile Configs", + "sample_action": "export", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/appliance/local-accounts", + "service": "Appliance LocalAccounts", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/local-accounts", + "service": "Appliance LocalAccounts", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/appliance/local-accounts", + "service": "Appliance LocalAccounts", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/local-accounts", + "service": "Appliance LocalAccounts", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/local-accounts", + "service": "Appliance LocalAccounts", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/local-accounts/policy", + "service": "Appliance LocalAccounts Policy", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/local-accounts/policy", + "service": "Appliance LocalAccounts Policy", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/logging/forwarding", + "service": "Appliance Logging Forwarding", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/logging/forwarding", + "service": "Appliance Logging Forwarding", + "sample_action": "test", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/logging/forwarding", + "service": "Appliance Logging Forwarding", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/logging/liagent/log-collection", + "service": "Appliance Logging Liagent LogCollection", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/logging/liagent/log-collection", + "service": "Appliance Logging Liagent LogCollection", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/monitoring", + "service": "Appliance Monitoring", + "sample_action": "query", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking", + "service": "Appliance Networking", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/appliance/networking", + "service": "Appliance Networking", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/networking", + "service": "Appliance Networking", + "sample_action": "reset", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/dns/domains", + "service": "Appliance Networking Dns Domains", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/networking/dns/domains", + "service": "Appliance Networking Dns Domains", + "sample_action": "add", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/networking/dns/domains/{domain}", + "service": "Appliance Networking Dns Domains", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/dns/hostname", + "service": "Appliance Networking Dns Hostname", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/networking/dns/hostname", + "service": "Appliance Networking Dns Hostname", + "sample_action": "test", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/networking/dns/hostname", + "service": "Appliance Networking Dns Hostname", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/dns/servers", + "service": "Appliance Networking Dns Servers", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/networking/dns/servers", + "service": "Appliance Networking Dns Servers", + "sample_action": "test", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/networking/dns/servers", + "service": "Appliance Networking Dns Servers", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/firewall/inbound", + "service": "Appliance Networking Firewall Inbound", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/networking/firewall/inbound", + "service": "Appliance Networking Firewall Inbound", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/interfaces", + "service": "Appliance Networking Interfaces", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/interfaces/{interface}", + "service": "Appliance Networking Interfaces", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/interfaces/{interface}/ipv4", + "service": "Appliance Networking Interfaces Ipv4", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/networking/interfaces/{interface}/ipv4", + "service": "Appliance Networking Interfaces Ipv4", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/interfaces/{interface}/ipv6", + "service": "Appliance Networking Interfaces Ipv6", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/networking/interfaces/{interface}/ipv6", + "service": "Appliance Networking Interfaces Ipv6", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/no-proxy", + "service": "Appliance Networking NoProxy", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/networking/no-proxy", + "service": "Appliance Networking NoProxy", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/appliance/networking/proxy", + "service": "Appliance Networking Proxy", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/proxy", + "service": "Appliance Networking Proxy", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/networking/proxy", + "service": "Appliance Networking Proxy", + "sample_action": "test", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/networking/proxy", + "service": "Appliance Networking Proxy", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/ntp", + "service": "Appliance Ntp", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/ntp", + "service": "Appliance Ntp", + "sample_action": "test", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/ntp", + "service": "Appliance Ntp", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/recovery", + "service": "Appliance Recovery", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/recovery/backup", + "service": "Appliance Recovery Backup", + "sample_action": "validate", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/recovery/backup/job", + "service": "Appliance Recovery Backup Job", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/recovery/backup/job", + "service": "Appliance Recovery Backup Job", + "sample_action": "cancel", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/recovery/backup/job/details", + "service": "Appliance Recovery Backup Job Details", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/recovery/backup/parts", + "service": "Appliance Recovery Backup Parts", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/appliance/recovery/backup/schedules", + "service": "Appliance Recovery Backup Schedules", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/recovery/backup/schedules", + "service": "Appliance Recovery Backup Schedules", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/appliance/recovery/backup/schedules", + "service": "Appliance Recovery Backup Schedules", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/recovery/backup/schedules", + "service": "Appliance Recovery Backup Schedules", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/recovery/backup/system-name", + "service": "Appliance Recovery Backup SystemName", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/recovery/backup/system-name/archive", + "service": "Appliance Recovery Backup SystemName Archive", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/recovery/reconciliation/job", + "service": "Appliance Recovery Reconciliation Job", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/recovery/reconciliation/job", + "service": "Appliance Recovery Reconciliation Job", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/recovery/restore", + "service": "Appliance Recovery Restore", + "sample_action": "validate", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/recovery/restore/job", + "service": "Appliance Recovery Restore Job", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/recovery/restore/job", + "service": "Appliance Recovery Restore Job", + "sample_action": "cancel", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/services", + "service": "Appliance Services", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/services", + "service": "Appliance Services", + "sample_action": "start", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/services/{service}", + "service": "Appliance Services", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/shutdown", + "service": "Appliance Shutdown", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/shutdown", + "service": "Appliance Shutdown", + "sample_action": "cancel", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/appliance/support-bundle", + "service": "Appliance SupportBundle", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/support-bundle", + "service": "Appliance SupportBundle", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/support-bundle", + "service": "Appliance SupportBundle", + "sample_action": "create$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/support-bundle/components", + "service": "Appliance SupportBundle Components", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/system/crypto-hash", + "service": "Appliance System CryptoHash", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/system/crypto-hash/options", + "service": "Appliance System CryptoHash Options", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/system/security/global-fips", + "service": "Appliance System Security GlobalFips", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/system/security/global-fips", + "service": "Appliance System Security GlobalFips", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/system/storage", + "service": "Appliance System Storage", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/system/storage", + "service": "Appliance System Storage", + "sample_action": "resize", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/system/time", + "service": "Appliance System Time", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/system/time/timezone", + "service": "Appliance System Time Timezone", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/system/time/timezone", + "service": "Appliance System Time Timezone", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/system/uptime", + "service": "Appliance System Uptime", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/system/version", + "service": "Appliance System Version", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/timesync", + "service": "Appliance Timesync", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/timesync", + "service": "Appliance Timesync", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/tls/manual-parameters/global", + "service": "Appliance Tls ManualParameters Global", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/tls/manual-parameters/global", + "service": "Appliance Tls ManualParameters Global", + "sample_action": "set$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/tls/manual-parameters/services", + "service": "Appliance Tls ManualParameters Services", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/appliance/tls/manual-parameters/services/{service}", + "service": "Appliance Tls ManualParameters Services", + "sample_action": "delete$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/tls/manual-parameters/services/{service}", + "service": "Appliance Tls ManualParameters Services", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/tls/manual-parameters/services/{service}", + "service": "Appliance Tls ManualParameters Services", + "sample_action": "set$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/tls/profiles", + "service": "Appliance Tls Profiles", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/tls/profiles/{profile}", + "service": "Appliance Tls Profiles", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/tls/profiles/{profile}/global", + "service": "Appliance Tls Profiles Global", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/tls/profiles/{profile}/global", + "service": "Appliance Tls Profiles Global", + "sample_action": "set$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/update", + "service": "Appliance Update", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/update", + "service": "Appliance Update", + "sample_action": "cancel", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/update/pending", + "service": "Appliance Update Pending", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/update/pending", + "service": "Appliance Update Pending", + "sample_action": "precheck", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/update/policy", + "service": "Appliance Update Policy", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/update/policy", + "service": "Appliance Update Policy", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/appliance/update/staged", + "service": "Appliance Update Staged", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/update/staged", + "service": "Appliance Update Staged", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/cis/tagging/category", + "service": "Cis Tagging Category", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/cis/tagging/category", + "service": "Cis Tagging Category", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/cis/tagging/category/{category_id}", + "service": "Cis Tagging Category", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/cis/tagging/category/{category_id}", + "service": "Cis Tagging Category", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/cis/tagging/category/{category_id}", + "service": "Cis Tagging Category", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/cis/tagging/tag", + "service": "Cis Tagging Tag", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/cis/tagging/tag", + "service": "Cis Tagging Tag", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/cis/tagging/tag-association", + "service": "Cis Tagging TagAssociation", + "sample_action": "attach", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/cis/tagging/tag/{tag_id}", + "service": "Cis Tagging Tag", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/cis/tagging/tag/{tag_id}", + "service": "Cis Tagging Tag", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/cis/tagging/tag/{tag_id}", + "service": "Cis Tagging Tag", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/cis/tasks", + "service": "Cis Tasks", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/cis/tasks/{task}", + "service": "Cis Tasks", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/configuration", + "service": "Content Configuration", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/content/configuration", + "service": "Content Configuration", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library", + "service": "Content Library", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library", + "service": "Content Library", + "sample_action": "find", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/library/{library_id}", + "service": "Content Library", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}", + "service": "Content Library", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/content/library/{library_id}", + "service": "Content Library", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}", + "service": "Content Library", + "sample_action": "forceDelete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item", + "service": "Content Library Item", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}/item", + "service": "Content Library Item", + "sample_action": "copy", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/library/{library_id}/item/{item_id}", + "service": "Content Library Item", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}", + "service": "Content Library Item", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/content/library/{library_id}/item/{item_id}", + "service": "Content Library Item", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/changes", + "service": "Content Library Item Changes", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/download-session", + "service": "Content Library Item DownloadSession", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}/item/{item_id}/download-session", + "service": "Content Library Item DownloadSession", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/library/{library_id}/item/{item_id}/download-session/{download_session_id}", + "service": "Content Library Item DownloadSession", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/download-session/{download_session_id}", + "service": "Content Library Item DownloadSession", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/downloadsession/file", + "service": "Content Library Item Downloadsession File", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}/item/{item_id}/downloadsession/file", + "service": "Content Library Item Downloadsession File", + "sample_action": "prepare", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/file", + "service": "Content Library Item File", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/storage", + "service": "Content Library Item Storage", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/update-session", + "service": "Content Library Item UpdateSession", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}/item/{item_id}/update-session", + "service": "Content Library Item UpdateSession", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/library/{library_id}/item/{item_id}/update-session/{update_session_id}", + "service": "Content Library Item UpdateSession", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/update-session/{update_session_id}", + "service": "Content Library Item UpdateSession", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/content/library/{library_id}/item/{item_id}/update-session/{update_session_id}", + "service": "Content Library Item UpdateSession", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/library/{library_id}/item/{item_id}/updatesession/file", + "service": "Content Library Item Updatesession File", + "sample_action": "remove", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/updatesession/file", + "service": "Content Library Item Updatesession File", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}/item/{item_id}/updatesession/file", + "service": "Content Library Item Updatesession File", + "sample_action": "validate", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}/subscribed-item", + "service": "Content Library SubscribedItem", + "sample_action": "evict", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/subscriptions", + "service": "Content Library Subscriptions", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}/subscriptions", + "service": "Content Library Subscriptions", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/library/{library_id}/subscriptions/{subscription_id}", + "service": "Content Library Subscriptions", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/subscriptions/{subscription_id}", + "service": "Content Library Subscriptions", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/content/library/{library_id}/subscriptions/{subscription_id}", + "service": "Content Library Subscriptions", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/usages", + "service": "Content Library Usages", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}/usages", + "service": "Content Library Usages", + "sample_action": "add", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/library/{library_id}/usages/{usage_id}", + "service": "Content Library Usages", + "sample_action": "remove", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/usages/{usage_id}", + "service": "Content Library Usages", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/local-library", + "service": "Content LocalLibrary", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/local-library", + "service": "Content LocalLibrary", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/local-library/{library_id}", + "service": "Content LocalLibrary", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/local-library/{library_id}", + "service": "Content LocalLibrary", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/content/local-library/{library_id}", + "service": "Content LocalLibrary", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/local-library/{library_id}", + "service": "Content LocalLibrary", + "sample_action": "forceDelete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/security-policies", + "service": "Content SecurityPolicies", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/subscribed-library", + "service": "Content SubscribedLibrary", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/subscribed-library", + "service": "Content SubscribedLibrary", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/subscribed-library/{library_id}", + "service": "Content SubscribedLibrary", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/subscribed-library/{library_id}", + "service": "Content SubscribedLibrary", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/content/subscribed-library/{library_id}", + "service": "Content SubscribedLibrary", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/subscribed-library/{library_id}", + "service": "Content SubscribedLibrary", + "sample_action": "forceDelete", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/trusted-certificates", + "service": "Content TrustedCertificates", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/trusted-certificates", + "service": "Content TrustedCertificates", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/trusted-certificates", + "service": "Content TrustedCertificates", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/type", + "service": "Content Type", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/hcl/compatibility-data", + "service": "Esx Hcl CompatibilityData", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/hcl/compatibility-data", + "service": "Esx Hcl CompatibilityData", + "sample_action": "update$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/hcl/hosts/{host}/compatibility-releases", + "service": "Esx Hcl Hosts CompatibilityReleases", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/hcl/hosts/{host}/compatibility-report", + "service": "Esx Hcl Hosts CompatibilityReport", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/hcl/hosts/{host}/compatibility-report", + "service": "Esx Hcl Hosts CompatibilityReport", + "sample_action": "create$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/hcl/reports", + "service": "Esx Hcl Reports", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/hosts/{host}/software", + "service": "Esx Hosts Software", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/hosts/{host}/software/installed-components", + "service": "Esx Hosts Software InstalledComponents", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration", + "service": "Esx Settings Clusters Configuration", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/configuration", + "service": "Esx Settings Clusters Configuration", + "sample_action": "exportConfig", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration/audit-records", + "service": "Esx Settings Clusters Configuration AuditRecords", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration/drafts", + "service": "Esx Settings Clusters Configuration Drafts", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/configuration/drafts", + "service": "Esx Settings Clusters Configuration Drafts", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/configuration/drafts/{draft}", + "service": "Esx Settings Clusters Configuration Drafts", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration/drafts/{draft}", + "service": "Esx Settings Clusters Configuration Drafts", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/configuration/drafts/{draft}", + "service": "Esx Settings Clusters Configuration Drafts", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration/reports/last-apply-result", + "service": "Esx Settings Clusters Configuration Reports LastApplyResult", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration/reports/last-compliance-result", + "service": "Esx Settings Clusters Configuration Reports LastComplianceResult", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration/reports/last-precheck-result", + "service": "Esx Settings Clusters Configuration Reports LastPrecheckResult", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration/reports/recent-tasks", + "service": "Esx Settings Clusters Configuration Reports RecentTasks", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration/schema", + "service": "Esx Settings Clusters Configuration Schema", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/depot-overrides", + "service": "Esx Settings Clusters DepotOverrides", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/depot-overrides", + "service": "Esx Settings Clusters DepotOverrides", + "sample_action": "add", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/enablement/configuration", + "service": "Esx Settings Clusters Enablement Configuration", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/enablement/configuration/transition", + "service": "Esx Settings Clusters Enablement Configuration Transition", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/enablement/configuration/transition", + "service": "Esx Settings Clusters Enablement Configuration Transition", + "sample_action": "cancel", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/enablement/software", + "service": "Esx Settings Clusters Enablement Software", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/enablement/software", + "service": "Esx Settings Clusters Enablement Software", + "sample_action": "check$Task", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/enablement/software", + "service": "Esx Settings Clusters Enablement Software", + "sample_action": "enable$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/installed-images", + "service": "Esx Settings Clusters InstalledImages", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/installed-images", + "service": "Esx Settings Clusters InstalledImages", + "sample_action": "extract$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/policies/{policy}/apply", + "service": "Esx Settings Clusters Policies Apply", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/policies/{policy}/apply", + "service": "Esx Settings Clusters Policies Apply", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/policies/{policy}/apply/effective", + "service": "Esx Settings Clusters Policies Apply Effective", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software", + "service": "Esx Settings Clusters Software", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/software", + "service": "Esx Settings Clusters Software", + "sample_action": "export", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/add-on", + "service": "Esx Settings Clusters Software AddOn", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images", + "service": "Esx Settings Clusters Software AlternativeImages", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/display-name", + "service": "Esx Settings Clusters Software AlternativeImages DisplayName", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/selection-criteria", + "service": "Esx Settings Clusters Software AlternativeImages SelectionCriteria", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software", + "service": "Esx Settings Clusters Software AlternativeImages Software", + "sample_action": "export", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software/add-on", + "service": "Esx Settings Clusters Software AlternativeImages Software AddOn", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software/base-image", + "service": "Esx Settings Clusters Software AlternativeImages Software BaseImage", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software/components", + "service": "Esx Settings Clusters Software AlternativeImages Software Components", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software/components/{component}", + "service": "Esx Settings Clusters Software AlternativeImages Software Components", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software/effective-components", + "service": "Esx Settings Clusters Software AlternativeImages Software EffectiveComponents", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software/hardware-support", + "service": "Esx Settings Clusters Software AlternativeImages Software HardwareSupport", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software/removed-components", + "service": "Esx Settings Clusters Software AlternativeImages Software RemovedComponents", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software/solutions", + "service": "Esx Settings Clusters Software AlternativeImages Software Solutions", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/base-image", + "service": "Esx Settings Clusters Software BaseImage", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/commits", + "service": "Esx Settings Clusters Software Commits", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/compliance", + "service": "Esx Settings Clusters Software Compliance", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/components", + "service": "Esx Settings Clusters Software Components", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/components/{component}", + "service": "Esx Settings Clusters Software Components", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts", + "service": "Esx Settings Clusters Software Drafts", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts", + "service": "Esx Settings Clusters Software Drafts", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}", + "service": "Esx Settings Clusters Software Drafts", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}", + "service": "Esx Settings Clusters Software Drafts", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/display-name", + "service": "Esx Settings Clusters Software Drafts DisplayName", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/display-name", + "service": "Esx Settings Clusters Software Drafts DisplayName", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/add-on", + "service": "Esx Settings Clusters Software Drafts Software AddOn", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/add-on", + "service": "Esx Settings Clusters Software Drafts Software AddOn", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/add-on", + "service": "Esx Settings Clusters Software Drafts Software AddOn", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/display-name", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages DisplayName", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/display-name", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages DisplayName", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/selection-criteria", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages SelectionCriteria", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/selection-criteria", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages SelectionCriteria", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/add-on", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages Software AddOn", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/add-on", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages Software AddOn", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/add-on", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages Software AddOn", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/base-image", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages Software BaseImage", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/components", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages Software Components", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/components/{component}", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages Software Components", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/components/{component}", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages Software Components", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/components/{component}", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages Software Components", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/components/{component}", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages Software Components", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/effective-components", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages Software EffectiveComponents", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/hardware-support", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages Software HardwareSupport", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/hardware-support", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages Software HardwareSupport", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/hardware-support", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages Software HardwareSupport", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/removed-components", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages Software RemovedComponents", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/removed-components", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages Software RemovedComponents", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/removed-components", + "service": "Esx Settings Clusters Software Drafts Software AlternativeImages Software RemovedComponents", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/base-image", + "service": "Esx Settings Clusters Software Drafts Software BaseImage", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/base-image", + "service": "Esx Settings Clusters Software Drafts Software BaseImage", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/components", + "service": "Esx Settings Clusters Software Drafts Software Components", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/components/{component}", + "service": "Esx Settings Clusters Software Drafts Software Components", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/components/{component}", + "service": "Esx Settings Clusters Software Drafts Software Components", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/components/{component}", + "service": "Esx Settings Clusters Software Drafts Software Components", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/components/{component}", + "service": "Esx Settings Clusters Software Drafts Software Components", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/effective-components", + "service": "Esx Settings Clusters Software Drafts Software EffectiveComponents", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/hardware-support", + "service": "Esx Settings Clusters Software Drafts Software HardwareSupport", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/hardware-support", + "service": "Esx Settings Clusters Software Drafts Software HardwareSupport", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/hardware-support", + "service": "Esx Settings Clusters Software Drafts Software HardwareSupport", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/removed-components", + "service": "Esx Settings Clusters Software Drafts Software RemovedComponents", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/removed-components", + "service": "Esx Settings Clusters Software Drafts Software RemovedComponents", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/removed-components", + "service": "Esx Settings Clusters Software Drafts Software RemovedComponents", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/effective-components", + "service": "Esx Settings Clusters Software EffectiveComponents", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/hardware-support", + "service": "Esx Settings Clusters Software HardwareSupport", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/recommendations", + "service": "Esx Settings Clusters Software Recommendations", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/software/recommendations", + "service": "Esx Settings Clusters Software Recommendations", + "sample_action": "generate$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/removed-components", + "service": "Esx Settings Clusters Software RemovedComponents", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/apply-impact", + "service": "Esx Settings Clusters Software Reports ApplyImpact", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/hardware-compatibility", + "service": "Esx Settings Clusters Software Reports HardwareCompatibility", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/hardware-compatibility", + "service": "Esx Settings Clusters Software Reports HardwareCompatibility", + "sample_action": "check$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/hardware-compatibility/details", + "service": "Esx Settings Clusters Software Reports HardwareCompatibility Details", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/hardware-compatibility/pci-device-overrides/vcg-entries", + "service": "Esx Settings Clusters Software Reports HardwareCompatibility PciDeviceOverrides VcgEntries", + "sample_action": "update$Task", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/hardware-compatibility/storage-device-overrides/compliance-status", + "service": "Esx Settings Clusters Software Reports HardwareCompatibility StorageDeviceOverrides ComplianceStatus", + "sample_action": "update$Task", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/hardware-compatibility/storage-device-overrides/vcg-entries", + "service": "Esx Settings Clusters Software Reports HardwareCompatibility StorageDeviceOverrides VcgEntries", + "sample_action": "update$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/last-apply-result", + "service": "Esx Settings Clusters Software Reports LastApplyResult", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/last-check-result", + "service": "Esx Settings Clusters Software Reports LastCheckResult", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/software-spec-metadata", + "service": "Esx Settings Clusters Software SoftwareSpecMetadata", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/solutions", + "service": "Esx Settings Clusters Software Solutions", + "sample_action": "delete$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/solutions", + "service": "Esx Settings Clusters Software Solutions", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/clusters/{cluster}/software/solutions", + "service": "Esx Settings Clusters Software Solutions", + "sample_action": "update$Task", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/solutions", + "service": "Esx Settings Clusters Software Solutions", + "sample_action": "set$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/vms/lifecycle-hooks", + "service": "Esx Settings Clusters Vms LifecycleHooks", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/vms/lifecycle-hooks", + "service": "Esx Settings Clusters Vms LifecycleHooks", + "sample_action": "markAsProcessed", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/vms/solutions", + "service": "Esx Settings Clusters Vms Solutions", + "sample_action": "delete$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/vms/solutions", + "service": "Esx Settings Clusters Vms Solutions", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/vms/solutions", + "service": "Esx Settings Clusters Vms Solutions", + "sample_action": "apply$Task", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/vms/solutions", + "service": "Esx Settings Clusters Vms Solutions", + "sample_action": "set$Task", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/vms/transition", + "service": "Esx Settings Clusters Vms Transition", + "sample_action": "enable$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/defaults/clusters/{cluster}/policies/{policy}/apply", + "service": "Esx Settings Defaults Clusters Policies Apply", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/defaults/clusters/{cluster}/policies/{policy}/apply", + "service": "Esx Settings Defaults Clusters Policies Apply", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/defaults/clusters/{cluster}/policies/{policy}/apply/effective", + "service": "Esx Settings Defaults Clusters Policies Apply Effective", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/defaults/hosts/{host}/policies/{policy}/apply", + "service": "Esx Settings Defaults Hosts Policies Apply", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/defaults/hosts/{host}/policies/{policy}/apply", + "service": "Esx Settings Defaults Hosts Policies Apply", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/defaults/hosts/{host}/policies/{policy}/apply/effective", + "service": "Esx Settings Defaults Hosts Policies Apply Effective", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depot-content/add-ons", + "service": "Esx Settings DepotContent AddOns", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depot-content/add-ons/versions", + "service": "Esx Settings DepotContent AddOns Versions", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depot-content/base-images", + "service": "Esx Settings DepotContent BaseImages", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depot-content/base-images/versions", + "service": "Esx Settings DepotContent BaseImages Versions", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depot-content/components", + "service": "Esx Settings DepotContent Components", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depot-content/components/{component}/versions", + "service": "Esx Settings DepotContent Components Versions", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/depots", + "service": "Esx Settings Depots", + "sample_action": "sync$Task", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/depots/{depot}/offline", + "service": "Esx Settings Depots Offline", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depots/{depot}/offline", + "service": "Esx Settings Depots Offline", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/depots/{depot}/offline", + "service": "Esx Settings Depots Offline", + "sample_action": "create$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depots/{depot}/offline/content", + "service": "Esx Settings Depots Offline Content", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/depots/{depot}/online", + "service": "Esx Settings Depots Online", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depots/{depot}/online", + "service": "Esx Settings Depots Online", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/depots/{depot}/online", + "service": "Esx Settings Depots Online", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/depots/{depot}/online", + "service": "Esx Settings Depots Online", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depots/{depot}/online/content", + "service": "Esx Settings Depots Online Content", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depots/{depot}/sync-schedule", + "service": "Esx Settings Depots SyncSchedule", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/depots/{depot}/sync-schedule", + "service": "Esx Settings Depots SyncSchedule", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/depots/{depot}/umds", + "service": "Esx Settings Depots Umds", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depots/{depot}/umds", + "service": "Esx Settings Depots Umds", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/depots/{depot}/umds", + "service": "Esx Settings Depots Umds", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/depots/{depot}/umds", + "service": "Esx Settings Depots Umds", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depots/{depot}/umds/content", + "service": "Esx Settings Depots Umds Content", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hardware-support/managers", + "service": "Esx Settings HardwareSupport Managers", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hardware-support/managers/packages", + "service": "Esx Settings HardwareSupport Managers Packages", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hardware-support/managers/packages/versions", + "service": "Esx Settings HardwareSupport Managers Packages Versions", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/hosts/{host}/configuration", + "service": "Esx Settings Hosts Configuration", + "sample_action": "extract", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/depot-overrides", + "service": "Esx Settings Hosts DepotOverrides", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/hosts/{host}/depot-overrides", + "service": "Esx Settings Hosts DepotOverrides", + "sample_action": "add", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/enablement/software", + "service": "Esx Settings Hosts Enablement Software", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/hosts/{host}/enablement/software", + "service": "Esx Settings Hosts Enablement Software", + "sample_action": "check$Task", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/hosts/{host}/enablement/software", + "service": "Esx Settings Hosts Enablement Software", + "sample_action": "enable$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/policies/{policy}/apply", + "service": "Esx Settings Hosts Policies Apply", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/hosts/{host}/policies/{policy}/apply", + "service": "Esx Settings Hosts Policies Apply", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/policies/{policy}/apply/effective", + "service": "Esx Settings Hosts Policies Apply Effective", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software", + "service": "Esx Settings Hosts Software", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/hosts/{host}/software", + "service": "Esx Settings Hosts Software", + "sample_action": "export", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/add-on", + "service": "Esx Settings Hosts Software AddOn", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/base-image", + "service": "Esx Settings Hosts Software BaseImage", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/commits", + "service": "Esx Settings Hosts Software Commits", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/compliance", + "service": "Esx Settings Hosts Software Compliance", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/components", + "service": "Esx Settings Hosts Software Components", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/components/{component}", + "service": "Esx Settings Hosts Software Components", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts", + "service": "Esx Settings Hosts Software Drafts", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/hosts/{host}/software/drafts", + "service": "Esx Settings Hosts Software Drafts", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}", + "service": "Esx Settings Hosts Software Drafts", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}", + "service": "Esx Settings Hosts Software Drafts", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/display-name", + "service": "Esx Settings Hosts Software Drafts DisplayName", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/display-name", + "service": "Esx Settings Hosts Software Drafts DisplayName", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/add-on", + "service": "Esx Settings Hosts Software Drafts Software AddOn", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/add-on", + "service": "Esx Settings Hosts Software Drafts Software AddOn", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/add-on", + "service": "Esx Settings Hosts Software Drafts Software AddOn", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/base-image", + "service": "Esx Settings Hosts Software Drafts Software BaseImage", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/base-image", + "service": "Esx Settings Hosts Software Drafts Software BaseImage", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/components", + "service": "Esx Settings Hosts Software Drafts Software Components", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/components/{component}", + "service": "Esx Settings Hosts Software Drafts Software Components", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/components/{component}", + "service": "Esx Settings Hosts Software Drafts Software Components", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/components/{component}", + "service": "Esx Settings Hosts Software Drafts Software Components", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/components/{component}", + "service": "Esx Settings Hosts Software Drafts Software Components", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/effective-components", + "service": "Esx Settings Hosts Software Drafts Software EffectiveComponents", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/removed-components", + "service": "Esx Settings Hosts Software Drafts Software RemovedComponents", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/removed-components", + "service": "Esx Settings Hosts Software Drafts Software RemovedComponents", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/removed-components", + "service": "Esx Settings Hosts Software Drafts Software RemovedComponents", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/effective-components", + "service": "Esx Settings Hosts Software EffectiveComponents", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/recommendations", + "service": "Esx Settings Hosts Software Recommendations", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/hosts/{host}/software/recommendations", + "service": "Esx Settings Hosts Software Recommendations", + "sample_action": "generate$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/removed-components", + "service": "Esx Settings Hosts Software RemovedComponents", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/reports/apply-impact", + "service": "Esx Settings Hosts Software Reports ApplyImpact", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/reports/last-apply-result", + "service": "Esx Settings Hosts Software Reports LastApplyResult", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/reports/last-check-result", + "service": "Esx Settings Hosts Software Reports LastCheckResult", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/software-spec-metadata", + "service": "Esx Settings Hosts Software SoftwareSpecMetadata", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/hosts/{host}/software/solutions", + "service": "Esx Settings Hosts Software Solutions", + "sample_action": "delete$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/solutions", + "service": "Esx Settings Hosts Software Solutions", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/hosts/{host}/software/solutions", + "service": "Esx Settings Hosts Software Solutions", + "sample_action": "set$Task", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/inventory", + "service": "Esx Settings Inventory", + "sample_action": "apply$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/inventory/reports/summary/clusters", + "service": "Esx Settings Inventory Reports Summary Clusters", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/inventory/reports/summary/hosts", + "service": "Esx Settings Inventory Reports Summary Hosts", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/inventory/reports/transition-summary/clusters", + "service": "Esx Settings Inventory Reports TransitionSummary Clusters", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/inventory/reports/transition-summary/hosts", + "service": "Esx Settings Inventory Reports TransitionSummary Hosts", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software", + "service": "Esx Settings Repository Software", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software", + "service": "Esx Settings Repository Software", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/repository/software", + "service": "Esx Settings Repository Software", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/repository/software", + "service": "Esx Settings Repository Software", + "sample_action": "export", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/alternative-images/effective-components", + "service": "Esx Settings Repository Software AlternativeImages EffectiveComponents", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts", + "service": "Esx Settings Repository Software Drafts", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/repository/software/drafts", + "service": "Esx Settings Repository Software Drafts", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}", + "service": "Esx Settings Repository Software Drafts", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}", + "service": "Esx Settings Repository Software Drafts", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/add-on", + "service": "Esx Settings Repository Software Drafts AddOn", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/add-on", + "service": "Esx Settings Repository Software Drafts AddOn", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/add-on", + "service": "Esx Settings Repository Software Drafts AddOn", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images", + "service": "Esx Settings Repository Software Drafts AlternativeImages", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images", + "service": "Esx Settings Repository Software Drafts AlternativeImages", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images", + "service": "Esx Settings Repository Software Drafts AlternativeImages", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/add-on", + "service": "Esx Settings Repository Software Drafts AlternativeImages AddOn", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/add-on", + "service": "Esx Settings Repository Software Drafts AlternativeImages AddOn", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/add-on", + "service": "Esx Settings Repository Software Drafts AlternativeImages AddOn", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/base-image", + "service": "Esx Settings Repository Software Drafts AlternativeImages BaseImage", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/components", + "service": "Esx Settings Repository Software Drafts AlternativeImages Components", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/components/{component}", + "service": "Esx Settings Repository Software Drafts AlternativeImages Components", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/components/{component}", + "service": "Esx Settings Repository Software Drafts AlternativeImages Components", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/components/{component}", + "service": "Esx Settings Repository Software Drafts AlternativeImages Components", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/components/{component}", + "service": "Esx Settings Repository Software Drafts AlternativeImages Components", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/display-name", + "service": "Esx Settings Repository Software Drafts AlternativeImages DisplayName", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/display-name", + "service": "Esx Settings Repository Software Drafts AlternativeImages DisplayName", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/effective-components", + "service": "Esx Settings Repository Software Drafts AlternativeImages EffectiveComponents", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/hardware-support", + "service": "Esx Settings Repository Software Drafts AlternativeImages HardwareSupport", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/hardware-support", + "service": "Esx Settings Repository Software Drafts AlternativeImages HardwareSupport", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/hardware-support", + "service": "Esx Settings Repository Software Drafts AlternativeImages HardwareSupport", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/removed-components", + "service": "Esx Settings Repository Software Drafts AlternativeImages RemovedComponents", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/removed-components", + "service": "Esx Settings Repository Software Drafts AlternativeImages RemovedComponents", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/removed-components", + "service": "Esx Settings Repository Software Drafts AlternativeImages RemovedComponents", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/selection-criteria", + "service": "Esx Settings Repository Software Drafts AlternativeImages SelectionCriteria", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/selection-criteria", + "service": "Esx Settings Repository Software Drafts AlternativeImages SelectionCriteria", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/base-image", + "service": "Esx Settings Repository Software Drafts BaseImage", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/base-image", + "service": "Esx Settings Repository Software Drafts BaseImage", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/components", + "service": "Esx Settings Repository Software Drafts Components", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/components/{component}", + "service": "Esx Settings Repository Software Drafts Components", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/components/{component}", + "service": "Esx Settings Repository Software Drafts Components", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/repository/software/drafts/{draft}/components/{component}", + "service": "Esx Settings Repository Software Drafts Components", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/components/{component}", + "service": "Esx Settings Repository Software Drafts Components", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/display-name", + "service": "Esx Settings Repository Software Drafts DisplayName", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/display-name", + "service": "Esx Settings Repository Software Drafts DisplayName", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/effective-components", + "service": "Esx Settings Repository Software Drafts EffectiveComponents", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/hardware-support", + "service": "Esx Settings Repository Software Drafts HardwareSupport", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/hardware-support", + "service": "Esx Settings Repository Software Drafts HardwareSupport", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/hardware-support", + "service": "Esx Settings Repository Software Drafts HardwareSupport", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/removed-components", + "service": "Esx Settings Repository Software Drafts RemovedComponents", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/removed-components", + "service": "Esx Settings Repository Software Drafts RemovedComponents", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/removed-components", + "service": "Esx Settings Repository Software Drafts RemovedComponents", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/effective-components", + "service": "Esx Settings Repository Software EffectiveComponents", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/session", + "service": "Cis Session", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/session", + "service": "Cis Session", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/session", + "service": "Cis Session", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/authentication/component", + "service": "Vapi Metadata Authentication Component", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/authentication/component/{component}", + "service": "Vapi Metadata Authentication Component", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/authentication/package", + "service": "Vapi Metadata Authentication Package", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/authentication/service", + "service": "Vapi Metadata Authentication Service", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/authentication/service/{service}", + "service": "Vapi Metadata Authentication Service", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/authentication/service/{service}/operation", + "service": "Vapi Metadata Authentication Service Operation", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/cli/command", + "service": "Vapi Metadata Cli Command", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vapi/metadata/cli/command", + "service": "Vapi Metadata Cli Command", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/cli/namespace", + "service": "Vapi Metadata Cli Namespace", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vapi/metadata/cli/namespace/{namespace}", + "service": "Vapi Metadata Cli Namespace", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/component", + "service": "Vapi Metadata Metamodel Component", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/component/{component}", + "service": "Vapi Metadata Metamodel Component", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/enumeration", + "service": "Vapi Metadata Metamodel Enumeration", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/package", + "service": "Vapi Metadata Metamodel Package", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/resource", + "service": "Vapi Metadata Metamodel Resource", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/resource/model", + "service": "Vapi Metadata Metamodel Resource Model", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/service", + "service": "Vapi Metadata Metamodel Service", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/service/{service}", + "service": "Vapi Metadata Metamodel Service", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/service/{service}/operation", + "service": "Vapi Metadata Metamodel Service Operation", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/structure", + "service": "Vapi Metadata Metamodel Structure", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/privilege/component", + "service": "Vapi Metadata Privilege Component", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/privilege/component/{component}", + "service": "Vapi Metadata Privilege Component", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/privilege/package", + "service": "Vapi Metadata Privilege Package", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/privilege/service", + "service": "Vapi Metadata Privilege Service", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/privilege/service/{service}", + "service": "Vapi Metadata Privilege Service", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/privilege/service/{service}/operation", + "service": "Vapi Metadata Privilege Service Operation", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/authentication/token", + "service": "Vcenter Authentication Token", + "sample_action": "issue", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/authorization/permissions", + "service": "Vcenter Authorization Permissions", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/authorization/permissions/{permission_id}", + "service": "Vcenter Authorization Permissions", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/authorization/permissions/{permission_id}", + "service": "Vcenter Authorization Permissions", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/authorization/permissions/{permission_id}", + "service": "Vcenter Authorization Permissions", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/authorization/privilege-checks", + "service": "Vcenter Authorization PrivilegeChecks", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/authorization/privilege-checks/latest", + "service": "Vcenter Authorization PrivilegeChecks Latest", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/authorization/roles", + "service": "Vcenter Authorization Roles", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/authorization/roles", + "service": "Vcenter Authorization Roles", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/authorization/roles/{role}", + "service": "Vcenter Authorization Roles", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/authorization/roles/{role}", + "service": "Vcenter Authorization Roles", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/authorization/roles/{role}", + "service": "Vcenter Authorization Roles", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/authorization/vt-containers/mappings", + "service": "Vcenter Authorization VtContainers Mappings", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/authorization/vt-containers/mappings", + "service": "Vcenter Authorization VtContainers Mappings", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/authorization/vt-containers/mappings", + "service": "Vcenter Authorization VtContainers Mappings", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/capacity/usage", + "service": "Vcenter Capacity Usage", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/certificate-management/vcenter/signing-certificate", + "service": "Vcenter CertificateManagement Vcenter SigningCertificate", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/certificate-management/vcenter/signing-certificate", + "service": "Vcenter CertificateManagement Vcenter SigningCertificate", + "sample_action": "refresh", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/certificate-management/vcenter/signing-certificate", + "service": "Vcenter CertificateManagement Vcenter SigningCertificate", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/certificate-management/vcenter/tls", + "service": "Vcenter CertificateManagement Vcenter Tls", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/certificate-management/vcenter/tls", + "service": "Vcenter CertificateManagement Vcenter Tls", + "sample_action": "renew", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/certificate-management/vcenter/tls", + "service": "Vcenter CertificateManagement Vcenter Tls", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/certificate-management/vcenter/tls-csr", + "service": "Vcenter CertificateManagement Vcenter TlsCsr", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/certificate-management/vcenter/trusted-root-chains", + "service": "Vcenter CertificateManagement Vcenter TrustedRootChains", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/certificate-management/vcenter/trusted-root-chains", + "service": "Vcenter CertificateManagement Vcenter TrustedRootChains", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/certificate-management/vcenter/trusted-root-chains/{chain}", + "service": "Vcenter CertificateManagement Vcenter TrustedRootChains", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/certificate-management/vcenter/trusted-root-chains/{chain}", + "service": "Vcenter CertificateManagement Vcenter TrustedRootChains", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/certificate-management/vcenter/vmca-root", + "service": "Vcenter CertificateManagement Vcenter VmcaRoot", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/cluster", + "service": "Vcenter Cluster", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/cluster/{cluster}", + "service": "Vcenter Cluster", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/cluster/{cluster}/evc-mode", + "service": "Vcenter Cluster EvcMode", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/cluster/{cluster}/evc-mode", + "service": "Vcenter Cluster EvcMode", + "sample_action": "checkSet$Task", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/cluster/{cluster}/evc-mode", + "service": "Vcenter Cluster EvcMode", + "sample_action": "set$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/compute/policies", + "service": "Vcenter Compute Policies", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/compute/policies", + "service": "Vcenter Compute Policies", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/compute/policies/{policy}", + "service": "Vcenter Compute Policies", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/compute/policies/{policy}", + "service": "Vcenter Compute Policies", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/compute/policies/{policy}", + "service": "Vcenter Compute Policies", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/compute/policies/{policy}/capabilities", + "service": "Vcenter Compute Policies Capabilities", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/compute/policies/{policy}/tag-usage", + "service": "Vcenter Compute Policies TagUsage", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/confidential-computing/sgx/hosts", + "service": "Vcenter ConfidentialComputing Sgx Hosts", + "sample_action": "register$Task", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/consumption-domains/zone-associations/association-changes", + "service": "Vcenter ConsumptionDomains ZoneAssociations AssociationChanges", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/consumption-domains/zone-associations/cluster", + "service": "Vcenter ConsumptionDomains ZoneAssociations Cluster", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/consumption-domains/zones", + "service": "Vcenter ConsumptionDomains Zones", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/consumption-domains/zones", + "service": "Vcenter ConsumptionDomains Zones", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/consumption-domains/zones/{zone}", + "service": "Vcenter ConsumptionDomains Zones", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/consumption-domains/zones/{zone}", + "service": "Vcenter ConsumptionDomains Zones", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/consumption-domains/zones/{zone}/capacity/summary", + "service": "Vcenter ConsumptionDomains Zones Capacity Summary", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/consumption-domains/zones/{zone}/capacity/summary", + "service": "Vcenter ConsumptionDomains Zones Capacity Summary", + "sample_action": "getPerCluster", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/consumption-domains/zones/{zone}/cluster/{cluster}/associations", + "service": "Vcenter ConsumptionDomains Zones Cluster Associations", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/consumption-domains/zones/{zone}/cluster/{cluster}/associations", + "service": "Vcenter ConsumptionDomains Zones Cluster Associations", + "sample_action": "add", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/content/registries/harbor", + "service": "Vcenter Content Registries Harbor", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/content/registries/harbor", + "service": "Vcenter Content Registries Harbor", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/content/registries/harbor", + "service": "Vcenter Content Registries Harbor", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/content/registries/harbor/projects", + "service": "Vcenter Content Registries Harbor Projects", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/content/registries/harbor/projects", + "service": "Vcenter Content Registries Harbor Projects", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/content/registries/harbor/projects/{project}", + "service": "Vcenter Content Registries Harbor Projects", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/content/registries/harbor/projects/{project}", + "service": "Vcenter Content Registries Harbor Projects", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/content/registries/health", + "service": "Vcenter Content Registries Health", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/crypto-manager/hosts/{host}/kms/providers", + "service": "Vcenter CryptoManager Hosts Kms Providers", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/crypto-manager/hosts/{host}/kms/providers/{provider}", + "service": "Vcenter CryptoManager Hosts Kms Providers", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/crypto-manager/kms/providers", + "service": "Vcenter CryptoManager Kms Providers", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/crypto-manager/kms/providers", + "service": "Vcenter CryptoManager Kms Providers", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/crypto-manager/kms/providers/{provider}", + "service": "Vcenter CryptoManager Kms Providers", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/crypto-manager/kms/providers/{provider}", + "service": "Vcenter CryptoManager Kms Providers", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/crypto-manager/kms/providers/{provider}", + "service": "Vcenter CryptoManager Kms Providers", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/crypto/fips/modules", + "service": "Vcenter Crypto Fips Modules", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/datacenter", + "service": "Vcenter Datacenter", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/datacenter", + "service": "Vcenter Datacenter", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/datacenter/{datacenter}", + "service": "Vcenter Datacenter", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/datacenter/{datacenter}", + "service": "Vcenter Datacenter", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/datastore", + "service": "Vcenter Datastore", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/datastore/{datastore}", + "service": "Vcenter Datastore", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/datastore/{datastore}/default-policy", + "service": "Vcenter Datastore DefaultPolicy", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment", + "service": "Vcenter Deployment", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment", + "service": "Vcenter Deployment", + "sample_action": "rollback", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment/import-history", + "service": "Vcenter Deployment ImportHistory", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/import-history", + "service": "Vcenter Deployment ImportHistory", + "sample_action": "start", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment/install", + "service": "Vcenter Deployment Install", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/install", + "service": "Vcenter Deployment Install", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment/install/initial-config/remote-psc/thumbprint", + "service": "Vcenter Deployment Install InitialConfig RemotePsc Thumbprint", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/install/psc/replicated", + "service": "Vcenter Deployment Install Psc Replicated", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/install/psc/standalone", + "service": "Vcenter Deployment Install Psc Standalone", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/install/remote-psc", + "service": "Vcenter Deployment Install RemotePsc", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment/migrate", + "service": "Vcenter Deployment Migrate", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/migrate", + "service": "Vcenter Deployment Migrate", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/migrate/active-directory", + "service": "Vcenter Deployment Migrate ActiveDirectory", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment/question", + "service": "Vcenter Deployment Question", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/question", + "service": "Vcenter Deployment Question", + "sample_action": "answer", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment/size", + "service": "Vcenter Deployment Size", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/deployment/size", + "service": "Vcenter Deployment Size", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment/size/status", + "service": "Vcenter Deployment Size Status", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment/upgrade", + "service": "Vcenter Deployment Upgrade", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/upgrade", + "service": "Vcenter Deployment Upgrade", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/environment-browser/config-option-descriptors", + "service": "Vcenter EnvironmentBrowser ConfigOptionDescriptors", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/environment-browser/config-options", + "service": "Vcenter EnvironmentBrowser ConfigOptions", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/environment-browser/config-targets", + "service": "Vcenter EnvironmentBrowser ConfigTargets", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/evc-modes", + "service": "Vcenter EvcModes", + "sample_action": "partition", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/folder", + "service": "Vcenter Folder", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/foundation-load-balancers", + "service": "Vcenter FoundationLoadBalancers", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/foundation-load-balancers", + "service": "Vcenter FoundationLoadBalancers", + "sample_action": "resetPassword", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/foundation-load-balancers/nodes", + "service": "Vcenter FoundationLoadBalancers Nodes", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/foundation-load-balancers/nodes", + "service": "Vcenter FoundationLoadBalancers Nodes", + "sample_action": "enterMaintenanceMode", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/foundation-load-balancers/nodes/{node}", + "service": "Vcenter FoundationLoadBalancers Nodes", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/guest/customization-specs", + "service": "Vcenter Guest CustomizationSpecs", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/guest/customization-specs", + "service": "Vcenter Guest CustomizationSpecs", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/guest/customization-specs", + "service": "Vcenter Guest CustomizationSpecs", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/guest/customization-specs", + "service": "Vcenter Guest CustomizationSpecs", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/host", + "service": "Vcenter Host", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/host", + "service": "Vcenter Host", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/host/{host}", + "service": "Vcenter Host", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/host/{host}/crypto/fips/modules", + "service": "Vcenter Host Crypto Fips Modules", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/host/{host}/entropy/external-pool", + "service": "Vcenter Host Entropy ExternalPool", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/host/{host}/entropy/external-pool", + "service": "Vcenter Host Entropy ExternalPool", + "sample_action": "add", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/host/{host}/hardware/direct-path-devices", + "service": "Vcenter Host Hardware DirectPathDevices", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/host/{host}/hardware/direct-path-devices", + "service": "Vcenter Host Hardware DirectPathDevices", + "sample_action": "configure$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/identity/broker/tenants/admin-client", + "service": "Vcenter Identity Broker Tenants AdminClient", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/identity/broker/tenants/operator-client", + "service": "Vcenter Identity Broker Tenants OperatorClient", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/identity/providers", + "service": "Vcenter Identity Providers", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/identity/providers", + "service": "Vcenter Identity Providers", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/identity/providers/{provider}", + "service": "Vcenter Identity Providers", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/identity/providers/{provider}", + "service": "Vcenter Identity Providers", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/identity/providers/{provider}", + "service": "Vcenter Identity Providers", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/inventory/datastore", + "service": "Vcenter Inventory Datastore", + "sample_action": "find", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/inventory/network", + "service": "Vcenter Inventory Network", + "sample_action": "find", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/iso/image", + "service": "Vcenter Iso Image", + "sample_action": "mount", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/deployment/migration-upgrade", + "service": "Vcenter Lcm Deployment MigrationUpgrade", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/lcm/deployment/migration-upgrade", + "service": "Vcenter Lcm Deployment MigrationUpgrade", + "sample_action": "apply", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/lcm/deployment/migration-upgrade", + "service": "Vcenter Lcm Deployment MigrationUpgrade", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/deployment/migration-upgrade/planned-downtime", + "service": "Vcenter Lcm Deployment MigrationUpgrade PlannedDowntime", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/deployment/migration-upgrade/status", + "service": "Vcenter Lcm Deployment MigrationUpgrade Status", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/deployment/repository", + "service": "Vcenter Lcm Deployment Repository", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/lcm/deployment/repository", + "service": "Vcenter Lcm Deployment Repository", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/depot/{depot}/services", + "service": "Vcenter Lcm Depot Services", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/lcm/depot/{depot}/services", + "service": "Vcenter Lcm Depot Services", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/lcm/discovery/associated-products", + "service": "Vcenter Lcm Discovery AssociatedProducts", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/discovery/associated-products", + "service": "Vcenter Lcm Discovery AssociatedProducts", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/lcm/discovery/associated-products", + "service": "Vcenter Lcm Discovery AssociatedProducts", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/lcm/discovery/associated-products", + "service": "Vcenter Lcm Discovery AssociatedProducts", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/lcm/discovery/interop-report", + "service": "Vcenter Lcm Discovery InteropReport", + "sample_action": "create$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/discovery/product-catalog", + "service": "Vcenter Lcm Discovery ProductCatalog", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/lcm/interop/interop-bundle", + "service": "Vcenter Lcm Interop InteropBundle", + "sample_action": "set$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/reports", + "service": "Vcenter Lcm Reports", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/update/pending", + "service": "Vcenter Lcm Update Pending", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/lcm/update/precheck-report", + "service": "Vcenter Lcm Update PrecheckReport", + "sample_action": "create$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/cluster-available-versions", + "service": "Vcenter NamespaceManagement ClusterAvailableVersions", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/cluster-compatibility", + "service": "Vcenter NamespaceManagement ClusterCompatibility", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/cluster-size-info", + "service": "Vcenter NamespaceManagement ClusterSizeInfo", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/clusters", + "service": "Vcenter NamespaceManagement Clusters", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/clusters", + "service": "Vcenter NamespaceManagement Clusters", + "sample_action": "enable", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/clusters/{cluster}", + "service": "Vcenter NamespaceManagement Clusters", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/clusters/{cluster}", + "service": "Vcenter NamespaceManagement Clusters", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/clusters/{cluster}", + "service": "Vcenter NamespaceManagement Clusters", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/clusters/{cluster}/topology", + "service": "Vcenter NamespaceManagement Clusters Topology", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/distributed-switch-compatibility", + "service": "Vcenter NamespaceManagement DistributedSwitchCompatibility", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/edge-cluster-compatibility", + "service": "Vcenter NamespaceManagement EdgeClusterCompatibility", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/hosts-config", + "service": "Vcenter NamespaceManagement HostsConfig", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/infrastructure-policies", + "service": "Vcenter NamespaceManagement InfrastructurePolicies", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/infrastructure-policies", + "service": "Vcenter NamespaceManagement InfrastructurePolicies", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/infrastructure-policies", + "service": "Vcenter NamespaceManagement InfrastructurePolicies", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/infrastructure-policies", + "service": "Vcenter NamespaceManagement InfrastructurePolicies", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/lifecycle/content/libraries", + "service": "Vcenter NamespaceManagement Lifecycle Content Libraries", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/lifecycle/content/libraries", + "service": "Vcenter NamespaceManagement Lifecycle Content Libraries", + "sample_action": "unassign", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/lifecycle/content/libraries/{library_id}", + "service": "Vcenter NamespaceManagement Lifecycle Content Libraries", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/lifecycle/content/libraries/{library_id}", + "service": "Vcenter NamespaceManagement Lifecycle Content Libraries", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/load-balancers", + "service": "Vcenter NamespaceManagement LoadBalancers", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/load-balancers", + "service": "Vcenter NamespaceManagement LoadBalancers", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/load-balancers", + "service": "Vcenter NamespaceManagement LoadBalancers", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/namespace-resource-options", + "service": "Vcenter NamespaceManagement NamespaceResourceOptions", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks", + "service": "Vcenter NamespaceManagement Networks", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/networks", + "service": "Vcenter NamespaceManagement Networks", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/networks/{network}", + "service": "Vcenter NamespaceManagement Networks", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks/{network}", + "service": "Vcenter NamespaceManagement Networks", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/networks/{network}", + "service": "Vcenter NamespaceManagement Networks", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/networks/{network}", + "service": "Vcenter NamespaceManagement Networks", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/distributed-switches", + "service": "Vcenter NamespaceManagement Networks Nsx DistributedSwitches", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/distributed-switches/compatibility", + "service": "Vcenter NamespaceManagement Networks Nsx DistributedSwitches Compatibility", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/edges", + "service": "Vcenter NamespaceManagement Networks Nsx Edges", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/edges/compatibility", + "service": "Vcenter NamespaceManagement Networks Nsx Edges Compatibility", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/projects", + "service": "Vcenter NamespaceManagement Networks Nsx Projects", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/projects/{project}", + "service": "Vcenter NamespaceManagement Networks Nsx Projects", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/projects/{project}/compatibility", + "service": "Vcenter NamespaceManagement Networks Nsx Projects Compatibility", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/projects/{project}/vpc-connectivity-profiles", + "service": "Vcenter NamespaceManagement Networks Nsx Projects VpcConnectivityProfiles", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/projects/{project}/vpcconnectivityprofiles/compatibility", + "service": "Vcenter NamespaceManagement Networks Nsx Projects Vpcconnectivityprofiles Compatibility", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/projects/{project}/vpcs", + "service": "Vcenter NamespaceManagement Networks Nsx Projects Vpcs", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/projects/{project}/vpcs/{vpc}", + "service": "Vcenter NamespaceManagement Networks Nsx Projects Vpcs", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/projects/{project}/vpcs/{vpc}/compatibility", + "service": "Vcenter NamespaceManagement Networks Nsx Projects Vpcs Compatibility", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/nsx-tier0-gateway", + "service": "Vcenter NamespaceManagement NSXTier0Gateway", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/software/clusters", + "service": "Vcenter NamespaceManagement Software Clusters", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/software/clusters", + "service": "Vcenter NamespaceManagement Software Clusters", + "sample_action": "upgrade", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/software/clusters/{cluster}", + "service": "Vcenter NamespaceManagement Software Clusters", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/software/supervisors/{supervisor}/prechecks", + "service": "Vcenter NamespaceManagement Software Supervisors Prechecks", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/software/supervisors/{supervisor}/prechecks", + "service": "Vcenter NamespaceManagement Software Supervisors Prechecks", + "sample_action": "run", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/software/supervisors/{supervisor}/upgrades", + "service": "Vcenter NamespaceManagement Software Supervisors Upgrades", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/software/supervisors/{supervisor}/upgrades/jobs", + "service": "Vcenter NamespaceManagement Software Supervisors Upgrades Jobs", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/software/supervisors/{supervisor}/versions", + "service": "Vcenter NamespaceManagement Software Supervisors Versions", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/software/supervisors/{supervisor}/versions", + "service": "Vcenter NamespaceManagement Software Supervisors Versions", + "sample_action": "checkCompatibility", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/software/supervisors/{supervisor}/versions/{version}", + "service": "Vcenter NamespaceManagement Software Supervisors Versions", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/software/supervisors/{supervisor}/versions/{version}/control-plane/sizes", + "service": "Vcenter NamespaceManagement Software Supervisors Versions ControlPlane Sizes", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/stats/time-series", + "service": "Vcenter NamespaceManagement Stats TimeSeries", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/storage/profiles", + "service": "Vcenter NamespaceManagement Storage Profiles", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisor-services", + "service": "Vcenter NamespaceManagement SupervisorServices", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisor-services", + "service": "Vcenter NamespaceManagement SupervisorServices", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisor-services", + "service": "Vcenter NamespaceManagement SupervisorServices", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisor-services", + "service": "Vcenter NamespaceManagement SupervisorServices", + "sample_action": "checkContent", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisor-services/cluster-supervisor-services", + "service": "Vcenter NamespaceManagement SupervisorServices ClusterSupervisorServices", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisor-services/cluster-supervisor-services", + "service": "Vcenter NamespaceManagement SupervisorServices ClusterSupervisorServices", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisor-services/cluster-supervisor-services", + "service": "Vcenter NamespaceManagement SupervisorServices ClusterSupervisorServices", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/supervisor-services/cluster-supervisor-services", + "service": "Vcenter NamespaceManagement SupervisorServices ClusterSupervisorServices", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisor-services/versions", + "service": "Vcenter NamespaceManagement SupervisorServices Versions", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisor-services/versions", + "service": "Vcenter NamespaceManagement SupervisorServices Versions", + "sample_action": "deactivate", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisor-services/versions", + "service": "Vcenter NamespaceManagement SupervisorServices Versions", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisor-services/versions/{version}", + "service": "Vcenter NamespaceManagement SupervisorServices Versions", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisor-services/versions/{version}", + "service": "Vcenter NamespaceManagement SupervisorServices Versions", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisors", + "service": "Vcenter NamespaceManagement Supervisors", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors", + "service": "Vcenter NamespaceManagement Supervisors", + "sample_action": "enableOnZones", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/capabilities", + "service": "Vcenter NamespaceManagement Supervisors Capabilities", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/certificates", + "service": "Vcenter NamespaceManagement Supervisors Certificates", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/certificates", + "service": "Vcenter NamespaceManagement Supervisors Certificates", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/certificates/key-sizes", + "service": "Vcenter NamespaceManagement Supervisors Certificates KeySizes", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/certificates/key-sizes", + "service": "Vcenter NamespaceManagement Supervisors Certificates KeySizes", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/certificates/signing-requests", + "service": "Vcenter NamespaceManagement Supervisors Certificates SigningRequests", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/conditions", + "service": "Vcenter NamespaceManagement Supervisors Conditions", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/container-image-registries", + "service": "Vcenter NamespaceManagement Supervisors ContainerImageRegistries", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/container-image-registries", + "service": "Vcenter NamespaceManagement Supervisors ContainerImageRegistries", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/container-image-registries", + "service": "Vcenter NamespaceManagement Supervisors ContainerImageRegistries", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/container-image-registries", + "service": "Vcenter NamespaceManagement Supervisors ContainerImageRegistries", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/control-plane/networks/{network}/settings", + "service": "Vcenter NamespaceManagement Supervisors ControlPlane Networks Settings", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/control-plane/networks/{network}/settings", + "service": "Vcenter NamespaceManagement Supervisors ControlPlane Networks Settings", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/control-plane/passwords", + "service": "Vcenter NamespaceManagement Supervisors ControlPlane Passwords", + "sample_action": "reset", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/control-plane/settings", + "service": "Vcenter NamespaceManagement Supervisors ControlPlane Settings", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/control-plane/settings", + "service": "Vcenter NamespaceManagement Supervisors ControlPlane Settings", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/control-plane/storage/policies", + "service": "Vcenter NamespaceManagement Supervisors ControlPlane Storage Policies", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/control-plane/storage/policies", + "service": "Vcenter NamespaceManagement Supervisors ControlPlane Storage Policies", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/crypto/fips/modules", + "service": "Vcenter NamespaceManagement Supervisors Crypto Fips Modules", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/domains", + "service": "Vcenter NamespaceManagement Supervisors Identity Domains", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/domains/{domain}", + "service": "Vcenter NamespaceManagement Supervisors Identity Domains", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/providers", + "service": "Vcenter NamespaceManagement Supervisors Identity Providers", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/providers", + "service": "Vcenter NamespaceManagement Supervisors Identity Providers", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/providers/{provider}", + "service": "Vcenter NamespaceManagement Supervisors Identity Providers", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/providers/{provider}", + "service": "Vcenter NamespaceManagement Supervisors Identity Providers", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/providers/{provider}", + "service": "Vcenter NamespaceManagement Supervisors Identity Providers", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/providers/{provider}", + "service": "Vcenter NamespaceManagement Supervisors Identity Providers", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/logs/agent-configuration", + "service": "Vcenter NamespaceManagement Supervisors Logs AgentConfiguration", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/logs/agent-configuration", + "service": "Vcenter NamespaceManagement Supervisors Logs AgentConfiguration", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/management-services", + "service": "Vcenter NamespaceManagement Supervisors ManagementServices", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/management-services", + "service": "Vcenter NamespaceManagement Supervisors ManagementServices", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/management-services", + "service": "Vcenter NamespaceManagement Supervisors ManagementServices", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/management-services", + "service": "Vcenter NamespaceManagement Supervisors ManagementServices", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/metrics/remote-endpoints", + "service": "Vcenter NamespaceManagement Supervisors Metrics RemoteEndpoints", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/metrics/remote-endpoints", + "service": "Vcenter NamespaceManagement Supervisors Metrics RemoteEndpoints", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/metrics/remote-endpoints", + "service": "Vcenter NamespaceManagement Supervisors Metrics RemoteEndpoints", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/metrics/remote-endpoints", + "service": "Vcenter NamespaceManagement Supervisors Metrics RemoteEndpoints", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/metrics/remote-endpoints", + "service": "Vcenter NamespaceManagement Supervisors Metrics RemoteEndpoints", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/networks", + "service": "Vcenter NamespaceManagement Supervisors Networks", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/networks", + "service": "Vcenter NamespaceManagement Supervisors Networks", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/networks/{network}", + "service": "Vcenter NamespaceManagement Supervisors Networks", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/networks/{network}", + "service": "Vcenter NamespaceManagement Supervisors Networks", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/networks/{network}", + "service": "Vcenter NamespaceManagement Supervisors Networks", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/networks/{network}/edges", + "service": "Vcenter NamespaceManagement Supervisors Networks Edges", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/networks/{network}/edges", + "service": "Vcenter NamespaceManagement Supervisors Networks Edges", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/networks/{network}/edges", + "service": "Vcenter NamespaceManagement Supervisors Networks Edges", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/recovery/backup/archives", + "service": "Vcenter NamespaceManagement Supervisors Recovery Backup Archives", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/recovery/backup/jobs", + "service": "Vcenter NamespaceManagement Supervisors Recovery Backup Jobs", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/recovery/restore/jobs", + "service": "Vcenter NamespaceManagement Supervisors Recovery Restore Jobs", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/storage/cloud-native/resource-checks", + "service": "Vcenter NamespaceManagement Supervisors Storage CloudNative ResourceChecks", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/storage/cloud-native/resource-checks", + "service": "Vcenter NamespaceManagement Supervisors Storage CloudNative ResourceChecks", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/summary", + "service": "Vcenter NamespaceManagement Supervisors Summary", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/supervisor-service-settings", + "service": "Vcenter NamespaceManagement Supervisors SupervisorServiceSettings", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/supervisor-service-settings", + "service": "Vcenter NamespaceManagement Supervisors SupervisorServiceSettings", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/supervisor-services", + "service": "Vcenter NamespaceManagement Supervisors SupervisorServices", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/supervisor-services", + "service": "Vcenter NamespaceManagement Supervisors SupervisorServices", + "sample_action": "getPrecheckResult", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/supervisor-services", + "service": "Vcenter NamespaceManagement Supervisors SupervisorServices", + "sample_action": "precheck", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/supervisor-services", + "service": "Vcenter NamespaceManagement Supervisors SupervisorServices", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/supervisor-services/signatures", + "service": "Vcenter NamespaceManagement Supervisors SupervisorServices Signatures", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/support-bundles", + "service": "Vcenter NamespaceManagement Supervisors SupportBundles", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/topology", + "service": "Vcenter NamespaceManagement Supervisors Topology", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/vsphere-pod-settings", + "service": "Vcenter NamespaceManagement Supervisors VspherePodSettings", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/vsphere-pod-settings", + "service": "Vcenter NamespaceManagement Supervisors VspherePodSettings", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/images/{image}/settings", + "service": "Vcenter NamespaceManagement Supervisors Workloads Images Settings", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/images/{image}/settings", + "service": "Vcenter NamespaceManagement Supervisors Workloads Images Settings", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/kube-api-server-settings", + "service": "Vcenter NamespaceManagement Supervisors Workloads KubeApiServerSettings", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/kube-api-server-settings", + "service": "Vcenter NamespaceManagement Supervisors Workloads KubeApiServerSettings", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/networks/{network}/settings", + "service": "Vcenter NamespaceManagement Supervisors Workloads Networks Settings", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/networks/{network}/settings", + "service": "Vcenter NamespaceManagement Supervisors Workloads Networks Settings", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/storage/cloud-native/file-volumes", + "service": "Vcenter NamespaceManagement Supervisors Workloads Storage CloudNative FileVolumes", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/storage/cloud-native/file-volumes", + "service": "Vcenter NamespaceManagement Supervisors Workloads Storage CloudNative FileVolumes", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/storage/policies", + "service": "Vcenter NamespaceManagement Supervisors Workloads Storage Policies", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/storage/policies", + "service": "Vcenter NamespaceManagement Supervisors Workloads Storage Policies", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/zones/{zone}/bindings", + "service": "Vcenter NamespaceManagement Supervisors Zones Bindings", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/zones/{zone}/bindings", + "service": "Vcenter NamespaceManagement Supervisors Zones Bindings", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/zones/{zone}/bindings", + "service": "Vcenter NamespaceManagement Supervisors Zones Bindings", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/zones/{zone}/bindings", + "service": "Vcenter NamespaceManagement Supervisors Zones Bindings", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/zones/{zone}/bindings", + "service": "Vcenter NamespaceManagement Supervisors Zones Bindings", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/support-bundle", + "service": "Vcenter NamespaceManagement SupportBundle", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/virtual-machine-classes", + "service": "Vcenter NamespaceManagement VirtualMachineClasses", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/virtual-machine-classes", + "service": "Vcenter NamespaceManagement VirtualMachineClasses", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/virtual-machine-classes", + "service": "Vcenter NamespaceManagement VirtualMachineClasses", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/virtual-machine-classes", + "service": "Vcenter NamespaceManagement VirtualMachineClasses", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/zones/{zone}/cluster-compatibilities", + "service": "Vcenter NamespaceManagement Zones ClusterCompatibilities", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespaces/{namespace}/access", + "service": "Vcenter Namespaces Access", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespaces/{namespace}/access", + "service": "Vcenter Namespaces Access", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespaces/{namespace}/access", + "service": "Vcenter Namespaces Access", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespaces/{namespace}/access", + "service": "Vcenter Namespaces Access", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespaces/{namespace}/instances", + "service": "Vcenter Namespaces Instances", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespaces/{namespace}/instances", + "service": "Vcenter Namespaces Instances", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespaces/{namespace}/instances", + "service": "Vcenter Namespaces Instances", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespaces/{namespace}/instances", + "service": "Vcenter Namespaces Instances", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespaces/{namespace}/instances", + "service": "Vcenter Namespaces Instances", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespaces/{namespace}/instances/zones", + "service": "Vcenter Namespaces Instances Zones", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespaces/{namespace}/management-services/access-grants", + "service": "Vcenter Namespaces ManagementServices AccessGrants", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespaces/{namespace}/management-services/access-grants", + "service": "Vcenter Namespaces ManagementServices AccessGrants", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespaces/{namespace}/management-services/access-grants", + "service": "Vcenter Namespaces ManagementServices AccessGrants", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespaces/{namespace}/management-services/access-grants", + "service": "Vcenter Namespaces ManagementServices AccessGrants", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespaces/{namespace}/mobility/virtualmachines/imports", + "service": "Vcenter Namespaces Mobility Virtualmachines Imports", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespaces/{namespace}/mobility/virtualmachines/imports", + "service": "Vcenter Namespaces Mobility Virtualmachines Imports", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespaces/{namespace}/namespace-self-service", + "service": "Vcenter Namespaces NamespaceSelfService", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespaces/{namespace}/namespace-self-service", + "service": "Vcenter Namespaces NamespaceSelfService", + "sample_action": "activate", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespaces/{namespace}/namespace-templates", + "service": "Vcenter Namespaces NamespaceTemplates", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespaces/{namespace}/namespace-templates", + "service": "Vcenter Namespaces NamespaceTemplates", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespaces/{namespace}/namespace-templates", + "service": "Vcenter Namespaces NamespaceTemplates", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespaces/{namespace}/networks/{network}/nsx/subnets", + "service": "Vcenter Namespaces Networks Nsx Subnets", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespaces/{namespace}/user/instances", + "service": "Vcenter Namespaces User Instances", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/network", + "service": "Vcenter Network", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/network/{network}/projects", + "service": "Vcenter Network Projects", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/network/{network}/projects/{project}", + "service": "Vcenter Network Projects", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/network/{network}/projects/{project}/vpcs", + "service": "Vcenter Network Projects Vpcs", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/network/{network}/projects/{project}/vpcs/{vpc}", + "service": "Vcenter Network Projects Vpcs", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/network/{network}/projects/{project}/vpcs/{vpc}/subnets", + "service": "Vcenter Network Projects Vpcs Subnets", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/network/{network}/projects/{project}/vpcs/{vpc}/subnets/{subnet}", + "service": "Vcenter Network Projects Vpcs Subnets", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/ovf/export-flag", + "service": "Vcenter Ovf ExportFlag", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/ovf/import-flag", + "service": "Vcenter Ovf ImportFlag", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/ovf/library-item", + "service": "Vcenter Ovf LibraryItem", + "sample_action": "deploy", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/ovfs", + "service": "Vcenter Ovfs", + "sample_action": "deploy$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/phm/about", + "service": "Vcenter Phm About", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/phm/hardware-support-managers", + "service": "Vcenter Phm HardwareSupportManagers", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/phm/hardware-support-managers", + "service": "Vcenter Phm HardwareSupportManagers", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/phm/hardware-support-managers", + "service": "Vcenter Phm HardwareSupportManagers", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/phm/hardware-support-managers", + "service": "Vcenter Phm HardwareSupportManagers", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/phm/hardware-support-managers/managed-hosts", + "service": "Vcenter Phm HardwareSupportManagers ManagedHosts", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/phm/hardware-support-managers/managed-hosts", + "service": "Vcenter Phm HardwareSupportManagers ManagedHosts", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/phm/hardware-support-managers/resource-bundle", + "service": "Vcenter Phm HardwareSupportManagers ResourceBundle", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/phm/hardware-support-managers/resource-bundle", + "service": "Vcenter Phm HardwareSupportManagers ResourceBundle", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/privilege", + "service": "Vcenter Authorization Privileges", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/registered-tokens", + "service": "Vcenter RegisteredTokens", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/resource-pool", + "service": "Vcenter ResourcePool", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/resource-pool", + "service": "Vcenter ResourcePool", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/resource-pool/{resource_pool}", + "service": "Vcenter ResourcePool", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/resource-pool/{resource_pool}", + "service": "Vcenter ResourcePool", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/resource-pool/{resource_pool}", + "service": "Vcenter ResourcePool", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/services/{service}/service", + "service": "Vcenter Services Service", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/services/{service}/service", + "service": "Vcenter Services Service", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/services/{service}/service", + "service": "Vcenter Services Service", + "sample_action": "start", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/storage/policies", + "service": "Vcenter Storage Policies", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/storage/policies", + "service": "Vcenter Storage Policies", + "sample_action": "checkCompatibility", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/storage/policies/{policy}/compliance", + "service": "Vcenter Storage Policies Compliance", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/storage/policies/{policy}/compliance/vm", + "service": "Vcenter Storage Policies Compliance VM", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/storage/policies/{policy}/vm", + "service": "Vcenter Storage Policies VM", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/system", + "service": "Vcenter System", + "sample_action": "hello", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/system-config/deployment-type", + "service": "Vcenter SystemConfig DeploymentType", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/system-config/deployment-type", + "service": "Vcenter SystemConfig DeploymentType", + "sample_action": "reconfigure", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/system-config/psc-registration", + "service": "Vcenter SystemConfig PscRegistration", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/system-config/psc-registration", + "service": "Vcenter SystemConfig PscRegistration", + "sample_action": "repoint", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/tagging/associations", + "service": "Vcenter Tagging Associations", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/tagging/associations", + "service": "Vcenter Tagging Associations", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/tagging/categories", + "service": "Vcenter Tagging Categories", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/tagging/tags", + "service": "Vcenter Tagging Tags", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/topology/nodes", + "service": "Vcenter Topology Nodes", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/topology/nodes/{node}", + "service": "Vcenter Topology Nodes", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/topology/replication-status", + "service": "Vcenter Topology ReplicationStatus", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/attestation/services", + "service": "Vcenter TrustedInfrastructure Attestation Services", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/attestation/services/{service}", + "service": "Vcenter TrustedInfrastructure Attestation Services", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/attestation/services/{service}", + "service": "Vcenter TrustedInfrastructure Attestation Services", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/hosts/{host}/hardware/tpm", + "service": "Vcenter TrustedInfrastructure Hosts Hardware Tpm", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/hosts/{host}/hardware/tpm/endorsement-keys", + "service": "Vcenter TrustedInfrastructure Hosts Hardware Tpm EndorsementKeys", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/hosts/{host}/hardware/tpm/endorsement-keys", + "service": "Vcenter TrustedInfrastructure Hosts Hardware Tpm EndorsementKeys", + "sample_action": "unseal", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/hosts/{host}/hardware/tpm/event-log", + "service": "Vcenter TrustedInfrastructure Hosts Hardware Tpm EventLog", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/kms/services", + "service": "Vcenter TrustedInfrastructure Kms Services", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/kms/services/{service}", + "service": "Vcenter TrustedInfrastructure Kms Services", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/kms/services/{service}", + "service": "Vcenter TrustedInfrastructure Kms Services", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/principal", + "service": "Vcenter TrustedInfrastructure Principal", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters", + "sample_action": "update$Task", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/os/esx/base-images", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Os Esx BaseImages", + "sample_action": "delete$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/os/esx/base-images", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Os Esx BaseImages", + "sample_action": "list$Task", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/os/esx/base-images", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Os Esx BaseImages", + "sample_action": "importFromImgdb$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/service-status", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation ServiceStatus", + "sample_action": "get$Task", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/tpm2/ca-certificates", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 CaCertificates", + "sample_action": "delete$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/tpm2/ca-certificates", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 CaCertificates", + "sample_action": "list$Task", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/tpm2/ca-certificates", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 CaCertificates", + "sample_action": "create$Task", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/tpm2/endorsement-keys", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 EndorsementKeys", + "sample_action": "delete$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/tpm2/endorsement-keys", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 EndorsementKeys", + "sample_action": "list$Task", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/tpm2/endorsement-keys", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 EndorsementKeys", + "sample_action": "create$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/tpm2/settings", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 Settings", + "sample_action": "get$Task", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/tpm2/settings", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 Settings", + "sample_action": "update$Task", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/consumer-principals", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters ConsumerPrincipals", + "sample_action": "delete$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/consumer-principals", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters ConsumerPrincipals", + "sample_action": "get$Task", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/consumer-principals", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters ConsumerPrincipals", + "sample_action": "create$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers", + "sample_action": "list$Task", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers", + "sample_action": "create$Task", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers", + "sample_action": "delete$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers", + "sample_action": "get$Task", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers", + "sample_action": "update$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/client-certificate", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers ClientCertificate", + "sample_action": "get$Task", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/client-certificate", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers ClientCertificate", + "sample_action": "update$Task", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/client-certificate", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers ClientCertificate", + "sample_action": "create$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/client-certificate/csr", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers ClientCertificate Csr", + "sample_action": "get$Task", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/client-certificate/csr", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers ClientCertificate Csr", + "sample_action": "create$Task", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/credential", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers Credential", + "sample_action": "set$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/current-peer-certificates", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers CurrentPeerCertificates", + "sample_action": "list$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/trusted-peer-certificates", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers TrustedPeerCertificates", + "sample_action": "get$Task", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/trusted-peer-certificates", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers TrustedPeerCertificates", + "sample_action": "update$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/service-status", + "service": "Vcenter TrustedInfrastructure TrustAuthorityClusters Kms ServiceStatus", + "sample_action": "get$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-hosts/attestation", + "service": "Vcenter TrustedInfrastructure TrustAuthorityHosts Attestation", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-hosts/attestation", + "service": "Vcenter TrustedInfrastructure TrustAuthorityHosts Attestation", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-hosts/kms", + "service": "Vcenter TrustedInfrastructure TrustAuthorityHosts Kms", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-hosts/kms", + "service": "Vcenter TrustedInfrastructure TrustAuthorityHosts Kms", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/attestation/services", + "service": "Vcenter TrustedInfrastructure TrustedClusters Attestation Services", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/attestation/services-applied-config", + "service": "Vcenter TrustedInfrastructure TrustedClusters Attestation ServicesAppliedConfig", + "sample_action": "delete$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/attestation/services-applied-config", + "service": "Vcenter TrustedInfrastructure TrustedClusters Attestation ServicesAppliedConfig", + "sample_action": "get$Task", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/attestation/services-applied-config", + "service": "Vcenter TrustedInfrastructure TrustedClusters Attestation ServicesAppliedConfig", + "sample_action": "update$Task", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/attestation/services-applied-config", + "service": "Vcenter TrustedInfrastructure TrustedClusters Attestation ServicesAppliedConfig", + "sample_action": "list$Task", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/attestation/services/{service}", + "service": "Vcenter TrustedInfrastructure TrustedClusters Attestation Services", + "sample_action": "delete$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/attestation/services/{service}", + "service": "Vcenter TrustedInfrastructure TrustedClusters Attestation Services", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/kms/services", + "service": "Vcenter TrustedInfrastructure TrustedClusters Kms Services", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/kms/services-applied-config", + "service": "Vcenter TrustedInfrastructure TrustedClusters Kms ServicesAppliedConfig", + "sample_action": "delete$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/kms/services-applied-config", + "service": "Vcenter TrustedInfrastructure TrustedClusters Kms ServicesAppliedConfig", + "sample_action": "get$Task", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/kms/services-applied-config", + "service": "Vcenter TrustedInfrastructure TrustedClusters Kms ServicesAppliedConfig", + "sample_action": "update$Task", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/kms/services-applied-config", + "service": "Vcenter TrustedInfrastructure TrustedClusters Kms ServicesAppliedConfig", + "sample_action": "list$Task", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/kms/services/{service}", + "service": "Vcenter TrustedInfrastructure TrustedClusters Kms Services", + "sample_action": "delete$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/kms/services/{service}", + "service": "Vcenter TrustedInfrastructure TrustedClusters Kms Services", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/services-applied-config", + "service": "Vcenter TrustedInfrastructure TrustedClusters ServicesAppliedConfig", + "sample_action": "delete$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/services-applied-config", + "service": "Vcenter TrustedInfrastructure TrustedClusters ServicesAppliedConfig", + "sample_action": "get$Task", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/services-applied-config", + "service": "Vcenter TrustedInfrastructure TrustedClusters ServicesAppliedConfig", + "sample_action": "update$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/utilization/connections", + "service": "Vcenter Utilization Connections", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/utilization/proxies", + "service": "Vcenter Utilization Proxies", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vcha/cluster", + "service": "Vcenter Vcha Cluster", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vcha/cluster/{cluster}/active", + "service": "Vcenter Vcha Cluster Active", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vcha/cluster/{cluster}/deployment-type", + "service": "Vcenter Vcha Cluster DeploymentType", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vcha/cluster/{cluster}/mode", + "service": "Vcenter Vcha Cluster Mode", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/vcha/cluster/{cluster}/mode", + "service": "Vcenter Vcha Cluster Mode", + "sample_action": "set$Task", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vcha/cluster/{cluster}/passive", + "service": "Vcenter Vcha Cluster Passive", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vcha/cluster/{cluster}/witness", + "service": "Vcenter Vcha Cluster Witness", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vcha/operations", + "service": "Vcenter Vcha Operations", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm", + "service": "Vcenter VM", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm", + "service": "Vcenter VM", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm-template/library-items", + "service": "Vcenter VmTemplate LibraryItems", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm-template/library-items/{item_id}", + "service": "Vcenter VmTemplate LibraryItems", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm-template/library-items/{item_id}/check-outs", + "service": "Vcenter VmTemplate LibraryItems CheckOuts", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm-template/library-items/{item_id}/check-outs", + "service": "Vcenter VmTemplate LibraryItems CheckOuts", + "sample_action": "checkOut", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm-template/library-items/{item_id}/check-outs/{vm}", + "service": "Vcenter VmTemplate LibraryItems CheckOuts", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm-template/library-items/{item_id}/check-outs/{vm}", + "service": "Vcenter VmTemplate LibraryItems CheckOuts", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm-template/library-items/{item_id}/versions", + "service": "Vcenter VmTemplate LibraryItems Versions", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm-template/library-items/{item_id}/versions", + "service": "Vcenter VmTemplate LibraryItems Versions", + "sample_action": "rollback", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm-template/library-items/{item_id}/versions/{version}", + "service": "Vcenter VmTemplate LibraryItems Versions", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm-template/library-items/{item_id}/versions/{version}", + "service": "Vcenter VmTemplate LibraryItems Versions", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}", + "service": "Vcenter VM", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}", + "service": "Vcenter VM", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/compute/policies", + "service": "Vcenter Vm Compute Policies", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/console/tickets", + "service": "Vcenter Vm Console Tickets", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/data-sets", + "service": "Vcenter Vm DataSets", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/data-sets", + "service": "Vcenter Vm DataSets", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/data-sets", + "service": "Vcenter Vm DataSets", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/data-sets", + "service": "Vcenter Vm DataSets", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/data-sets/entries", + "service": "Vcenter Vm DataSets Entries", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/data-sets/entries", + "service": "Vcenter Vm DataSets Entries", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/vm/{vm}/data-sets/entries", + "service": "Vcenter Vm DataSets Entries", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/evc-mode", + "service": "Vcenter Vm EvcMode", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/vm/{vm}/evc-mode", + "service": "Vcenter Vm EvcMode", + "sample_action": "set$Task", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/customization", + "service": "Vcenter Vm Guest Customization", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/customization", + "service": "Vcenter Vm Guest Customization", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/vm/{vm}/guest/customization", + "service": "Vcenter Vm Guest Customization", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/customization-live", + "service": "Vcenter Vm Guest CustomizationLive", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/customization-live", + "service": "Vcenter Vm Guest CustomizationLive", + "sample_action": "run$Task", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/environment", + "service": "Vcenter Vm Guest Environment", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/filesystem/directories", + "service": "Vcenter Vm Guest Filesystem Directories", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/filesystem/files", + "service": "Vcenter Vm Guest Filesystem Files", + "sample_action": "move", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/filesystem/transfers", + "service": "Vcenter Vm Guest Filesystem Transfers", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/identity", + "service": "Vcenter Vm Guest Identity", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/local-filesystem", + "service": "Vcenter Vm Guest LocalFilesystem", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/networking", + "service": "Vcenter Vm Guest Networking", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/networking/interfaces", + "service": "Vcenter Vm Guest Networking Interfaces", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/networking/routes", + "service": "Vcenter Vm Guest Networking Routes", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/operations", + "service": "Vcenter Vm Guest Operations", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/power", + "service": "Vcenter Vm Guest Power", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/power", + "service": "Vcenter Vm Guest Power", + "sample_action": "shutdown", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/processes", + "service": "Vcenter Vm Guest Processes", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware", + "service": "Vcenter Vm Hardware", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware", + "service": "Vcenter Vm Hardware", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware", + "service": "Vcenter Vm Hardware", + "sample_action": "upgrade", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/nvme", + "service": "Vcenter Vm Hardware Adapter Nvme", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/nvme", + "service": "Vcenter Vm Hardware Adapter Nvme", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/nvme/{adapter}", + "service": "Vcenter Vm Hardware Adapter Nvme", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/nvme/{adapter}", + "service": "Vcenter Vm Hardware Adapter Nvme", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/sata", + "service": "Vcenter Vm Hardware Adapter Sata", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/sata", + "service": "Vcenter Vm Hardware Adapter Sata", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/sata/{adapter}", + "service": "Vcenter Vm Hardware Adapter Sata", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/sata/{adapter}", + "service": "Vcenter Vm Hardware Adapter Sata", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/scsi", + "service": "Vcenter Vm Hardware Adapter Scsi", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/scsi", + "service": "Vcenter Vm Hardware Adapter Scsi", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/scsi/{adapter}", + "service": "Vcenter Vm Hardware Adapter Scsi", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/scsi/{adapter}", + "service": "Vcenter Vm Hardware Adapter Scsi", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/scsi/{adapter}", + "service": "Vcenter Vm Hardware Adapter Scsi", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/boot", + "service": "Vcenter Vm Hardware Boot", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/boot", + "service": "Vcenter Vm Hardware Boot", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/boot/device", + "service": "Vcenter Vm Hardware Boot Device", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/vm/{vm}/hardware/boot/device", + "service": "Vcenter Vm Hardware Boot Device", + "sample_action": "set", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/cdrom", + "service": "Vcenter Vm Hardware Cdrom", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/cdrom", + "service": "Vcenter Vm Hardware Cdrom", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/cdrom/{cdrom}", + "service": "Vcenter Vm Hardware Cdrom", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/cdrom/{cdrom}", + "service": "Vcenter Vm Hardware Cdrom", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/cdrom/{cdrom}", + "service": "Vcenter Vm Hardware Cdrom", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/cpu", + "service": "Vcenter Vm Hardware Cpu", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/cpu", + "service": "Vcenter Vm Hardware Cpu", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/disk", + "service": "Vcenter Vm Hardware Disk", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/disk", + "service": "Vcenter Vm Hardware Disk", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/disk/{disk}", + "service": "Vcenter Vm Hardware Disk", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/disk/{disk}", + "service": "Vcenter Vm Hardware Disk", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/disk/{disk}", + "service": "Vcenter Vm Hardware Disk", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/ethernet", + "service": "Vcenter Vm Hardware Ethernet", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/ethernet", + "service": "Vcenter Vm Hardware Ethernet", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/ethernet/{nic}", + "service": "Vcenter Vm Hardware Ethernet", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/ethernet/{nic}", + "service": "Vcenter Vm Hardware Ethernet", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/ethernet/{nic}", + "service": "Vcenter Vm Hardware Ethernet", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/floppy", + "service": "Vcenter Vm Hardware Floppy", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/floppy", + "service": "Vcenter Vm Hardware Floppy", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/floppy/{floppy}", + "service": "Vcenter Vm Hardware Floppy", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/floppy/{floppy}", + "service": "Vcenter Vm Hardware Floppy", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/floppy/{floppy}", + "service": "Vcenter Vm Hardware Floppy", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/memory", + "service": "Vcenter Vm Hardware Memory", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/memory", + "service": "Vcenter Vm Hardware Memory", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/parallel", + "service": "Vcenter Vm Hardware Parallel", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/parallel", + "service": "Vcenter Vm Hardware Parallel", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/parallel/{port}", + "service": "Vcenter Vm Hardware Parallel", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/parallel/{port}", + "service": "Vcenter Vm Hardware Parallel", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/parallel/{port}", + "service": "Vcenter Vm Hardware Parallel", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/serial", + "service": "Vcenter Vm Hardware Serial", + "sample_action": "list", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/serial", + "service": "Vcenter Vm Hardware Serial", + "sample_action": "create", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/serial/{port}", + "service": "Vcenter Vm Hardware Serial", + "sample_action": "delete", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/serial/{port}", + "service": "Vcenter Vm Hardware Serial", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/serial/{port}", + "service": "Vcenter Vm Hardware Serial", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/library-item", + "service": "Vcenter Vm LibraryItem", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/power", + "service": "Vcenter Vm Power", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/power", + "service": "Vcenter Vm Power", + "sample_action": "start", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/storage/policy", + "service": "Vcenter Vm Storage Policy", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/storage/policy", + "service": "Vcenter Vm Storage Policy", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/storage/policy/{policy}/compliance", + "service": "Vcenter Vm Storage Policy Compliance", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/storage/policy/{policy}/compliance", + "service": "Vcenter Vm Storage Policy Compliance", + "sample_action": "check", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/tools", + "service": "Vcenter Vm Tools", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/tools", + "service": "Vcenter Vm Tools", + "sample_action": "update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/tools", + "service": "Vcenter Vm Tools", + "sample_action": "upgrade", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/tools/installer", + "service": "Vcenter Vm Tools Installer", + "sample_action": "get", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/tools/installer", + "service": "Vcenter Vm Tools Installer", + "sample_action": "connect", + "status": "stub" + } + ] +} diff --git a/app/vsphere/rest/version_gate.py b/app/vsphere/rest/version_gate.py new file mode 100644 index 0000000..228d16d --- /dev/null +++ b/app/vsphere/rest/version_gate.py @@ -0,0 +1,29 @@ +"""HTTP middleware: resolve registered Automation API surface (lab: no version 501). + +Historically this returned HTTP 501 when the hot-swapped catalog major was below +a path's PATH_FLOOR. That blocked real lab data for Ansible/Terraform/apps. +Catalog majors still filter the UI browse list; runtime always serves registered +routes with deep handlers or DB-backed stubs. +""" + +from __future__ import annotations + +from collections.abc import Callable + +from starlette.middleware.base import BaseHTTPMiddleware +from starlette.requests import Request +from starlette.responses import Response + +from app.vsphere.contracts.matrix import available_for_request + + +class VsphereVersionGateMiddleware(BaseHTTPMiddleware): + async def dispatch(self, request: Request, call_next: Callable) -> Response: + path = request.url.path + if not (path.startswith("/api/") or path.startswith("/rest/")): + return await call_next(request) + major = getattr(request.app.state, "vsphere_contract_major", 9) + # Touch resolver so unknown paths still fall through to FastAPI 404 / + # stub catch-all; registered paths are never version-blocked. + available_for_request(request.method, path, int(major)) + return await call_next(request) diff --git a/app/vsphere/rest/vm_ext.py b/app/vsphere/rest/vm_ext.py new file mode 100644 index 0000000..2dc840f --- /dev/null +++ b/app/vsphere/rest/vm_ext.py @@ -0,0 +1,227 @@ +"""VM hardware, snapshots, clone, tools — REST extensions.""" + +from __future__ import annotations + +from typing import Any + +from fastapi import APIRouter, Depends, Query, Response + +from app.db.pool import Database +from app.dependencies import get_database +from app.vsphere.domain import vm_ops +from app.vsphere.errors import invalid_argument +from app.vsphere.rest import mappers +from app.vsphere.security.authz import require_privilege, require_read +from app.vsphere.security.session import SessionInfo + +router = APIRouter(tags=["vSphere VM Ext"]) + + +@router.get("/api/vcenter/vm/{vm}/tools") +async def vm_tools( + vm: str, database: Database = Depends(get_database), _: SessionInfo = Depends(require_read) +) -> dict[str, Any]: + obj = await vm_ops.require_vm(database, vm) + tools = obj.props.get("tools") + if isinstance(tools, dict) and tools: + out = dict(tools) + out["run_state"] = ( + "RUNNING" if obj.props.get("power_state") == "POWERED_ON" else "NOT_RUNNING" + ) + return out + return {} + + +@router.get("/api/vcenter/vm/{vm}/hardware") +async def vm_hardware( + vm: str, database: Database = Depends(get_database), _: SessionInfo = Depends(require_read) +) -> dict[str, Any]: + obj = await vm_ops.require_vm(database, vm) + return mappers.vm_info(obj)["hardware"] + + +@router.get("/api/vcenter/vm/{vm}/hardware/cpu") +async def get_cpu( + vm: str, database: Database = Depends(get_database), _: SessionInfo = Depends(require_read) +) -> dict[str, Any]: + obj = await vm_ops.require_vm(database, vm) + cpu = dict(obj.props.get("cpu") or {}) + return { + "count": obj.props.get("cpu_count") + if obj.props.get("cpu_count") is not None + else cpu.get("count"), + "cores_per_socket": cpu.get("cores_per_socket"), + "hot_add_enabled": cpu.get("hot_add_enabled"), + } + + +@router.patch("/api/vcenter/vm/{vm}/hardware/cpu") +async def patch_cpu( + vm: str, + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Config.CPUCount")), +) -> Response: + await vm_ops.update_hardware_cpu(database, vm, int(body.get("count") or 1)) + return Response(status_code=204) + + +@router.get("/api/vcenter/vm/{vm}/hardware/memory") +async def get_memory( + vm: str, database: Database = Depends(get_database), _: SessionInfo = Depends(require_read) +) -> dict[str, Any]: + obj = await vm_ops.require_vm(database, vm) + memory = dict(obj.props.get("memory") or {}) + return { + "size_MiB": obj.props.get("memory_size_mib") + if obj.props.get("memory_size_mib") is not None + else memory.get("size_MiB"), + "hot_add_enabled": memory.get("hot_add_enabled"), + } + + +@router.patch("/api/vcenter/vm/{vm}/hardware/memory") +async def patch_memory( + vm: str, + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Config.Memory")), +) -> Response: + await vm_ops.update_hardware_memory( + database, vm, int(body.get("size_MiB") or body.get("size_mib") or 1024) + ) + return Response(status_code=204) + + +@router.get("/api/vcenter/vm/{vm}/hardware/disk") +async def list_disks( + vm: str, database: Database = Depends(get_database), _: SessionInfo = Depends(require_read) +) -> list[dict[str, Any]]: + obj = await vm_ops.require_vm(database, vm) + return list(obj.props.get("disks") or []) + + +@router.post("/api/vcenter/vm/{vm}/hardware/disk") +async def create_disk( + vm: str, + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Config.AddNewDisk")), +) -> str: + capacity = int( + (body.get("new_vmdk") or {}).get("capacity") or body.get("capacity") or 10737418240 + ) + disk = await vm_ops.add_disk(database, vm, capacity) + return str(disk["key"]) + + +@router.get("/api/vcenter/vm/{vm}/hardware/ethernet") +async def list_nics( + vm: str, database: Database = Depends(get_database), _: SessionInfo = Depends(require_read) +) -> list[dict[str, Any]]: + obj = await vm_ops.require_vm(database, vm) + return list(obj.props.get("nics") or []) + + +@router.post("/api/vcenter/vm/{vm}/hardware/ethernet") +async def create_nic( + vm: str, + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Config.AddRemoveDevice")), +) -> str: + network = ((body.get("backing") or {}).get("network")) or body.get("network") or "network-41" + nic = await vm_ops.add_nic(database, vm, str(network)) + return str(nic["key"]) + + +@router.get("/api/vcenter/vm/{vm}/hardware/boot") +async def get_boot( + vm: str, database: Database = Depends(get_database), _: SessionInfo = Depends(require_read) +) -> dict[str, Any]: + obj = await vm_ops.require_vm(database, vm) + boot = obj.props.get("boot") + if isinstance(boot, dict) and boot: + return boot + from app.vsphere.domain import api_state + + payload = await api_state.get_payload(database, "GET", "/api/vcenter/vm/{vm}/hardware/boot") + return payload if isinstance(payload, dict) else {} + + +@router.get("/api/vcenter/vm/{vm}/snapshots") +async def list_snapshots( + vm: str, database: Database = Depends(get_database), _: SessionInfo = Depends(require_read) +) -> list[dict[str, Any]]: + return await vm_ops.list_snapshots(database, vm) + + +@router.post("/api/vcenter/vm/{vm}/snapshots") +async def create_snapshot( + vm: str, + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.State.CreateSnapshot")), +) -> dict[str, str]: + snap_id, task_id = await vm_ops.create_snapshot( + database, + vm, + name=str(body.get("name") or "snapshot"), + description=str(body.get("description") or ""), + memory=bool(body.get("memory")), + ) + return {"snapshot": snap_id, "task": task_id} + + +@router.delete("/api/vcenter/vm/{vm}/snapshots/{snapshot}") +async def delete_snapshot( + vm: str, + snapshot: str, + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.State.RemoveSnapshot")), +) -> dict[str, str]: + task_id = await vm_ops.delete_snapshot(database, vm, snapshot) + return {"task": task_id} + + +@router.post("/api/vcenter/vm/{vm}/snapshots/{snapshot}") +async def revert_snapshot( + vm: str, + snapshot: str, + action: str = Query("revert"), + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.State.RevertToSnapshot")), +) -> dict[str, str]: + if action != "revert": + raise invalid_argument(f"unsupported action {action}") + task_id = await vm_ops.revert_snapshot(database, vm, snapshot) + return {"task": task_id} + + +@router.post("/api/vcenter/vm/{vm}/clone") +async def clone_vm( + vm: str, + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Provisioning.Clone")), +) -> dict[str, str]: + name = str(body.get("name") or f"{vm}-clone") + folder = (body.get("placement") or {}).get("folder") + moid, task_id = await vm_ops.clone_vm( + database, source_vm=vm, name=name, folder=folder, power_on=bool(body.get("power_on")) + ) + return {"vm": moid, "task": task_id} + + +@router.post("/api/vcenter/vm/{vm}/relocate") +async def relocate_vm( + vm: str, + body: dict[str, Any], + database: Database = Depends(get_database), + _: SessionInfo = Depends(require_privilege("VirtualMachine.Inventory.Move")), +) -> dict[str, str]: + placement = body.get("placement") or body + task_id = await vm_ops.relocate_vm( + database, vm, host=placement.get("host"), datastore=placement.get("datastore") + ) + return {"task": task_id} diff --git a/app/vsphere/security/__init__.py b/app/vsphere/security/__init__.py new file mode 100644 index 0000000..7b95f76 --- /dev/null +++ b/app/vsphere/security/__init__.py @@ -0,0 +1 @@ +"""vSphere session authentication.""" diff --git a/app/vsphere/security/authz.py b/app/vsphere/security/authz.py new file mode 100644 index 0000000..769c543 --- /dev/null +++ b/app/vsphere/security/authz.py @@ -0,0 +1,179 @@ +"""Role / privilege authorization for vSphere REST (and SOAP gates).""" + +from __future__ import annotations + +from collections.abc import Awaitable, Callable +from functools import wraps +from typing import Any + +from fastapi import Depends + +from app.db.pool import Database +from app.dependencies import get_database +from app.vsphere.errors import unauthorized +from app.vsphere.security.session import SessionInfo, require_session + +# Privilege catalog (subset of vSphere privilege ids). +PRIVILEGES: dict[str, str] = { + "System.Anonymous": "Anonymous access", + "System.Read": "Read inventory", + "System.View": "View inventory", + "Global.ManageCustomFields": "Manage custom fields", + "Authorization.ModifyPermissions": "Modify permissions", + "VirtualMachine.Inventory.Create": "Create VM", + "VirtualMachine.Inventory.Delete": "Delete VM", + "VirtualMachine.Inventory.Move": "Move VM", + "VirtualMachine.Interact.PowerOn": "Power on VM", + "VirtualMachine.Interact.PowerOff": "Power off VM", + "VirtualMachine.Interact.Suspend": "Suspend VM", + "VirtualMachine.Interact.Reset": "Reset VM", + "VirtualMachine.Interact.DeviceConnection": "Connect devices", + "VirtualMachine.Interact.ConsoleInteract": "Console", + "VirtualMachine.Config.AddNewDisk": "Add disk", + "VirtualMachine.Config.AddExistingDisk": "Add existing disk", + "VirtualMachine.Config.RemoveDisk": "Remove disk", + "VirtualMachine.Config.CPUCount": "Change CPU", + "VirtualMachine.Config.Memory": "Change memory", + "VirtualMachine.Config.AddRemoveDevice": "Add/remove device", + "VirtualMachine.Config.Rename": "Rename VM", + "VirtualMachine.Provisioning.Clone": "Clone VM", + "VirtualMachine.Provisioning.DeployTemplate": "Deploy template", + "VirtualMachine.Provisioning.MarkAsTemplate": "Mark as template", + "VirtualMachine.State.CreateSnapshot": "Create snapshot", + "VirtualMachine.State.RemoveSnapshot": "Remove snapshot", + "VirtualMachine.State.RevertToSnapshot": "Revert snapshot", + "Datastore.Browse": "Browse datastore", + "Datastore.FileManagement": "Manage datastore files", + "Host.Config.Maintenance": "Host maintenance", + "Folder.Create": "Create folder", + "Folder.Delete": "Delete folder", + "Folder.Rename": "Rename folder", + "Folder.Move": "Move folder", + "Datacenter.Create": "Create datacenter", + "Datacenter.Delete": "Delete datacenter", + "Cluster.Create": "Create cluster", + "Cluster.Delete": "Delete cluster", + "Resource.CreatePool": "Create resource pool", + "Resource.DeletePool": "Delete resource pool", + "Network.Assign": "Assign network", + "ContentLibrary.CreateLocalLibrary": "Create content library", + "ContentLibrary.AddLibraryItem": "Add library item", + "InventoryService.Tagging.CreateCategory": "Create tag category", + "InventoryService.Tagging.CreateTag": "Create tag", + "InventoryService.Tagging.AttachTag": "Attach tag", +} + +_ALL = frozenset(PRIVILEGES) +_READ = frozenset({"System.Anonymous", "System.Read", "System.View", "Datastore.Browse"}) +_POWER = frozenset( + { + *_READ, + "VirtualMachine.Interact.PowerOn", + "VirtualMachine.Interact.PowerOff", + "VirtualMachine.Interact.Suspend", + "VirtualMachine.Interact.Reset", + "VirtualMachine.Interact.ConsoleInteract", + "VirtualMachine.State.CreateSnapshot", + "VirtualMachine.State.RemoveSnapshot", + "VirtualMachine.State.RevertToSnapshot", + "VirtualMachine.Provisioning.Clone", + } +) +_VM_ADMIN = frozenset( + { + *_POWER, + "VirtualMachine.Inventory.Create", + "VirtualMachine.Inventory.Delete", + "VirtualMachine.Inventory.Move", + "VirtualMachine.Config.AddNewDisk", + "VirtualMachine.Config.AddExistingDisk", + "VirtualMachine.Config.RemoveDisk", + "VirtualMachine.Config.CPUCount", + "VirtualMachine.Config.Memory", + "VirtualMachine.Config.AddRemoveDevice", + "VirtualMachine.Config.Rename", + "VirtualMachine.Provisioning.DeployTemplate", + "VirtualMachine.Provisioning.MarkAsTemplate", + "VirtualMachine.Interact.DeviceConnection", + "Datastore.FileManagement", + "Network.Assign", + "InventoryService.Tagging.CreateCategory", + "InventoryService.Tagging.CreateTag", + "InventoryService.Tagging.AttachTag", + "ContentLibrary.CreateLocalLibrary", + "ContentLibrary.AddLibraryItem", + } +) + +ROLE_PRIVILEGES: dict[str, frozenset[str]] = { + "Administrator": _ALL, + "ReadOnly": _READ, + "VirtualMachinePowerUser": _POWER, + "VirtualMachineAdministrator": _VM_ADMIN, +} + + +def privileges_for_roles(roles: list[str] | tuple[str, ...]) -> frozenset[str]: + granted: set[str] = set() + for role in roles: + granted.update(ROLE_PRIVILEGES.get(role, ())) + return frozenset(granted) + + +def has_privilege(roles: list[str] | tuple[str, ...], privilege: str) -> bool: + granted = privileges_for_roles(roles) + if privilege in granted: + return True + # Wildcard Administrator already has exact set; keep prefix convenience. + return any(p.endswith(".*") and privilege.startswith(p[:-1]) for p in granted) + + +async def load_roles(database: Database, username: str) -> list[str]: + pool = database.pool # type: ignore[attr-defined] + async with pool.acquire() as conn: + row = await conn.fetchrow( + "SELECT roles FROM vsphere_credentials WHERE username = $1", + username, + ) + if row is None: + return ["Administrator"] if username.endswith("@vsphere.local") else ["ReadOnly"] + roles = list(row["roles"] or []) + return roles or ["ReadOnly"] + + +def require_privilege(*needed: str) -> Callable[..., Any]: + """FastAPI dependency factory: session must hold every listed privilege.""" + + async def _dependency( + session: SessionInfo = Depends(require_session), + database: Database = Depends(get_database), + ) -> SessionInfo: + roles = list(session.roles) + if not roles: + roles = await load_roles(database, session.username) + for privilege in needed: + if not has_privilege(roles, privilege): + raise unauthorized(f"Missing privilege: {privilege}") + return session + + return _dependency + + +require_read = require_privilege("System.Read") +require_power = require_privilege("VirtualMachine.Interact.PowerOn") +require_vm_mutate = require_privilege("VirtualMachine.Inventory.Create") +require_admin = require_privilege("Authorization.ModifyPermissions") + + +def guard(*needed: str) -> Callable[[Callable[..., Awaitable[Any]]], Callable[..., Awaitable[Any]]]: + """Decorator-style helper for non-FastAPI call sites (SOAP).""" + + def decorator(fn: Callable[..., Awaitable[Any]]) -> Callable[..., Awaitable[Any]]: + @wraps(fn) + async def wrapper(*args: Any, **kwargs: Any) -> Any: + return await fn(*args, **kwargs) + + wrapper.__vsphere_privileges__ = needed # type: ignore[attr-defined] + return wrapper + + return decorator diff --git a/app/vsphere/security/session.py b/app/vsphere/security/session.py new file mode 100644 index 0000000..474cb6b --- /dev/null +++ b/app/vsphere/security/session.py @@ -0,0 +1,154 @@ +"""Session IDs compatible with vmware-api-session-id header.""" + +from __future__ import annotations + +import secrets +from dataclasses import dataclass, field +from datetime import UTC, datetime, timedelta +from typing import Any + +from fastapi import Depends, Request +from fastapi.security import HTTPBasic, HTTPBasicCredentials + +from app.db.pool import AsyncpgDatabase, Database +from app.dependencies import get_database +from app.security.auth import hash_secret, verify_secret +from app.vsphere.errors import unauthenticated + +SESSION_TTL = timedelta(hours=2) +SESSION_HEADER = "vmware-api-session-id" +DEFAULT_USER = "administrator@vsphere.local" +DEFAULT_PASSWORD = "VMware1!" + +_basic = HTTPBasic(auto_error=False) + + +@dataclass(frozen=True, slots=True) +class SessionInfo: + id: str + username: str + roles: tuple[str, ...] = field(default_factory=tuple) + + +def _pool(database: Database) -> Any: + return database.pool # type: ignore[attr-defined] + + +async def ensure_default_credentials(database: Database) -> None: + """Idempotently insert lab SSO credentials (full set via seed preferred).""" + + from app.vsphere.profiles import lab_credentials + + pool = _pool(database) + async with pool.acquire() as conn: + for cred in lab_credentials(): + await conn.execute( + """ + INSERT INTO vsphere_credentials (username, password_hash, roles) + VALUES ($1, $2, $3) + ON CONFLICT (username) DO UPDATE SET + password_hash = EXCLUDED.password_hash, + roles = EXCLUDED.roles + """, + cred.username, + hash_secret(cred.password), + list(cred.roles), + ) + + +async def verify_password(database: Database, username: str, password: str) -> bool: + pool = _pool(database) + async with pool.acquire() as conn: + row = await conn.fetchrow( + "SELECT password_hash FROM vsphere_credentials WHERE username = $1", + username, + ) + if row is None: + return username == DEFAULT_USER and password == DEFAULT_PASSWORD + return verify_secret(password, str(row["password_hash"])) + + +async def create_session(database: Database, username: str) -> str: + session_id = secrets.token_hex(16) + expires = datetime.now(UTC) + SESSION_TTL + pool = _pool(database) + async with pool.acquire() as conn: + await conn.execute( + """ + INSERT INTO vsphere_sessions (id, username, expires_at) + VALUES ($1, $2, $3) + """, + session_id, + username, + expires, + ) + return session_id + + +async def delete_session(database: Database, session_id: str) -> None: + pool = _pool(database) + async with pool.acquire() as conn: + await conn.execute("DELETE FROM vsphere_sessions WHERE id = $1", session_id) + + +async def _roles_for(database: Database, username: str) -> tuple[str, ...]: + pool = _pool(database) + async with pool.acquire() as conn: + row = await conn.fetchrow( + "SELECT roles FROM vsphere_credentials WHERE username = $1", + username, + ) + if row is None: + return ("Administrator",) if username == DEFAULT_USER else ("ReadOnly",) + roles = tuple(str(r) for r in (row["roles"] or [])) + return roles or ("ReadOnly",) + + +async def lookup_session(database: Database, session_id: str) -> SessionInfo | None: + pool = _pool(database) + async with pool.acquire() as conn: + row = await conn.fetchrow( + """ + SELECT id, username, expires_at FROM vsphere_sessions + WHERE id = $1 + """, + session_id, + ) + if row is None: + return None + if row["expires_at"] <= datetime.now(UTC): + await conn.execute("DELETE FROM vsphere_sessions WHERE id = $1", session_id) + return None + await conn.execute( + "UPDATE vsphere_sessions SET expires_at = $2 WHERE id = $1", + session_id, + datetime.now(UTC) + SESSION_TTL, + ) + username = str(row["username"]) + roles = await _roles_for(database, username) + return SessionInfo(id=str(row["id"]), username=username, roles=roles) + + +async def require_session( + request: Request, + database: Database = Depends(get_database), +) -> SessionInfo: + session_id = request.headers.get(SESSION_HEADER) or request.cookies.get(SESSION_HEADER) + if not session_id: + raise unauthenticated() + info = await lookup_session(database, session_id) + if info is None: + raise unauthenticated("Invalid or expired session") + return info + + +async def optional_basic( + credentials: HTTPBasicCredentials | None = Depends(_basic), +) -> HTTPBasicCredentials | None: + return credentials + + +def as_asyncpg(database: Database) -> AsyncpgDatabase: + if not isinstance(database, AsyncpgDatabase): + raise TypeError("vsphere routes require AsyncpgDatabase") + return database diff --git a/app/vsphere/seed.py b/app/vsphere/seed.py new file mode 100644 index 0000000..fa28460 --- /dev/null +++ b/app/vsphere/seed.py @@ -0,0 +1,199 @@ +"""Deterministic vSphere inventory seed for labs.""" + +from __future__ import annotations + +import os +from typing import Any + +from app.db.pool import Database +from app.security.auth import hash_secret +from app.vsphere import inventory +from app.vsphere.domain.api_state import seed_api_surface +from app.vsphere.domain.appliance import seed_appliance_state +from app.vsphere.domain.content import seed_platform_extras +from app.vsphere.domain.platform_surface import seed_platform_surface +from app.vsphere.profiles import VsphereSeedProfile, build_vsphere_profile, props_json +from app.vsphere.security.session import ensure_default_credentials + + +async def _seed_platform(database: Database) -> dict[str, Any]: + """Libraries/tags/files + full Automation API surface state (all profiles).""" + + extras: dict[str, Any] = {} + try: + await seed_platform_extras(database) + extras["platform_extras"] = True + except Exception as error: + extras["platform_extras_error"] = str(error) + try: + extras["api_surface"] = await seed_api_surface(database) + except Exception as error: + extras["api_surface_error"] = str(error) + try: + await seed_appliance_state(database) + extras["appliance"] = True + except Exception as error: + extras["appliance_error"] = str(error) + try: + extras["platform_surface"] = await seed_platform_surface(database) + except Exception as error: + extras["platform_surface_error"] = str(error) + return extras + + +async def seed_vsphere_inventory( + database: Database, + *, + force: bool = False, + profile: str | None = None, + large_hosts: int | None = None, + large_vms: int | None = None, +) -> dict[str, Any]: + """Populate vCenter-like inventory from a named profile (default: large / 1000 VMs).""" + + resolved = build_vsphere_profile(profile, large_hosts=large_hosts, large_vms=large_vms) + existing = await inventory.count_objects(database) + if existing and not force: + await ensure_default_credentials(database) + platform = await _seed_platform(database) + by_type = await inventory.count_by_type(database) + return { + "seeded": False, + "profile": resolved.name, + "objects": existing, + "by_type": by_type, + "vms": by_type.get("VirtualMachine", 0), + "hosts": by_type.get("HostSystem", 0), + **platform, + } + + await _wipe(database) + await _apply_profile(database, resolved) + await ensure_default_credentials(database) + platform = await _seed_platform(database) + by_type = await inventory.count_by_type(database) + return { + "seeded": True, + "profile": resolved.name, + "objects": await inventory.count_objects(database), + "by_type": by_type, + "vms": by_type.get("VirtualMachine", 0), + "hosts": by_type.get("HostSystem", 0), + **platform, + } + + +async def _wipe(database: Database) -> None: + from app.vsphere.domain.content import clear_transfer_sessions + from app.vsphere.soap.property_collector import clear_pc_state + + await clear_pc_state(database) + await clear_transfer_sessions(database) + pool = database.pool # type: ignore[attr-defined] + async with pool.acquire() as conn: + await conn.execute( + """ + DO $$ BEGIN + IF to_regclass('public.vsphere_nfc_leases') IS NOT NULL THEN + DELETE FROM vsphere_nfc_leases; + END IF; + IF to_regclass('public.vsphere_transfer_sessions') IS NOT NULL THEN + DELETE FROM vsphere_transfer_sessions; + END IF; + IF to_regclass('public.vsphere_console_tickets') IS NOT NULL THEN + DELETE FROM vsphere_console_tickets; + END IF; + IF to_regclass('public.vsphere_pc_state') IS NOT NULL THEN + DELETE FROM vsphere_pc_state; + END IF; + END $$; + """ + ) + await conn.execute("DELETE FROM vsphere_permissions") + await conn.execute("DELETE FROM vsphere_datastore_files") + await conn.execute("DELETE FROM vsphere_snapshots") + await conn.execute("DELETE FROM vsphere_tag_associations") + await conn.execute("DELETE FROM vsphere_tags") + await conn.execute("DELETE FROM vsphere_tag_categories") + await conn.execute("DELETE FROM vsphere_library_items") + await conn.execute("DELETE FROM vsphere_libraries") + await conn.execute("DELETE FROM vsphere_tasks") + await conn.execute( + """ + DO $$ BEGIN + IF to_regclass('public.vsphere_api_state') IS NOT NULL THEN + DELETE FROM vsphere_api_state; + END IF; + END $$; + """ + ) + await conn.execute("UPDATE vsphere_objects SET parent_moid = NULL") + await conn.execute("DELETE FROM vsphere_objects") + + +async def _apply_profile(database: Database, profile: VsphereSeedProfile) -> None: + rows = [ + { + "moid": obj.moid, + "type": obj.type, + "name": obj.name, + "parent_moid": obj.parent_moid, + "props": obj.props, + } + for obj in profile.objects + ] + # Parents first: folders → dc → cluster → hosts/vms. Spec order already topological. + await inventory.upsert_objects_batch(database, rows) + + pool = database.pool # type: ignore[attr-defined] + async with pool.acquire() as conn: + for cred in profile.credentials: + await conn.execute( + """ + INSERT INTO vsphere_credentials (username, password_hash, roles) + VALUES ($1, $2, $3) + ON CONFLICT (username) DO UPDATE SET + password_hash = EXCLUDED.password_hash, + roles = EXCLUDED.roles + """, + cred.username, + hash_secret(cred.password), + list(cred.roles), + ) + for perm in profile.permissions: + await conn.execute( + """ + INSERT INTO vsphere_permissions (principal, role, entity_moid, propagate) + VALUES ($1, $2, $3, $4) + """, + perm.principal, + perm.role, + perm.entity_moid, + perm.propagate, + ) + + +def default_profile_name() -> str: + return os.getenv("SEED_VSPHERE_PROFILE", "large") + + +async def vsphere_state_summary(database: Database) -> dict[str, Any]: + by_type = await inventory.count_by_type(database) + return { + "hosts": by_type.get("HostSystem", 0), + "vms": by_type.get("VirtualMachine", 0), + "datastores": by_type.get("Datastore", 0), + "datacenters": by_type.get("Datacenter", 0), + "clusters": by_type.get("ClusterComputeResource", 0), + "objects": sum(by_type.values()), + "by_type": by_type, + "profile_hint": default_profile_name(), + } + + +__all__ = [ + "default_profile_name", + "props_json", + "seed_vsphere_inventory", + "vsphere_state_summary", +] diff --git a/app/vsphere/soap/__init__.py b/app/vsphere/soap/__init__.py new file mode 100644 index 0000000..c40bc9b --- /dev/null +++ b/app/vsphere/soap/__init__.py @@ -0,0 +1,5 @@ +"""VIM SOAP /sdk surface.""" + +from app.vsphere.soap.router import router as vsphere_soap_router + +__all__ = ["vsphere_soap_router"] diff --git a/app/vsphere/soap/pbm.py b/app/vsphere/soap/pbm.py new file mode 100644 index 0000000..98303c9 --- /dev/null +++ b/app/vsphere/soap/pbm.py @@ -0,0 +1,92 @@ +"""Minimal PBM (Profile-Based Management) SOAP endpoint for Terraform/govmomi.""" + +from __future__ import annotations + +import re +from xml.sax.saxutils import escape + +from fastapi import APIRouter, Request, Response +from fastapi.responses import PlainTextResponse + +router = APIRouter(tags=["vSphere PBM"]) + +NS_SOAP = "http://schemas.xmlsoap.org/soap/envelope/" + + +@router.get("/pbm") +@router.get("/pbm/") +@router.get("/pbm/sdk") +@router.get("/pbm/sdk/") +async def pbm_get() -> PlainTextResponse: + return PlainTextResponse("VMware PBM SDK simulator — POST SOAP to /pbm/sdk") + + +@router.post("/pbm") +@router.post("/pbm/") +@router.post("/pbm/sdk") +@router.post("/pbm/sdk/") +async def pbm_post(request: Request) -> Response: + body = (await request.body()).decode("utf-8", errors="replace") + if "PbmRetrieveServiceContent" in body or "RetrieveContent" in body: + xml = _wrap( + "PbmRetrieveServiceContentResponse", + """ + + VMware vCenter Profile-Driven Storage Service + 2.0 + + SessionManager + CapabilityMetadataManager + ProfileManager + ComplianceManager + PlacementSolver + """, + ) + return Response(content=xml, media_type='text/xml; charset="utf-8"') + if "PbmQueryProfile" in body or "PbmQueryDefaultRequirementProfile" in body: + xml = _wrap( + "PbmQueryProfileResponse", + """ + com.vmware.storage.default + vSAN Default Storage Policy + + + policy-thin + Thin provision + """, + ) + return Response(content=xml, media_type='text/xml; charset="utf-8"') + if "PbmQueryAssociatedProfile" in body: + # Empty association list (no storage policy) — must use the correct response + # tag so govmomi unmarshals []types.PbmProfileId instead of panicking. + xml = _wrap("PbmQueryAssociatedProfileResponse", "") + return Response(content=xml, media_type='text/xml; charset="utf-8"') + if "PbmRetrieveContent" in body: + xml = _wrap("PbmRetrieveContentResponse", "") + return Response(content=xml, media_type='text/xml; charset="utf-8"') + # Unknown PBM op — empty success so clients continue. + op = "PbmMethod" + match = re.search(r"<(?:\w+:)?([A-Za-z0-9_]+)(?:\s|>)", body) + if match: + op = match.group(1) + return Response( + content=_wrap(f"{op}Response", ""), + media_type='text/xml; charset="utf-8"', + ) + + +def _wrap(response_tag: str, inner: str) -> str: + return f""" + + + <{response_tag} xmlns="urn:pbm"> + {inner} + + + +""" + + +# silence unused escape import warning by using it in fault helper +def _fault(message: str) -> str: + return f"{escape(message)}" diff --git a/app/vsphere/soap/property_collector.py b/app/vsphere/soap/property_collector.py new file mode 100644 index 0000000..4310be2 --- /dev/null +++ b/app/vsphere/soap/property_collector.py @@ -0,0 +1,1639 @@ +"""PropertyCollector helpers: filter specs, updates, folder traversal props.""" + +from __future__ import annotations + +import json +import re +import secrets +from typing import Any +from xml.sax.saxutils import escape + +from app.db.pool import Database +from app.vsphere import inventory +from app.vsphere.inventory import ManagedObject + +# Types that inherit ManagedEntity (govmomi Ancestors / Finder propSet Type=ManagedEntity). +_MANAGED_ENTITY_TYPES = frozenset( + { + "Folder", + "Datacenter", + "VirtualMachine", + "HostSystem", + "ClusterComputeResource", + "ComputeResource", + "ResourcePool", + "VirtualApp", + "StoragePod", + "Datastore", + "Network", + "DistributedVirtualPortgroup", + "VmwareDistributedVirtualSwitch", + "DistributedVirtualSwitch", + "OpaqueNetwork", + } +) + + +def _decode(value: Any) -> Any: + current = value + while isinstance(current, str): + try: + current = json.loads(current) + except json.JSONDecodeError: + break + return current + + +async def clear_pc_state(database: Database | None = None) -> None: + """Drop durable PC views/tokens/versions (and orphan ContainerView inventory rows).""" + + if database is None: + return + pool = database.pool # type: ignore[attr-defined] + async with pool.acquire() as conn: + await conn.execute( + """ + DO $$ BEGIN + IF to_regclass('public.vsphere_pc_state') IS NOT NULL THEN + DELETE FROM vsphere_pc_state; + END IF; + END $$; + """ + ) + await conn.execute("DELETE FROM vsphere_objects WHERE type = 'ContainerView'") + + +async def _pc_put(database: Database, kind: str, key: str, payload: Any) -> None: + pool = database.pool # type: ignore[attr-defined] + async with pool.acquire() as conn: + await conn.execute( + """ + INSERT INTO vsphere_pc_state (kind, key, payload, updated_at) + VALUES ($1, $2, $3::jsonb, now()) + ON CONFLICT (kind, key) DO UPDATE SET + payload = EXCLUDED.payload, + updated_at = now() + """, + kind, + key, + json.dumps(payload), + ) + + +async def _pc_get(database: Database, kind: str, key: str) -> Any | None: + pool = database.pool # type: ignore[attr-defined] + async with pool.acquire() as conn: + row = await conn.fetchrow( + "SELECT payload FROM vsphere_pc_state WHERE kind = $1 AND key = $2", + kind, + key, + ) + if row is None: + return None + return _decode(row["payload"]) + + +async def _pc_pop(database: Database, kind: str, key: str) -> Any | None: + pool = database.pool # type: ignore[attr-defined] + async with pool.acquire() as conn: + row = await conn.fetchrow( + """ + DELETE FROM vsphere_pc_state + WHERE kind = $1 AND key = $2 + RETURNING payload + """, + kind, + key, + ) + if row is None: + return None + return _decode(row["payload"]) + + +def parse_path_sets(body: str) -> list[str]: + return re.findall(r"<(?:\w+:)?pathSet[^>]*>([^<]+)", body) + + +def parse_obj_refs(body: str) -> list[tuple[str, str]]: + return [ + (m.group(1), m.group(2)) + for m in re.finditer( + r'<(?:\w+:)?obj[^>]*type="([^"]+)"[^>]*>([^<]+)', + body, + ) + ] + + +def parse_view_types(body: str) -> list[str]: + return re.findall(r"<(?:\w+:)?type[^>]*>([^<]+)", body) + + +def parse_prop_types(body: str) -> list[str]: + """Types listed under propSet (what the client wants returned).""" + + return re.findall( + r"<(?:\w+:)?propSet\b[^>]*>\s*<(?:\w+:)?type[^>]*>([^<]+)", + body, + flags=re.DOTALL, + ) + + +def parse_continue_token(body: str) -> str | None: + match = re.search(r"<(?:\w+:)?token[^>]*>([^<]+)", body) + return match.group(1).strip() if match else None + + +async def next_view_id(database: Database) -> str: + pool = database.pool # type: ignore[attr-defined] + async with pool.acquire() as conn: + row = await conn.fetchrow( + """ + INSERT INTO vsphere_pc_state (kind, key, payload, updated_at) + VALUES ('meta', 'view_seq', '{"n": 1}'::jsonb, now()) + ON CONFLICT (kind, key) DO UPDATE SET + payload = jsonb_build_object( + 'n', COALESCE((vsphere_pc_state.payload->>'n')::int, 0) + 1 + ), + updated_at = now() + RETURNING payload + """ + ) + n = int((_decode(row["payload"]) or {}).get("n") or 1) + return f"view-{n}" + + +async def register_container_view(database: Database, view_id: str, moids: list[str]) -> None: + payload = {"moids": list(moids)} + await _pc_put(database, "view", view_id, payload) + await inventory.upsert_object( + database, + moid=view_id, + type_name="ContainerView", + name=view_id, + parent_moid=None, + props={"view_moids": list(moids)}, + ) + + +def view_moids_from_object(obj: ManagedObject) -> list[str]: + props = obj.props or {} + return [str(m) for m in (props.get("view_moids") or [])] + + +async def store_page_token( + database: Database, + remaining_moids: list[str], + path_sets: list[str] | None = None, +) -> str: + token = f"token-{secrets.token_hex(8)}" + await _pc_put( + database, + "token", + token, + {"moids": list(remaining_moids), "path_sets": list(path_sets or [])}, + ) + return token + + +async def take_page_token(database: Database, token: str) -> list[str] | None: + payload = await _pc_pop(database, "token", token) + if payload is None: + return None + if isinstance(payload, list): + return payload + return list(payload.get("moids") or []) + + +async def take_page_token_full( + database: Database, token: str +) -> tuple[list[str], list[str]] | None: + payload = await _pc_pop(database, "token", token) + if payload is None: + return None + if isinstance(payload, list): + return payload, [] + return list(payload.get("moids") or []), list(payload.get("path_sets") or []) + + +def _xsi(type_name: str) -> str: + return f'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="{escape(type_name)}"' + + +def _prop(name: str, value: str, *, xsi_type: str | None = None) -> str: + # govmomi SOAP AnyType decode requires xsi:type; bare leaves Name empty → Ancestors panic. + type_name = xsi_type or "xsd:string" + return ( + f"{escape(name)}" + f"{escape(value)}" + ) + + +def _prop_bool(name: str, value: bool) -> str: + return _prop(name, "true" if value else "false", xsi_type="xsd:boolean") + + +def _prop_int(name: str, value: int) -> str: + return _prop(name, str(value), xsi_type="xsd:int") + + +def _prop_long(name: str, value: int) -> str: + return _prop(name, str(value), xsi_type="xsd:long") + + +def _prop_raw(name: str, inner_xml: str, *, xsi_type: str) -> str: + return f"{escape(name)}{inner_xml}" + + +def _prop_mor(name: str, type_name: str, moid: str) -> str: + return ( + f"{escape(name)}" + f'' + f"{escape(moid)}" + ) + + +def _prop_array_mor(name: str, items: list[tuple[str, str]]) -> str: + if not items: + return ( + f"{escape(name)}" + f"" + ) + inner = "".join( + f'{escape(m)}' + for t, m in items + ) + return ( + f"{escape(name)}" + f"{inner}" + ) + + +def _vim_power(state: str) -> str: + return { + "POWERED_ON": "poweredOn", + "POWERED_OFF": "poweredOff", + "SUSPENDED": "suspended", + }.get(state, "poweredOff") + + +def _parent_type(moid: str) -> str: + if moid.startswith("group-"): + return "Folder" + if moid.startswith("datacenter-"): + return "Datacenter" + if moid.startswith("domain-"): + return "ClusterComputeResource" + if moid.startswith("host-"): + return "HostSystem" + if moid.startswith("resgroup-"): + return "ResourcePool" + if moid.startswith("network-"): + return "Network" + if moid.startswith("dvportgroup-"): + return "DistributedVirtualPortgroup" + if moid.startswith("dvs-"): + return "VmwareDistributedVirtualSwitch" + if moid.startswith("datastore-"): + return "Datastore" + return "ManagedEntity" + + +def _tools_status(props: dict[str, Any]) -> str: + raw = str(props.get("tools_status") or "") + mapping = { + "GUEST_TOOLS_RUNNING": "toolsOk", + "GUEST_TOOLS_NOT_RUNNING": "toolsNotRunning", + "GUEST_TOOLS_OLD": "toolsOld", + } + return mapping.get( + raw, "toolsOk" if props.get("power_state") == "POWERED_ON" else "toolsNotRunning" + ) + + +def _guest_id(props: dict[str, Any]) -> str: + guest = str(props.get("guest_OS") or "OTHER_GUEST_64") + # REST enums often use UBUNTU_64_GUEST; SOAP guestId uses ubuntu64Guest. + mapping = { + "UBUNTU_64_GUEST": "ubuntu64Guest", + "CENTOS_64_GUEST": "centos64Guest", + "RHEL_8_64_GUEST": "rhel8_64Guest", + "WINDOWS_2019_64_GUEST": "windows2019srv_64Guest", + "OTHER_GUEST_64": "otherGuest64", + "OTHER_GUEST": "otherGuest", + } + if guest in mapping: + return mapping[guest] + if guest.endswith("_GUEST"): + return guest.lower().replace("_guest", "Guest").replace("_64", "64") + return guest + + +def _instance_uuid(obj: ManagedObject) -> str: + identity = obj.props.get("identity") or {} + if identity.get("instance_uuid"): + return str(identity["instance_uuid"]) + # Stable synthetic UUID from moid digits. + digits = "".join(ch for ch in obj.moid if ch.isdigit()) or "0" + n = int(digits) % 10_000_000_000_000 + return f"5029aaaa-bbbb-cccc-dddd-{n:012d}" + + +def _bios_uuid(obj: ManagedObject) -> str: + identity = obj.props.get("identity") or {} + if identity.get("bios_uuid"): + return str(identity["bios_uuid"]) + digits = "".join(ch for ch in obj.moid if ch.isdigit()) or "0" + n = int(digits) % 10_000_000_000_000 + return f"4200aaaa-bbbb-cccc-dddd-{n:012d}" + + +def _folder_child_types(obj: ManagedObject, children: list[ManagedObject]) -> list[str]: + """Declare Folder.childType the way vCenter does (not ManagedEntity).""" + + from_children = sorted({c.type for c in children}) + name = (obj.name or "").lower() + moid = obj.moid or "" + if name in {"datacenters", "datacenter"} or moid.startswith("group-d"): + return ["Folder", "Datacenter"] + if name == "vm" or moid.startswith("group-v"): + return ["Folder", "VirtualMachine", "VirtualApp"] + if name == "host" or moid.startswith("group-h"): + return ["Folder", "ComputeResource", "ClusterComputeResource", "HostSystem"] + if name in {"datastore", "datastores"} or moid.startswith("group-s"): + return ["Folder", "Datastore", "StoragePod"] + if name == "network" or moid.startswith("group-n"): + return [ + "Folder", + "Network", + "DistributedVirtualPortgroup", + "VmwareDistributedVirtualSwitch", + "DistributedVirtualSwitch", + ] + if from_children: + return ["Folder", *from_children] + return ["Folder", "VirtualMachine"] + + +def _vm_devices_xml(props: dict[str, Any]) -> str: + """Minimal ArrayOfVirtualDevice suitable for govmomi / Terraform device reads.""" + + xsi = 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' + datastore = str(props.get("datastore") or "datastore-31") + devices: list[str] = [] + # PCI root + SCSI — Terraform device sorter requires controller assignment. + devices.append( + f'' + "100" + "PCI controller 0" + "0" + ) + devices.append( + f'' + "1000" + "LSI Logic" + "1003" + "0noSharing" + "7" + "" + ) + devices.append( + f'' + "200IDE 0" + "0" + ) + # Terraform/pulumi-vsphere getVirtualMachine requires a video card device. + devices.append( + f'' + "500" + "Video card" + "1000" + "4096" + "1false" + "false" + "" + ) + disks = list(props.get("disks") or []) + if not disks: + disks = [{"key": "2000", "value": {"label": "Hard disk 1", "capacity": 42949672960}}] + for disk in disks: + key = int(str(disk.get("key") or 2000)) + value = disk.get("value") or disk + capacity = int(value.get("capacity") or 42949672960) + capacity_kb = max(capacity // 1024, 1) + label = escape(str(value.get("label") or f"Hard disk {key}")) + uuid = escape(str(value.get("uuid") or f"6000C29{key:08x}-0000-0000-0000-000000000001")) + file_name = escape(str(value.get("file_name") or f"[datastore1] disk-{key}.vmdk")) + devices.append( + f'' + f"{key}" + f"{capacity_kb} KB" + f"1000{max(key - 2000, 0)}" + f"{capacity_kb}" + f"{capacity}" + f'' + f"{file_name}" + f'{escape(datastore)}' + f"persistent" + f"true" + f"false" + f"false" + f"{uuid}" + f"" + ) + nics = list(props.get("nics") or []) + if not nics: + nics = [ + { + "key": "4000", + "value": { + "label": "Network adapter 1", + "mac": "00:50:56:01:00:01", + "state": "CONNECTED", + "backing": {"network": "network-41"}, + }, + } + ] + for nic in nics: + key = int(str(nic.get("key") or 4000)) + value = nic.get("value") or nic + backing = value.get("backing") or {} + network = str(backing.get("network") or "network-41") + mac = escape(str(value.get("mac") or "00:50:56:00:00:01")) + label = escape(str(value.get("label") or f"Network adapter {key}")) + connected = "true" if str(value.get("state") or "").upper() == "CONNECTED" else "false" + devices.append( + f'' + f"{key}" + f"VMXNET3" + f"1007" + f"{mac}" + f"assigned" + f"{connected}" + f"truetrue" + f"" + "0-1" + "50normal" + "" + f'' + f"VM Network" + f'{escape(network)}' + f"" + ) + for cdrom in props.get("cdroms") or []: + key = int(str(cdrom.get("cdrom") or cdrom.get("key") or 3000)) + label = escape(str(cdrom.get("label") or "CD/DVD drive 1")) + devices.append( + f'' + f"{key}" + f"CD/DVD" + f"2000" + f'' + f"[datastore1] ISO/ubuntu.iso" + f"" + ) + return "".join(devices) + + +def build_prop_map( + obj: ManagedObject, + *, + children: list[ManagedObject], + all_by_moid: dict[str, ManagedObject], +) -> dict[str, str]: + """Map property path -> already-escaped XML fragment for ….""" + + props = obj.props + out: dict[str, str] = { + "name": _prop("name", obj.name), + "overallStatus": _prop("overallStatus", "green"), + } + if obj.parent_moid: + out["parent"] = _prop_mor("parent", _parent_type(obj.parent_moid), obj.parent_moid) + + child_items = [(c.type, c.moid) for c in children] + if obj.type == "Folder": + out["childEntity"] = _prop_array_mor("childEntity", child_items) + # Folder.childType is ArrayOfString (govmomi folder helpers reject scalar "ManagedEntity"). + child_types = _folder_child_types(obj, children) + out["childType"] = _prop_raw( + "childType", + "".join(f"{escape(t)}" for t in child_types), + xsi_type="ArrayOfString", + ) + if obj.type == "Datacenter": + out["hostFolder"] = _prop_mor( + "hostFolder", "Folder", str(props.get("host_folder") or "group-h23") + ) + out["vmFolder"] = _prop_mor( + "vmFolder", "Folder", str(props.get("vm_folder") or "group-v23") + ) + out["datastoreFolder"] = _prop_mor( + "datastoreFolder", "Folder", str(props.get("datastore_folder") or "group-s23") + ) + out["networkFolder"] = _prop_mor( + "networkFolder", "Folder", str(props.get("network_folder") or "group-n23") + ) + datastores = [("Datastore", o.moid) for o in all_by_moid.values() if o.type == "Datastore"] + networks = [ + (o.type, o.moid) + for o in all_by_moid.values() + if o.type in {"Network", "DistributedVirtualPortgroup"} + ] + out["datastore"] = _prop_array_mor("datastore", datastores) + out["network"] = _prop_array_mor("network", networks) + if obj.type == "ClusterComputeResource": + hosts = [ + ("HostSystem", c.moid) + for c in all_by_moid.values() + if c.type == "HostSystem" and c.parent_moid == obj.moid + ] + out["host"] = _prop_array_mor("host", hosts) + out["resourcePool"] = _prop_mor( + "resourcePool", "ResourcePool", str(props.get("resource_pool") or "resgroup-22") + ) + # Terraform CreateVM loads default devices via EnvironmentBrowser. + env_browser = str(props.get("environment_browser") or f"envbrowser-{obj.moid}") + out["environmentBrowser"] = _prop_mor( + "environmentBrowser", "EnvironmentBrowser", env_browser + ) + out["datastore"] = _prop_array_mor( + "datastore", + [("Datastore", o.moid) for o in all_by_moid.values() if o.type == "Datastore"][:8], + ) + out["network"] = _prop_array_mor( + "network", + [ + (o.type, o.moid) + for o in all_by_moid.values() + if o.type in {"Network", "DistributedVirtualPortgroup"} + ][:20], + ) + out["name"] = _prop("name", obj.name) + out["summary.effectiveCpu"] = _prop_int("summary.effectiveCpu", 48000) + out["summary.effectiveMemory"] = _prop_long("summary.effectiveMemory", 256 * 1024) + out["summary.numHosts"] = _prop_int("summary.numHosts", len(hosts)) + out["configuration.drsConfig.enabled"] = _prop_bool("configuration.drsConfig.enabled", True) + out["configuration.dasConfig.enabled"] = _prop_bool( + "configuration.dasConfig.enabled", False + ) + if obj.type == "ResourcePool": + out["owner"] = _prop_mor("owner", "ClusterComputeResource", obj.parent_moid or "domain-c21") + vms = [ + ("VirtualMachine", o.moid) + for o in all_by_moid.values() + if o.type == "VirtualMachine" and str(o.props.get("resource_pool") or "") == obj.moid + ] + if not vms: + vms = [ + ("VirtualMachine", o.moid) + for o in all_by_moid.values() + if o.type == "VirtualMachine" + and o.parent_moid + and "group-v" in (o.parent_moid or "") + ][:50] + out["vm"] = _prop_array_mor("vm", vms) + out["resourcePool"] = _prop_array_mor("resourcePool", []) + out["config.cpuAllocation.limit"] = _prop_long("config.cpuAllocation.limit", -1) + out["config.memoryAllocation.limit"] = _prop_long("config.memoryAllocation.limit", -1) + if obj.type == "VirtualMachine": + power = _vim_power(str(props.get("power_state", "POWERED_OFF"))) + cpu = int(props.get("cpu_count") or 1) + mem = int(props.get("memory_size_mib") or 1024) + guest_id = _guest_id(props) + inst_uuid = _instance_uuid(obj) + bios_uuid = _bios_uuid(obj) + host = str(props.get("host") or "") + datastore = str(props.get("datastore") or "datastore-31") + ds_obj = all_by_moid.get(datastore) + datastore_name = ds_obj.name if ds_obj is not None else "datastore1" + pool = str(props.get("resource_pool") or "resgroup-22") + networks = [str(n) for n in (props.get("networks") or ["network-41"])] + guest_ip = str(props.get("guest_ip") or props.get("ip_address") or "") + hostname = str((props.get("identity") or {}).get("name") or obj.name) + template = bool(props.get("template")) + tools = _tools_status(props) + + out["runtime.powerState"] = _prop("runtime.powerState", power) + out["summary.runtime.powerState"] = _prop("summary.runtime.powerState", power) + out["config.hardware.numCPU"] = _prop_int("config.hardware.numCPU", cpu) + out["config.hardware.memoryMB"] = _prop_int("config.hardware.memoryMB", mem) + out["config.hardware.numCoresPerSocket"] = _prop_int("config.hardware.numCoresPerSocket", 1) + out["config.uuid"] = _prop("config.uuid", bios_uuid) + out["config.instanceUuid"] = _prop("config.instanceUuid", inst_uuid) + out["config.guestId"] = _prop("config.guestId", guest_id) + out["config.guestFullName"] = _prop( + "config.guestFullName", str(props.get("guest_OS") or guest_id) + ) + out["config.name"] = _prop("config.name", obj.name) + out["config.version"] = _prop( + "config.version", str(props.get("hardware_version") or "vmx-19").lower() + ) + out["config.template"] = _prop_bool("config.template", template) + out["config.files.vmPathName"] = _prop( + "config.files.vmPathName", f"[{datastore_name}] {obj.name}/{obj.name}.vmx" + ) + out["config.hardware.device"] = _prop_raw( + "config.hardware.device", _vm_devices_xml(props), xsi_type="ArrayOfVirtualDevice" + ) + # Terraform flattenVirtualMachineConfigInfo requires non-nil Tools / allocations / bootOptions. + out["config.tools"] = _prop_raw( + "config.tools", + "manual" + "true" + "true" + "true" + "true" + "true" + "false" + "true", + xsi_type="ToolsConfigInfo", + ) + out["config.firmware"] = _prop("config.firmware", str(props.get("firmware") or "bios")) + out["config.changeVersion"] = _prop("config.changeVersion", "1") + out["config.annotation"] = _prop("config.annotation", str(props.get("annotation") or "")) + out["config.alternateGuestName"] = _prop("config.alternateGuestName", "") + out["config.memoryHotAddEnabled"] = _prop_bool("config.memoryHotAddEnabled", False) + out["config.cpuHotAddEnabled"] = _prop_bool("config.cpuHotAddEnabled", False) + out["config.cpuHotRemoveEnabled"] = _prop_bool("config.cpuHotRemoveEnabled", False) + out["config.memoryReservationLockedToMax"] = _prop_bool( + "config.memoryReservationLockedToMax", False + ) + out["config.nestedHVEnabled"] = _prop_bool("config.nestedHVEnabled", False) + out["config.vPMCEnabled"] = _prop_bool("config.vPMCEnabled", False) + out["config.swapPlacement"] = _prop("config.swapPlacement", "inherit") + out["config.flags"] = _prop_raw( + "config.flags", + "true" + "false" + "automatic" + "hvAuto" + "false" + "release" + "false" + "false", + xsi_type="VirtualMachineFlagInfo", + ) + alloc = ( + "0-1" + "1000normal" + ) + out["config.cpuAllocation"] = _prop_raw( + "config.cpuAllocation", alloc, xsi_type="ResourceAllocationInfo" + ) + out["config.memoryAllocation"] = _prop_raw( + "config.memoryAllocation", + "0-1" + "20480normal", + xsi_type="ResourceAllocationInfo", + ) + out["config.bootOptions"] = _prop_raw( + "config.bootOptions", + "0" + "false" + "false" + "10000" + "false", + xsi_type="VirtualMachineBootOptions", + ) + out["summary.config.numCpu"] = _prop_int("summary.config.numCpu", cpu) + out["summary.config.memorySizeMB"] = _prop_int("summary.config.memorySizeMB", mem) + out["summary.config.name"] = _prop("summary.config.name", obj.name) + out["summary.config.uuid"] = _prop("summary.config.uuid", bios_uuid) + out["summary.config.instanceUuid"] = _prop("summary.config.instanceUuid", inst_uuid) + out["summary.config.guestId"] = _prop("summary.config.guestId", guest_id) + out["summary.guest.ipAddress"] = _prop("summary.guest.ipAddress", guest_ip) + out["summary.guest.hostName"] = _prop("summary.guest.hostName", hostname) + out["summary.guest.toolsStatus"] = _prop("summary.guest.toolsStatus", tools) + out["guest.ipAddress"] = _prop("guest.ipAddress", guest_ip) + out["guest.hostName"] = _prop("guest.hostName", hostname) + out["guest.toolsStatus"] = _prop("guest.toolsStatus", tools) + out["guest.guestId"] = _prop("guest.guestId", guest_id) + out["guest.guestState"] = _prop( + "guest.guestState", "running" if power == "poweredOn" else "notRunning" + ) + if host: + out["runtime.host"] = _prop_mor("runtime.host", "HostSystem", host) + out["summary.runtime.host"] = _prop_mor("summary.runtime.host", "HostSystem", host) + out["resourcePool"] = _prop_mor("resourcePool", "ResourcePool", pool) + out["datastore"] = _prop_array_mor("datastore", [("Datastore", datastore)]) + net_items: list[tuple[str, str]] = [] + for net_id in networks: + net_obj = all_by_moid.get(net_id) + net_items.append((net_obj.type if net_obj else "Network", net_id)) + out["network"] = _prop_array_mor("network", net_items) + out["layoutEx.file"] = _prop_raw( + "layoutEx.file", + f"0" + f"[{escape(datastore_name)}] {escape(obj.name)}/{escape(obj.name)}.vmx" + f"config4096", + xsi_type="ArrayOfVirtualMachineFileLayoutExFileInfo", + ) + if obj.type == "HostSystem": + cpu_mhz = int(props.get("cpu_mhz") or 2400) + cpu_cores = int(props.get("cpu_cores") or props.get("num_cpu_cores") or 16) + mem_bytes = int(props.get("memory_bytes") or props.get("memory_size") or 137438953472) + out["runtime.connectionState"] = _prop("runtime.connectionState", "connected") + out["runtime.powerState"] = _prop("runtime.powerState", "poweredOn") + out["runtime.inMaintenanceMode"] = _prop_bool( + "runtime.inMaintenanceMode", bool(props.get("maintenance_mode")) + ) + out["summary.config.name"] = _prop("summary.config.name", obj.name) + out["summary.hardware.uuid"] = _prop( + "summary.hardware.uuid", str(props.get("uuid") or f"host-uuid-{obj.moid}") + ) + out["summary.hardware.memorySize"] = _prop_long("summary.hardware.memorySize", mem_bytes) + out["summary.hardware.numCpuCores"] = _prop_int("summary.hardware.numCpuCores", cpu_cores) + out["summary.hardware.cpuMhz"] = _prop_int("summary.hardware.cpuMhz", cpu_mhz) + out["hardware.memorySize"] = _prop_long("hardware.memorySize", mem_bytes) + out["hardware.cpuInfo.numCpuCores"] = _prop_int("hardware.cpuInfo.numCpuCores", cpu_cores) + out["hardware.cpuInfo.hz"] = _prop_long("hardware.cpuInfo.hz", cpu_mhz * 1_000_000) + out["config.product.version"] = _prop( + "config.product.version", str(props.get("version") or "8.0.0") + ) + out["config.product.fullName"] = _prop( + "config.product.fullName", f"VMware ESXi {props.get('version') or '8.0.0'}" + ) + ds_ids = ( + props.get("datastores") + or [o.moid for o in all_by_moid.values() if o.type == "Datastore"][:4] + ) + out["datastore"] = _prop_array_mor("datastore", [("Datastore", str(d)) for d in ds_ids]) + net_ids = ( + props.get("networks") + or [o.moid for o in all_by_moid.values() if o.type == "Network"][:4] + ) + out["network"] = _prop_array_mor("network", [("Network", str(n)) for n in net_ids]) + vms = [ + ("VirtualMachine", o.moid) + for o in all_by_moid.values() + if o.type == "VirtualMachine" and str(o.props.get("host") or "") == obj.moid + ] + out["vm"] = _prop_array_mor("vm", vms) + out["environmentBrowser"] = _prop_mor( + "environmentBrowser", + "EnvironmentBrowser", + str(props.get("environment_browser") or f"envbrowser-{obj.moid}"), + ) + if obj.type == "EnvironmentBrowser" or obj.moid.startswith("envbrowser-"): + out["name"] = _prop("name", obj.name) + if obj.type == "Datastore": + capacity = int(props.get("capacity") or 0) + free = int(props.get("free_space") or 0) + out["summary.capacity"] = _prop_long("summary.capacity", capacity) + out["summary.freeSpace"] = _prop_long("summary.freeSpace", free) + out["summary.type"] = _prop("summary.type", str(props.get("type") or "VMFS")) + out["summary.name"] = _prop("summary.name", obj.name) + out["summary.url"] = _prop("summary.url", f"ds:///vmfs/volumes/{obj.moid}/") + out["summary.accessible"] = _prop_bool("summary.accessible", True) + out["summary.multipleHostAccess"] = _prop_bool("summary.multipleHostAccess", True) + out["info.name"] = _prop("info.name", obj.name) + out["info.url"] = _prop("info.url", f"ds:///vmfs/volumes/{obj.moid}/") + out["info.freeSpace"] = _prop_long("info.freeSpace", free) + out["info.maxFileSize"] = _prop_long("info.maxFileSize", 62 * 1024**4) + hosts = [o.moid for o in all_by_moid.values() if o.type == "HostSystem"][:20] + # Datastore.host is ArrayOfDatastoreHostMount — not ArrayOfManagedObjectReference. + host_mounts = "".join( + "" + f'{escape(hid)}' + "" + f"/vmfs/volumes/{escape(obj.moid)}" + "readWrite" + "true" + "true" + "" + "" + for hid in hosts + ) + out["host"] = _prop_raw("host", host_mounts, xsi_type="ArrayOfDatastoreHostMount") + vms = [ + ("VirtualMachine", o.moid) + for o in all_by_moid.values() + if o.type == "VirtualMachine" and str(o.props.get("datastore") or "") == obj.moid + ][:100] + out["vm"] = _prop_array_mor("vm", vms) + if obj.type in {"Network", "DistributedVirtualPortgroup", "VmwareDistributedVirtualSwitch"}: + out["summary.name"] = _prop("summary.name", obj.name) + out["summary.accessible"] = _prop_bool("summary.accessible", True) + hosts = [("HostSystem", o.moid) for o in all_by_moid.values() if o.type == "HostSystem"][ + :20 + ] + out["host"] = _prop_array_mor("host", hosts) + vms = [ + ("VirtualMachine", o.moid) + for o in all_by_moid.values() + if o.type == "VirtualMachine" + and ( + obj.moid in (o.props.get("networks") or []) + or obj.name in (o.props.get("networks") or []) + ) + ][:100] + out["vm"] = _prop_array_mor("vm", vms) + if obj.type == "DistributedVirtualPortgroup": + key = str(props.get("key") or obj.moid) + out["key"] = _prop("key", key) + out["config.name"] = _prop("config.name", obj.name) + out["config.key"] = _prop("config.key", key) + dvs = str(props.get("dvs") or props.get("distributed_switch") or "dvs-41") + out["config.distributedVirtualSwitch"] = _prop_mor( + "config.distributedVirtualSwitch", "VmwareDistributedVirtualSwitch", dvs + ) + if obj.type == "VmwareDistributedVirtualSwitch": + out["uuid"] = _prop("uuid", str(props.get("uuid") or f"dvs-uuid-{obj.moid}")) + out["summary.name"] = _prop("summary.name", obj.name) + out["config.uuid"] = _prop( + "config.uuid", str(props.get("uuid") or f"dvs-uuid-{obj.moid}") + ) + pgs = [ + ("DistributedVirtualPortgroup", o.moid) + for o in all_by_moid.values() + if o.type == "DistributedVirtualPortgroup" + ] + out["portgroup"] = _prop_array_mor("portgroup", pgs) + if obj.type == "ContainerView" or obj.moid.startswith("view-"): + moids = view_moids_from_object(obj) + items = [] + for moid in moids: + child = all_by_moid.get(moid) + if child: + items.append((child.type, child.moid)) + out["view"] = _prop_array_mor("view", items) + if obj.type == "Task": + state = str(props.get("state") or "success") + progress = 100 if state == "success" else 50 + xsi = 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' + result_xml = "" + entity_xml = "" + if props.get("result_moid"): + rtype = str(props.get("result_type") or "VirtualMachine") + rmoid = escape(str(props["result_moid"])) + result_xml = ( + f'' + f"{rmoid}" + ) + entity_xml = ( + f'' + f"{rmoid}{escape(rtype)}" + ) + info_inner = ( + f"{escape(obj.moid)}" + f'{escape(obj.moid)}' + f"{escape(state)}" + "falsefalse" + f"{escape(str(props.get('operation') or 'task'))}" + f"{progress}" + f"{entity_xml}{result_xml}" + ) + out["info"] = _prop_raw("info", info_inner, xsi_type="TaskInfo") + out["info.state"] = _prop("info.state", state) + out["info.descriptionId"] = _prop( + "info.descriptionId", str(props.get("operation") or "task") + ) + if props.get("entity"): + out["info.entity"] = _prop_mor("info.entity", "VirtualMachine", str(props["entity"])) + out["info.progress"] = _prop_int("info.progress", progress) + if props.get("result_moid"): + out["info.result"] = _prop_mor( + "info.result", + str(props.get("result_type") or "VirtualMachine"), + str(props["result_moid"]), + ) + if obj.type == "HttpNfcLease" or obj.moid.startswith("lease-"): + # Lease document is durable in vsphere_objects.props (+ vsphere_nfc_leases). + lease = props if isinstance(props, dict) else {} + state = str(lease.get("state") or "ready") + out["state"] = _prop("state", state) + out["info.state"] = _prop("info.state", state) + out["info.entity"] = _prop_mor( + "info.entity", "VirtualMachine", str(lease.get("entity") or "vm-101") + ) + out["info.initializeProgress"] = _prop_int( + "info.initializeProgress", int(lease.get("initializeProgress") or 100) + ) + out["info.transferProgress"] = _prop_int( + "info.transferProgress", int(lease.get("transferProgress") or 0) + ) + urls = (lease.get("info") or {}).get("deviceUrl") or [] + url_xml = "".join( + f"{escape(str(u.get('key')))}" + f"{escape(str(u.get('importKey')))}" + f"{escape(str(u.get('url')))}" + f"{escape(str(u.get('sslThumbprint') or ''))}" + f"" + for u in urls + ) + out["info.deviceUrl"] = _prop_raw( + "info.deviceUrl", url_xml, xsi_type="ArrayOfHttpNfcLeaseDeviceUrl" + ) + return out + + +def object_content_xml( + obj: ManagedObject, + *, + children: list[ManagedObject], + all_by_moid: dict[str, ManagedObject], + path_sets: list[str] | None = None, +) -> str: + if obj.props.get("_not_found"): + xsi = 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' + # Shape must decode to types.ManagedObjectNotFound so terraform + # viapi.IsManagedObjectNotFoundError is true (CreateVM vs CreateChildVM). + # MissingProperty.fault is the MethodFault itself (no nested ). + path = (path_sets[0] if path_sets else None) or "name" + return ( + f'{escape(obj.moid)}' + f"{escape(path)}" + f'' + f'{escape(obj.moid)}' + f"" + f"" + ) + prop_map = build_prop_map(obj, children=children, all_by_moid=all_by_moid) + if path_sets: + selected = [] + for path in path_sets: + if path in prop_map: + selected.append(prop_map[path]) + else: + # prefix match e.g. runtime / config + for key, frag in prop_map.items(): + if key == path or key.startswith(path + "."): + selected.append(frag) + prop_xml = selected or list(prop_map.values()) + else: + prop_xml = list(prop_map.values()) + return ( + f'{escape(obj.moid)}' + + "".join(prop_xml) + + "" + ) + + +def resolve_inventory_path(path: str, objects: list[ManagedObject]) -> ManagedObject | None: + """Resolve inventory paths (govmomi omits root ``Datacenters`` folder).""" + + parts = [p for p in path.strip("/").split("/") if p] + if not parts: + return None + by_moid = {o.moid: o for o in objects} + + def _walk(start_parent: str | None) -> ManagedObject | None: + current_parent = start_parent + match: ManagedObject | None = None + for part in parts: + found = None + if current_parent: + found = find_child(current_parent, part, objects) + if found is None: + found = next( + (o for o in objects if o.parent_moid == current_parent and o.name == part), + None, + ) + if found is None and current_parent is None: + hits = [o for o in objects if o.name == part] + if len(hits) == 1: + found = hits[0] + # Standard DC folder names even if the Folder.name was renamed in lab. + if found is None and current_parent and current_parent in by_moid: + parent = by_moid[current_parent] + if parent.type == "Datacenter": + key = { + "vm": "vm_folder", + "host": "host_folder", + "datastore": "datastore_folder", + "network": "network_folder", + }.get(part.lower()) + if key and parent.props.get(key): + found = by_moid.get(str(parent.props[key])) + if found is None: + return None + match = found + current_parent = found.moid + return match + + hit = _walk(None) + if hit is not None: + return hit + for root in (o for o in objects if o.parent_moid is None): + hit = _walk(root.moid) + if hit is not None: + return hit + return None + + +def find_child(parent_moid: str, name: str, objects: list[ManagedObject]) -> ManagedObject | None: + """SearchIndex.FindChild — direct child by name.""" + + hits = [o for o in objects if o.parent_moid == parent_moid and o.name == name] + if len(hits) == 1: + return hits[0] + # Datacenter folder props (vmFolder etc.) are not parent_moid edges for DC itself. + parent = next((o for o in objects if o.moid == parent_moid), None) + if parent and parent.type == "Datacenter": + for key in ("host_folder", "vm_folder", "datastore_folder", "network_folder"): + folder_moid = parent.props.get(key) + if not folder_moid: + continue + folder = next((o for o in objects if o.moid == folder_moid and o.name == name), None) + if folder: + return folder + if hits: + return hits[0] + return None + + +def _descendants( + roots: list[ManagedObject], + all_objects: list[ManagedObject], + *, + max_depth: int = 32, +) -> list[ManagedObject]: + """BFS descendants by parent_moid (folder/datacenter/cluster inventory walk).""" + + by_parent: dict[str | None, list[ManagedObject]] = {} + for obj in all_objects: + by_parent.setdefault(obj.parent_moid, []).append(obj) + seen: dict[str, ManagedObject] = {o.moid: o for o in roots} + frontier = list(roots) + depth = 0 + while frontier and depth < max_depth: + nxt: list[ManagedObject] = [] + for obj in frontier: + for child in by_parent.get(obj.moid, []): + if child.moid not in seen: + seen[child.moid] = child + nxt.append(child) + # Datacenter folders live as props, not parent_moid edges. + if obj.type == "Datacenter": + for key in ("host_folder", "vm_folder", "datastore_folder", "network_folder"): + folder_moid = obj.props.get(key) + if not folder_moid: + continue + folder = next((o for o in all_objects if o.moid == folder_moid), None) + if folder and folder.moid not in seen: + seen[folder.moid] = folder + nxt.append(folder) + if obj.type == "ClusterComputeResource": + rp = obj.props.get("resource_pool") + if rp: + pool = next((o for o in all_objects if o.moid == rp), None) + if pool and pool.moid not in seen: + seen[pool.moid] = pool + nxt.append(pool) + frontier = nxt + depth += 1 + return list(seen.values()) + + +async def select_objects_for_retrieve( + database: Any, + body: str, +) -> tuple[list[ManagedObject], list[str]]: + path_sets = parse_path_sets(body) + prop_types = parse_prop_types(body) + continue_token = parse_continue_token(body) + all_objects = await inventory.list_objects(database) + by_moid = {o.moid: o for o in all_objects} + + if continue_token: + remaining = await take_page_token(database, continue_token) + if remaining is None: + return [], path_sets + selected = [by_moid[m] for m in remaining if m in by_moid] + return selected, path_sets + + refs = parse_obj_refs(body) + selected: list[ManagedObject] = [] + if refs: + for type_name, moid in refs: + if type_name == "ContainerView" or moid.startswith("view-"): + view_obj = by_moid.get(moid) + if view_obj is not None: + selected.append(view_obj) + else: + stored = await _pc_get(database, "view", moid) + moids = ( + list((stored or {}).get("moids") or []) if isinstance(stored, dict) else [] + ) + selected.append( + ManagedObject( + moid=moid, + type="ContainerView", + name=moid, + parent_moid=None, + props={"view_moids": moids}, + ) + ) + elif type_name == "Task" or moid.startswith("task-"): + selected.append( + ManagedObject( + moid=moid, + type="Task", + name=moid, + parent_moid=None, + props={"task": True}, + ) + ) + elif type_name == "HttpNfcLease" or moid.startswith("lease-"): + selected.append( + ManagedObject( + moid=moid, + type="HttpNfcLease", + name=moid, + parent_moid=None, + props={"lease": True}, + ) + ) + elif type_name == "EnvironmentBrowser" or moid.startswith("envbrowser-"): + selected.append( + ManagedObject( + moid=moid, + type="EnvironmentBrowser", + name=moid, + parent_moid=None, + props={"environment_browser": True}, + ) + ) + elif moid in by_moid: + obj = by_moid[moid] + # Honor requested MOR type — VirtualApp:resgroup-X must NOT resolve a ResourcePool. + if type_name and not _type_compatible(type_name, obj.type): + # Return the underlying ResourcePool for VirtualApp probes so the + # provider proceeds to CreateChildVM_Task (which we implement) instead + # of failing/hanging on ManagedObjectNotFound fault decoding. + if type_name == "VirtualApp" and obj.type == "ResourcePool": + selected.append(obj) + continue + selected.append( + ManagedObject( + moid=moid, + type=type_name, + name=moid, + parent_moid=None, + props={"_not_found": True}, + ) + ) + continue + selected.append(obj) + elif moid in {"propertyCollector", "TaskManager", "SearchIndex", "ViewManager"}: + continue + else: + pass + wants_traversal = "selectSet" in body or "TraversalSpec" in body + if wants_traversal and selected: + # Include ContainerView — govmomi view.Retrieve traverses Path=view from the view MOR. + inventory_roots = [o for o in selected if o.type != "Task"] + if inventory_roots: + if _wants_parent_traversal(body): + expanded = _ancestors(inventory_roots, all_objects) + elif _is_recursive_traversal(body): + expanded = _descendants(inventory_roots, all_objects) + else: + # govmomi list.Lister TraversalSpec is one hop (e.g. Folder.childEntity). + expanded = _one_level_traverse(inventory_roots, all_objects, body) + skip_root = _object_set_skip(body) + if prop_types: + type_set = set(prop_types) + filtered = [o for o in expanded if _type_matches(o.type, type_set)] + if not skip_root: + for root in inventory_roots: + if root.type == "ContainerView": + continue + if root.moid not in {o.moid for o in filtered}: + if _type_matches(root.type, type_set) or not type_set: + filtered.append(root) + selected = ( + filtered if filtered else [o for o in expanded if o.type != "ContainerView"] + ) + else: + selected = [o for o in expanded if o.type != "ContainerView" or not skip_root] + if not skip_root: + for root in inventory_roots: + if root.type == "ContainerView": + continue + if root.moid not in {o.moid for o in selected}: + selected.append(root) + else: + selected = all_objects + if prop_types: + type_set = set(prop_types) + selected = [o for o in selected if _type_matches(o.type, type_set)] + return selected, path_sets + + +def children_of(moid: str, all_objects: list[ManagedObject]) -> list[ManagedObject]: + return [o for o in all_objects if o.parent_moid == moid] + + +def _type_compatible(requested: str, actual: str) -> bool: + """Whether an inventory object may satisfy a client MOR of ``requested`` type.""" + + if not requested or requested == actual: + return True + if requested == "ManagedEntity": + return actual in _MANAGED_ENTITY_TYPES + if requested == "ComputeResource" and actual in {"ComputeResource", "ClusterComputeResource"}: + return True + if requested == "ResourcePool" and actual in {"ResourcePool", "VirtualApp"}: + return True + # Plain ResourcePool must NOT satisfy VirtualApp (CreateChildVM vs CreateVM). + # Exception: none — keep strict. CreateChildVM path is handled separately. + if requested == "VirtualApp": + return actual == "VirtualApp" + if requested == "DistributedVirtualSwitch" and actual in { + "VmwareDistributedVirtualSwitch", + "DistributedVirtualSwitch", + }: + return True + if requested == "Network" and actual in { + "Network", + "DistributedVirtualPortgroup", + "OpaqueNetwork", + }: + return True + return False + + +def _type_matches(obj_type: str, type_set: set[str]) -> bool: + if obj_type in type_set: + return True + return any(_type_compatible(t, obj_type) for t in type_set) + + +def _traversal_paths(body: str) -> list[str]: + """Paths from TraversalSpec (), not PropertySpec ().""" + + return re.findall(r"<(?:\w+:)?path(?:\s[^>]*)?>([^<]+)", body) + + +def _wants_parent_traversal(body: str) -> bool: + """govmomi mo.Ancestors walks parent/parentVApp — not inventory descendants.""" + + paths = {p.strip() for p in _traversal_paths(body)} + if not paths: + return "traverseParent" in body + parentish = {"parent", "parentVApp"} + childish = { + "childEntity", + "hostFolder", + "vmFolder", + "datastoreFolder", + "networkFolder", + "host", + "resourcePool", + "vm", + "datastore", + "network", + "view", + "portgroup", + } + return bool(paths & parentish) and not bool(paths & childish) + + +def _is_recursive_traversal(body: str) -> bool: + """True when a TraversalSpec nests a SelectionSpec (name-only selectSet) to recurse.""" + + if _wants_parent_traversal(body): + return True + # Nested SelectionSpec: inside TraversalSpec. + # Do not match the TraversalSpec's own sibling of . + return bool( + re.search( + r'xsi:type="TraversalSpec"[^>]*>[\s\S]*?' + r"<(?:\w+:)?selectSet(?:\s[^>]*)?>\s*" + r"<(?:\w+:)?name(?:\s[^>]*)?>[^<]+\s*" + r"", + body, + flags=re.IGNORECASE, + ) + ) + + +def _object_set_skip(body: str) -> bool: + """objectSet/@skip — ListFolder uses skip=true so the folder itself is omitted.""" + + match = re.search( + r"<(?:\w+:)?objectSet\b[^>]*>.*?<(?:\w+:)?skip[^>]*>([^<]+)", + body, + flags=re.DOTALL | re.IGNORECASE, + ) + if not match: + return False + return match.group(1).strip().lower() == "true" + + +def _ancestors(roots: list[ManagedObject], all_objects: list[ManagedObject]) -> list[ManagedObject]: + by_moid = {o.moid: o for o in all_objects} + seen: dict[str, ManagedObject] = {} + for root in roots: + cur: ManagedObject | None = root + while cur is not None: + if cur.moid in seen: + break + seen[cur.moid] = cur + parent_moid = cur.parent_moid + if not parent_moid: + break + cur = by_moid.get(parent_moid) + return list(seen.values()) + + +def _follow_path( + root: ManagedObject, + path: str, + all_objects: list[ManagedObject], + by_moid: dict[str, ManagedObject], +) -> list[ManagedObject]: + """One PropertyCollector TraversalSpec hop (govmomi list.Lister).""" + + if path == "childEntity": + return children_of(root.moid, all_objects) + if path in {"parent", "parentVApp"}: + if not root.parent_moid: + return [] + parent = by_moid.get(root.parent_moid) + return [parent] if parent else [] + folder_keys = { + "vmFolder": "vm_folder", + "hostFolder": "host_folder", + "datastoreFolder": "datastore_folder", + "networkFolder": "network_folder", + } + if path in folder_keys: + folder_moid = root.props.get(folder_keys[path]) + if not folder_moid: + return [] + folder = by_moid.get(str(folder_moid)) + return [folder] if folder else [] + if path == "resourcePool": + rp = root.props.get("resource_pool") or root.props.get("resourcePool") + if rp and str(rp) in by_moid: + return [by_moid[str(rp)]] + return [o for o in all_objects if o.type == "ResourcePool" and o.parent_moid == root.moid] + if path == "host": + return [o for o in all_objects if o.type == "HostSystem" and o.parent_moid == root.moid] + if path == "vm": + if root.type == "ResourcePool": + return [ + o + for o in all_objects + if o.type == "VirtualMachine" + and str(o.props.get("resource_pool") or "") == root.moid + ] + if root.type == "HostSystem": + return [ + o + for o in all_objects + if o.type == "VirtualMachine" and str(o.props.get("host") or "") == root.moid + ] + return children_of(root.moid, all_objects) + if path == "datastore": + if root.type == "Datacenter": + return [o for o in all_objects if o.type == "Datastore"] + ds_ids = root.props.get("datastores") or root.props.get("datastore") or [] + if isinstance(ds_ids, str): + ds_ids = [ds_ids] + out = [by_moid[str(d)] for d in ds_ids if str(d) in by_moid] + if out: + return out + return [o for o in all_objects if o.type == "Datastore"][:20] + if path == "network": + return [ + o + for o in all_objects + if o.type in {"Network", "DistributedVirtualPortgroup", "OpaqueNetwork"} + ][:50] + if path == "portgroup": + return [o for o in all_objects if o.type == "DistributedVirtualPortgroup"] + if path == "view": + moids = view_moids_from_object(root) + return [by_moid[m] for m in moids if m in by_moid] + return [] + + +def _one_level_traverse( + roots: list[ManagedObject], + all_objects: list[ManagedObject], + body: str, +) -> list[ManagedObject]: + paths = [p.strip() for p in _traversal_paths(body)] or ["childEntity"] + by_moid = {o.moid: o for o in all_objects} + seen: dict[str, ManagedObject] = {} + for root in roots: + for path in paths: + for hit in _follow_path(root, path, all_objects, by_moid): + seen[hit.moid] = hit + return list(seen.values()) + + +def _vim_task_state(status: str) -> str: + return { + "SUCCEEDED": "success", + "FAILED": "error", + "RUNNING": "running", + "PENDING": "queued", + }.get(status, "error") + + +def _parse_max_wait_seconds(body: str) -> float: + match = re.search( + r"<(?:\w+:)?maxWaitSeconds[^>]*>([^<]*)", + body, + ) + if not match: + return 0.0 + try: + return max(0.0, float(match.group(1).strip() or "0")) + except ValueError: + return 0.0 + + +def _task_object_set_xml(task: dict[str, Any]) -> str: + """PropertyCollector update so govmomi ``task.Wait`` observes completion. + + govmomi waits on the whole ``info`` property (TaskInfo), not ``info.state``. + """ + + task_id = str(task.get("task") or "") + state = _vim_task_state(str(task.get("status") or "FAILED")) + progress = 100 if state in {"success", "error"} else int(task.get("progress") or 50) + result = task.get("result") if isinstance(task.get("result"), dict) else {} + vm_moid = str((result or {}).get("vm") or "") + xsi = 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' + result_xml = "" + entity_xml = "" + if vm_moid: + result_xml = ( + f'' + f"{escape(vm_moid)}" + ) + entity_xml = ( + f'' + f"{escape(vm_moid)}" + "VirtualMachine" + ) + info_xml = ( + f'' + f"{escape(task_id)}" + f'{escape(task_id)}' + f"{escape(state)}" + f"false" + f"false" + f"{escape(str(task.get('operation') or 'task'))}" + f"{progress}" + f"{entity_xml}{result_xml}" + f"" + ) + return ( + "" + f'{escape(task_id)}' + "modify" + f"infoassign{info_xml}" + "" + ) + + +def _vim_power_state(raw: str) -> str: + return { + "POWERED_ON": "poweredOn", + "POWERED_OFF": "poweredOff", + "SUSPENDED": "suspended", + }.get(raw, "poweredOff") + + +def _vm_runtime_object_set_xml(obj: ManagedObject) -> str: + """Push VM runtime/guest props so post-CreateVM waiters can finish.""" + + props = obj.props if isinstance(obj.props, dict) else {} + power = _vim_power_state(str(props.get("power_state") or "POWERED_OFF")) + identity = props.get("identity") if isinstance(props.get("identity"), dict) else {} + uuid = str(identity.get("instance_uuid") or props.get("uuid") or f"uuid-{obj.moid}") + bios = str(identity.get("bios_uuid") or f"bios-{obj.moid}") + xsi = 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' + changes = [ + f"nameassign{escape(obj.name)}", + f"runtime.powerStateassign" + f'{escape(power)}', + f"summary.runtime.powerStateassign" + f'{escape(power)}', + f"config.uuidassign{escape(uuid)}", + f"config.instanceUuidassign" + f"{escape(uuid)}", + f"summary.config.uuidassign" + f"{escape(uuid)}", + f"summary.config.instanceUuidassign" + f"{escape(uuid)}", + f"summary.config.guestIdassign" + f"otherGuest64", + f"guest.toolsStatusassign" + f'toolsOk', + f"guest.toolsRunningStatusassign" + f"guestToolsRunning", + f"guest.ipAddressassign" + f"192.168.1.50", + f"summary.guest.ipAddressassign" + f"192.168.1.50", + f"config.hardware.deviceChangeassign" + f'false', + ] + del bios # reserved for future BIOS UUID prop parity + return ( + "" + f'{escape(obj.moid)}' + "modify" + "".join(changes) + "" + ) + + +async def wait_updates_xml( + database: Database, + *, + session_key: str, + body: str, + objects: list[ManagedObject], +) -> str: + from app.vsphere.domain import tasks as task_store + + version_match = re.search( + r"<(?:\w+:)?version[^>]*>([^<]*)", + body, + ) + client_version = (version_match.group(1).strip() if version_match else "") or "" + stored = await _pc_get(database, "version", session_key) + last = int((stored or {}).get("n") or 0) if isinstance(stored, dict) else int(stored or 0) + + notified_raw = await _pc_get(database, "meta", f"tasks_notified:{session_key}") + notified: set[str] = set() + if isinstance(notified_raw, dict): + notified = {str(x) for x in (notified_raw.get("ids") or [])} + elif isinstance(notified_raw, list): + notified = {str(x) for x in notified_raw} + + all_tasks = await task_store.list_tasks(database) + new_tasks = [t for t in all_tasks if str(t.get("task") or "") not in notified] + synced = bool(client_version) and int(client_version or "0") >= last and last > 0 + max_wait = _parse_max_wait_seconds(body) + + # Late task.Wait callers often subscribe after CreateVM already SUCCEEDED and after + # an earlier WaitForUpdates marked that task "notified". Re-assert the newest task + # once while the client is blocking (maxWaitSeconds > 0). + replay_tasks: list[dict[str, Any]] = [] + if synced and not new_tasks and max_wait > 0: + newest = next( + (t for t in all_tasks if str(t.get("status") or "") in {"SUCCEEDED", "FAILED"}), + None, + ) + if newest is None: + return f"{last}" + # Cap replay storms: only bump when client still has maxWait (blocking wait). + replay_tasks = [newest] + elif synced and not new_tasks: + return f"{last}" + + next_ver = max(last, 0) + 1 + await _pc_put(database, "version", session_key, {"n": next_ver}) + + objects_xml: list[str] = [] + by_moid = {o.moid: o for o in objects} + # First update for a session: seed inventory name props (Finder / ContainerView). + if last == 0: + limited: list[ManagedObject] = [] + vm_count = 0 + for obj in objects: + if obj.type == "VirtualMachine": + if vm_count >= 200: + continue + vm_count += 1 + limited.append(obj) + for obj in limited: + objects_xml.append( + "" + f'{escape(obj.moid)}' + "enter" + f"nameassign" + f"{escape(obj.name)}" + "" + ) + + emit_tasks = new_tasks or replay_tasks + vm_ids: set[str] = set() + for task in emit_tasks: + objects_xml.append(_task_object_set_xml(task)) + result = task.get("result") if isinstance(task.get("result"), dict) else {} + vm_moid = str((result or {}).get("vm") or "") + if vm_moid: + vm_ids.add(vm_moid) + for vm_moid in sorted(vm_ids): + obj = by_moid.get(vm_moid) + if obj is not None: + objects_xml.append(_vm_runtime_object_set_xml(obj)) + if new_tasks: + notified.update(str(t.get("task") or "") for t in new_tasks) + await _pc_put(database, "meta", f"tasks_notified:{session_key}", {"ids": sorted(notified)}) + + return ( + "" + f"{next_ver}" + 'filter-1' + + "".join(objects_xml) + + "" + ) diff --git a/app/vsphere/soap/router.py b/app/vsphere/soap/router.py new file mode 100644 index 0000000..b43395b --- /dev/null +++ b/app/vsphere/soap/router.py @@ -0,0 +1,1255 @@ +"""Minimal VIM SOAP SDK for pyvmomi / govmomi style clients.""" + +from __future__ import annotations + +import re +from xml.sax.saxutils import escape + +from fastapi import APIRouter, Depends, Request, Response +from fastapi.responses import JSONResponse, PlainTextResponse + +from app.db.pool import Database +from app.dependencies import get_database +from app.vsphere import inventory +from app.vsphere.security.session import ( + SESSION_HEADER, + create_session, + delete_session, + ensure_default_credentials, + lookup_session, + verify_password, +) + +router = APIRouter(tags=["vSphere SOAP"]) + +NS_SOAP = "http://schemas.xmlsoap.org/soap/envelope/" +# Keep ≤3 dotted components — hashicorp/vsphere parses AboutInfo.version strictly. +VIM_VERSION = "8.0.2" + + +class SoapFaultError(Exception): + def __init__(self, fault_code: str, message: str) -> None: + self.fault_code = fault_code + self.message = message + super().__init__(message) + + +@router.get("/sdk") +@router.get("/sdk/") +async def sdk_get() -> PlainTextResponse: + return PlainTextResponse( + "VMware VIM SDK simulator — POST SOAP bodies to /sdk", + media_type="text/plain", + ) + + +@router.get("/sdk/about.do") +@router.get("/about.do") +async def sdk_about() -> Response: + html = ( + "VMware vCenter" + f"

VMware vCenter Server

Version {VIM_VERSION} (API Simulator)

" + "

SOAP endpoint: /sdk · " + 'WSDL

' + ) + return Response(content=html, media_type="text/html") + + +@router.get("/sdk/vimService.wsdl") +@router.get("/sdk/vim.wsdl") +async def sdk_wsdl() -> Response: + ops = [ + "RetrieveServiceContent", + "Login", + "Logout", + "RetrieveProperties", + "RetrievePropertiesEx", + "ContinueRetrievePropertiesEx", + "CreateFilter", + "WaitForUpdatesEx", + "CreateContainerView", + "DestroyPropertyFilter", + "FindByInventoryPath", + "FindByUuid", + "FindByDnsName", + "FindByIp", + "FindChild", + "CreateVM_Task", + "CreateChildVM_Task", + "CreateFolder", + "PowerOnVM_Task", + "PowerOffVM_Task", + "CloneVM_Task", + "CreateSnapshot_Task", + "Rename_Task", + "ReconfigVM_Task", + "RelocateVM_Task", + "Destroy_Task", + "CustomizeVM_Task", + "CancelTask", + "CurrentTime", + "InitiateFileTransferToGuest", + "InitiateFileTransferFromGuest", + "ListFilesInGuest", + "DeleteFileInGuest", + "MakeDirectoryInGuest", + "ImportVApp_Task", + "CreateImportSpec", + "HttpNfcLeaseComplete", + "HttpNfcLeaseProgress", + "HttpNfcLeaseAbort", + "HttpNfcLeaseGetManifest", + "QueryConfigOption", + "QueryConfigOptionEx", + "QueryConfigOptionDescriptor", + "QueryConfigTarget", + ] + elements = "".join(f'' for op in ops) + messages = "".join( + f'' + for op in ops + ) + operations = "".join( + f'' for op in ops + ) + wsdl = f""" + + {elements} + {messages} + {operations} + + + + + + + + + +""" + return Response(content=wsdl, media_type="text/xml") + + +@router.post("/sdk") +@router.post("/sdk/") +async def sdk_post( + request: Request, + database: Database = Depends(get_database), +) -> Response: + body = (await request.body()).decode("utf-8", errors="replace") + action = _soap_action(request, body) + try: + xml, session_id = await _dispatch(action, body, request, database) + except SoapFaultError as fault: + return Response( + content=_fault_envelope(fault), + media_type='text/xml; charset="utf-8"', + status_code=500, + ) + headers: dict[str, str] = {} + if session_id: + headers["Set-Cookie"] = f'vmware_soap_session="{session_id}"; Path=/; Secure; HttpOnly' + headers[SESSION_HEADER] = session_id + return Response(content=xml, media_type='text/xml; charset="utf-8"', headers=headers) + + +@router.post("/sdk/vim25/{version}/SessionManager/SessionManager/Login") +async def vim25_json_login( + version: str, + request: Request, + database: Database = Depends(get_database), +) -> Response: + del version + await ensure_default_credentials(database) + payload = await request.json() + username = str(payload.get("userName") or payload.get("username") or "") + password = str(payload.get("password") or "") + if not await verify_password(database, username, password): + return JSONResponse({"error": "InvalidLogin"}, status_code=401) + session_id = await create_session(database, username) + return Response( + content="null", + media_type="application/json", + headers={SESSION_HEADER: session_id}, + status_code=200, + ) + + +async def _dispatch( + action: str, + body: str, + request: Request, + database: Database, +) -> tuple[str, str | None]: + if "RetrieveServiceContent" in action or "RetrieveServiceContent" in body: + return _service_content_response(), None + if _has_op(action, body, "Login"): + xml, session_id = await _login_response(body, database) + return xml, session_id + if _has_op(action, body, "Logout"): + session_id = request.headers.get(SESSION_HEADER) or _cookie_session(request) + if session_id: + await delete_session(database, session_id) + return _empty_response("LogoutResponse"), None + if _has_op(action, body, "CreateContainerView"): + return await _create_container_view(body, database), None + if _has_op(action, body, "ContinueRetrievePropertiesEx"): + return await _continue_retrieve_properties(body, request, database), None + if ( + "RetrieveProperties" in action + or "RetrievePropertiesEx" in body + or _has_op(action, body, "RetrieveProperties") + or _has_op(action, body, "RetrievePropertiesEx") + ): + return await _retrieve_properties(body, request, database), None + if "DestroyPropertyFilter" in body or "DestroyContainerView" in body or "DestroyView" in body: + return _empty_response("DestroyPropertyFilterResponse"), None + if "CurrentTime" in action or _has_op(action, body, "CurrentTime"): + return _wrap("CurrentTimeResponse", "2026-01-01T00:00:00.000Z"), None + if _has_op(action, body, "FindByInventoryPath"): + return await _find_by_path(body, database), None + if _has_op(action, body, "FindChild"): + return await _find_child(body, database), None + if ( + _has_op(action, body, "FindByUuid") + or _has_op(action, body, "FindByDnsName") + or _has_op(action, body, "FindByIp") + ): + return await _find_by_attr(body, database), None + if _has_op(action, body, "CreateFilter"): + return _wrap( + "CreateFilterResponse", + 'filter-1', + ), None + if ( + _has_op(action, body, "WaitForUpdatesEx") + or _has_op(action, body, "WaitForUpdates") + or _has_op(action, body, "CheckForUpdates") + ): + return await _wait_for_updates(body, request, database), None + if _has_op(action, body, "CancelTask"): + return await _cancel_task(body, database), None + if _has_op(action, body, "CreateVM_Task") or _has_op(action, body, "CreateChildVM_Task"): + return await _create_vm_task(body, request, database), None + if _has_op(action, body, "CreateFolder"): + return await _create_folder(body, request, database), None + if _has_op(action, body, "CloneVM_Task"): + return await _clone_vm_task(body, request, database), None + if _has_op(action, body, "CreateSnapshot_Task"): + return await _snapshot_task(body, request, database), None + if _has_op(action, body, "CustomizeVM_Task"): + return await _customize_vm_task(body, request, database), None + if _has_op(action, body, "QueryTask") or ("TaskManager" in body and "info" in body): + return await _query_task(body, database), None + if ( + _has_op(action, body, "PowerOnVM_Task") + or _has_op(action, body, "PowerOffVM_Task") + or _has_op(action, body, "ResetVM_Task") + or _has_op(action, body, "SuspendVM_Task") + ): + return await _power_task(body, request, database), None + if _has_op(action, body, "Rename_Task"): + return await _rename_task(body, request, database), None + if _has_op(action, body, "MarkAsTemplate") or _has_op(action, body, "MarkAsVirtualMachine"): + return await _template_task(body, request, database), None + if _has_op(action, body, "UnregisterVM") or _has_op(action, body, "Destroy_Task"): + return await _destroy_or_unregister(body, request, database), None + if _has_op(action, body, "ReconfigVM_Task"): + return await _reconfig_vm_task(body, request, database), None + if _has_op(action, body, "MigrateVM_Task") or _has_op(action, body, "RelocateVM_Task"): + return await _relocate_task(body, request, database), None + if ( + _has_op(action, body, "ListFilesInGuest") + or _has_op(action, body, "InitiateFileTransferToGuest") + or _has_op(action, body, "InitiateFileTransferFromGuest") + or _has_op(action, body, "DeleteFileInGuest") + or _has_op(action, body, "MakeDirectoryInGuest") + ): + return await _guest_file_ops(body, request, database), None + if ( + _has_op(action, body, "ImportVApp_Task") + or _has_op(action, body, "CreateImportSpec") + or _has_op(action, body, "HttpNfcLeaseComplete") + or _has_op(action, body, "HttpNfcLeaseProgress") + or _has_op(action, body, "HttpNfcLeaseAbort") + or _has_op(action, body, "HttpNfcLeaseGetManifest") + or _has_op(action, body, "HttpNfcLease") + ): + return await _nfc_lease_ops(body, request, database), None + if ( + _has_op(action, body, "QueryConfigOptionEx") + or _has_op(action, body, "QueryConfigOption") + or _has_op(action, body, "QueryConfigOptionDescriptor") + or _has_op(action, body, "QueryConfigTarget") + ): + return _environment_browser_ops(action, body), None + if _has_op(action, body, "QueryEvents") or _has_op(action, body, "RetrieveArgumentDescription"): + return _wrap("QueryEventsResponse", ""), None + if ( + _has_op(action, body, "QueryAlarmState") + or _has_op(action, body, "GetAlarm") + or _has_op(action, body, "AreAlarmActionsEnabled") + ): + return _wrap("QueryAlarmStateResponse", ""), None + if _has_op(action, body, "QueryPerf") or _has_op(action, body, "QueryPerfProviderSummary"): + return _wrap("QueryPerfResponse", ""), None + return _empty_response("MethodFaultResponse"), None + + +def _has_op(action: str, body: str, name: str) -> bool: + """Match SOAP op in SOAPAction or namespaced element tags (e.g. ````).""" + + if name in action: + return True + return re.search(rf"<(?:\w+:)?{re.escape(name)}(?:\s|>|/)", body) is not None + + +def _soap_action(request: Request, body: str) -> str: + header = request.headers.get("SOAPAction") or request.headers.get("soapaction") or "" + if header: + return header.strip('"') + match = re.search(r"<(\w+)", body) + return match.group(1) if match else "" + + +def _cookie_session(request: Request) -> str | None: + cookie = request.headers.get("cookie") or "" + for part in cookie.split(";"): + part = part.strip() + if part.startswith("vmware_soap_session="): + return part.split("=", 1)[1].strip('"') + return None + + +async def _require_soap_session(request: Request, database: Database) -> str: + session_id = request.headers.get(SESSION_HEADER) or _cookie_session(request) + if not session_id: + raise SoapFaultError("NotAuthenticated", "Session required") + info = await lookup_session(database, session_id) + if info is None: + raise SoapFaultError("NotAuthenticated", "Invalid session") + return session_id + + +async def _login_response(body: str, database: Database) -> tuple[str, str]: + await ensure_default_credentials(database) + username = _xml_text(body, "userName") or _xml_text(body, "username") or "" + password = _xml_text(body, "password") or "" + if not await verify_password(database, username, password): + raise SoapFaultError( + "InvalidLogin", + "Cannot complete login due to an incorrect user name or password", + ) + session_id = await create_session(database, username) + xml = _wrap( + "LoginResponse", + f""" + {escape(session_id)} + {escape(username)} + {escape(username)} + 2026-01-01T00:00:00.000Z + 2026-01-01T00:00:00.000Z + en + en + """, + ) + return xml, session_id + + +async def _create_container_view(body: str, database: Database) -> str: + from app.vsphere.soap import property_collector as pc + + types = pc.parse_view_types(body) or ["VirtualMachine"] + objects = await inventory.list_objects(database) + moids = [o.moid for o in objects if o.type in types] + view_id = await pc.next_view_id(database) + await pc.register_container_view(database, view_id, moids) + return _wrap( + "CreateContainerViewResponse", + f'{escape(view_id)}', + ) + + +async def _retrieve_properties(body: str, request: Request, database: Database) -> str: + from app.vsphere.domain import tasks as task_store + from app.vsphere.soap import property_collector as pc + + await _require_soap_session(request, database) + selected, path_sets = await pc.select_objects_for_retrieve(database, body) + all_objects = await inventory.list_objects(database) + by_moid = {o.moid: o for o in all_objects} + enriched = [] + for obj in selected: + if obj.type == "Task": + task = await task_store.get_task(database, obj.moid) + result = (task or {}).get("result") or {} + props = { + "state": { + "SUCCEEDED": "success", + "FAILED": "error", + "RUNNING": "running", + "PENDING": "queued", + }.get((task or {}).get("status", ""), "error"), + "operation": (task or {}).get("operation") or "task", + "entity": result.get("vm"), + "result_moid": result.get("vm"), + "result_type": "VirtualMachine" if result.get("vm") else None, + } + from app.vsphere.inventory import ManagedObject + + enriched.append( + ManagedObject( + moid=obj.moid, type="Task", name=obj.moid, parent_moid=None, props=props + ) + ) + else: + enriched.append(obj) + selected = enriched + # Match SOAP op name carefully — ContinueRetrievePropertiesEx also contains this substring. + is_ex = "RetrievePropertiesEx" in body and "ContinueRetrievePropertiesEx" not in body + max_objects = 100 if is_ex else None + token = None + if max_objects is not None and len(selected) > max_objects: + page, rest = selected[:max_objects], selected[max_objects:] + selected = page + token = await pc.store_page_token( + database, [o.moid for o in rest], path_sets=path_sets or None + ) + parts = [ + pc.object_content_xml( + obj, + children=pc.children_of(obj.moid, all_objects), + all_by_moid=by_moid, + path_sets=path_sets or None, + ) + for obj in selected + ] + tag = ( + "RetrievePropertiesExResponse" + if "RetrievePropertiesEx" in body + else "RetrievePropertiesResponse" + ) + # RetrieveResult.objects (plural) — govmomi/Terraform panic on . + if token: + objects_xml = "".join( + p.replace("", "").replace("", "") + for p in parts + ) + return _wrap(tag, f"{objects_xml}{escape(token)}") + if "RetrievePropertiesEx" in body: + objects_xml = "".join( + p.replace("", "").replace("", "") + for p in parts + ) + return _wrap(tag, f"{objects_xml}") + return _wrap(tag, "".join(parts)) + + +async def _continue_retrieve_properties(body: str, request: Request, database: Database) -> str: + """ContinueRetrievePropertiesEx — required when RetrievePropertiesEx paginates.""" + + from app.vsphere.soap import property_collector as pc + + await _require_soap_session(request, database) + token = pc.parse_continue_token(body) + if not token: + return _wrap("ContinueRetrievePropertiesExResponse", "") + page_full = await pc.take_page_token_full(database, token) + if page_full is None: + return _wrap("ContinueRetrievePropertiesExResponse", "") + remaining, path_sets = page_full + all_objects = await inventory.list_objects(database) + by_moid = {o.moid: o for o in all_objects} + selected = [by_moid[m] for m in remaining if m in by_moid] + max_objects = 100 + next_token = None + if len(selected) > max_objects: + page, rest = selected[:max_objects], selected[max_objects:] + selected = page + next_token = await pc.store_page_token( + database, [o.moid for o in rest], path_sets=path_sets or None + ) + parts = [ + pc.object_content_xml( + obj, + children=pc.children_of(obj.moid, all_objects), + all_by_moid=by_moid, + path_sets=path_sets or None, + ) + for obj in selected + ] + objects_xml = "".join( + p.replace("", "").replace("", "") for p in parts + ) + if next_token: + return _wrap( + "ContinueRetrievePropertiesExResponse", + f"{objects_xml}{escape(next_token)}", + ) + return _wrap("ContinueRetrievePropertiesExResponse", f"{objects_xml}") + + +async def _power_task(body: str, request: Request, database: Database) -> str: + await _require_soap_session(request, database) + from app.vsphere.domain import tasks as task_store + + moid = _xml_text(body, "_this") or "" + obj = await inventory.get_object(database, moid) + if obj is None or obj.type != "VirtualMachine": + raise SoapFaultError("ManagedObjectNotFound", f"VM {moid} not found") + props = dict(obj.props) + if "PowerOnVM_Task" in body or "ResetVM_Task" in body: + props["power_state"] = "POWERED_ON" + op = "PowerOn" + elif "PowerOffVM_Task" in body: + props["power_state"] = "POWERED_OFF" + op = "PowerOff" + else: + props["power_state"] = "SUSPENDED" + op = "Suspend" + await inventory.update_props(database, moid, props) + task_id = await task_store.create_task( + database, + description=f"{op} {moid}", + service="vim.VirtualMachine", + operation=op.lower(), + result={"vm": moid, "power_state": props["power_state"]}, + ) + tag = f"{op}VM_TaskResponse" if op != "Suspend" else "SuspendVM_TaskResponse" + if op == "PowerOn" and "ResetVM_Task" in body: + tag = "ResetVM_TaskResponse" + return _wrap(tag, f'{escape(task_id)}') + + +async def _wait_for_updates(body: str, request: Request, database: Database) -> str: + from app.vsphere.soap import property_collector as pc + + await _require_soap_session(request, database) + session_key = request.headers.get(SESSION_HEADER) or _cookie_session(request) or "anon" + objects = await inventory.list_objects(database) + inner = await pc.wait_updates_xml(database, session_key=session_key, body=body, objects=objects) + if "CheckForUpdates" in body: + return _wrap("CheckForUpdatesResponse", inner) + if "WaitForUpdatesEx" in body: + return _wrap("WaitForUpdatesExResponse", inner) + return _wrap("WaitForUpdatesResponse", inner) + + +async def _cancel_task(body: str, database: Database) -> str: + from app.vsphere.domain import tasks as task_store + + task_id = _xml_text(body, "_this") or "" + task = await task_store.get_task(database, task_id) + if task is None: + raise SoapFaultError("ManagedObjectNotFound", f"Task {task_id} not found") + return _empty_response("CancelTaskResponse") + + +async def _find_by_attr(body: str, database: Database) -> str: + uuid = _xml_text(body, "uuid") + dns = _xml_text(body, "dnsName") + ip = _xml_text(body, "ip") + objects = await inventory.list_objects(database) + for obj in objects: + identity = obj.props.get("identity") or {} + if uuid and uuid in { + str(identity.get("instance_uuid") or ""), + str(identity.get("bios_uuid") or ""), + }: + return _wrap( + "FindByUuidResponse", + f'{escape(obj.moid)}', + ) + if dns and (obj.name == dns or obj.props.get("ip_address") == dns): + return _wrap( + "FindByDnsNameResponse", + f'{escape(obj.moid)}', + ) + if ip and str(obj.props.get("ip_address") or "") == ip: + return _wrap( + "FindByIpResponse", + f'{escape(obj.moid)}', + ) + tag = "FindByUuidResponse" if uuid else "FindByDnsNameResponse" if dns else "FindByIpResponse" + return _wrap(tag, "") + + +def _config_option_xml() -> str: + """Minimal VirtualMachineConfigOption for Terraform DefaultDevices / OSFamily.""" + + xsi = 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' + guests = [ + ("otherGuest64", "otherGuestFamily", "Other (64-bit)"), + ("otherGuest", "otherGuestFamily", "Other (32-bit)"), + ("ubuntu64Guest", "linuxGuest", "Ubuntu Linux (64-bit)"), + ("rhel8_64Guest", "linuxGuest", "Red Hat Enterprise Linux 8 (64-bit)"), + ("windows9_64Guest", "windowsGuest", "Microsoft Windows 10 (64-bit)"), + ("windows2019srv_64Guest", "windowsGuest", "Microsoft Windows Server 2019 (64-bit)"), + ] + guest_xml = "".join( + "" + f"{escape(gid)}{escape(family)}" + f"{escape(full)}" + "128" + "16777216" + "4" + "60" + "0" + "67108864" + "60" + "60" + "1024" + "16" + "8" + "VirtualLsiLogicController" + "VirtualLsiLogicSASController" + "ParaVirtualSCSIController" + "VirtualVmxnet3" + "VirtualE1000e" + "true" + "false" + "true" + "true" + "true" + f"" + for gid, family, full in guests + ) + defaults = ( + f'' + "2000" + "IDE 0" + f'' + "2011" + "IDE 1" + f'' + "300" + "PS2 controller 0" + f'' + "100" + "PCI controller 0" + f'' + "400" + "SIO Controller 0" + f'' + "600" + "Keyboard" + f'' + "700" + "Pointing device" + f'' + "autodetect" + f'' + "500" + "Video card" + "4096" + ) + return ( + "vmx-19" + "Default hardware for lab simulator" + "0" + f"{guest_xml}{defaults}" + "" + "19" + "mhz" + "" + ) + + +def _environment_browser_ops(action: str, body: str) -> str: + if _has_op(action, body, "QueryConfigOptionDescriptor"): + return _wrap( + "QueryConfigOptionDescriptorResponse", + "" + "vmx-19ESXi 8.0 and later" + 'host-11' + "true" + "true" + "true" + "true" + "", + ) + if _has_op(action, body, "QueryConfigTarget"): + return _wrap( + "QueryConfigTargetResponse", + "" + "6464" + "1" + "false" + "", + ) + # QueryConfigOption / QueryConfigOptionEx + tag = ( + "QueryConfigOptionExResponse" + if _has_op(action, body, "QueryConfigOptionEx") + else "QueryConfigOptionResponse" + ) + return _wrap(tag, f"{_config_option_xml()}") + + +async def _create_vm_task(body: str, request: Request, database: Database) -> str: + await _require_soap_session(request, database) + from app.vsphere.domain import vm_ops + + # CreateChildVM_Task is invoked on a ResourcePool/VirtualApp; place the VM in the + # datacenter VM folder. CreateVM_Task is invoked on a Folder. + if "CreateChildVM_Task" in body: + folder = "group-v23" + else: + folder = _xml_text(body, "_this") or "group-v23" + name = _xml_text(body, "name") or "unnamed-vm" + guest = _xml_text(body, "guestId") or "otherGuest64" + cpu = int(_xml_text(body, "numCPUs") or _xml_text(body, "numCpu") or "1") + memory = int(_xml_text(body, "memoryMB") or "1024") + pool = _xml_attr_or_text(body, "pool") or "resgroup-22" + host = _xml_attr_or_text(body, "host") or "host-11" + # Parse datastore from [datastore1] path or datastore MOR. + datastore = _xml_attr_or_text(body, "datastore") or "datastore-31" + path_name = _xml_text(body, "vmPathName") or "" + if path_name.startswith("[") and "]" in path_name: + ds_name = path_name[1 : path_name.index("]")] + objects = await inventory.list_objects(database, type_name="Datastore") + match = next((o for o in objects if o.name == ds_name or o.moid == ds_name), None) + if match: + datastore = match.moid + # Optional network from VirtualEthernetCard backing. + network = _xml_attr_or_text(body, "network") or "network-41" + moid, task_id = await vm_ops.create_vm( + database, + name=name, + folder=folder, + host=host, + datastore=datastore, + resource_pool=pool, + guest_os=_rest_guest_from_vim(guest), + cpu_count=cpu, + memory_size_mib=memory, + networks=[network], + ) + del moid + tag = "CreateChildVM_TaskResponse" if "CreateChildVM_Task" in body else "CreateVM_TaskResponse" + return _wrap(tag, f'{escape(task_id)}') + + +async def _create_folder(body: str, request: Request, database: Database) -> str: + await _require_soap_session(request, database) + from app.vsphere.domain import inventory_ops + + parent = _xml_text(body, "_this") or "group-v23" + name = _xml_text(body, "name") or "New Folder" + moid = await inventory_ops.create_folder(database, parent=parent, name=name) + return _wrap("CreateFolderResponse", f'{escape(moid)}') + + +async def _clone_vm_task(body: str, request: Request, database: Database) -> str: + await _require_soap_session(request, database) + from app.vsphere.domain import vm_ops + + source = _xml_text(body, "_this") or "" + name = _xml_text(body, "name") or f"{source}-clone" + folder = _xml_attr_or_text(body, "folder") + host = _xml_attr_or_text(body, "host") + datastore = _xml_attr_or_text(body, "datastore") + pool = _xml_attr_or_text(body, "pool") + power_on = (_xml_text(body, "powerOn") or "false").lower() == "true" + moid, task_id = await vm_ops.clone_vm( + database, + source_vm=source, + name=name, + folder=folder, + host=host, + datastore=datastore, + resource_pool=pool, + power_on=power_on, + ) + del moid + return _wrap("CloneVM_TaskResponse", f'{escape(task_id)}') + + +async def _customize_vm_task(body: str, request: Request, database: Database) -> str: + await _require_soap_session(request, database) + from app.vsphere.domain import vm_ops + + vm = _xml_text(body, "_this") or "" + hostname = _xml_text(body, "hostName") or _xml_text(body, "name") + ip = _xml_text(body, "ipAddress") or _xml_text(body, "ip") + task_id = await vm_ops.customize_vm( + database, + vm, + {"hostname": hostname, "ip": ip, "raw": True}, + ) + return _wrap( + "CustomizeVM_TaskResponse", + f'{escape(task_id)}', + ) + + +async def _snapshot_task(body: str, request: Request, database: Database) -> str: + await _require_soap_session(request, database) + from app.vsphere.domain import vm_ops + + vm = _xml_text(body, "_this") or "" + name = _xml_text(body, "name") or "snapshot" + _, task_id = await vm_ops.create_snapshot(database, vm, name=name) + return _wrap( + "CreateSnapshot_TaskResponse", + f'{escape(task_id)}', + ) + + +async def _query_task(body: str, database: Database) -> str: + from app.vsphere.domain import tasks as task_store + + task_id = _xml_text(body, "_this") or "" + # Also accept obj refs in RetrieveProperties body + if not task_id or not task_id.startswith("task-"): + import re as _re + + m = _re.search(r'type="Task"[^>]*>([^<]+)<', body) + if m: + task_id = m.group(1) + task = await task_store.get_task(database, task_id) + if task is None: + state = "error" + description = "unknown" + entity = "" + else: + state = { + "SUCCEEDED": "success", + "FAILED": "error", + "RUNNING": "running", + "PENDING": "queued", + }.get(task["status"], "running") + description = task.get("operation") or "task" + entity = (task.get("result") or {}).get("vm") or "" + entity_xml = ( + f'info.entity{escape(entity)}' + if entity + else "" + ) + return _wrap( + "RetrievePropertiesResponse", + f""" + {escape(task_id)} + info.state{state} + info.descriptionId{escape(description)} + info.queueTime{escape(str((task or {}).get("created_at") or ""))} + info.completeTime{escape(str((task or {}).get("completed_at") or ""))} + {entity_xml} + """, + ) + + +async def _rename_task(body: str, request: Request, database: Database) -> str: + await _require_soap_session(request, database) + from app.vsphere.domain import inventory_ops + from app.vsphere.domain import tasks as task_store + + moid = _xml_text(body, "_this") or "" + name = _xml_text(body, "newName") or _xml_text(body, "name") or moid + await inventory_ops.rename_object(database, moid, name) + task_id = await task_store.create_task( + database, + description=f"Rename {moid}", + service="vim.ManagedEntity", + operation="rename", + result={"moid": moid, "name": name}, + ) + return _wrap("Rename_TaskResponse", f'{escape(task_id)}') + + +async def _template_task(body: str, request: Request, database: Database) -> str: + await _require_soap_session(request, database) + from app.vsphere.domain import vm_ops + + vm = _xml_text(body, "_this") or "" + as_template = "MarkAsTemplate" in body + task_id = await vm_ops.set_template(database, vm, template=as_template) + tag = "MarkAsTemplateResponse" if as_template else "MarkAsVirtualMachineResponse" + return _wrap(tag, f'{escape(task_id)}') + + +async def _destroy_or_unregister(body: str, request: Request, database: Database) -> str: + await _require_soap_session(request, database) + from app.vsphere.domain import vm_ops + + vm = _xml_text(body, "_this") or "" + if "UnregisterVM" in body: + task_id = await vm_ops.unregister_vm(database, vm) + return _wrap("UnregisterVMResponse", "") + # Destroy_Task — power off then delete + obj = await inventory.get_object(database, vm) + if obj and obj.props.get("power_state") == "POWERED_ON": + await vm_ops.set_power(database, vm, "stop") + await inventory.delete_object(database, vm) + from app.vsphere.domain import tasks as task_store + + task_id = await task_store.create_task( + database, + description=f"Destroy {vm}", + service="vim.ManagedEntity", + operation="destroy", + result={"vm": vm}, + ) + return _wrap("Destroy_TaskResponse", f'{escape(task_id)}') + + +async def _reconfig_vm_task(body: str, request: Request, database: Database) -> str: + await _require_soap_session(request, database) + from app.vsphere.domain import tasks as task_store + from app.vsphere.domain import vm_ops + + vm = _xml_text(body, "_this") or "" + obj = await inventory.get_object(database, vm) + if obj is None: + raise SoapFaultError("ManagedObjectNotFound", vm) + props = dict(obj.props) + num_cpu = _xml_text(body, "numCPUs") or _xml_text(body, "numCpu") + memory = _xml_text(body, "memoryMB") + if num_cpu: + props["cpu_count"] = int(num_cpu) + if memory: + props["memory_size_mib"] = int(memory) + # Parse deviceChange adds: VirtualDisk capacity + VirtualEthernetCard network. + if "VirtualDisk" in body: + capacities = re.findall( + r"<(?:\w+:)?capacityInKB[^>]*>(\d+)", + body, + ) + for cap_kb in capacities: + capacity = int(cap_kb) * 1024 + # Prefer vm_ops when adding; avoid double-adding on pure edit. + if "operation>add" in body.replace(" ", "") or "add" in body: + await vm_ops.add_disk(database, vm, capacity) + obj = await inventory.get_object(database, vm) + props = dict(obj.props) if obj else props + elif props.get("disks"): + disks = list(props["disks"]) + value = dict(disks[0].get("value") or disks[0]) + value["capacity"] = capacity + disks[0] = {**disks[0], "value": value} if "value" in disks[0] else value + props["disks"] = disks + if "VirtualEthernetCard" in body or "VirtualVmxnet3" in body: + network = _xml_attr_or_text(body, "network") + if network and ( + "add" in body or "operation>add" in body.replace(" ", "") + ): + await vm_ops.add_nic(database, vm, network) + obj = await inventory.get_object(database, vm) + props = dict(obj.props) if obj else props + elif network: + props["networks"] = [network] + nics = list(props.get("nics") or []) + if nics: + value = dict(nics[0].get("value") or nics[0]) + backing = dict(value.get("backing") or {}) + backing["network"] = network + value["backing"] = backing + nics[0] = {**nics[0], "value": value} if "value" in nics[0] else value + props["nics"] = nics + name = _xml_text(body, "name") + if name: + await inventory.upsert_object( + database, + moid=vm, + type_name="VirtualMachine", + name=name, + parent_moid=obj.parent_moid, + props=props, + ) + else: + await inventory.update_props(database, vm, props) + task_id = await task_store.create_task( + database, + description=f"Reconfig {vm}", + service="vim.VirtualMachine", + operation="reconfig", + result={"vm": vm}, + ) + return _wrap("ReconfigVM_TaskResponse", f'{escape(task_id)}') + + +async def _guest_file_ops(body: str, request: Request, database: Database) -> str: + await _require_soap_session(request, database) + from app.vsphere.domain import vm_ops + + # Guest ops target GuestOperationsManager; vm MoRef often in element. + vm = _xml_attr_or_text(body, "vm") or _xml_text(body, "_this") or "" + if vm in {"guestOperationsManager", "GuestOperationsManager", "fileManager"}: + vm = _xml_attr_or_text(body, "vm") or "" + path = ( + _xml_text(body, "filePath") + or _xml_text(body, "guestFilePath") + or _xml_text(body, "path") + or "/" + ) + if "ListFilesInGuest" in body: + entries = await vm_ops.guest_list_files(database, vm, path) + items = "".join( + f"{escape(e['path'])}" + f"{escape(str(e['type']))}" + f"{int(e.get('size') or 0)}" + for e in entries + ) + return _wrap("ListFilesInGuestResponse", f"{items}") + if "InitiateFileTransferToGuest" in body: + content = _xml_text(body, "content") or "" + await vm_ops.guest_write_file(database, vm, path, content or f"lab-upload:{path}") + url = f"https://localhost/api/vcenter/vm/{vm}/guest/filesystem?path={path}" + return _wrap("InitiateFileTransferToGuestResponse", f"{escape(url)}") + if "InitiateFileTransferFromGuest" in body: + url = f"https://localhost/api/vcenter/vm/{vm}/guest/filesystem?path={path}" + return _wrap( + "InitiateFileTransferFromGuestResponse", + f"{escape(url)}", + ) + if "DeleteFileInGuest" in body: + await vm_ops.guest_delete_file(database, vm, path) + return _empty_response("DeleteFileInGuestResponse") + if "MakeDirectoryInGuest" in body: + await vm_ops.guest_write_file(database, vm, path.rstrip("/") + "/.keep", "") + return _empty_response("MakeDirectoryInGuestResponse") + return _empty_response("MethodFaultResponse") + + +async def _nfc_lease_ops(body: str, request: Request, database: Database) -> str: + await _require_soap_session(request, database) + from app.vsphere.domain import platform_surface + from app.vsphere.domain import tasks as task_store + + if "CreateImportSpec" in body: + return _wrap( + "CreateImportSpecResponse", + """ + + imported-lab-vmotherGuest64 + 11024 + + + """, + ) + if "ImportVApp_Task" in body: + # VIM: _this is ResourcePool; folder/host are separate args. + name = _xml_text(body, "name") or "imported-lab-vm" + folder = _xml_text(body, "folder") or "group-v23" + pool = _xml_text(body, "_this") or "resgroup-22" + host = _xml_text(body, "host") or "host-11" + from app.vsphere.domain import vm_ops + + moid, _create_task = await vm_ops.create_vm( + database, + name=name, + folder=folder, + host=host, + resource_pool=pool, + guest_os="OTHER_GUEST_64", + cpu_count=1, + memory_size_mib=1024, + ) + lease = await platform_surface.create_nfc_lease( + database, vm=moid, files=[f"{name}.vmdk", f"{name}.nvram"] + ) + task_id = await task_store.create_task( + database, + description=f"ImportVApp {moid}", + service="vim.ResourcePool", + operation="import_vapp", + result={"vm": moid, "lease": lease["lease"]}, + ) + return _wrap( + "ImportVApp_TaskResponse", + f'{escape(task_id)}', + ) + lease_id = _xml_text(body, "_this") or "" + lease = await platform_surface.get_nfc_lease(database, lease_id) + if "HttpNfcLeaseComplete" in body: + await platform_surface.complete_nfc_lease(database, lease_id) + return _empty_response("HttpNfcLeaseCompleteResponse") + if "HttpNfcLeaseAbort" in body: + if lease: + lease["state"] = "error" + await platform_surface._save_nfc_lease(database, lease_id, lease) + return _empty_response("HttpNfcLeaseAbortResponse") + if "HttpNfcLeaseProgress" in body: + percent = int(_xml_text(body, "percent") or "100") + if lease: + lease["transferProgress"] = percent + await platform_surface._save_nfc_lease(database, lease_id, lease) + return _empty_response("HttpNfcLeaseProgressResponse") + if "HttpNfcLeaseGetManifest" in body or lease is not None: + files_xml = "" + if lease: + for name, meta in (lease.get("files") or {}).items(): + files_xml += ( + f"{escape(name)}" + f"{int(meta.get('size') or 0)}" + ) + return _wrap("HttpNfcLeaseGetManifestResponse", f"{files_xml}") + return _empty_response("MethodFaultResponse") + + +async def _relocate_task(body: str, request: Request, database: Database) -> str: + await _require_soap_session(request, database) + from app.vsphere.domain import vm_ops + + vm = _xml_text(body, "_this") or "" + host = _xml_text(body, "host") + datastore = _xml_text(body, "datastore") + task_id = await vm_ops.relocate_vm(database, vm, host=host, datastore=datastore) + tag = "MigrateVM_TaskResponse" if "MigrateVM_Task" in body else "RelocateVM_TaskResponse" + return _wrap(tag, f'{escape(task_id)}') + + +async def _find_by_path(body: str, database: Database) -> str: + from app.vsphere.soap import property_collector as pc + + path = _xml_text(body, "inventoryPath") or "" + objects = await inventory.list_objects(database) + obj = pc.resolve_inventory_path(path, objects) + if obj is None: + return _wrap("FindByInventoryPathResponse", "") + return _wrap( + "FindByInventoryPathResponse", + f'{escape(obj.moid)}', + ) + + +async def _find_child(body: str, database: Database) -> str: + from app.vsphere.soap import property_collector as pc + + parent = _xml_attr_or_text(body, "entity") or _xml_text(body, "_this") or "" + name = _xml_text(body, "name") or "" + objects = await inventory.list_objects(database) + obj = pc.find_child(parent, name, objects) + if obj is None: + return _wrap("FindChildResponse", "") + return _wrap( + "FindChildResponse", + f'{escape(obj.moid)}', + ) + + +def _parent_type(moid: str) -> str: + if moid.startswith("group-"): + return "Folder" + if moid.startswith("datacenter-"): + return "Datacenter" + if moid.startswith("domain-"): + return "ClusterComputeResource" + if moid.startswith("host-"): + return "HostSystem" + return "ManagedEntity" + + +def _vim_power(state: str) -> str: + return { + "POWERED_ON": "poweredOn", + "POWERED_OFF": "poweredOff", + "SUSPENDED": "suspended", + }.get(state, "poweredOff") + + +def _prop(name: str, value: str) -> str: + return f"{escape(name)}{escape(value)}" + + +def _service_content_response() -> str: + return _wrap( + "RetrieveServiceContentResponse", + f""" + group-d1 + propertyCollector + ViewManager + + VMware vCenter Server + VMware vCenter Server {VIM_VERSION} simulator + VMware, Inc. + {VIM_VERSION} + 22361780 + INTL + 000 + linux-x64 + vpx + VirtualCenter + {VIM_VERSION} + 5029aaaa-bbbb-cccc-dddd-eeeeeeeeeeee + VMware VirtualCenter Server + 8.0 + + SessionManager + AuthorizationManager + SearchIndex + EventManager + TaskManager + guestOperationsManager + FileManager + VirtualDiskManager + OvfManager + IpPoolManager + CustomizationSpecManager + """, + ) + + +def _empty_response(tag: str) -> str: + return _wrap(tag, "") + + +def _wrap(response_tag: str, inner: str) -> str: + return f""" + + + <{response_tag} xmlns="urn:vim25"> + {inner} + + + +""" + + +def _fault_envelope(fault: SoapFaultError) -> str: + return f""" + + + + {escape(fault.fault_code)} + {escape(fault.message)} + + + +""" + + +def _xml_text(body: str, tag: str) -> str | None: + match = re.search( + rf"<(?:\w+:)?{re.escape(tag)}[^>]*>([^<]*)", + body, + ) + return match.group(1) if match else None + + +def _xml_attr_or_text(body: str, tag: str) -> str | None: + """Read MOR-style tags: host-11 or plain text.""" + + match = re.search( + rf"<(?:\w+:)?{re.escape(tag)}\b[^>]*>([^<]*)", + body, + ) + if match and match.group(1).strip(): + return match.group(1).strip() + return None + + +def _rest_guest_from_vim(guest_id: str) -> str: + mapping = { + "ubuntu64Guest": "UBUNTU_64_GUEST", + "centos64Guest": "CENTOS_64_GUEST", + "rhel8_64Guest": "RHEL_8_64_GUEST", + "windows2019srv_64Guest": "WINDOWS_2019_64_GUEST", + "otherGuest64": "OTHER_GUEST_64", + "otherGuest": "OTHER_GUEST", + } + return mapping.get(guest_id, guest_id.upper() if guest_id.islower() else guest_id) diff --git a/app/web/__init__.py b/app/web/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/web/assets.py b/app/web/assets.py new file mode 100644 index 0000000..1760ad0 --- /dev/null +++ b/app/web/assets.py @@ -0,0 +1,21 @@ +"""Static web console assets.""" + +from __future__ import annotations + +from pathlib import Path + +_WEB_ROOT = Path(__file__).parent +_CONSOLE_HTML = _WEB_ROOT / "index.html" +_COMPACT_CONSOLE_HTML = _WEB_ROOT / "console.html" + + +def console_html() -> str: + """Return the latest lab UI markup from disk.""" + + return _CONSOLE_HTML.read_text(encoding="utf-8") + + +def compact_console_html() -> str: + """Return the compact vSphere session console markup.""" + + return _COMPACT_CONSOLE_HTML.read_text(encoding="utf-8") diff --git a/app/web/compatibility_catalog.py b/app/web/compatibility_catalog.py new file mode 100644 index 0000000..54eb151 --- /dev/null +++ b/app/web/compatibility_catalog.py @@ -0,0 +1,77 @@ +"""Catalog-scoped compatibility summaries for the web console.""" + +from __future__ import annotations + +from app.compatibility import CompatibilityDimension, CompatibilityReport, build_report +from app.config import Settings +from app.contracts.model import Snapshot +from app.web.contract_catalog import major_release + +MethodKey = tuple[str, str] + + +def compatibility_payload( + snapshot: Snapshot, + major: int, + *, + implemented_methods: frozenset[MethodKey] | None, + runtime_report: CompatibilityReport | None, + runtime_version: str | None, + settings: Settings | None, +) -> dict[str, object]: + """Build a compatibility summary for the selected catalog major.""" + + declared = frozenset( + (contract_path.path, method.verb.upper()) + for contract_path in snapshot.paths + for method in contract_path.methods + ) + implemented = (implemented_methods or frozenset()) & declared + + if runtime_report is not None and runtime_report.source_version == snapshot.source_version: + payload = runtime_report.as_json() + evidence_scope = "full" + else: + dimensions: dict[CompatibilityDimension, frozenset[MethodKey]] = { + CompatibilityDimension.ROUTE_METHOD: declared, + } + if runtime_report is not None: + for dimension, methods in runtime_report.dimensions.items(): + if dimension == CompatibilityDimension.ROUTE_METHOD: + continue + dimensions[dimension] = methods & declared + else: + for dimension in CompatibilityDimension: + if dimension != CompatibilityDimension.ROUTE_METHOD: + dimensions[dimension] = frozenset() + + empty: frozenset[MethodKey] = frozenset() + if runtime_report is None: + observed = empty + verified = empty + incompatible = empty + regressions = empty + else: + observed = runtime_report.observed & declared + verified = runtime_report.verified & declared + incompatible = runtime_report.incompatible & declared + regressions = runtime_report.regressions & declared + catalog_report = build_report( + snapshot, + implemented=implemented, + observed=observed, + verified=verified, + dimensions=dimensions, + incompatible=incompatible, + regressions=regressions, + ) + payload = catalog_report.as_json() + evidence_scope = "catalog" + + release = major_release(major, settings) + payload["major"] = major + payload["catalog_version"] = snapshot.source_version + payload["latest_version"] = release.latest_version + payload["runtime_version"] = runtime_version + payload["evidence_scope"] = evidence_scope + return payload diff --git a/app/web/console.html b/app/web/console.html new file mode 100644 index 0000000..6bfb9ea --- /dev/null +++ b/app/web/console.html @@ -0,0 +1,342 @@ + + + + + + VMware API Emulator · Console + + + +
+
+
+

VMware API Emulator

+

+ Lab console for the vSphere REST surface. Sign in with a session, inspect + inventory, and send requests using the vmware-api-session-id header. +

+
+ +
+ +
+
+

Authentication

+ + + + + + +

Default lab user: administrator@vsphere.local / VMware1!.

+ + +
Not authenticated
+
+ +
+

Inventory snapshot

+
+
vCenter
+
Hosts
+
VMs
+
+
+ + + +
+
+ +
+

Quick request

+
+
+ + +
+
+ + +
+
+ + + +

Authenticated requests attach the session header automatically.

+
+ +
+

Response

+
Waiting for a request…
+
+ +
+

Task lookup

+
+
+ + +
+
+ + +
+
+
+ + +
+
+
+
+ + + + diff --git a/app/web/contract_catalog.py b/app/web/contract_catalog.py new file mode 100644 index 0000000..cf1e726 --- /dev/null +++ b/app/web/contract_catalog.py @@ -0,0 +1,358 @@ +"""Lazy-loaded API contract catalog grouped by vSphere release labels. + +Wire format keeps integer ``major`` ids (6-9) for hot-swap compatibility with the +console; each id maps to a vSphere version label (7.0...8.0 U2). +Bundled snapshots are temporary stubs carried from the Proxmox skeleton until +real vSphere REST/SOAP contracts land in a later iteration. +""" + +from __future__ import annotations + +import asyncio +import re +from dataclasses import dataclass +from datetime import UTC, datetime +from functools import lru_cache +from pathlib import Path + +from app.api.openapi import contract_openapi_tag +from app.config import Settings +from app.contracts.examples import path_param_example, schema_example +from app.contracts.importer import RemoteSourceImporter +from app.contracts.model import Method, Parameter, Snapshot +from app.contracts.normalize import normalize_snapshot +from app.contracts.source import ApiViewerParser +from app.contracts.store import RevisionStore + +_PATH_PARAM = re.compile(r"\{([^{}]+)\}") + + +@dataclass(frozen=True, slots=True) +class MajorReleaseMeta: + major: int + series: str + latest_version: str + bundled_revision: str | None = None + + +@dataclass(frozen=True, slots=True) +class MajorRelease: + major: int + series: str + latest_version: str + artifact_url: str + bundled_revision: str | None = None + + +# Integer majors are stable wire ids used by /ui/api/* and the console. +# Series names are the vSphere version labels shown in the UI. +_MAJOR_METADATA: tuple[MajorReleaseMeta, ...] = ( + MajorReleaseMeta( + major=6, + series="vSphere 7.0", + latest_version="6.4-15", # stub contract revision label + bundled_revision="96cd7121e75cdb3efd58f79ca988f6b235a2f28e6f7eae276ae243f65d8a6724", + ), + MajorReleaseMeta( + major=7, + series="vSphere 7.0 U3", + latest_version="7.4-16", + bundled_revision="2cf632fa6ea4939ca9cb7998ade688150db25b0684600f53ac0ca95730f1d99f", + ), + MajorReleaseMeta( + major=8, + series="vSphere 8.0", + latest_version="8.4.5", + bundled_revision="fce6db0a784b3a9b447895895fc6ff4b4437c2dce82e5f3db99227af217726fa", + ), + MajorReleaseMeta( + major=9, + series="vSphere 8.0 U2", + latest_version="9.2.3", + bundled_revision="e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1", + ), +) + +# Placeholder artifact URLs — temporary stubs until vSphere contracts are imported. +_DEFAULT_ARTIFACT_URLS: dict[int, str] = { + 6: "stub://vmware/vsphere-7.0/api-contract", + 7: "stub://vmware/vsphere-7.0u3/api-contract", + 8: "stub://vmware/vsphere-8.0/api-contract", + 9: "stub://vmware/vsphere-8.0u2/api-contract", +} + +_SNAPSHOT_CACHE: dict[int, Snapshot] = {} +_SNAPSHOT_LOCK = asyncio.Lock() +_DEFAULT_STORE = Path("contracts") + + +def _artifact_urls(settings: Settings | None) -> dict[int, str]: + if settings is None: + return dict(_DEFAULT_ARTIFACT_URLS) + return settings.catalog_artifact_urls() + + +def get_major_releases(settings: Settings | None = None) -> tuple[MajorRelease, ...]: + urls = _artifact_urls(settings) + return tuple( + MajorRelease( + major=meta.major, + series=meta.series, + latest_version=meta.latest_version, + artifact_url=urls[meta.major], + bundled_revision=meta.bundled_revision, + ) + for meta in _MAJOR_METADATA + ) + + +def series_name(major: int, settings: Settings | None = None) -> str: + return major_release(major, settings).series + + +def major_release(major: int, settings: Settings | None = None) -> MajorRelease: + releases = {release.major: release for release in get_major_releases(settings)} + try: + return releases[major] + except KeyError as error: + raise ValueError(f"unsupported major version: {major}") from error + + +def list_majors( + *, + runtime_version: str | None, + settings: Settings | None = None, +) -> dict[str, object]: + return { + "runtime_version": runtime_version, + "majors": [ + { + "major": release.major, + "series": release.series, + "latest_version": release.latest_version, + "artifact_url": release.artifact_url, + "bundled": release.bundled_revision is not None, + } + for release in get_major_releases(settings) + ], + } + + +async def load_snapshot( + major: int, + store_root: Path | None = None, + *, + settings: Settings | None = None, +) -> Snapshot: + if major in _SNAPSHOT_CACHE: + return _SNAPSHOT_CACHE[major] + async with _SNAPSHOT_LOCK: + if major in _SNAPSHOT_CACHE: + return _SNAPSHOT_CACHE[major] + release = major_release(major, settings) + store = RevisionStore(store_root or _DEFAULT_STORE) + if release.bundled_revision is not None: + snapshot_path = store.root / release.bundled_revision / "snapshot.json" + if snapshot_path.is_file(): + snapshot = Snapshot.model_validate_json(snapshot_path.read_bytes()) + _SNAPSHOT_CACHE[major] = snapshot + return snapshot + existing = _find_cached_revision(store, release.latest_version) + if existing is not None: + snapshot = Snapshot.model_validate_json(existing.read_bytes()) + _SNAPSHOT_CACHE[major] = snapshot + return snapshot + raw = await RemoteSourceImporter(release.artifact_url).load() + parsed = ApiViewerParser().parse(raw) + snapshot, manifest = normalize_snapshot( + parsed, + raw=raw, + source_version=release.latest_version, + retrieved_at=datetime.now(UTC), + ) + try: + store.save(raw, snapshot, manifest) + except OSError: + pass + _SNAPSHOT_CACHE[major] = snapshot + return snapshot + + +def _find_cached_revision(store: RevisionStore, source_version: str) -> Path | None: + if not store.root.is_dir(): + return None + for revision in store.list(): + manifest = store.manifest(revision) + if manifest.source_version == source_version: + return store.root / revision / "snapshot.json" + return None + + +def _catalog_entry_path(entry: dict[str, object]) -> str: + return str(entry["path"]) + + +def catalog_payload( + snapshot: Snapshot, + major: int, + *, + implemented_methods: frozenset[tuple[str, str]] | None = None, + settings: Settings | None = None, +) -> dict[str, object]: + grouped: dict[str, list[dict[str, object]]] = {} + for contract_path in snapshot.paths: + tag = contract_openapi_tag(contract_path.path) + methods = [ + { + "verb": method.verb, + "name": method.name, + "description": method.description, + "protected": method.protected, + "implemented": ( + (contract_path.path, method.verb.upper()) in implemented_methods + if implemented_methods is not None + else None + ), + } + for method in contract_path.methods + ] + entry: dict[str, object] = { + "path": contract_path.path, + "methods": methods, + } + grouped.setdefault(tag, []).append(entry) + categories: list[dict[str, object]] = [] + for tag in sorted(grouped): + entries = grouped[tag] + categories.append( + { + "tag": tag, + "paths": sorted(entries, key=_catalog_entry_path), + } + ) + release = major_release(major, settings) + return { + "major": major, + "series": release.series, + "source_version": snapshot.source_version, + "latest_version": release.latest_version, + "artifact_url": release.artifact_url, + "bundled": release.bundled_revision is not None, + "path_count": snapshot.path_count, + "method_count": snapshot.method_count, + "categories": categories, + } + + +def _path_param_names(path: str) -> tuple[str, ...]: + return tuple(match.group(1) for match in _PATH_PARAM.finditer(path)) + + +def _parameter_payload(parameter: Parameter) -> dict[str, object]: + schema = parameter.definition + return { + "name": parameter.name, + "type": schema.type, + "description": schema.description, + "optional": bool(schema.optional), + "enum": list(schema.enum), + "example": schema_example(schema, name=parameter.name), + } + + +def method_payload( + snapshot: Snapshot, + *, + major: int, + path: str, + verb: str, + runtime_version: str | None, + implemented_methods: frozenset[tuple[str, str]] | None, +) -> dict[str, object]: + contract_path = next((item for item in snapshot.paths if item.path == path), None) + if contract_path is None: + raise KeyError(path) + method = next( + (item for item in contract_path.methods if item.verb.upper() == verb.upper()), + None, + ) + if method is None: + raise KeyError(verb) + path_params = _path_param_names(path) + path_fields = [ + _parameter_payload(parameter) + for parameter in method.parameters + if parameter.name in path_params + ] + for name in path_params: + if name not in {field["name"] for field in path_fields}: + path_fields.append( + { + "name": name, + "type": "string", + "description": None, + "optional": False, + "enum": [], + "example": path_param_example(name) or name, + } + ) + body_fields = [ + _parameter_payload(parameter) + for parameter in method.parameters + if parameter.name not in path_params and "[n]" not in parameter.name + ] + indexed_fields = [ + _parameter_payload(parameter) for parameter in method.parameters if "[n]" in parameter.name + ] + body_example = _body_example(method, path_params) + resolved_path = _resolve_path(path, path_fields) + implemented = ( + (path, method.verb.upper()) in implemented_methods + if implemented_methods is not None + else None + ) + return { + "major": major, + "source_version": snapshot.source_version, + "runtime_version": runtime_version, + "path": path, + "verb": method.verb.upper(), + "name": method.name, + "description": method.description, + "resolved_path": resolved_path, + "path_fields": path_fields, + "body_fields": body_fields, + "indexed_fields": indexed_fields, + "body_example": body_example, + "implemented": implemented, + } + + +def _resolve_path(path: str, path_fields: list[dict[str, object]]) -> str: + resolved = path + for field in path_fields: + name = str(field["name"]) + example = field.get("example", name) + resolved = resolved.replace(f"{{{name}}}", str(example)) + return resolved + + +def _body_example(method: Method, path_params: tuple[str, ...]) -> dict[str, object]: + body: dict[str, object] = {} + for parameter in method.parameters: + if parameter.name in path_params: + continue + if "[n]" in parameter.name: + concrete = parameter.name.replace("[n]", "0") + if not parameter.definition.optional: + body[concrete] = schema_example(parameter.definition, name=concrete) + continue + if parameter.definition.optional: + continue + body[parameter.name] = schema_example(parameter.definition, name=parameter.name) + return body + + +@lru_cache(maxsize=1) +def default_store_root() -> Path: + return _DEFAULT_STORE diff --git a/app/web/index.html b/app/web/index.html new file mode 100644 index 0000000..4cff525 --- /dev/null +++ b/app/web/index.html @@ -0,0 +1,7014 @@ + + + + + + VMware API Emulator + + + + + +
+
+
+ +
+
+ + + + + + VMWARE + + API Simulator + + +
+ +
+
+
+
+ +
+ Endpoint +
+ + +
+
+
+ + +
+
+
+ + + + +
+ +
+
+
+
+ +
+
+ +
+
+ Response +
+ + +
+
+
Waiting for a request…
+
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/app/web/routes.py b/app/web/routes.py new file mode 100644 index 0000000..bd9ac01 --- /dev/null +++ b/app/web/routes.py @@ -0,0 +1,340 @@ +"""Browser console for exercising the simulator API.""" + +from __future__ import annotations + +from pathlib import Path +from typing import Annotated + +from asyncpg import Pool # type: ignore[import-untyped] +from fastapi import APIRouter, HTTPException, Query, Request +from fastapi.responses import HTMLResponse, JSONResponse + +from app.api.registry import HandlerRegistry +from app.config import Settings +from app.contracts.runtime import apply_runtime_contract_locked, contract_store_root +from app.contracts.source import SourceError +from app.db.pool import AsyncpgDatabase +from app.dependencies import get_database +from app.simulation.seed import apply_seed, build_profile, simulation_state_summary +from app.web.assets import compact_console_html, console_html +from app.web.compatibility_catalog import compatibility_payload +from app.web.contract_catalog import catalog_payload, list_majors, load_snapshot, method_payload + +router = APIRouter(tags=["Simulator"]) + + +@router.get("/", response_class=HTMLResponse, include_in_schema=True) +async def console() -> HTMLResponse: + """Interactive API console and cluster overview.""" + + return HTMLResponse( + console_html(), + headers={"Cache-Control": "no-store"}, + ) + + +@router.get("/console.html", response_class=HTMLResponse, include_in_schema=False) +async def compact_console() -> HTMLResponse: + """Compact session console for quick REST smoke.""" + + return HTMLResponse( + compact_console_html(), + headers={"Cache-Control": "no-store"}, + ) + + +def _use_vsphere_plane(request: Request) -> bool: + settings = _settings(request) + return settings is None or not bool(getattr(settings, "enable_pve_stub", False)) + + +@router.get("/ui/api/versions", include_in_schema=False) +async def ui_versions(request: Request) -> JSONResponse: + settings = _settings(request) + runtime_version = _runtime_version(request) + if _use_vsphere_plane(request): + from app.vsphere.contracts.catalog import list_vsphere_majors + + return JSONResponse(list_vsphere_majors(runtime_version=runtime_version)) + return JSONResponse(list_majors(runtime_version=runtime_version, settings=settings)) + + +@router.get("/ui/api/catalog", include_in_schema=False) +async def ui_catalog( + request: Request, + major: Annotated[int, Query(ge=6, le=9)], +) -> JSONResponse: + if _use_vsphere_plane(request): + from app.vsphere.contracts.catalog import vsphere_catalog_payload + + return JSONResponse(vsphere_catalog_payload(major)) + settings = _settings(request) + try: + snapshot = await load_snapshot(major, _store_root(request), settings=settings) + except SourceError as error: + raise HTTPException(status_code=503, detail=str(error)) from error + implemented = getattr(request.app.state, "implemented_methods", None) + return JSONResponse( + catalog_payload(snapshot, major, implemented_methods=implemented, settings=settings) + ) + + +@router.get("/ui/api/method", include_in_schema=False) +async def ui_method( + request: Request, + major: Annotated[int, Query(ge=6, le=9)], + path: Annotated[str, Query(min_length=1)], + verb: Annotated[str, Query(min_length=1)], +) -> JSONResponse: + if _use_vsphere_plane(request): + from app.vsphere.contracts.catalog import vsphere_method_payload + + return JSONResponse( + vsphere_method_payload( + major=major, + path=path, + verb=verb, + runtime_version=_runtime_version(request), + ) + ) + settings = _settings(request) + try: + snapshot = await load_snapshot(major, _store_root(request), settings=settings) + except SourceError as error: + raise HTTPException(status_code=503, detail=str(error)) from error + runtime_version = _runtime_version(request) + implemented = getattr(request.app.state, "implemented_methods", None) + try: + payload = method_payload( + snapshot, + major=major, + path=path, + verb=verb, + runtime_version=runtime_version, + implemented_methods=implemented, + ) + except KeyError as error: + raise HTTPException(status_code=404, detail=f"unknown contract method: {error}") from error + return JSONResponse(payload) + + +@router.get("/ui/api/compatibility", include_in_schema=False) +async def ui_compatibility( + request: Request, + major: Annotated[int, Query(ge=6, le=9)], +) -> JSONResponse: + if _use_vsphere_plane(request): + from app.vsphere.contracts.compatibility import vsphere_compatibility_payload + + return JSONResponse( + vsphere_compatibility_payload( + major, + runtime_version=_runtime_version(request), + ) + ) + settings = _settings(request) + try: + snapshot = await load_snapshot(major, _store_root(request), settings=settings) + except SourceError as error: + raise HTTPException(status_code=503, detail=str(error)) from error + implemented = getattr(request.app.state, "implemented_methods", None) + runtime_report = getattr(request.app.state, "compatibility_report", None) + runtime_version = _runtime_version(request) + return JSONResponse( + compatibility_payload( + snapshot, + major, + implemented_methods=implemented, + runtime_report=runtime_report, + runtime_version=runtime_version, + settings=settings, + ) + ) + + +@router.post("/ui/api/contract/apply", include_in_schema=False) +async def ui_contract_apply( + request: Request, + major: Annotated[int, Query(ge=6, le=9)], +) -> JSONResponse: + """Hot-swap the in-memory runtime contract to a catalog major (memory-only).""" + + if _use_vsphere_plane(request): + from app.vsphere.contracts.matrix import VERSIONS, catalog_entries_for_major + + meta = VERSIONS.get(major) or VERSIONS[9] + entries = catalog_entries_for_major(major) + request.app.state.vsphere_contract_major = major + request.app.state.runtime_source_version = meta["version"] + request.app.state.vsphere_implemented_methods = {(e["verb"], e["path"]) for e in entries} + return JSONResponse( + { + "ok": True, + "major": major, + "runtime_version": meta["version"], + "plane": "vsphere-rest", + "path_count": len({e["path"] for e in entries}), + "method_count": len(entries), + } + ) + + settings = _settings(request) + handlers = getattr(request.app.state, "handlers", None) + if ( + settings is None + or settings.contract_snapshot is None + or not isinstance(handlers, HandlerRegistry) + ): + raise HTTPException(status_code=503, detail="runtime contract is not available") + store_root = _store_root(request) + try: + snapshot = await load_snapshot(major, store_root, settings=settings) + except SourceError as error: + raise HTTPException(status_code=503, detail=str(error)) from error + await apply_runtime_contract_locked( + request.app, + snapshot, + handlers=handlers, + store_root=store_root, + fallback=settings.contract_fallback, + settings=settings, + require_evidence_match=False, + register_admin=True, + ) + method_count = sum(len(path.methods) for path in snapshot.paths) + return JSONResponse( + { + "ok": True, + "major": major, + "runtime_version": snapshot.source_version, + "path_count": len(snapshot.paths), + "method_count": method_count, + } + ) + + +@router.get("/ui/api/demo/state", include_in_schema=False) +async def ui_demo_state(request: Request) -> JSONResponse: + from app.vsphere.seed import vsphere_state_summary + + settings = _settings(request) + try: + vsphere = await vsphere_state_summary(get_database(request)) + except Exception as error: + raise HTTPException(status_code=503, detail=f"database is not ready: {error}") from error + if settings is not None and getattr(settings, "enable_pve_stub", False): + try: + pool = _database_pool(request) + except Exception as error: + raise HTTPException(status_code=503, detail=str(error)) from error + async with pool.acquire() as connection: + pve = await simulation_state_summary(connection) + return JSONResponse({"vsphere": vsphere, "proxmox_stub": pve}) + return JSONResponse( + { + "vsphere": vsphere, + "loaded": vsphere.get("vms", 0) >= 100, + "label": f"{vsphere.get('hosts', 0)} hosts · {vsphere.get('vms', 0)} VMs", + } + ) + + +@router.post("/ui/api/demo/load", include_in_schema=False) +async def ui_demo_load(request: Request) -> JSONResponse: + from app.vsphere.seed import seed_vsphere_inventory + + settings = _settings(request) + summary: dict = {} + profile_name = "demo-cluster" + if settings is not None and getattr(settings, "enable_pve_stub", False): + pool = _database_pool(request) + profile = build_profile("demo-cluster") + async with pool.acquire() as connection: + await apply_seed(connection, profile) + summary = await simulation_state_summary(connection) + profile_name = profile.name + try: + vsphere = await seed_vsphere_inventory( + get_database(request), force=True, profile="demo-cluster" + ) + except Exception as error: + raise HTTPException(status_code=503, detail=f"database is not ready: {error}") from error + return JSONResponse( + {"ok": True, "profile": profile_name, "summary": summary, "vsphere": vsphere} + ) + + +@router.post("/ui/api/demo/unload", include_in_schema=False) +async def ui_demo_unload(request: Request) -> JSONResponse: + """Reset seed, wiping API-created state first.""" + from app.vsphere.seed import seed_vsphere_inventory + + settings = _settings(request) + summary: dict = {} + profile_name = "small" + try: + if settings is not None and getattr(settings, "enable_pve_stub", False): + pool = _database_pool(request) + profile = build_profile("minimal") + async with pool.acquire() as connection: + await apply_seed(connection, profile) + summary = await simulation_state_summary(connection) + profile_name = profile.name + vsphere = await seed_vsphere_inventory(get_database(request), force=True, profile="small") + except HTTPException: + raise + except Exception as error: + raise HTTPException( + status_code=503, detail=f"failed to remove demo data: {error}" + ) from error + return JSONResponse( + {"ok": True, "profile": profile_name, "summary": summary, "vsphere": vsphere} + ) + + +@router.post("/ui/api/vsphere/seed", include_in_schema=False) +async def ui_vsphere_seed(request: Request) -> JSONResponse: + """(Re)seed native vSphere inventory used by /api and /sdk.""" + + from app.vsphere.seed import seed_vsphere_inventory + + profile = request.query_params.get("profile") or "large" + try: + result = await seed_vsphere_inventory(get_database(request), force=True, profile=profile) + except Exception as error: + raise HTTPException(status_code=500, detail=str(error)) from error + return JSONResponse({"ok": True, **result}) + + +def _database_pool(request: Request) -> Pool: + database = get_database(request) + if not isinstance(database, AsyncpgDatabase): + raise HTTPException(status_code=503, detail="database is not available") + return database.pool + + +def _settings(request: Request) -> Settings | None: + return getattr(request.app.state, "settings", None) + + +def _runtime_version(request: Request) -> str | None: + active = getattr(request.app.state, "runtime_source_version", None) + if isinstance(active, str) and active: + return active + settings = _settings(request) + if settings is None or settings.contract_snapshot is None: + return None + from app.contracts.model import Snapshot + + snapshot = Snapshot.model_validate_json(settings.contract_snapshot.read_bytes()) + return snapshot.source_version + + +def _store_root(request: Request) -> Path: + stored = getattr(request.app.state, "contract_store_root", None) + if isinstance(stored, Path): + return stored + settings = _settings(request) + if settings is not None: + return contract_store_root(settings) + return Path("contracts") diff --git a/app/web/static/vmware-favicon.png b/app/web/static/vmware-favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..6810c024ffc0fdd8edf10c88928ca2049346c3e5 GIT binary patch literal 2423 zcmV--35fQIP)4Tx0C=2zkg-d{P!PtyR;8eI5FH#GGKoW!k_x&wv=u~g2vx!Al)k2^kj6)n zA_X`9fr9^m3eIj8hdMeq2%?kd=H#T{qUCuniKHTWkK=xP@4MqTAUSSuZubMIJHA_7 z$}5|tEhY7g1ic^(=JA}auS))|KjZyA^xjU(S-=1PjlqiPF{+=G8OB{7NT|g6p3f!k z6OXyH6md(k74nJXa>(a_XT4Y;z9v>!&8QH+5Ub@L-Rj}G-C)rUa{ILDY^=#SloMFQ z4m@z!Fwleo9oawpvw^>WU2-?!QlEtyeCo-OA}5%{%W%Lj1C>}qhEkJvj_!9C-A|3R zgC}62BZRn!wUrKVHb*CG$J*39Ffs&OwYlLMfz(HttX6^7Q((9RjNVYswpYz+;r8h~ zFz_hE+a!=W1iCFDK8}Rw9#iuJaOr#j1E*pW!Pr_8000NtNklh=iKl6&iPI$Yi$fM zQsg-|Z+ys~UOCTyE?sBRIuxJYRu+a+$2WNL@rM}>_tRR7RtnX&ZOrqWzr6Z)e)_AI z_+SsREC;1O#qdCkc;9m5K*qP8e~L#RIgPaz6=RIAo&5(t{PFMT@7ti?GsGB|?i3v4 ze}$6$C*>7CF+NIVOlnI#y2cN_^FrhH{ap%G1=7{rP zTm7-r%rBpwl}F6aX+>r{VCnZVLOjebUU-=YPaVgcfAbx#T(21nS8&d!;E{-mvn0BQ zIjdOR=Q;l19{r(3WnE&{1$>C<6MP_gfx7zyA8{7OHwtz(*HOB_d(WU(a^-_P&cF2z z=HlfoeAG+$MTkm%g`bp=_b}Y=`NCJPFg!BBJCz`nEd)s-rsRF=vDRbTfV0z&^Tg=5 zc=9I!=)?N(ISL7bumsKEJ+9sviyi^G@p53oPv*UX1La%be0mcHl(1g z^|X>e849VSId!McEIE*ME-p)S*J)5=Yusdj75y&P!k zKBCGHA~6`eP!LG)I~N(QTkbe9!FhS0XrW5yRkqNFnTt0qy+dFo!jyz$q$5#>bj}ok z*Zg!5ym6X8awuU|0hSe-X23R z7ucn@d|VD@Cj6NWME*}b_W{Sw?9n!z+67uE!?qSkV#j%ewN+2Bns!%9O9iV%Ef^IT z9Ue?1KYsH(Uy&q6?-?c)T{G81d+Rn=pqtTn}WzaA!u~e=+L5~ zg-mrp(ux<6((0G!Phy|xC5Av%HLMOj!7J7efiWr}>b>LaZztT`9;Rba;EW~JhpQB2 zL`z@xk!YJ~)qJ!^rhK}pPFo5bBTZ`)ohH?z^NdDyYO_)?$sPL{=U=LL_4jwPdhj4s z6$#R?l%m&<>{fxg)kNFkoWmGVuOz83;v3UkI_TwiM_uDBJ~q^iO^KMuyM-I8ft2FDn$$98ljq(jED?*VdSS7P+cUwjiMV2XIh*)Qt zG!=W}F-F@|%CiK`LWB!_L;^OnOxlXA?FpYhY5DFqu1@P%cTn3L+J+ZjZ28-}YYciM zKadAs-YVG~AAndfp41f0h}ODS!Ug*D|+6Tc;{WUKk9n4)n}T zUVmHh>$At$zoM{hmR4ahMPVG73X}usgo*vR4n9%^aoP!H+rr(t6{Ys66q%N$*zv4= zjna-XHw+5L#vK*C1KXWZO{a(b>ou`|6>nw6aKs?Xmj~X0KwMT!Lcxo>g+K^lacwdQ z;Z&3#lK4oKA(oplJXmq~;eSz2^t9=83$U%B=w<9|TU;|huPoIfORaczM7}yN-7h46 zUv3`3YgEXHO-*nTLZ{Z7k``yI4YtXMIJ|489k5|Ca$Gz+q}M-2#3Dp45Qs~iYT7h{ z>nv7~5HGl~BNGV}{Qz|fdQ8!mdTrUdQIP3Q?NYv3?s)e#&*<7oOeyqfY~74Ohg21Q z;fBJw?4@5cjReo}ZjZ^%eg^%F7~9miqM8l4wj` zn@_hXcvu7%s3n2(L-+IGb+3*G5Rq5VGr+@%56GdiXdgu7C$L<%e}|%#5{2SeLViz zqx|8|*Eq6q7;9ThA*1vP!R_n#OO$p@CizWYK-BVH)LzOtvGv)@&1|}sYtmoxqQ}nH#c!&sbZ*Fp|glGA?;-}OD`j7fBUDSPfU!cQCjZr zM)%owRE`T7*EX+mV!h&z23leKrIy zy*4dPILqf2#}rycR?EN>XYS@J&p*qZNAF5=gp${DDJ@ANc*}(g7kKZ|W$L>5c&`7? pt=B8K=h$7`bK+ifX1d@?@n7Qc+czw}V%Gow002ovPDHLkV1jstudx6C literal 0 HcmV?d00001 diff --git a/app/web/static/vmware-mark.png b/app/web/static/vmware-mark.png new file mode 100644 index 0000000000000000000000000000000000000000..7a7c09ab54c5144e70182bed453407e1911383fb GIT binary patch literal 8477 zcmV+&A>!VNP)NbdV~hZA?Du_NfBjwkHNgMDB?SVP0Z1uHrBb1TgOdb?^}ZRHl55t0%DG=U zIk+pv;RL|c)Re4@R|F7PyY`PHpCFzj0dOfn#9T(>P237NhsBjTaKmp>#Lp2@@03D- z+LQqLu-=eTf>bRq`=vQgNX@?He7vW?d+3{j1R@ClkwVsr>-o3qH7P~l!P2~#Yb?O` zr;n}w;pk|2S-&d~qMIx)3j&l%B}xdv_u`-Z)<d z?HW~FwYzn1MuZK@JP3u*_*6tLw+KT7BC_#=ghNCtqyh+z`_&a7BsIj+`|u;UA*7(u zK6Mv!jL`h;B9v--(^UYCY6wHS&YXPFPrm(u`BUMi3Ay`0(;h+yk(YD~KygDzS(M)Q zzHPVMUi{nqU~QE2b6BcYfrlL5Q!}mlXudJr)8W3&oUa(!aJf*&ai4jAMHH!z;|Kql zUSf%438a4G`R16yy}h6561WWpw^B$(7$aWJgW8gS*=HMHdF&f2zxbc`-M5I$S1y;u zB_V))_(yiW_4Z>>h0mARRbG#_~ zj=Xhxu_h>B=RDv0TKTPhMaZ`rjK)u_%_u~h-V!0pLAE;0+)s-V-Fu=Zs4*czYD`#{ zfDzK|_@KKT4}tXbGP(H$JwFQo_wF9sBB8u?Jpjdv-1~-^Jp+Seuu=E1f1cNKg~m?| zmKlY^>6RNKbw(3GAG2b_aIZN{56XI5&f2y^w@SugeQ-7c8eff!l#Wn<1qZC$fC>iP=t=9+}ucad+A zmLAk2&bQYXt;zJDnEP#ijN7PzkTB%3cObuM%hrMGa8IeE$AXLB1B`27!=M-tB!mlr zd}-B30m=Z=;zesAmP4&vR(ibc5$3%3V|tT1$7nQ0^^C7K-}aisSfJY#5v6IrZMoK$ zay?8I`@NUzeG_y|2rvv|${yl^?3FUa7hKgdrRF;Ht%QU^NEr#42ZAxwp+GRIzX^Wh z$I~B1rT%S>tNm08g6EoR)pbPwZaUu_)AyEw5Q)zS0YoUJMDtv>Lw+=_Skr?8cpf3^ zxAx==V%EwM)~Zg82gTmB!0ZH43NMdF4WpbB8a4z3J_o-R0#6x9TBnb$i#go55Mqrc z){wNuIk zq9$uXNUv*!UrH$p#T-3-WC>0mTlwDXiIpdUIy~KI@VS8v`9pzvjQ~Pdss+h=s6&Yp z%>JfbxWm)uYlyRvu6dPEba+WXGjeOx+`wF{c8~fgC9(m-E z=g@~#fhjUMv5P35`|dT26*#bKa+>Vky+y(Zz$mF4x^e4=UYFZ^_TakpjU9_;8^WsB zG3OKQVO2ZzJqSr^B5Oqe^xt-rJrcD7kI2Rfr$-;3`9nm0X?!G4NZE(W3`*mre0lWF zg@4@pH}70O6jl}%PH~2ATnko>ZMqUY*)gnDFho)cK}Qk@2`tCRsUwT>>4#?yDj(A1 zuJhAfFA|K6j0GiGqH~j*|0ArylfAtKCI$9is~)*N4E;yhimCh1i|&S?M2@`uy@T}? z@?$(u24HJ45D?6xWO<=J{p6vO&r%AqTrOXhp*?i0?XFCbKl-CzT`A`CPv!GD?FGey zkoYS`a%5y2 z<$1S+C-o(oBRxbR7(LCA;7N1<^Y&y72{1M`rrOg3tRMvGwfb-?kgER@$Q8V!>iP-A zFf9pSt;hpC8Kx^Qovw1DScwwKwg3#;0w_sIO#)!w!NEy zD3iaw5@>6&4d_^_?j85vfB&|tudUux%vJkpehnCS1e*M<41jZoP7b{|{tsn;u?Rts zKl;Uohb9Sm?Mm10=WCaRHR6&DbvK$FVcxk!w(R!q-BToymXU@Tpr!pK@xw1DbG{CQ z6tfsgx((Gno3>nMMbkqMf9j=sUM&C06Nhi<8=&jKm_rKLN(FQ-!ni&XAPfLR;5hFs z$6{!13F?a>+_CS(@i#yA?)&fk?BRC+>F%q9()4Y=L<2&2F?~c@KYpYsbP`hjOeG$I|BqBd(fK)NXSTqn75Y;lA0bxCP@Ba;4+yA!Tc*C~o7wj#M8FAE|h)dAH z5;rk2bWZ>+W5+O@A3gj}-*fj>FMSDRTdxV_>@2ye5s+&Z8p~1$lRART$IZ6{3IasV zqdNx&{dIvKsMG+rtum#X;cuH_k_{zBNI87!slWUAEn9*YLv^OX1&4q zy~;R$G*Vb%Ff{RhO#~%U1kcZ}h)o;wfBeY(Z~GTQ?tVs=fRb{%@hCF-4I}A6H+E2G zLrVgT%W+0j-cA`l|J8e6v-ukTHedLA7sJI@dWC>iivSykynLaj07J-K?KD~TvDdO-126C6%M5_GD+-D7Q2Rj74DLI|ZKb>ipb z$fTm-71z{191bkYdX0x3BL4z`4JStVGcp<6j#ECmxtlA|(lXtEGS4u~h@!_3AhTgD ze`q&iCs2g9J<&!65;{Q47>R5Grw5ewm%K75hxa{r#qGr*a`VDsl`~4c3+0G$pY8g} zWn?8fnG79`PZ#M%^kis05OIGO8f4QrV8AlNMCa?ZA*@x-rhD6QE_GRKR1NP|O(?8y zyp8l=*mD&Tl+JBSWUyJz=Vs*9!StAKx|4E__{lNHh-MorD$9;NtC`byM)UOPe zL>2)E%Ko?9bdOgU;CpI*!zk3}4~g#Qv?0zskeX4gsnXWwbZ=}pAHOrs$GB}$^JxJj zz0qvZb_ZFFaK5tWYY9-2I!EOtZ(q5t&`-DdjZoQ#t9g9OW`xWxjlr(y; z!diN;ZQ3xKow*@_c<0ilre)yNb5*Pt?HpKN=;I)kL85ut4HzG|@NyKGhYG8{Qle|X zh+k!xD-*(`2iim@iN{35`8*U}Pj3Oyzpm4BRru8oeD2%hz=9w9@GK;Bzp3XmCh3AhfNgl{&!ay$dY{(tr4I^s^ zK)yGJffns@P~t}G!edsic!KA}?gmRbX zB^!jJkVbw-y+5<(Wbxc8eQz!9pEN9++m-2NAf341qoTeN(zz4WzsA90Y+{U+%LhWt zbzF0hR`gizUnS?BrwZy`kWdI5(E=8uA za2lmY@pduiwvcYUV>xww$4t&oYD78|k<@<^1gP=`a8wK1^Z~pNrG!C?ps5+gA0;G&p{RA=ycUBlj!|fxiV#R%K90L42d7EX7=ReU z%K{mwyn0F~P+&j_i+Tmc>@`Z+z!in>1DshNmm|!~dCCNgG3d~y?#&}3<3-rM9ky@Z z?ws{p7jL*7R{E#O{PGsLZ^!Y096MNq(7GH}!TsI$1_E5j9Ap2jehqgJvne;0mH&cs z2zUsbhafx;Sg$^Bl%PE*?6_>& zs`se`D@?TFG7#*{g1@A8cL)dTj->A?1c#6Z5F*k!;t<6px~Un4bDKqwg?3gC5&{W= z@d;lr2*QALk-NhmfBc@GzGlbLcwfI<4;$^Y_9}qX(yQ$oxgJjyu{ZnCZBa+gw}Y>m z3meTmY<;g5$5Mc4=4^9c{^S#94jnzX@L%>_+Rxe)5Mas+5gPF}^~FvTHP14M7ZEgx zpiY3rGeY5mAJ#j_{IY!Lq0jx;3$8x-g}&aoVz}%FSdyUiphlbDBiBu@%tDuIsV~n0vZYGTWa_34!p5C#G*3Sl1|u6+fWVL-%D@#Wx_q{ZzA! z%G)(BrLs#n2oXpOnAYlI`Q$STCE|HUJR(Ra^<V0L2j*S7NtD9s2W3IYsl62Et--7YF7C}*2 z7xTLt#lOFY2LN2>31&J=NNU?~yv=gR%B?{LP?4@U(_x^O)%Nc%c{>2S9m7+>#DrGy z&JBh!K9W+G+XBhujdhhuM@m36ew~8|O4MD5Zq~VdJq63kS@>vH+7$95?nk+Al4_;X z8!*d(Hvl-!T0&7sfD)gg?@8`2LDxB)En(H}6uIFF8qCe>vNqPxZ8EMC(_U9G?q=m! zCg$X}gRb>+l4^>ZVi-3>>HFBJ1R~$6u0q)?YYnJ)O-}BTr4M~#0~N3nYhXmyqJy(m zi0_&JQ5h>Ykt!;H)B#o#Op;02FI}}$9XD<)a?bwG-}~8(oIvWWf*IbKmC8JAd?nd2#a9&(E9{ImW1ql4wwN zd`(Coj_wmD64gWiHBHD2Cho{?>+D4J72slVKQxa!QAv}GZl@a89b>=Zb#GsH#ilE| zZW*5HH|iu`=#ksD`B!h<-n;F}t69%twfaWcbLfq;eDSJhPn;GWO(8!@y-a4p<1{9$ zbJ4K}*c;%0jtNtGriqh88)O~|D&cr^l)u07XRjB%OP`!M zb3{<0%~hSXuDMAg%t_$Im^Wq|V4xP+lG2U!bv^VnryzzZ%A$RI{VXUgq;Z?B?%fe zj<*UWm(hD`MBAxL$*hG)qqpT|fH6;3gJ?2^nh2SGI=WYDV&Tl((qY_VC!i-qkYnwt z@yg17w_jPAe6HcY2wbG;B&(#4!`6Cprk18{gH?beYSzAzS$3k79Ur6bwAirCu-qJR zXx0OqH%sSKVGM;4T3c$IeE2gzIPJcCLQ}UQH^Kcj@~5d|2E^6mZ+0j9Wm>kWoKnO6 zQF7^dco;Gs?`j!|Vtdh{l=bhRHB0VCc|lFjA`*!oRKri<3ztf_>M4xPgRrfetP!lM zQaO!uOa7kMU|@Xw77{K8tJ$FZH@W>S<-OtGb76**=xH)3;+kakXW~0~Zc^P$JVr=~ z1)mmYs`XPx=RS?Q%5XrmwpHE2c#dGRS<8_nd_FxuCS4FR&DnYpgO*8BJ!8cv;BT-N|r4#Q9ETSwoCY(Cj2jAycBy#~J0+MLNY$ zS-l;tZR>39ULI;C1AARERnT(05j)s9%v`}XoNoqPCHHZrI3WzP!&N4@1X!M{&CZ=z z{)>Nq@BWXpDqrul6hTHUh$_w6v~p*=6Vw_ZtdD-BT@1P&e}cnZ(bGxBIbtCU#Hvam zXL7T1fMSS~F)xz;iIbAtuL#N|gjmh79{7}!A5|CqnXn#y^6CFRdHTqz1Flmst;LuJVA`c$4Uc^CU0?ktI7dKPKLHc;z}Nv^=@1}FjR8)1ai@T3q!!v> ze7n$_0-SFQFh5^>tWj-{LY`6HfB+;$%XI>ML_}%tucKW$zdtKQ-sOC4++a2YG&r4~ zZTtv#Rc5xdX%_3y=D6T0q2OVO`BPW!B!^EP?s|L~h6AEpR@r-cMrs$S-U$NKut0?! zbhR3lD2DAiw!+WJ2D8hQfKt_W|cEmH?c*S?Jea*=D^ts&LuZIL4djC zD&%ouzVh{G!C||sUM9rxf!J4Vkuj#$iYb-oH7|VkhrjcUw;j5EchA0tFK<*s2Ulrg zfcZYg{{a#U`h|^Tq$hivk;J1=$g#<1k1QRy{`LR*fYC78j@tPi8is26nmd}tjC9_X z{W(H{04p^gg3wD@ziE%C=^i(UJNKszgn`4WLrkLsKs?qNH zFjgF{6(k2??ks-b`h?uIQp}`kFGsto=ZQT*EowG`Gen^e@=Mn5)D;OLi zLBNBU%Tp_8G#OfJ1W9+aT^}n^Pd`~>AEip@3$boXU-8@v&Bg$Z)k{rr z4f7Ue&`mB_g9f8t5BXI)H@yCrOSg~hBjqu5zNuOC=ik6}vO1QSg4lW;?y@M4h3tEm zUtPv2@(PUp?*DV;BR7*xr#^agdX`fxWStg02Fw_s(zm?=Q<>3~$|w?xUvvVfy8Nou zjc*Iy`vyIu30)Df{EyblG7aZ}V7USjFaGh(rQiAcH}9M|!aq>?VC5hlFYjCJl+^>P zY<9cz^|E|_^NA1c*m14=r3O3w&Zp;}TerASmmbpu$n-DJK zB$752PPkBuE<$9Qx{IbI+z{>>j;e?ehQ=x67=!-a9BkR#t7h+D7D-TJd%YZZ`Ftp) z_sk1UN+=$G?li2_0+I6=ZIweB1yoF=IH>cErIRl#0VXsmmgmU#Yl|Ux1xe$TM0KOA zYa$j!T6GW{Xrt=$z6}&t@p#e3AuLeIcB^a5illnnixa(+r5$!E;k2 zjvvoG`og8)%=#kTgex_vXmZqLBlh1j$s6xWI+Af%m7X?0-)w97t+&_iOm0V6$@N4!6Yr zNuP%1eK%7gK5m#ajzp>1DY0iQ=~Q#q{7v>S`}owint9H-k?tp;pRXD! zvEBoI*O$qcq;gzpW_JBQ_N5}R5!nY$;M#t<^JXKrhPyCwoM~-wqc~Ad6V1-LaIlyP z-8La#Ge@&{OKs}#kfNcKUY^PNa`4olr=C}fFP~2`@9OOUGY-riC7+ppz7bFc#4Jo4 zBR}F=cil$kZf**reN~I(OgZ8}iX+ot?`Mr}Hx=9!XLe63?`F&p=~NOTPg}>wDzy68q_V)eS%EF4zIVht?(kk(^+9Q__Py-9f$t85D~7-2ADfAAbFFlQ;g_@G&0)D{Em9 zC#XC+QV|%#Jo1pZ^SK{ZA1d?}@<1TK+VpBs%QW(BeAvEp7V_;G5z8fegiIj4S@fiT zrNx%r$U=S^n#TdPR78l#Us{;5Rrnmt$=Vcg1S$qKKD+jkwVW^+=;JGND-ol+gkQCN`65k8Y%P6zY3B z8RTloT3dS#qXO15m?`)5pf8D9)r?S2=j~wn$PZ3EHUGO`{NT5~iL$?&si_wVGA+Hh z5xerg{k|K1eccxFj@}LQMZN3uYMO7vrAD=kdWFlOQTS4)?Ii2~1JZJ?Bc@!4)zx@> zN!-HCS+y5ri5(}tp?>RiYA}`L;pN%-*T4SnkNwr@$4;-HKdVw%Ti1DOQyUox4OZ3W z?ZweQdHJ5cf$(Ml;?}+mxhwL$3~~ibMM7&=XFVV?BEwatM1qTWhrdL0uKQ?nL?+L7 zOsS+Cw-`_KApJx29FA5ym$(|M-{8k&D83~_F + + + + + + + + + + + + + diff --git a/contracts/2cf632fa6ea4939ca9cb7998ade688150db25b0684600f53ac0ca95730f1d99f/manifest.json b/contracts/2cf632fa6ea4939ca9cb7998ade688150db25b0684600f53ac0ca95730f1d99f/manifest.json new file mode 100644 index 0000000..9c912c3 --- /dev/null +++ b/contracts/2cf632fa6ea4939ca9cb7998ade688150db25b0684600f53ac0ca95730f1d99f/manifest.json @@ -0,0 +1 @@ +{"method_count":540,"path_count":364,"raw_sha256":"125f0af24951e901800e49559593678edd95af66da27c88311faecda708ebaf1","snapshot_sha256":"2cf632fa6ea4939ca9cb7998ade688150db25b0684600f53ac0ca95730f1d99f","source_version":"7.4-16"} \ No newline at end of file diff --git a/contracts/2cf632fa6ea4939ca9cb7998ade688150db25b0684600f53ac0ca95730f1d99f/raw.js b/contracts/2cf632fa6ea4939ca9cb7998ade688150db25b0684600f53ac0ca95730f1d99f/raw.js new file mode 100644 index 0000000..b0c38d7 --- /dev/null +++ b/contracts/2cf632fa6ea4939ca9cb7998ade688150db25b0684600f53ac0ca95730f1d99f/raw.js @@ -0,0 +1,51901 @@ +const apiSchema = [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Mark replication job for removal.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "Will remove the jobconfig entry, but will not cleanup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "keep" : { + "default" : 0, + "description" : "Keep replicated data at target (do not remove).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read replication job configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/.", + "user" : "all" + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update replication job configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable/deactivate the entry.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 1, + "optional" : 1, + "type" : "number", + "typetext" : " (1 - N)" + }, + "remove_job" : { + "description" : "Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.", + "enum" : [ + "local", + "full" + ], + "optional" : 1, + "type" : "string" + }, + "schedule" : { + "default" : "*/15", + "description" : "Storage replication schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "For internal use, to detect if the guest was stolen.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/replication/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List replication jobs.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new replication job", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable/deactivate the entry.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 1, + "optional" : 1, + "type" : "number", + "typetext" : " (1 - N)" + }, + "remove_job" : { + "description" : "Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.", + "enum" : [ + "local", + "full" + ], + "optional" : 1, + "type" : "string" + }, + "schedule" : { + "default" : "*/15", + "description" : "Storage replication schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "For internal use, to detect if the guest was stolen.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Section type.", + "enum" : [ + "local" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/replication", + "text" : "replication" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove Metric server.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read metric server configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new external metric server config", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "api-path-prefix" : { + "description" : "An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bucket" : { + "description" : "The InfluxDB bucket/db. Only necessary when using the http v2 api.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the plugin.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the entry.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "influxdbproto" : { + "default" : "udp", + "enum" : [ + "udp", + "http", + "https" + ], + "optional" : 1, + "type" : "string" + }, + "max-body-size" : { + "default" : 25000000, + "description" : "InfluxDB max-body-size in bytes. Requests are batched up to this size.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mtu" : { + "default" : 1500, + "description" : "MTU for metrics transmission over UDP", + "maximum" : 65536, + "minimum" : 512, + "optional" : 1, + "type" : "integer", + "typetext" : " (512 - 65536)" + }, + "organization" : { + "description" : "The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "root graphite path (ex: proxmox.mycluster.mykey)", + "format" : "graphite-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "server network port", + "maximum" : 65536, + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - 65536)" + }, + "proto" : { + "description" : "Protocol to send graphite data. TCP or UDP (default)", + "enum" : [ + "udp", + "tcp" + ], + "optional" : 1, + "type" : "string" + }, + "server" : { + "description" : "server dns name or IP address", + "format" : "address", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 1, + "description" : "graphite TCP socket timeout (default=1)", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "token" : { + "description" : "The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "graphite", + "influxdb" + ], + "format" : "pve-configid", + "type" : "string" + }, + "verify-certificate" : { + "default" : 1, + "description" : "Set to 0 to disable certificate verification for https endpoints.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update metric server configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "api-path-prefix" : { + "description" : "An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bucket" : { + "description" : "The InfluxDB bucket/db. Only necessary when using the http v2 api.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the plugin.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the entry.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "influxdbproto" : { + "default" : "udp", + "enum" : [ + "udp", + "http", + "https" + ], + "optional" : 1, + "type" : "string" + }, + "max-body-size" : { + "default" : 25000000, + "description" : "InfluxDB max-body-size in bytes. Requests are batched up to this size.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mtu" : { + "default" : 1500, + "description" : "MTU for metrics transmission over UDP", + "maximum" : 65536, + "minimum" : 512, + "optional" : 1, + "type" : "integer", + "typetext" : " (512 - 65536)" + }, + "organization" : { + "description" : "The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "root graphite path (ex: proxmox.mycluster.mykey)", + "format" : "graphite-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "server network port", + "maximum" : 65536, + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - 65536)" + }, + "proto" : { + "description" : "Protocol to send graphite data. TCP or UDP (default)", + "enum" : [ + "udp", + "tcp" + ], + "optional" : 1, + "type" : "string" + }, + "server" : { + "description" : "server dns name or IP address", + "format" : "address", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 1, + "description" : "graphite TCP socket timeout (default=1)", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "token" : { + "description" : "The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "verify-certificate" : { + "default" : 1, + "description" : "Set to 0 to disable certificate verification for https endpoints.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/metrics/server/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List configured metric servers.", + "method" : "GET", + "name" : "server_index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "disable" : { + "description" : "Flag to disable the plugin.", + "type" : "boolean" + }, + "id" : { + "description" : "The ID of the entry.", + "type" : "string" + }, + "port" : { + "description" : "Server network port", + "type" : "integer" + }, + "server" : { + "description" : "Server dns name or IP address", + "type" : "string" + }, + "type" : { + "description" : "Plugin type.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/metrics/server", + "text" : "server" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Metrics index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/metrics", + "text" : "metrics" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Return the version of the cluster join API available on this node.", + "method" : "GET", + "name" : "join_api_version", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "description" : "Cluster Join API version, currently 1", + "minimum" : 0, + "type" : "integer" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/apiversion", + "text" : "apiversion" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Removes a node from the cluster configuration.", + "method" : "DELETE", + "name" : "delnode", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Adds a node to the cluster configuration. This call is for internal use.", + "method" : "POST", + "name" : "addnode", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "apiversion" : { + "description" : "The JOIN_API_VERSION of the new node.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "force" : { + "description" : "Do not throw error if node already exists.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "link[n]" : { + "description" : "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)", + "format" : { + "address" : { + "default_key" : 1, + "description" : "Hostname (or IP) of this corosync link address.", + "format" : "address", + "format_description" : "IP", + "type" : "string" + }, + "priority" : { + "default" : 0, + "description" : "The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.", + "maximum" : 255, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[address=] [,priority=]" + }, + "new_node_ip" : { + "description" : "IP Address of node to add. Used as fallback if no links are given.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nodeid" : { + "description" : "Node id for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "votes" : { + "description" : "Number of votes for this node", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "protected" : 1, + "returns" : { + "properties" : { + "corosync_authkey" : { + "type" : "string" + }, + "corosync_conf" : { + "type" : "string" + }, + "warnings" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/nodes/{node}", + "text" : "{node}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Corosync node list.", + "method" : "GET", + "name" : "nodes", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "node" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{node}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/config/nodes", + "text" : "nodes" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get information needed to join this cluster over the connected node.", + "method" : "GET", + "name" : "join_info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "default" : "current connected node", + "description" : "The node for which the joinee gets the nodeinfo. ", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "config_digest" : { + "type" : "string" + }, + "nodelist" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "name" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "nodeid" : { + "description" : "Node id for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "pve_addr" : { + "format" : "ip", + "type" : "string" + }, + "pve_fp" : { + "description" : "Certificate SHA 256 fingerprint.", + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "quorum_votes" : { + "minimum" : 0, + "type" : "integer" + }, + "ring0_addr" : { + "description" : "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)", + "format" : { + "address" : { + "default_key" : 1, + "description" : "Hostname (or IP) of this corosync link address.", + "format" : "address", + "format_description" : "IP", + "type" : "string" + }, + "priority" : { + "default" : 0, + "description" : "The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.", + "maximum" : 255, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "preferred_node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "totem" : { + "type" : "object" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Joins this node into an existing cluster. If no links are given, default to IP resolved by node's hostname on single link (fallback fails for clusters with multiple links).", + "method" : "POST", + "name" : "join", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "force" : { + "description" : "Do not throw error if node already exists.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hostname" : { + "description" : "Hostname (or IP) of an existing cluster member.", + "type" : "string", + "typetext" : "" + }, + "link[n]" : { + "description" : "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)", + "format" : { + "address" : { + "default_key" : 1, + "description" : "Hostname (or IP) of this corosync link address.", + "format" : "address", + "format_description" : "IP", + "type" : "string" + }, + "priority" : { + "default" : 0, + "description" : "The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.", + "maximum" : 255, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[address=] [,priority=]" + }, + "nodeid" : { + "description" : "Node id for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "password" : { + "description" : "Superuser (root) password of peer node.", + "maxLength" : 128, + "type" : "string", + "typetext" : "" + }, + "votes" : { + "description" : "Number of votes for this node", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/join", + "text" : "join" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get corosync totem protocol settings.", + "method" : "GET", + "name" : "totem", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/totem", + "text" : "totem" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get QDevice status", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/qdevice", + "text" : "qdevice" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Generate new cluster configuration. If no links given, default to local IP address as link0.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "clustername" : { + "description" : "The name of the cluster.", + "format" : "pve-node", + "maxLength" : 15, + "type" : "string", + "typetext" : "" + }, + "link[n]" : { + "description" : "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)", + "format" : { + "address" : { + "default_key" : 1, + "description" : "Hostname (or IP) of this corosync link address.", + "format" : "address", + "format_description" : "IP", + "type" : "string" + }, + "priority" : { + "default" : 0, + "description" : "The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.", + "maximum" : 255, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[address=] [,priority=]" + }, + "nodeid" : { + "description" : "Node id for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "votes" : { + "description" : "Number of votes for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/config", + "text" : "config" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "dest" : { + "optional" : 1, + "type" : "string" + }, + "dport" : { + "optional" : 1, + "type" : "string" + }, + "enable" : { + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "optional" : 1, + "type" : "string" + }, + "iface" : { + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "optional" : 1, + "type" : "string" + }, + "pos" : { + "type" : "integer" + }, + "proto" : { + "optional" : 1, + "type" : "string" + }, + "source" : { + "optional" : 1, + "type" : "string" + }, + "sport" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/groups/{group}/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete security group.", + "method" : "DELETE", + "name" : "delete_security_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "pos" : { + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 0, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/groups/{group}", + "text" : "{group}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List security groups.", + "method" : "GET", + "name" : "list_security_groups", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{group}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new security group.", + "method" : "POST", + "name" : "create_security_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "rename" : { + "description" : "Rename/update an existing security group. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing group.", + "maxLength" : 18, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/groups", + "text" : "groups" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "dest" : { + "optional" : 1, + "type" : "string" + }, + "dport" : { + "optional" : 1, + "type" : "string" + }, + "enable" : { + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "optional" : 1, + "type" : "string" + }, + "iface" : { + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "optional" : 1, + "type" : "string" + }, + "pos" : { + "type" : "integer" + }, + "proto" : { + "optional" : 1, + "type" : "string" + }, + "source" : { + "optional" : 1, + "type" : "string" + }, + "sport" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "pos" : { + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 0, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/rules", + "text" : "rules" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network from IPSet.", + "method" : "DELETE", + "name" : "remove_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read IP or Network settings from IPSet.", + "method" : "GET", + "name" : "read_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network settings", + "method" : "PUT", + "name" : "update_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/ipset/{name}/{cidr}", + "text" : "{cidr}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete IPSet", + "method" : "DELETE", + "name" : "delete_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "Delete all members of the IPSet, if there are any.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List IPSet content", + "method" : "GET", + "name" : "get_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{cidr}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add IP or Network to IPSet.", + "method" : "POST", + "name" : "create_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/ipset/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List IPSets", + "method" : "GET", + "name" : "ipset_index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new IPSet", + "method" : "POST", + "name" : "create_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "rename" : { + "description" : "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/ipset", + "text" : "ipset" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network alias.", + "method" : "DELETE", + "name" : "remove_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read alias.", + "method" : "GET", + "name" : "read_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network alias.", + "method" : "PUT", + "name" : "update_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "rename" : { + "description" : "Rename an existing alias.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/aliases/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List aliases", + "method" : "GET", + "name" : "get_aliases", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create IP or Network Alias.", + "method" : "POST", + "name" : "create_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/aliases", + "text" : "aliases" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "properties" : { + "ebtables" : { + "default" : 1, + "description" : "Enable ebtables rules cluster wide.", + "optional" : 1, + "type" : "boolean" + }, + "enable" : { + "description" : "Enable or disable the firewall cluster wide.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "log_ratelimit" : { + "description" : "Log ratelimiting settings", + "format" : { + "burst" : { + "default" : 5, + "description" : "Initial burst of packages which will always get logged before the rate is applied", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "enable" : { + "default" : "1", + "default_key" : 1, + "description" : "Enable or disable log rate limiting", + "type" : "boolean" + }, + "rate" : { + "default" : "1/second", + "description" : "Frequency with which the burst bucket gets refilled", + "format_description" : "rate", + "optional" : 1, + "pattern" : "[1-9][0-9]*\\/(second|minute|hour|day)", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ebtables" : { + "default" : 1, + "description" : "Enable ebtables rules cluster wide.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "enable" : { + "description" : "Enable or disable the firewall cluster wide.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "log_ratelimit" : { + "description" : "Log ratelimiting settings", + "format" : { + "burst" : { + "default" : 5, + "description" : "Initial burst of packages which will always get logged before the rate is applied", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "enable" : { + "default" : "1", + "default_key" : 1, + "description" : "Enable or disable log rate limiting", + "type" : "boolean" + }, + "rate" : { + "default" : "1/second", + "description" : "Frequency with which the burst bucket gets refilled", + "format_description" : "rate", + "optional" : 1, + "pattern" : "[1-9][0-9]*\\/(second|minute|hour|day)", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[enable=]<1|0> [,burst=] [,rate=]" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List available macros", + "method" : "GET", + "name" : "get_macros", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "descr" : { + "description" : "More verbose description (if available).", + "type" : "string" + }, + "macro" : { + "description" : "Macro name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/macros", + "text" : "macros" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Lists possible IPSet/Alias reference which are allowed in source/dest properties.", + "method" : "GET", + "name" : "refs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list references of specified type.", + "enum" : [ + "alias", + "ipset" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "ref" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "alias", + "ipset" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/refs", + "text" : "refs" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall", + "text" : "firewall" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns included guests and the backup status of their disks. Optimized to be used in ExtJS tree views.", + "method" : "GET", + "name" : "get_volume_backup_included", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "Root node of the tree object. Children represent guests, grandchildren represent volumes of that guest.", + "properties" : { + "children" : { + "items" : { + "properties" : { + "children" : { + "description" : "The volumes of the guest with the information if they will be included in backups.", + "items" : { + "properties" : { + "id" : { + "description" : "Configuration key of the volume.", + "type" : "string" + }, + "included" : { + "description" : "Whether the volume is included in the backup or not.", + "type" : "boolean" + }, + "name" : { + "description" : "Name of the volume.", + "type" : "string" + }, + "reason" : { + "description" : "The reason why the volume is included (or excluded).", + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "id" : { + "description" : "VMID of the guest.", + "type" : "integer" + }, + "name" : { + "description" : "Name of the guest", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Type of the guest, VM, CT or unknown for removed but not purged guests.", + "enum" : [ + "qemu", + "lxc", + "unknown" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/backup/{id}/included_volumes", + "text" : "included_volumes" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete vzdump backup job definition.", + "method" : "DELETE", + "name" : "delete_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read vzdump backup job definition.", + "method" : "GET", + "name" : "read_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update vzdump backup job definition.", + "method" : "PUT", + "name" : "update_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (KBytes per second).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "comment" : { + "description" : "Description for the Job.", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dow" : { + "description" : "Day of week selection.", + "format" : "pve-day-of-week-list", + "optional" : 1, + "requires" : "starttime", + "type" : "string", + "typetext" : "" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enabled" : { + "default" : "1", + "description" : "Enable or disable the job.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "format" : "string-alist", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "type" : "string", + "typetext" : "" + }, + "ionice" : { + "default" : 7, + "description" : "Set CFQ ionice priority.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 8)" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mailnotification" : { + "default" : "always", + "description" : "Specify when to send an email", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "maxfiles" : { + "description" : "Deprecated: use 'prune-backups' instead. Maximal number of backup files per guest system.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "notes-template" : { + "description" : "Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.", + "maxLength" : 1024, + "optional" : 1, + "requires" : "storage", + "type" : "string", + "typetext" : "" + }, + "performance" : { + "description" : "Other performance-related settings.", + "format" : "backup-performance", + "optional" : 1, + "type" : "string", + "typetext" : "[max-workers=]" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protected" : { + "description" : "If true, mark backup(s) as protected.", + "optional" : 1, + "requires" : "storage", + "type" : "boolean", + "typetext" : "" + }, + "prune-backups" : { + "default" : "keep-all=1", + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove" : { + "default" : 1, + "description" : "Prune older backups according to 'prune-backups'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "repeat-missed" : { + "default" : 0, + "description" : "If true, the job will be run as soon as possible if it was missed while the scheduler was not running.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "schedule" : { + "description" : "Backup schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "starttime" : { + "description" : "Job Start time.", + "optional" : 1, + "pattern" : "\\d{1,2}:\\d{1,2}", + "type" : "string", + "typetext" : "HH:MM" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, N>0 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/backup/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List vzdump backup schedule.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new vzdump backup job.", + "method" : "POST", + "name" : "create_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (KBytes per second).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "comment" : { + "description" : "Description for the Job.", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "dow" : { + "default" : "mon,tue,wed,thu,fri,sat,sun", + "description" : "Day of week selection.", + "format" : "pve-day-of-week-list", + "optional" : 1, + "requires" : "starttime", + "type" : "string", + "typetext" : "" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enabled" : { + "default" : "1", + "description" : "Enable or disable the job.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "format" : "string-alist", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "id" : { + "description" : "Job ID (will be autogenerated).", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ionice" : { + "default" : 7, + "description" : "Set CFQ ionice priority.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 8)" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mailnotification" : { + "default" : "always", + "description" : "Specify when to send an email", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "maxfiles" : { + "description" : "Deprecated: use 'prune-backups' instead. Maximal number of backup files per guest system.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "notes-template" : { + "description" : "Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.", + "maxLength" : 1024, + "optional" : 1, + "requires" : "storage", + "type" : "string", + "typetext" : "" + }, + "performance" : { + "description" : "Other performance-related settings.", + "format" : "backup-performance", + "optional" : 1, + "type" : "string", + "typetext" : "[max-workers=]" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protected" : { + "description" : "If true, mark backup(s) as protected.", + "optional" : 1, + "requires" : "storage", + "type" : "boolean", + "typetext" : "" + }, + "prune-backups" : { + "default" : "keep-all=1", + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove" : { + "default" : 1, + "description" : "Prune older backups according to 'prune-backups'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "repeat-missed" : { + "default" : 0, + "description" : "If true, the job will be run as soon as possible if it was missed while the scheduler was not running.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "schedule" : { + "description" : "Backup schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "starttime" : { + "description" : "Job Start time.", + "optional" : 1, + "pattern" : "\\d{1,2}:\\d{1,2}", + "type" : "string", + "typetext" : "HH:MM" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, N>0 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/backup", + "text" : "backup" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Shows all guests which are not covered by any backup job.", + "method" : "GET", + "name" : "get_guests_not_in_backup", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "Contains the guest objects.", + "items" : { + "properties" : { + "name" : { + "description" : "Name of the guest", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Type of the guest.", + "enum" : [ + "qemu", + "lxc" + ], + "type" : "string" + }, + "vmid" : { + "description" : "VMID of the guest.", + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/backup-info/not-backed-up", + "text" : "not-backed-up" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index for backup info related endpoints", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "returns" : { + "description" : "Directory index.", + "items" : { + "properties" : { + "subdir" : { + "description" : "API sub-directory endpoint", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/backup-info", + "text" : "backup-info" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Request resource migration (online) to another node.", + "method" : "POST", + "name" : "migrate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/resources/{sid}/migrate", + "text" : "migrate" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Request resource relocatzion to another node. This stops the service on the old node, and restarts it on the target node.", + "method" : "POST", + "name" : "relocate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/resources/{sid}/relocate", + "text" : "relocate" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete resource configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read resource configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "properties" : { + "comment" : { + "description" : "Description.", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Can be used to prevent concurrent modifications.", + "type" : "string" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string" + }, + "max_relocate" : { + "description" : "Maximal number of service relocate tries when a service failes to start.", + "optional" : 1, + "type" : "integer" + }, + "max_restart" : { + "description" : "Maximal number of tries to restart the service on a node after its start failed.", + "optional" : 1, + "type" : "integer" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + }, + "state" : { + "description" : "Requested resource state.", + "enum" : [ + "started", + "stopped", + "enabled", + "disabled", + "ignored" + ], + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "The type of the resources.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update resource configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "max_relocate" : { + "default" : 1, + "description" : "Maximal number of service relocate tries when a service failes to start.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "max_restart" : { + "default" : 1, + "description" : "Maximal number of tries to restart the service on a node after its start failed.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + }, + "state" : { + "default" : "started", + "description" : "Requested resource state.", + "enum" : [ + "started", + "stopped", + "enabled", + "disabled", + "ignored" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Requested resource state. The CRM reads this state and acts accordingly.\nPlease note that `enabled` is just an alias for `started`.\n\n`started`;;\n\nThe CRM tries to start the resource. Service state is\nset to `started` after successful start. On node failures, or when start\nfails, it tries to recover the resource. If everything fails, service\nstate it set to `error`.\n\n`stopped`;;\n\nThe CRM tries to keep the resource in `stopped` state, but it\nstill tries to relocate the resources on node failures.\n\n`disabled`;;\n\nThe CRM tries to put the resource in `stopped` state, but does not try\nto relocate the resources on node failures. The main purpose of this\nstate is error recovery, because it is the only way to move a resource out\nof the `error` state.\n\n`ignored`;;\n\nThe resource gets removed from the manager status and so the CRM and the LRM do\nnot touch the resource anymore. All {pve} API calls affecting this resource\nwill be executed, directly bypassing the HA stack. CRM commands will be thrown\naway while there source is in this state. The resource will not get relocated\non node failures.\n\n" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/resources/{sid}", + "text" : "{sid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List HA resources.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list resources of specific type", + "enum" : [ + "ct", + "vm" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "sid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{sid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new HA resource.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "max_relocate" : { + "default" : 1, + "description" : "Maximal number of service relocate tries when a service failes to start.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "max_restart" : { + "default" : 1, + "description" : "Maximal number of tries to restart the service on a node after its start failed.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + }, + "state" : { + "default" : "started", + "description" : "Requested resource state.", + "enum" : [ + "started", + "stopped", + "enabled", + "disabled", + "ignored" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Requested resource state. The CRM reads this state and acts accordingly.\nPlease note that `enabled` is just an alias for `started`.\n\n`started`;;\n\nThe CRM tries to start the resource. Service state is\nset to `started` after successful start. On node failures, or when start\nfails, it tries to recover the resource. If everything fails, service\nstate it set to `error`.\n\n`stopped`;;\n\nThe CRM tries to keep the resource in `stopped` state, but it\nstill tries to relocate the resources on node failures.\n\n`disabled`;;\n\nThe CRM tries to put the resource in `stopped` state, but does not try\nto relocate the resources on node failures. The main purpose of this\nstate is error recovery, because it is the only way to move a resource out\nof the `error` state.\n\n`ignored`;;\n\nThe resource gets removed from the manager status and so the CRM and the LRM do\nnot touch the resource anymore. All {pve} API calls affecting this resource\nwill be executed, directly bypassing the HA stack. CRM commands will be thrown\naway while there source is in this state. The resource will not get relocated\non node failures.\n\n" + }, + "type" : { + "description" : "Resource type.", + "enum" : [ + "ct", + "vm" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/resources", + "text" : "resources" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete ha group configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read ha group configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : {} + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update ha group configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names with optional priority.", + "format" : "pve-ha-group-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "[:]{,[:]}*", + "verbose_description" : "List of cluster node members, where a priority can be given to each node. A resource bound to a group will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the services will get distributed to those nodes. The priorities have a relative meaning only." + }, + "nofailback" : { + "default" : 0, + "description" : "The CRM tries to run services on the node with the highest priority. If a node with higher priority comes online, the CRM migrates the service to that node. Enabling nofailback prevents that behavior.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restricted" : { + "default" : 0, + "description" : "Resources bound to restricted groups may only run on nodes defined by the group.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Resources bound to restricted groups may only run on nodes defined by the group. The resource will be placed in the stopped state if no group node member is online. Resources on unrestricted groups may run on any cluster node if all group members are offline, but they will migrate back as soon as a group member comes online. One can implement a 'preferred node' behavior using an unrestricted group with only one member." + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/groups/{group}", + "text" : "{group}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get HA groups.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "group" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{group}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new HA group.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names with optional priority.", + "format" : "pve-ha-group-node-list", + "optional" : 0, + "type" : "string", + "typetext" : "[:]{,[:]}*", + "verbose_description" : "List of cluster node members, where a priority can be given to each node. A resource bound to a group will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the services will get distributed to those nodes. The priorities have a relative meaning only." + }, + "nofailback" : { + "default" : 0, + "description" : "The CRM tries to run services on the node with the highest priority. If a node with higher priority comes online, the CRM migrates the service to that node. Enabling nofailback prevents that behavior.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restricted" : { + "default" : 0, + "description" : "Resources bound to restricted groups may only run on nodes defined by the group.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Resources bound to restricted groups may only run on nodes defined by the group. The resource will be placed in the stopped state if no group node member is online. Resources on unrestricted groups may run on any cluster node if all group members are offline, but they will migrate back as soon as a group member comes online. One can implement a 'preferred node' behavior using an unrestricted group with only one member." + }, + "type" : { + "description" : "Group type.", + "enum" : [ + "group" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/groups", + "text" : "groups" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get HA manger status.", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/status/current", + "text" : "current" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get full HA manger status, including LRM status.", + "method" : "GET", + "name" : "manager_status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/status/manager_status", + "text" : "manager_status" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/status", + "text" : "status" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha", + "text" : "ha" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete ACME plugin configuration.", + "method" : "DELETE", + "name" : "delete_plugin", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Unique identifier for ACME plugin instance.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get ACME plugin configuration.", + "method" : "GET", + "name" : "get_plugin_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Unique identifier for ACME plugin instance.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update ACME plugin configuration.", + "method" : "PUT", + "name" : "update_plugin", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "api" : { + "description" : "API plugin name", + "enum" : [ + "1984hosting", + "acmedns", + "acmeproxy", + "active24", + "ad", + "ali", + "anx", + "arvan", + "aurora", + "autodns", + "aws", + "azion", + "azure", + "bunny", + "cf", + "clouddns", + "cloudns", + "cn", + "conoha", + "constellix", + "cpanel", + "curanet", + "cyon", + "da", + "ddnss", + "desec", + "df", + "dgon", + "dnshome", + "dnsimple", + "dnsservices", + "do", + "doapi", + "domeneshop", + "dp", + "dpi", + "dreamhost", + "duckdns", + "durabledns", + "dyn", + "dynu", + "dynv6", + "easydns", + "edgedns", + "euserv", + "exoscale", + "fornex", + "freedns", + "gandi_livedns", + "gcloud", + "gd", + "geoscaling", + "he", + "hetzner", + "hexonet", + "hostingde", + "huaweicloud", + "infoblox", + "infomaniak", + "internetbs", + "inwx", + "ionos", + "ispconfig", + "jd", + "joker", + "kappernet", + "kas", + "kinghost", + "knot", + "la", + "leaseweb", + "lexicon", + "linode", + "linode_v4", + "loopia", + "lua", + "maradns", + "me", + "miab", + "misaka", + "myapi", + "mydevil", + "mydnsjp", + "mythic_beasts", + "namecheap", + "namecom", + "namesilo", + "nederhost", + "neodigit", + "netcup", + "netlify", + "nic", + "njalla", + "nm", + "nsd", + "nsone", + "nsupdate", + "nw", + "oci", + "one", + "online", + "openprovider", + "openstack", + "opnsense", + "ovh", + "pdns", + "pleskxml", + "pointhq", + "porkbun", + "rackcorp", + "rackspace", + "rage4", + "rcode0", + "regru", + "scaleway", + "schlundtech", + "selectel", + "selfhost", + "servercow", + "simply", + "tele3", + "transip", + "udr", + "ultra", + "unoeuro", + "variomedia", + "veesp", + "vercel", + "vscale", + "vultr", + "websupport", + "world4you", + "yandex", + "yc", + "zilore", + "zone", + "zonomi" + ], + "optional" : 1, + "type" : "string" + }, + "data" : { + "description" : "DNS plugin data. (base64 encoded)", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "ACME Plugin ID name", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "validation-delay" : { + "default" : 30, + "description" : "Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.", + "maximum" : 172800, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 172800)" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/plugins/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "ACME plugin index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list ACME plugins of a specific type", + "enum" : [ + "dns", + "standalone" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "plugin" : { + "description" : "Unique identifier for ACME plugin instance.", + "format" : "pve-configid", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{plugin}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add ACME plugin configuration.", + "method" : "POST", + "name" : "add_plugin", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "api" : { + "description" : "API plugin name", + "enum" : [ + "1984hosting", + "acmedns", + "acmeproxy", + "active24", + "ad", + "ali", + "anx", + "arvan", + "aurora", + "autodns", + "aws", + "azion", + "azure", + "bunny", + "cf", + "clouddns", + "cloudns", + "cn", + "conoha", + "constellix", + "cpanel", + "curanet", + "cyon", + "da", + "ddnss", + "desec", + "df", + "dgon", + "dnshome", + "dnsimple", + "dnsservices", + "do", + "doapi", + "domeneshop", + "dp", + "dpi", + "dreamhost", + "duckdns", + "durabledns", + "dyn", + "dynu", + "dynv6", + "easydns", + "edgedns", + "euserv", + "exoscale", + "fornex", + "freedns", + "gandi_livedns", + "gcloud", + "gd", + "geoscaling", + "he", + "hetzner", + "hexonet", + "hostingde", + "huaweicloud", + "infoblox", + "infomaniak", + "internetbs", + "inwx", + "ionos", + "ispconfig", + "jd", + "joker", + "kappernet", + "kas", + "kinghost", + "knot", + "la", + "leaseweb", + "lexicon", + "linode", + "linode_v4", + "loopia", + "lua", + "maradns", + "me", + "miab", + "misaka", + "myapi", + "mydevil", + "mydnsjp", + "mythic_beasts", + "namecheap", + "namecom", + "namesilo", + "nederhost", + "neodigit", + "netcup", + "netlify", + "nic", + "njalla", + "nm", + "nsd", + "nsone", + "nsupdate", + "nw", + "oci", + "one", + "online", + "openprovider", + "openstack", + "opnsense", + "ovh", + "pdns", + "pleskxml", + "pointhq", + "porkbun", + "rackcorp", + "rackspace", + "rage4", + "rcode0", + "regru", + "scaleway", + "schlundtech", + "selectel", + "selfhost", + "servercow", + "simply", + "tele3", + "transip", + "udr", + "ultra", + "unoeuro", + "variomedia", + "veesp", + "vercel", + "vscale", + "vultr", + "websupport", + "world4you", + "yandex", + "yc", + "zilore", + "zone", + "zonomi" + ], + "optional" : 1, + "type" : "string" + }, + "data" : { + "description" : "DNS plugin data. (base64 encoded)", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "ACME Plugin ID name", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "ACME challenge type.", + "enum" : [ + "dns", + "standalone" + ], + "type" : "string" + }, + "validation-delay" : { + "default" : 30, + "description" : "Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.", + "maximum" : 172800, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 172800)" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/acme/plugins", + "text" : "plugins" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Deactivate existing ACME account at CA.", + "method" : "DELETE", + "name" : "deactivate_account", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Return existing ACME account information.", + "method" : "GET", + "name" : "get_account", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "account" : { + "optional" : 1, + "renderer" : "yaml", + "type" : "object" + }, + "directory" : { + "description" : "URL of ACME CA directory endpoint.", + "optional" : 1, + "pattern" : "^https?://.*", + "type" : "string" + }, + "location" : { + "optional" : 1, + "type" : "string" + }, + "tos" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update existing ACME account information with CA. Note: not specifying any new account information triggers a refresh.", + "method" : "PUT", + "name" : "update_account", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "contact" : { + "description" : "Contact email addresses.", + "format" : "email-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/account/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "ACMEAccount index.", + "method" : "GET", + "name" : "account_index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Register a new ACME account with CA.", + "method" : "POST", + "name" : "register_account", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "contact" : { + "description" : "Contact email addresses.", + "format" : "email-list", + "type" : "string", + "typetext" : "" + }, + "directory" : { + "default" : "https://acme-v02.api.letsencrypt.org/directory", + "description" : "URL of ACME CA directory endpoint.", + "optional" : 1, + "pattern" : "^https?://.*", + "type" : "string" + }, + "name" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tos_url" : { + "description" : "URL of CA TermsOfService - setting this indicates agreement.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/acme/account", + "text" : "account" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Retrieve ACME TermsOfService URL from CA.", + "method" : "GET", + "name" : "get_tos", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "directory" : { + "default" : "https://acme-v02.api.letsencrypt.org/directory", + "description" : "URL of ACME CA directory endpoint.", + "optional" : 1, + "pattern" : "^https?://.*", + "type" : "string" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "description" : "ACME TermsOfService URL.", + "optional" : 1, + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/tos", + "text" : "tos" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get named known ACME directory endpoints.", + "method" : "GET", + "name" : "get_directories", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "type" : "string" + }, + "url" : { + "description" : "URL of ACME CA directory endpoint.", + "pattern" : "^https?://.*", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/directories", + "text" : "directories" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get schema of ACME challenge types.", + "method" : "GET", + "name" : "challengeschema", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "type" : "string" + }, + "name" : { + "description" : "Human readable name, falls back to id", + "type" : "string" + }, + "schema" : { + "type" : "object" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/challenge-schema", + "text" : "challenge-schema" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "ACMEAccount index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/acme", + "text" : "acme" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get ceph metadata.", + "method" : "GET", + "name" : "metadata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "scope" : { + "default" : "all", + "enum" : [ + "all", + "versions" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "returns" : { + "description" : "Items for each type of service containing objects for each instance.", + "properties" : { + "mds" : { + "description" : "Metadata servers configured in the cluster and their properties.", + "properties" : { + "{id}" : { + "description" : "Useful properties are listed, but not the full list.", + "properties" : { + "addr" : { + "description" : "Bind addresses and ports.", + "type" : "string" + }, + "ceph_release" : { + "description" : "Ceph release codename currently used.", + "type" : "string" + }, + "ceph_version" : { + "description" : "Version info currently used by the service.", + "type" : "string" + }, + "ceph_version_short" : { + "description" : "Short version (numerical) info currently used by the service.", + "type" : "string" + }, + "hostname" : { + "description" : "Hostname on which the service is running.", + "type" : "string" + }, + "mem_swap_kb" : { + "description" : "Memory of the service currently in swap.", + "type" : "integer" + }, + "mem_total_kb" : { + "description" : "Memory consumption of the service.", + "type" : "integer" + }, + "name" : { + "description" : "Name of the service instance.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "type" : "object" + }, + "mgr" : { + "description" : "Managers configured in the cluster and their properties.", + "properties" : { + "{id}" : { + "description" : "Useful properties are listed, but not the full list.", + "properties" : { + "addr" : { + "description" : "Bind address", + "type" : "string" + }, + "ceph_release" : { + "description" : "Ceph release codename currently used.", + "type" : "string" + }, + "ceph_version" : { + "description" : "Version info currently used by the service.", + "type" : "string" + }, + "ceph_version_short" : { + "description" : "Short version (numerical) info currently used by the service.", + "type" : "string" + }, + "hostname" : { + "description" : "Hostname on which the service is running.", + "type" : "string" + }, + "mem_swap_kb" : { + "description" : "Memory of the service currently in swap.", + "type" : "integer" + }, + "mem_total_kb" : { + "description" : "Memory consumption of the service.", + "type" : "integer" + }, + "name" : { + "description" : "Name of the service instance.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "type" : "object" + }, + "mon" : { + "description" : "Monitors configured in the cluster and their properties.", + "properties" : { + "{id}" : { + "description" : "Useful properties are listed, but not the full list.", + "properties" : { + "addrs" : { + "description" : "Bind addresses and ports.", + "type" : "string" + }, + "ceph_release" : { + "description" : "Ceph release codename currently used.", + "type" : "string" + }, + "ceph_version" : { + "description" : "Version info currently used by the service.", + "type" : "string" + }, + "ceph_version_short" : { + "description" : "Short version (numerical) info currently used by the service.", + "type" : "string" + }, + "hostname" : { + "description" : "Hostname on which the service is running.", + "type" : "string" + }, + "mem_swap_kb" : { + "description" : "Memory of the service currently in swap.", + "type" : "integer" + }, + "mem_total_kb" : { + "description" : "Memory consumption of the service.", + "type" : "integer" + }, + "name" : { + "description" : "Name of the service instance.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "type" : "object" + }, + "node" : { + "description" : "Ceph version installed on the nodes.", + "properties" : { + "{node}" : { + "properties" : { + "buildcommit" : { + "description" : "GIT commit used for the build.", + "type" : "string" + }, + "version" : { + "description" : "Version info.", + "properties" : { + "parts" : { + "description" : "major, minor & patch", + "type" : "array" + }, + "str" : { + "description" : "Version as single string.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "type" : "object" + } + }, + "type" : "object" + }, + "osd" : { + "description" : "OSDs configured in the cluster and their properties.", + "properties" : { + "{id}" : { + "description" : "Useful properties are listed, but not the full list.", + "properties" : { + "back_addr" : { + "description" : "Bind addresses and ports for backend inter OSD traffic.", + "type" : "string" + }, + "ceph_release" : { + "description" : "Ceph release codename currently used.", + "type" : "string" + }, + "ceph_version" : { + "description" : "Version info currently used by the service.", + "type" : "string" + }, + "ceph_version_short" : { + "description" : "Short version (numerical) info currently used by the service.", + "type" : "string" + }, + "device_id" : { + "description" : "Devices used by the OSD.", + "type" : "string" + }, + "front_addr" : { + "description" : "Bind addresses and ports for frontend traffic to OSDs.", + "type" : "string" + }, + "hostname" : { + "description" : "Hostname on which the service is running.", + "type" : "string" + }, + "id" : { + "description" : "OSD ID.", + "type" : "integer" + }, + "mem_swap_kb" : { + "description" : "Memory of the service currently in swap.", + "type" : "integer" + }, + "mem_total_kb" : { + "description" : "Memory consumption of the service.", + "type" : "integer" + }, + "osd_data" : { + "description" : "Path to the OSD data directory.", + "type" : "string" + }, + "osd_objectstore" : { + "description" : "OSD objectstore type.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ceph/metadata", + "text" : "metadata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get ceph status.", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ceph/status", + "text" : "status" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the status of a specific ceph flag.", + "method" : "GET", + "name" : "get_flag", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "flag" : { + "description" : "The name of the flag name to get.", + "enum" : [ + "nobackfill", + "nodeep-scrub", + "nodown", + "noin", + "noout", + "norebalance", + "norecover", + "noscrub", + "notieragent", + "noup", + "pause" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "boolean" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set or clear (unset) a specific ceph flag", + "method" : "PUT", + "name" : "update_flag", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "flag" : { + "description" : "The ceph flag to update", + "enum" : [ + "nobackfill", + "nodeep-scrub", + "nodown", + "noin", + "noout", + "norebalance", + "norecover", + "noscrub", + "notieragent", + "noup", + "pause" + ], + "type" : "string" + }, + "value" : { + "description" : "The new value of the flag", + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ceph/flags/{flag}", + "text" : "{flag}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "get the status of all ceph flags", + "method" : "GET", + "name" : "get_all_flags", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "description" : { + "description" : "Flag description.", + "type" : "string" + }, + "name" : { + "description" : "Flag name.", + "enum" : [ + "nobackfill", + "nodeep-scrub", + "nodown", + "noin", + "noout", + "norebalance", + "norecover", + "noscrub", + "notieragent", + "noup", + "pause" + ], + "type" : "string" + }, + "value" : { + "description" : "Flag value.", + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set/Unset multiple ceph flags at once.", + "method" : "PUT", + "name" : "set_flags", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "nobackfill" : { + "description" : "Backfilling of PGs is suspended.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nodeep-scrub" : { + "description" : "Deep Scrubbing is disabled.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nodown" : { + "description" : "OSD failure reports are being ignored, such that the monitors will not mark OSDs down.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "noin" : { + "description" : "OSDs that were previously marked out will not be marked back in when they start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "noout" : { + "description" : "OSDs will not automatically be marked out after the configured interval.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "norebalance" : { + "description" : "Rebalancing of PGs is suspended.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "norecover" : { + "description" : "Recovery of PGs is suspended.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "noscrub" : { + "description" : "Scrubbing is disabled.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "notieragent" : { + "description" : "Cache tiering activity is suspended.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "noup" : { + "description" : "OSDs are not allowed to start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "pause" : { + "description" : "Pauses read and writes.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ceph/flags", + "text" : "flags" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Cluster ceph index.", + "method" : "GET", + "name" : "cephindex", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ceph", + "text" : "ceph" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns a list of future schedule runtimes.", + "method" : "GET", + "name" : "schedule-analyze", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "iterations" : { + "default" : 10, + "description" : "Number of event-iteration to simulate and return.", + "maximum" : 100, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 100)" + }, + "schedule" : { + "description" : "Job schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "type" : "string", + "typetext" : "" + }, + "starttime" : { + "description" : "UNIX timestamp to start the calculation from. Defaults to the current time.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "description" : "An array of the next events since .", + "items" : { + "properties" : { + "timestamp" : { + "description" : "UNIX timestamp for the run.", + "type" : "integer" + }, + "utc" : { + "description" : "UTC timestamp for the run.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/jobs/schedule-analyze", + "text" : "schedule-analyze" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index for jobs related endpoints.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "description" : "Directory index.", + "items" : { + "properties" : { + "subdir" : { + "description" : "API sub-directory endpoint", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/jobs", + "text" : "jobs" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn subnet object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "subnet" : { + "description" : "The SDN subnet object identifier.", + "format" : "pve-sdn-subnet-id", + "type" : "string", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/vnets/{vnet}/subnets", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn subnet configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "subnet" : { + "description" : "The SDN subnet object identifier.", + "format" : "pve-sdn-subnet-id", + "type" : "string", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/vnets/{vnet}/subnets/{subnet}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn subnet object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dnszoneprefix" : { + "description" : "dns domain zone prefix ex: 'adm' -> .adm.mydomain.com", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway" : { + "description" : "Subnet Gateway: Will be assign on vnet for layer3 zones", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "snat" : { + "description" : "enable masquerade for this subnet if pve-firewall", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "subnet" : { + "description" : "The SDN subnet object identifier.", + "format" : "pve-sdn-subnet-id", + "type" : "string", + "typetext" : "" + }, + "vnet" : { + "description" : "associated vnet", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/vnets/{vnet}/subnets", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "text" : "{subnet}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN subnets index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/subnets/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{subnet}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn subnet object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dnszoneprefix" : { + "description" : "dns domain zone prefix ex: 'adm' -> .adm.mydomain.com", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway" : { + "description" : "Subnet Gateway: Will be assign on vnet for layer3 zones", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "snat" : { + "description" : "enable masquerade for this subnet if pve-firewall", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "subnet" : { + "description" : "The SDN subnet object identifier.", + "format" : "pve-sdn-subnet-id", + "type" : "string", + "typetext" : "" + }, + "type" : { + "enum" : [ + "subnet" + ], + "type" : "string" + }, + "vnet" : { + "description" : "associated vnet", + "optional" : 0, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/vnets/{vnet}/subnets", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/vnets/{vnet}/subnets", + "text" : "subnets" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn vnet object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/vnets", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn vnet configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/vnets/{vnet}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn vnet object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "alias" : { + "description" : "alias name of the vnet", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})", + "type" : "string" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tag" : { + "description" : "vlan or vxlan id", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "vlanaware" : { + "description" : "Allow vm VLANs to pass through this vnet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "zone id", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/vnets", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/vnets/{vnet}", + "text" : "{vnet}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN vnets index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/vnets/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{vnet}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn vnet object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "alias" : { + "description" : "alias name of the vnet", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})", + "type" : "string" + }, + "tag" : { + "description" : "vlan or vxlan id", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "type" : { + "description" : "Type", + "enum" : [ + "vnet" + ], + "optional" : 1, + "type" : "string" + }, + "vlanaware" : { + "description" : "Allow vm VLANs to pass through this vnet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "zone id", + "optional" : 0, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/vnets", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/vnets", + "text" : "vnets" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn zone object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn zone configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn zone object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "advertise-subnets" : { + "description" : "Advertise evpn subnets if you have silent hosts", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bridge" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge-disable-mac-learning" : { + "description" : "Disable auto mac learning.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "controller" : { + "description" : "Frr router name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable-arp-nd-suppression" : { + "description" : "Disable ipv4 arp && ipv6 neighbour discovery suppression", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "dns" : { + "description" : "dns api server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dnszone" : { + "description" : "dns domain zone ex: mydomain.com", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dp-id" : { + "description" : "Faucet dataplane id", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "exitnodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exitnodes-local-routing" : { + "description" : "Allow exitnodes to connect to evpn guests", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "exitnodes-primary" : { + "description" : "Force traffic to this exitnode first.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ipam" : { + "description" : "use a specific ipam", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mac" : { + "description" : "Anycast logical router mac address", + "format" : "mac-addr", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mtu" : { + "description" : "MTU", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peers" : { + "description" : "peers address list.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "reversedns" : { + "description" : "reverse dns api server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rt-import" : { + "description" : "Route-Target import", + "format" : "pve-sdn-bgp-rt-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tag" : { + "description" : "Service-VLAN Tag", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vlan-protocol" : { + "default" : "802.1q", + "enum" : [ + "802.1q", + "802.1ad" + ], + "optional" : 1, + "type" : "string" + }, + "vrf-vxlan" : { + "description" : "l3vni.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/zones/{zone}", + "text" : "{zone}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN zones index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "type" : { + "description" : "Only list SDN zones of specific type", + "enum" : [ + "evpn", + "faucet", + "qinq", + "simple", + "vlan", + "vxlan" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "dns" : { + "optional" : 1, + "type" : "string" + }, + "dnszone" : { + "optional" : 1, + "type" : "string" + }, + "ipam" : { + "optional" : 1, + "type" : "string" + }, + "mtu" : { + "optional" : 1, + "type" : "integer" + }, + "nodes" : { + "optional" : 1, + "type" : "string" + }, + "pending" : { + "optional" : 1 + }, + "reversedns" : { + "optional" : 1, + "type" : "string" + }, + "state" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + }, + "zone" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{zone}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn zone object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "advertise-subnets" : { + "description" : "Advertise evpn subnets if you have silent hosts", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bridge" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge-disable-mac-learning" : { + "description" : "Disable auto mac learning.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "controller" : { + "description" : "Frr router name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable-arp-nd-suppression" : { + "description" : "Disable ipv4 arp && ipv6 neighbour discovery suppression", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "dns" : { + "description" : "dns api server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dnszone" : { + "description" : "dns domain zone ex: mydomain.com", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dp-id" : { + "description" : "Faucet dataplane id", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "exitnodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exitnodes-local-routing" : { + "description" : "Allow exitnodes to connect to evpn guests", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "exitnodes-primary" : { + "description" : "Force traffic to this exitnode first.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ipam" : { + "description" : "use a specific ipam", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mac" : { + "description" : "Anycast logical router mac address", + "format" : "mac-addr", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mtu" : { + "description" : "MTU", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peers" : { + "description" : "peers address list.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "reversedns" : { + "description" : "reverse dns api server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rt-import" : { + "description" : "Route-Target import", + "format" : "pve-sdn-bgp-rt-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tag" : { + "description" : "Service-VLAN Tag", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "evpn", + "faucet", + "qinq", + "simple", + "vlan", + "vxlan" + ], + "format" : "pve-configid", + "type" : "string" + }, + "vlan-protocol" : { + "default" : "802.1q", + "enum" : [ + "802.1q", + "802.1ad" + ], + "optional" : 1, + "type" : "string" + }, + "vrf-vxlan" : { + "description" : "l3vni.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/zones", + "text" : "zones" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn controller object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "controller" : { + "description" : "The SDN controller object identifier.", + "format" : "pve-sdn-controller-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn controller configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "controller" : { + "description" : "The SDN controller object identifier.", + "format" : "pve-sdn-controller-id", + "type" : "string", + "typetext" : "" + }, + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/controllers/{controller}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn controller object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "asn" : { + "description" : "autonomous system number", + "maximum" : 4294967296, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 4294967296)" + }, + "bgp-multipath-as-path-relax" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "controller" : { + "description" : "The SDN controller object identifier.", + "format" : "pve-sdn-controller-id", + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ebgp" : { + "description" : "Enable ebgp. (remote-as external)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ebgp-multihop" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "loopback" : { + "description" : "source loopback interface.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peers" : { + "description" : "peers address list.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/controllers/{controller}", + "text" : "{controller}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN controllers index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "type" : { + "description" : "Only list sdn controllers of specific type", + "enum" : [ + "bgp", + "evpn", + "faucet" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/controllers/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "controller" : { + "type" : "string" + }, + "pending" : { + "optional" : 1 + }, + "state" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{controller}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn controller object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "asn" : { + "description" : "autonomous system number", + "maximum" : 4294967296, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 4294967296)" + }, + "bgp-multipath-as-path-relax" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "controller" : { + "description" : "The SDN controller object identifier.", + "format" : "pve-sdn-controller-id", + "type" : "string", + "typetext" : "" + }, + "ebgp" : { + "description" : "Enable ebgp. (remote-as external)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ebgp-multihop" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "loopback" : { + "description" : "source loopback interface.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peers" : { + "description" : "peers address list.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "bgp", + "evpn", + "faucet" + ], + "format" : "pve-configid", + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/controllers", + "text" : "controllers" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn ipam object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ipam" : { + "description" : "The SDN ipam object identifier.", + "format" : "pve-sdn-ipam-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn ipam configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ipam" : { + "description" : "The SDN ipam object identifier.", + "format" : "pve-sdn-ipam-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/ipams/{ipam}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn ipam object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ipam" : { + "description" : "The SDN ipam object identifier.", + "format" : "pve-sdn-ipam-id", + "type" : "string", + "typetext" : "" + }, + "section" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "token" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "url" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/ipams/{ipam}", + "text" : "{ipam}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN ipams index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list sdn ipams of specific type", + "enum" : [ + "netbox", + "phpipam", + "pve" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/ipams/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "ipam" : { + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{ipam}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn ipam object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ipam" : { + "description" : "The SDN ipam object identifier.", + "format" : "pve-sdn-ipam-id", + "type" : "string", + "typetext" : "" + }, + "section" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "token" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "netbox", + "phpipam", + "pve" + ], + "format" : "pve-configid", + "type" : "string" + }, + "url" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/ipams", + "text" : "ipams" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn dns object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dns" : { + "description" : "The SDN dns object identifier.", + "format" : "pve-sdn-dns-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn dns configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dns" : { + "description" : "The SDN dns object identifier.", + "format" : "pve-sdn-dns-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/dns/{dns}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn dns object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dns" : { + "description" : "The SDN dns object identifier.", + "format" : "pve-sdn-dns-id", + "type" : "string", + "typetext" : "" + }, + "key" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "reversemaskv6" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "ttl" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "url" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/dns/{dns}", + "text" : "{dns}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN dns index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list sdn dns of specific type", + "enum" : [ + "powerdns" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/dns/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "dns" : { + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{dns}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn dns object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dns" : { + "description" : "The SDN dns object identifier.", + "format" : "pve-sdn-dns-id", + "type" : "string", + "typetext" : "" + }, + "key" : { + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "reversemaskv6" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "reversev6mask" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "ttl" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "powerdns" + ], + "format" : "pve-configid", + "type" : "string" + }, + "url" : { + "optional" : 0, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/dns", + "text" : "dns" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "SDN.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Apply sdn controller changes && reload.", + "method" : "PUT", + "name" : "reload", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn", + "text" : "sdn" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read cluster log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "max" : { + "description" : "Maximum number of entries.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Resources index (cluster wide).", + "method" : "GET", + "name" : "resources", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "enum" : [ + "vm", + "storage", + "node", + "sdn" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "cgroup-mode" : { + "description" : "The cgroup mode the node operates under (when type == node).", + "optional" : 1, + "type" : "integer" + }, + "content" : { + "description" : "Allowed storage content types (when type == storage).", + "format" : "pve-storage-content-list", + "optional" : 1, + "type" : "string" + }, + "cpu" : { + "description" : "CPU utilization (when type in node,qemu,lxc).", + "minimum" : 0, + "optional" : 1, + "renderer" : "fraction_as_percentage", + "type" : "number" + }, + "disk" : { + "description" : "Used disk space in bytes (when type in storage), used root image spave for VMs (type in qemu,lxc).", + "minimum" : 0, + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "hastate" : { + "description" : "HA service status (for HA managed VMs).", + "optional" : 1, + "type" : "string" + }, + "id" : { + "type" : "string" + }, + "level" : { + "description" : "Support level (when type == node).", + "optional" : 1, + "type" : "string" + }, + "maxcpu" : { + "description" : "Number of available CPUs (when type in node,qemu,lxc).", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "maxdisk" : { + "description" : "Storage size in bytes (when type in storage), root image size for VMs (type in qemu,lxc).", + "minimum" : 0, + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Number of available memory in bytes (when type in node,qemu,lxc).", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "mem" : { + "description" : "Used memory in bytes (when type in node,qemu,lxc).", + "minimum" : 0, + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "Name of the resource.", + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name (when type in node,storage,qemu,lxc).", + "format" : "pve-node", + "optional" : 1, + "type" : "string" + }, + "plugintype" : { + "description" : "More specific type, if available.", + "optional" : 1, + "type" : "string" + }, + "pool" : { + "description" : "The pool name (when type in pool,qemu,lxc).", + "optional" : 1, + "type" : "string" + }, + "status" : { + "description" : "Resource type dependent status.", + "optional" : 1, + "type" : "string" + }, + "storage" : { + "description" : "The storage identifier (when type == storage).", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Resource type.", + "enum" : [ + "node", + "storage", + "pool", + "qemu", + "lxc", + "openvz", + "sdn" + ], + "type" : "string" + }, + "uptime" : { + "description" : "Node uptime in seconds (when type in node,qemu,lxc).", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The numerical vmid (when type in qemu,lxc).", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/resources", + "text" : "resources" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List recent tasks (cluster wide).", + "method" : "GET", + "name" : "tasks", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "upid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/tasks", + "text" : "tasks" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get datacenter options. Without 'Sys.Audit' on '/' not all options are returned.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ], + "user" : "all" + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set datacenter options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "description" : "Set bandwidth/io limits various operations.", + "format" : { + "clone" : { + "description" : "bandwidth limit in KiB/s for cloning disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "default" : { + "description" : "default bandwidth limit in KiB/s", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "migration" : { + "description" : "bandwidth limit in KiB/s for migrating guests (including moving local disks)", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "move" : { + "description" : "bandwidth limit in KiB/s for moving disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "restore" : { + "description" : "bandwidth limit in KiB/s for restoring guests from backups", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[clone=] [,default=] [,migration=] [,move=] [,restore=]" + }, + "console" : { + "description" : "Select the default Console viewer. You can either use the builtin java applet (VNC; deprecated and maps to html5), an external virt-viewer comtatible application (SPICE), an HTML5 based vnc viewer (noVNC), or an HTML5 based console client (xtermjs). If the selected viewer is not available (e.g. SPICE not activated for the VM), the fallback is noVNC.", + "enum" : [ + "applet", + "vv", + "html5", + "xtermjs" + ], + "optional" : 1, + "type" : "string" + }, + "crs" : { + "description" : "Cluster resource scheduling settings.", + "format" : { + "ha" : { + "default" : "basic", + "description" : "Use this resource scheduler mode for HA.", + "enum" : [ + "basic", + "static" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Configures how the HA manager should select nodes to start or recover services. With 'basic', only the number of services is used, with 'static', static CPU and memory configuration of services is considered." + }, + "ha-rebalance-on-start" : { + "default" : 0, + "description" : "Set to use CRS for selecting a suited node when a HA services request-state changes from stop to start.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[ha=] [,ha-rebalance-on-start=<1|0>]" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Datacenter description. Shown in the web-interface datacenter notes panel. This is saved as comment inside the configuration file.", + "maxLength" : 65536, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "email_from" : { + "description" : "Specify email address to send notification from (default is root@$hostname)", + "format" : "email-opt", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fencing" : { + "default" : "watchdog", + "description" : "Set the fencing mode of the HA cluster. Hardware mode needs a valid configuration of fence devices in /etc/pve/ha/fence.cfg. With both all two modes are used.\n\nWARNING: 'hardware' and 'both' are EXPERIMENTAL & WIP", + "enum" : [ + "watchdog", + "hardware", + "both" + ], + "optional" : 1, + "type" : "string" + }, + "ha" : { + "description" : "Cluster wide HA settings.", + "format" : { + "shutdown_policy" : { + "default" : "conditional", + "description" : "The policy for HA services on node shutdown. 'freeze' disables auto-recovery, 'failover' ensures recovery, 'conditional' recovers on poweroff and freezes on reboot. 'migrate' will migrate running services to other nodes, if possible. With 'freeze' or 'failover', HA Services will always get stopped first on shutdown.", + "enum" : [ + "freeze", + "failover", + "conditional", + "migrate" + ], + "type" : "string", + "verbose_description" : "Describes the policy for handling HA services on poweroff or reboot of a node. Freeze will always freeze services which are still located on the node on shutdown, those services won't be recovered by the HA manager. Failover will not mark the services as frozen and thus the services will get recovered to other nodes, if the shutdown node does not come up again quickly (< 1min). 'conditional' chooses automatically depending on the type of shutdown, i.e., on a reboot the service will be frozen but on a poweroff the service will stay as is, and thus get recovered after about 2 minutes. Migrate will try to move all running services to another node when a reboot or shutdown was triggered. The poweroff process will only continue once no running services are located on the node anymore. If the node comes up again, the service will be moved back to the previously powered-off node, at least if no other migration, reloaction or recovery took place." + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "shutdown_policy=" + }, + "http_proxy" : { + "description" : "Specify external http proxy which is used for downloads (example: 'http://username:password@host:port/')", + "optional" : 1, + "pattern" : "http://.*", + "type" : "string" + }, + "keyboard" : { + "description" : "Default keybord layout for vnc server.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "language" : { + "description" : "Default GUI language.", + "enum" : [ + "ca", + "da", + "de", + "en", + "es", + "eu", + "fa", + "fr", + "he", + "it", + "ja", + "nb", + "nn", + "pl", + "pt_BR", + "ru", + "sl", + "sv", + "tr", + "zh_CN", + "zh_TW" + ], + "optional" : 1, + "type" : "string" + }, + "mac_prefix" : { + "description" : "Prefix for autogenerated MAC addresses.", + "format" : "mac-prefix", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "max_workers" : { + "description" : "Defines how many workers (per node) are maximal started on actions like 'stopall VMs' or task from the ha-manager.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "migration" : { + "description" : "For cluster wide migration settings.", + "format" : { + "network" : { + "description" : "CIDR of the (sub) network that is used for migration.", + "format" : "CIDR", + "format_description" : "CIDR", + "optional" : 1, + "type" : "string" + }, + "type" : { + "default" : "secure", + "default_key" : 1, + "description" : "Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.", + "enum" : [ + "secure", + "insecure" + ], + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[type=] [,network=]" + }, + "migration_unsecure" : { + "description" : "Migration is secure using SSH tunnel by default. For secure private networks you can disable it to speed up migration. Deprecated, use the 'migration' property instead!", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "next-id" : { + "description" : "Control the range for the free VMID auto-selection pool.", + "format" : { + "lower" : { + "default" : 100, + "description" : "Lower, inclusive boundary for free next-id API range.", + "max" : 999999999, + "min" : 100, + "optional" : 1, + "type" : "integer" + }, + "upper" : { + "default" : 1000000, + "description" : "Upper, exclusive boundary for free next-id API range.", + "max" : 1000000000, + "min" : 100, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[lower=] [,upper=]" + }, + "notify" : { + "description" : "Cluster-wide notification settings.", + "format" : { + "package-updates" : { + "default" : "auto", + "description" : "Control when the daily update job should send out notification mails.", + "enum" : [ + "auto", + "always", + "never" + ], + "type" : "string", + "verbose_description" : "Control how often the daily update job should send out notification mails:\n* 'auto' daily for systems with a valid subscription, as those are assumed to be production-ready and thus should know about pending updates.\n* 'always' every update, if there are new pending updates.\n* 'never' never send a notification for new pending updates.\n" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "package-updates=" + }, + "registered-tags" : { + "description" : "A list of tags that require a `Sys.Modify` on '/' to set and delete. Tags set here that are also in 'user-tag-access' also require `Sys.Modify`.", + "optional" : 1, + "pattern" : "(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*);)*(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*)", + "type" : "string", + "typetext" : "[;...]" + }, + "tag-style" : { + "description" : "Tag style options.", + "format" : { + "case-sensitive" : { + "default" : 0, + "description" : "Controls if filtering for unique tags on update should check case-sensitive.", + "optional" : 1, + "type" : "boolean" + }, + "color-map" : { + "description" : "Manual color mapping for tags (semicolon separated).", + "optional" : 1, + "pattern" : "(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*):[0-9a-fA-F]{6}(?::[0-9a-fA-F]{6})?)(?:;(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*):[0-9a-fA-F]{6}(?::[0-9a-fA-F]{6})?))*", + "type" : "string", + "typetext" : ":[:][;=...]" + }, + "ordering" : { + "default" : "alphabetical", + "description" : "Controls the sorting of the tags in the web-interface and the API update.", + "enum" : [ + "config", + "alphabetical" + ], + "optional" : 1, + "type" : "string" + }, + "shape" : { + "default" : "circle", + "description" : "Tag shape for the web ui tree. 'full' draws the full tag. 'circle' draws only a circle with the background color. 'dense' only draws a small rectancle (useful when many tags are assigned to each guest).'none' disables showing the tags.", + "enum" : [ + "full", + "circle", + "dense", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[case-sensitive=<1|0>] [,color-map=:[:][;=...]] [,ordering=] [,shape=]" + }, + "u2f" : { + "description" : "u2f", + "format" : { + "appid" : { + "description" : "U2F AppId URL override. Defaults to the origin.", + "format_description" : "APPID", + "optional" : 1, + "type" : "string" + }, + "origin" : { + "description" : "U2F Origin override. Mostly useful for single nodes with a single URL.", + "format_description" : "URL", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[appid=] [,origin=]" + }, + "user-tag-access" : { + "description" : "Privilege options for user-settable tags", + "format" : { + "user-allow" : { + "default" : "free", + "description" : "Controls tag usage for users without `Sys.Modify` on `/` by either allowing `none`, a `list`, already `existing` or anything (`free`).", + "enum" : [ + "none", + "list", + "existing", + "free" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Controls which tags can be set or deleted on resources a user controls (such as guests). Users with the `Sys.Modify` privilege on `/` are always unrestricted. * 'none' no tags are usable. * 'list' tags from 'user-allow-list' are usable. * 'existing' like list, but already existing tags of resources are also usable.* 'free' no tag restrictions." + }, + "user-allow-list" : { + "description" : "List of tags users are allowed to set and delete (semicolon separated) for 'user-allow' values 'list' and 'existing'.", + "optional" : 1, + "pattern" : "(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*)(?:;(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*))*", + "type" : "string", + "typetext" : "[;...]" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[user-allow=] [,user-allow-list=[;...]]" + }, + "webauthn" : { + "description" : "webauthn configuration", + "format" : { + "allow-subdomains" : { + "default" : 1, + "description" : "Whether to allow the origin to be a subdomain, rather than the exact URL.", + "optional" : 1, + "type" : "boolean" + }, + "id" : { + "description" : "Relying party ID. Must be the domain name without protocol, port or location. Changing this *will* break existing credentials.", + "format_description" : "DOMAINNAME", + "optional" : 1, + "type" : "string" + }, + "origin" : { + "description" : "Site origin. Must be a `https://` URL (or `http://localhost`). Should contain the address users type in their browsers to access the web interface. Changing this *may* break existing credentials.", + "format_description" : "URL", + "optional" : 1, + "type" : "string" + }, + "rp" : { + "description" : "Relying party name. Any text identifier. Changing this *may* break existing credentials.", + "format_description" : "RELYING_PARTY", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[allow-subdomains=<1|0>] [,id=] [,origin=] [,rp=]" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get cluster status information.", + "method" : "GET", + "name" : "get_status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + }, + "ip" : { + "description" : "[node] IP of the resolved nodename.", + "optional" : 1, + "type" : "string" + }, + "level" : { + "description" : "[node] Proxmox VE Subscription level, indicates if eligible for enterprise support as well as access to the stable Proxmox VE Enterprise Repository.", + "optional" : 1, + "type" : "string" + }, + "local" : { + "description" : "[node] Indicates if this is the responding node.", + "optional" : 1, + "type" : "boolean" + }, + "name" : { + "type" : "string" + }, + "nodeid" : { + "description" : "[node] ID of the node from the corosync configuration.", + "optional" : 1, + "type" : "integer" + }, + "nodes" : { + "description" : "[cluster] Nodes count, including offline nodes.", + "optional" : 1, + "type" : "integer" + }, + "online" : { + "description" : "[node] Indicates if the node is online or offline.", + "optional" : 1, + "type" : "boolean" + }, + "quorate" : { + "description" : "[cluster] Indicates if there is a majority of nodes online to make decisions", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "description" : "Indicates the type, either cluster or node. The type defines the object properties e.g. quorate available for type cluster.", + "enum" : [ + "cluster", + "node" + ], + "type" : "string" + }, + "version" : { + "description" : "[cluster] Current version of the corosync configuration file.", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get next free VMID. Pass a VMID to assert that its free (at time of check).", + "method" : "GET", + "name" : "nextid", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "description" : "The next free VMID.", + "type" : "integer" + } + } + }, + "leaf" : 1, + "path" : "/cluster/nextid", + "text" : "nextid" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Cluster index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster", + "text" : "cluster" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "dest" : { + "optional" : 1, + "type" : "string" + }, + "dport" : { + "optional" : 1, + "type" : "string" + }, + "enable" : { + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "optional" : 1, + "type" : "string" + }, + "iface" : { + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "optional" : 1, + "type" : "string" + }, + "pos" : { + "type" : "integer" + }, + "proto" : { + "optional" : 1, + "type" : "string" + }, + "source" : { + "optional" : 1, + "type" : "string" + }, + "sport" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "pos" : { + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 0, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/rules", + "text" : "rules" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network alias.", + "method" : "DELETE", + "name" : "remove_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read alias.", + "method" : "GET", + "name" : "read_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network alias.", + "method" : "PUT", + "name" : "update_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "rename" : { + "description" : "Rename an existing alias.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List aliases", + "method" : "GET", + "name" : "get_aliases", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create IP or Network Alias.", + "method" : "POST", + "name" : "create_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/aliases", + "text" : "aliases" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network from IPSet.", + "method" : "DELETE", + "name" : "remove_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read IP or Network settings from IPSet.", + "method" : "GET", + "name" : "read_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network settings", + "method" : "PUT", + "name" : "update_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "text" : "{cidr}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete IPSet", + "method" : "DELETE", + "name" : "delete_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "Delete all members of the IPSet, if there are any.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List IPSet content", + "method" : "GET", + "name" : "get_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{cidr}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add IP or Network to IPSet.", + "method" : "POST", + "name" : "create_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List IPSets", + "method" : "GET", + "name" : "ipset_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new IPSet", + "method" : "POST", + "name" : "create_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "rename" : { + "description" : "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/ipset", + "text" : "ipset" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get VM firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "dhcp" : { + "default" : 0, + "description" : "Enable DHCP.", + "optional" : 1, + "type" : "boolean" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean" + }, + "ipfilter" : { + "description" : "Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.", + "optional" : 1, + "type" : "boolean" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macfilter" : { + "default" : 1, + "description" : "Enable/disable MAC address filter.", + "optional" : 1, + "type" : "boolean" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "radv" : { + "description" : "Allow sending Router Advertisement.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp" : { + "default" : 0, + "description" : "Enable DHCP.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ipfilter" : { + "description" : "Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macfilter" : { + "default" : 1, + "description" : "Enable/disable MAC address filter.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "radv" : { + "description" : "Allow sending Router Advertisement.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read firewall log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display log since this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "until" : { + "description" : "Display log until this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Lists possible IPSet/Alias reference which are allowed in source/dest properties.", + "method" : "GET", + "name" : "refs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Only list references of specified type.", + "enum" : [ + "alias", + "ipset" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "alias", + "ipset" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/refs", + "text" : "refs" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall", + "text" : "firewall" + }, + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute fsfreeze-freeze.", + "method" : "POST", + "name" : "fsfreeze-freeze", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze", + "text" : "fsfreeze-freeze" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute fsfreeze-status.", + "method" : "POST", + "name" : "fsfreeze-status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status", + "text" : "fsfreeze-status" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute fsfreeze-thaw.", + "method" : "POST", + "name" : "fsfreeze-thaw", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw", + "text" : "fsfreeze-thaw" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute fstrim.", + "method" : "POST", + "name" : "fstrim", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/fstrim", + "text" : "fstrim" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-fsinfo.", + "method" : "GET", + "name" : "get-fsinfo", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-fsinfo", + "text" : "get-fsinfo" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-host-name.", + "method" : "GET", + "name" : "get-host-name", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-host-name", + "text" : "get-host-name" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-memory-block-info.", + "method" : "GET", + "name" : "get-memory-block-info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info", + "text" : "get-memory-block-info" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-memory-blocks.", + "method" : "GET", + "name" : "get-memory-blocks", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks", + "text" : "get-memory-blocks" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-osinfo.", + "method" : "GET", + "name" : "get-osinfo", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-osinfo", + "text" : "get-osinfo" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-time.", + "method" : "GET", + "name" : "get-time", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-time", + "text" : "get-time" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-timezone.", + "method" : "GET", + "name" : "get-timezone", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-timezone", + "text" : "get-timezone" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-users.", + "method" : "GET", + "name" : "get-users", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-users", + "text" : "get-users" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-vcpus.", + "method" : "GET", + "name" : "get-vcpus", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-vcpus", + "text" : "get-vcpus" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute info.", + "method" : "GET", + "name" : "info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/info", + "text" : "info" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute network-get-interfaces.", + "method" : "GET", + "name" : "network-get-interfaces", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces", + "text" : "network-get-interfaces" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute ping.", + "method" : "POST", + "name" : "ping", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/ping", + "text" : "ping" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute shutdown.", + "method" : "POST", + "name" : "shutdown", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/shutdown", + "text" : "shutdown" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute suspend-disk.", + "method" : "POST", + "name" : "suspend-disk", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/suspend-disk", + "text" : "suspend-disk" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute suspend-hybrid.", + "method" : "POST", + "name" : "suspend-hybrid", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid", + "text" : "suspend-hybrid" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute suspend-ram.", + "method" : "POST", + "name" : "suspend-ram", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/suspend-ram", + "text" : "suspend-ram" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Sets the password for the given user to the given password", + "method" : "POST", + "name" : "set-user-password", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "crypted" : { + "default" : 0, + "description" : "set to 1 if the password has already been passed through crypt()", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The new password.", + "maxLength" : 1024, + "minLength" : 5, + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "The user to set the password for.", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/set-user-password", + "text" : "set-user-password" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Executes the given command in the vm via the guest-agent and returns an object with the pid.", + "method" : "POST", + "name" : "exec", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "command" : { + "description" : "The command as a list of program + arguments", + "format" : "string-alist", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "input-data" : { + "description" : "Data to pass as 'input-data' to the guest. Usually treated as STDIN to 'command'.", + "maxLength" : 65536, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "pid" : { + "description" : "The PID of the process started by the guest-agent.", + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/exec", + "text" : "exec" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Gets the status of the given pid started by the guest-agent", + "method" : "GET", + "name" : "exec-status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pid" : { + "description" : "The PID to query", + "type" : "integer", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "err-data" : { + "description" : "stderr of the process", + "optional" : 1, + "type" : "string" + }, + "err-truncated" : { + "description" : "true if stderr was not fully captured", + "optional" : 1, + "type" : "boolean" + }, + "exitcode" : { + "description" : "process exit code if it was normally terminated.", + "optional" : 1, + "type" : "integer" + }, + "exited" : { + "description" : "Tells if the given command has exited yet.", + "type" : "boolean" + }, + "out-data" : { + "description" : "stdout of the process", + "optional" : 1, + "type" : "string" + }, + "out-truncated" : { + "description" : "true if stdout was not fully captured", + "optional" : 1, + "type" : "boolean" + }, + "signal" : { + "description" : "signal number or exception code if the process was abnormally terminated.", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/exec-status", + "text" : "exec-status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Reads the given file via guest agent. Is limited to 16777216 bytes.", + "method" : "GET", + "name" : "file-read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "file" : { + "description" : "The path to the file", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a `content` property.", + "properties" : { + "content" : { + "description" : "The content of the file, maximum 16777216", + "type" : "string" + }, + "truncated" : { + "description" : "If set to 1, the output is truncated and not complete", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/file-read", + "text" : "file-read" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Writes the given file via guest agent.", + "method" : "POST", + "name" : "file-write", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "content" : { + "description" : "The content to write into the file.", + "maxLength" : 61440, + "type" : "string", + "typetext" : "" + }, + "encode" : { + "default" : 1, + "description" : "If set, the content will be encoded as base64 (required by QEMU).Otherwise the content needs to be encoded beforehand - defaults to true.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "file" : { + "description" : "The path to the file.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/file-write", + "text" : "file-write" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "QEMU Guest Agent command index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 1, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "description" : "Returns the list of QEMU Guest Agent commands", + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Execute QEMU Guest Agent commands.", + "method" : "POST", + "name" : "agent", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "command" : { + "description" : "The QGA command.", + "enum" : [ + "fsfreeze-freeze", + "fsfreeze-status", + "fsfreeze-thaw", + "fstrim", + "get-fsinfo", + "get-host-name", + "get-memory-block-info", + "get-memory-blocks", + "get-osinfo", + "get-time", + "get-timezone", + "get-users", + "get-vcpus", + "info", + "network-get-interfaces", + "ping", + "shutdown", + "suspend-disk", + "suspend-hybrid", + "suspend-ram" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/agent", + "text" : "agent" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read VM RRD statistics (returns PNG)", + "method" : "GET", + "name" : "rrd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "ds" : { + "description" : "The list of datasources you want to display.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "filename" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/rrd", + "text" : "rrd" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read VM RRD statistics", + "method" : "GET", + "name" : "rrddata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/rrddata", + "text" : "rrddata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the virtual machine configuration with pending configuration changes applied. Set the 'current' parameter to get the current configuration instead.", + "method" : "GET", + "name" : "vm_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "current" : { + "default" : 0, + "description" : "Get current values (instead of pending values).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapshot" : { + "description" : "Fetch config values from given snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "description" : "The VM configuration.", + "properties" : { + "acpi" : { + "default" : 1, + "description" : "Enable/disable ACPI.", + "optional" : 1, + "type" : "boolean" + }, + "affinity" : { + "description" : "List of host cores used to execute guest processes, for example: 0,5,8-11", + "format" : "pve-cpuset", + "optional" : 1, + "type" : "string" + }, + "agent" : { + "description" : "Enable/disable communication with the QEMU Guest Agent and its properties.", + "format" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.", + "type" : "boolean" + }, + "freeze-fs-on-backup" : { + "default" : 1, + "description" : "Freeze/thaw guest filesystems on backup for consistency.", + "optional" : 1, + "type" : "boolean" + }, + "fstrim_cloned_disks" : { + "default" : 0, + "description" : "Run fstrim after moving a disk or migrating the VM.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default" : "virtio", + "description" : "Select the agent type", + "enum" : [ + "virtio", + "isa" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "args" : { + "description" : "Arbitrary arguments passed to kvm.", + "optional" : 1, + "type" : "string", + "verbose_description" : "Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -no-hpet\n\nNOTE: this option is for experts only.\n" + }, + "audio0" : { + "description" : "Configure a audio device, useful in combination with QXL/Spice.", + "format" : { + "device" : { + "description" : "Configure an audio device.", + "enum" : [ + "ich9-intel-hda", + "intel-hda", + "AC97" + ], + "type" : "string" + }, + "driver" : { + "default" : "spice", + "description" : "Driver backend for the audio device.", + "enum" : [ + "spice", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "autostart" : { + "default" : 0, + "description" : "Automatic restart after crash (currently ignored).", + "optional" : 1, + "type" : "boolean" + }, + "balloon" : { + "description" : "Amount of target RAM for the VM in MiB. Using zero disables the ballon driver.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "bios" : { + "default" : "seabios", + "description" : "Select BIOS implementation.", + "enum" : [ + "seabios", + "ovmf" + ], + "optional" : 1, + "type" : "string" + }, + "boot" : { + "description" : "Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.", + "format" : "pve-qm-boot", + "optional" : 1, + "type" : "string" + }, + "bootdisk" : { + "description" : "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format" : "pve-qm-bootdisk", + "optional" : 1, + "pattern" : "(ide|sata|scsi|virtio)\\d+", + "type" : "string" + }, + "cdrom" : { + "description" : "This is an alias for option -ide2", + "format" : "pve-qm-ide", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cicustom" : { + "description" : "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format" : "pve-qm-cicustom", + "optional" : 1, + "type" : "string" + }, + "cipassword" : { + "description" : "cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.", + "optional" : 1, + "type" : "string" + }, + "citype" : { + "description" : "Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.", + "enum" : [ + "configdrive2", + "nocloud", + "opennebula" + ], + "optional" : 1, + "type" : "string" + }, + "ciuser" : { + "description" : "cloud-init: User name to change ssh keys and password for instead of the image's configured default user.", + "optional" : 1, + "type" : "string" + }, + "cores" : { + "default" : 1, + "description" : "The number of cores per socket.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cpu" : { + "description" : "Emulated CPU type.", + "format" : "pve-vm-cpu-conf", + "optional" : 1, + "type" : "string" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "verbose_description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit." + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 262144, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "verbose_description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs." + }, + "description" : { + "description" : "Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "SHA1 digest of configuration file. This can be used to prevent concurrent modifications.", + "type" : "string" + }, + "efidisk0" : { + "description" : "Configure a disk for storing EFI vars.", + "format" : { + "efitype" : { + "default" : "2m", + "description" : "Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarc64 (ARM).", + "enum" : [ + "2m", + "4m" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "pre-enrolled-keys" : { + "default" : 0, + "description" : "Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string" + }, + "freeze" : { + "description" : "Freeze CPU at startup (use 'c' monitor command to start execution).", + "optional" : 1, + "type" : "boolean" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the vms lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string" + }, + "hostpci[n]" : { + "description" : "Map host PCI devices into guest.", + "format" : "pve-qm-hostpci", + "optional" : 1, + "type" : "string", + "verbose_description" : "Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "hotplug" : { + "default" : "network,disk,usb", + "description" : "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.", + "format" : "pve-hotplug-features", + "optional" : 1, + "type" : "string" + }, + "hugepages" : { + "description" : "Enable/disable hugepages memory.", + "enum" : [ + "any", + "2", + "1024" + ], + "optional" : 1, + "type" : "string" + }, + "ide[n]" : { + "description" : "Use volume as IDE hard disk or CD-ROM (n is 0 to 3).", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "model" : { + "description" : "The drive's reported model name, url-encoded, up to 40 bytes long.", + "format" : "urlencoded", + "format_description" : "model", + "maxLength" : 120, + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "ipconfig[n]" : { + "description" : "cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n", + "format" : "pve-qm-ipconfig", + "optional" : 1, + "type" : "string" + }, + "ivshmem" : { + "description" : "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + "format" : { + "name" : { + "description" : "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + "format_description" : "string", + "optional" : 1, + "pattern" : "[a-zA-Z0-9\\-]+", + "type" : "string" + }, + "size" : { + "description" : "The size of the file in MB.", + "minimum" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string" + }, + "keephugepages" : { + "default" : 0, + "description" : "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "optional" : 1, + "type" : "boolean" + }, + "keyboard" : { + "default" : null, + "description" : "Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "kvm" : { + "default" : 1, + "description" : "Enable/disable KVM hardware virtualization.", + "optional" : 1, + "type" : "boolean" + }, + "localtime" : { + "description" : "Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.", + "optional" : 1, + "type" : "boolean" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ], + "optional" : 1, + "type" : "string" + }, + "machine" : { + "description" : "Specifies the QEMU machine type.", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.", + "minimum" : 16, + "optional" : 1, + "type" : "integer" + }, + "migrate_downtime" : { + "default" : 0.1, + "description" : "Set maximum tolerated downtime (in seconds) for migrations.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "migrate_speed" : { + "default" : 0, + "description" : "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "Set a name for the VM. Only used on the configuration web interface.", + "format" : "dns-name", + "optional" : 1, + "type" : "string" + }, + "nameserver" : { + "description" : "cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "format" : "address-list", + "optional" : 1, + "type" : "string" + }, + "net[n]" : { + "description" : "Specify network devices.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n", + "format" : "pve-bridge-id", + "format_description" : "bridge", + "optional" : 1, + "type" : "string" + }, + "e1000" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82540em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82544gc" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82545em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000e" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "firewall" : { + "description" : "Whether this interface should be protected by the firewall.", + "optional" : 1, + "type" : "boolean" + }, + "i82551" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82557b" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82559er" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "macaddr" : { + "description" : "MAC address. That address must be unique withing your network. This is automatically generated if not specified.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "model" : { + "default_key" : 1, + "description" : "Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.", + "enum" : [ + "e1000", + "e1000-82540em", + "e1000-82544gc", + "e1000-82545em", + "e1000e", + "i82551", + "i82557b", + "i82559er", + "ne2k_isa", + "ne2k_pci", + "pcnet", + "rtl8139", + "virtio", + "vmxnet3" + ], + "type" : "string" + }, + "mtu" : { + "description" : "Force MTU, for VirtIO only. Set to '1' to use the bridge MTU", + "maximum" : 65520, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "ne2k_isa" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "ne2k_pci" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "pcnet" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "queues" : { + "description" : "Number of packet queues to be used on the device.", + "maximum" : 64, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "rtl8139" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "tag" : { + "description" : "VLAN tag to apply to packets on this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN trunks to pass through this interface.", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "virtio" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "vmxnet3" : { + "alias" : "macaddr", + "keyAlias" : "model" + } + }, + "optional" : 1, + "type" : "string" + }, + "numa" : { + "default" : 0, + "description" : "Enable/disable NUMA.", + "optional" : 1, + "type" : "boolean" + }, + "numa[n]" : { + "description" : "NUMA topology.", + "format" : { + "cpus" : { + "description" : "CPUs accessing this NUMA node.", + "format_description" : "id[-id];...", + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "hostnodes" : { + "description" : "Host NUMA nodes to use.", + "format_description" : "id[-id];...", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "memory" : { + "description" : "Amount of memory this NUMA node provides.", + "optional" : 1, + "type" : "number" + }, + "policy" : { + "description" : "NUMA allocation policy.", + "enum" : [ + "preferred", + "bind", + "interleave" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean" + }, + "ostype" : { + "description" : "Specify guest operating system.", + "enum" : [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "win11", + "l24", + "l26", + "solaris" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 6.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n" + }, + "parallel[n]" : { + "description" : "Map host parallel devices (n is 0 to 2).", + "optional" : 1, + "pattern" : "/dev/parport\\d+|/dev/usb/lp\\d+", + "type" : "string", + "verbose_description" : "Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "optional" : 1, + "type" : "boolean" + }, + "reboot" : { + "default" : 1, + "description" : "Allow reboot. If set to '0' the VM exit on reboot.", + "optional" : 1, + "type" : "boolean" + }, + "rng0" : { + "description" : "Configure a VirtIO-based Random Number Generator.", + "format" : { + "max_bytes" : { + "default" : 1024, + "description" : "Maximum bytes of entropy allowed to get injected into the guest every 'period' milliseconds. Prefer a lower value when using '/dev/random' as source. Use `0` to disable limiting (potentially dangerous!).", + "optional" : 1, + "type" : "integer" + }, + "period" : { + "default" : 1000, + "description" : "Every 'period' milliseconds the entropy-injection quota is reset, allowing the guest to retrieve another 'max_bytes' of entropy.", + "optional" : 1, + "type" : "integer" + }, + "source" : { + "default_key" : 1, + "description" : "The file on the host to gather entropy from. In most cases '/dev/urandom' should be preferred over '/dev/random' to avoid entropy-starvation issues on the host. Using urandom does *not* decrease security in any meaningful way, as it's still seeded from real entropy, and the bytes provided will most likely be mixed with real entropy on the guest as well. '/dev/hwrng' can be used to pass through a hardware RNG from the host.", + "enum" : [ + "/dev/urandom", + "/dev/random", + "/dev/hwrng" + ], + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "sata[n]" : { + "description" : "Use volume as SATA hard disk or CD-ROM (n is 0 to 5).", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "scsi[n]" : { + "description" : "Use volume as SCSI hard disk or CD-ROM (n is 0 to 30).", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "queues" : { + "description" : "Number of queues.", + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "scsiblock" : { + "default" : 0, + "description" : "whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "scsihw" : { + "default" : "lsi", + "description" : "SCSI controller model", + "enum" : [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "optional" : 1, + "type" : "string" + }, + "serial[n]" : { + "description" : "Create a serial device inside the VM (n is 0 to 3)", + "optional" : 1, + "pattern" : "(/dev/.+|socket)", + "type" : "string", + "verbose_description" : "Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "shares" : { + "default" : 1000, + "description" : "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.", + "maximum" : 50000, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "smbios1" : { + "description" : "Specify SMBIOS type 1 fields.", + "format" : "pve-qm-smbios1", + "maxLength" : 512, + "optional" : 1, + "type" : "string" + }, + "smp" : { + "default" : 1, + "description" : "The number of CPUs. Please use option -sockets instead.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "sockets" : { + "default" : 1, + "description" : "The number of CPU sockets.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "spice_enhancements" : { + "description" : "Configure additional enhancements for SPICE.", + "format" : { + "foldersharing" : { + "default" : "0", + "description" : "Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.", + "optional" : 1, + "type" : "boolean" + }, + "videostreaming" : { + "default" : "off", + "description" : "Enable video streaming. Uses compression for detected video streams.", + "enum" : [ + "off", + "all", + "filter" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "sshkeys" : { + "description" : "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format" : "urlencoded", + "optional" : 1, + "type" : "string" + }, + "startdate" : { + "default" : "now", + "description" : "Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.", + "optional" : 1, + "pattern" : "(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)", + "type" : "string", + "typetext" : "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "tablet" : { + "default" : 1, + "description" : "Enable/disable the USB tablet device.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)." + }, + "tags" : { + "description" : "Tags of the VM. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string" + }, + "tdf" : { + "default" : 0, + "description" : "Enable/disable time drift fix.", + "optional" : 1, + "type" : "boolean" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean" + }, + "tpmstate0" : { + "description" : "Configure a Disk for storing TPM state. The format is fixed to 'raw'.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "version" : { + "default" : "v2.0", + "description" : "The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.", + "enum" : [ + "v1.2", + "v2.0" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string" + }, + "usb[n]" : { + "description" : "Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).", + "format" : { + "host" : { + "default_key" : 1, + "description" : "The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadeciaml numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n", + "format" : "pve-qm-usb-device", + "format_description" : "HOSTUSBDEVICE|spice", + "type" : "string" + }, + "usb3" : { + "default" : 0, + "description" : "Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string" + }, + "vcpus" : { + "default" : 0, + "description" : "Number of hotplugged vcpus.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "vga" : { + "description" : "Configure the VGA hardware.", + "format" : { + "memory" : { + "description" : "Sets the VGA memory (in MiB). Has no effect with serial display.", + "maximum" : 512, + "minimum" : 4, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "default" : "std", + "default_key" : 1, + "description" : "Select the VGA type.", + "enum" : [ + "cirrus", + "qxl", + "qxl2", + "qxl3", + "qxl4", + "none", + "serial0", + "serial1", + "serial2", + "serial3", + "std", + "virtio", + "virtio-gl", + "vmware" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "verbose_description" : "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal." + }, + "virtio[n]" : { + "description" : "Use volume as VIRTIO hard disk (n is 0 to 15).", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "vmgenid" : { + "default" : "1 (autogenerated)", + "description" : "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "format_description" : "UUID", + "optional" : 1, + "pattern" : "(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])", + "type" : "string", + "verbose_description" : "The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file." + }, + "vmstatestorage" : { + "description" : "Default storage for VM state volumes/files.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string" + }, + "watchdog" : { + "description" : "Create a virtual hardware watchdog device.", + "format" : "pve-qm-watchdog", + "optional" : 1, + "type" : "string", + "verbose_description" : "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Set virtual machine options (asynchrounous API).", + "method" : "POST", + "name" : "update_vm_async", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acpi" : { + "default" : 1, + "description" : "Enable/disable ACPI.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "affinity" : { + "description" : "List of host cores used to execute guest processes, for example: 0,5,8-11", + "format" : "pve-cpuset", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "agent" : { + "description" : "Enable/disable communication with the QEMU Guest Agent and its properties.", + "format" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.", + "type" : "boolean" + }, + "freeze-fs-on-backup" : { + "default" : 1, + "description" : "Freeze/thaw guest filesystems on backup for consistency.", + "optional" : 1, + "type" : "boolean" + }, + "fstrim_cloned_disks" : { + "default" : 0, + "description" : "Run fstrim after moving a disk or migrating the VM.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default" : "virtio", + "description" : "Select the agent type", + "enum" : [ + "virtio", + "isa" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[enabled=]<1|0> [,freeze-fs-on-backup=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "args" : { + "description" : "Arbitrary arguments passed to kvm.", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -no-hpet\n\nNOTE: this option is for experts only.\n" + }, + "audio0" : { + "description" : "Configure a audio device, useful in combination with QXL/Spice.", + "format" : { + "device" : { + "description" : "Configure an audio device.", + "enum" : [ + "ich9-intel-hda", + "intel-hda", + "AC97" + ], + "type" : "string" + }, + "driver" : { + "default" : "spice", + "description" : "Driver backend for the audio device.", + "enum" : [ + "spice", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "device= [,driver=]" + }, + "autostart" : { + "default" : 0, + "description" : "Automatic restart after crash (currently ignored).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "background_delay" : { + "description" : "Time to wait for the task to finish. We return 'null' if the task finish within that time.", + "maximum" : 30, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 30)" + }, + "balloon" : { + "description" : "Amount of target RAM for the VM in MiB. Using zero disables the ballon driver.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "bios" : { + "default" : "seabios", + "description" : "Select BIOS implementation.", + "enum" : [ + "seabios", + "ovmf" + ], + "optional" : 1, + "type" : "string" + }, + "boot" : { + "description" : "Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.", + "format" : "pve-qm-boot", + "optional" : 1, + "type" : "string", + "typetext" : "[[legacy=]<[acdn]{1,4}>] [,order=]" + }, + "bootdisk" : { + "description" : "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format" : "pve-qm-bootdisk", + "optional" : 1, + "pattern" : "(ide|sata|scsi|virtio)\\d+", + "type" : "string" + }, + "cdrom" : { + "description" : "This is an alias for option -ide2", + "format" : "pve-qm-ide", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cicustom" : { + "description" : "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format" : "pve-qm-cicustom", + "optional" : 1, + "type" : "string", + "typetext" : "[meta=] [,network=] [,user=] [,vendor=]" + }, + "cipassword" : { + "description" : "cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "citype" : { + "description" : "Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.", + "enum" : [ + "configdrive2", + "nocloud", + "opennebula" + ], + "optional" : 1, + "type" : "string" + }, + "ciuser" : { + "description" : "cloud-init: User name to change ssh keys and password for instead of the image's configured default user.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cores" : { + "default" : 1, + "description" : "The number of cores per socket.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "cpu" : { + "description" : "Emulated CPU type.", + "format" : "pve-vm-cpu-conf", + "optional" : 1, + "type" : "string", + "typetext" : "[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 128)", + "verbose_description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit." + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 262144, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 262144)", + "verbose_description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs." + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "efidisk0" : { + "description" : "Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "efitype" : { + "default" : "2m", + "description" : "Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarc64 (ARM).", + "enum" : [ + "2m", + "4m" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "pre-enrolled-keys" : { + "default" : 0, + "description" : "Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,pre-enrolled-keys=<1|0>] [,size=]" + }, + "force" : { + "description" : "Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.", + "optional" : 1, + "requires" : "delete", + "type" : "boolean", + "typetext" : "" + }, + "freeze" : { + "description" : "Freeze CPU at startup (use 'c' monitor command to start execution).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the vms lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostpci[n]" : { + "description" : "Map host PCI devices into guest.", + "format" : "pve-qm-hostpci", + "optional" : 1, + "type" : "string", + "typetext" : "[host=] [,device-id=] [,legacy-igd=<1|0>] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]", + "verbose_description" : "Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "hotplug" : { + "default" : "network,disk,usb", + "description" : "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.", + "format" : "pve-hotplug-features", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hugepages" : { + "description" : "Enable/disable hugepages memory.", + "enum" : [ + "any", + "2", + "1024" + ], + "optional" : 1, + "type" : "string" + }, + "ide[n]" : { + "description" : "Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "model" : { + "description" : "The drive's reported model name, url-encoded, up to 40 bytes long.", + "format" : "urlencoded", + "format_description" : "model", + "maxLength" : 120, + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "ipconfig[n]" : { + "description" : "cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n", + "format" : "pve-qm-ipconfig", + "optional" : 1, + "type" : "string", + "typetext" : "[gw=] [,gw6=] [,ip=] [,ip6=]" + }, + "ivshmem" : { + "description" : "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + "format" : { + "name" : { + "description" : "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + "format_description" : "string", + "optional" : 1, + "pattern" : "[a-zA-Z0-9\\-]+", + "type" : "string" + }, + "size" : { + "description" : "The size of the file in MB.", + "minimum" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "size= [,name=]" + }, + "keephugepages" : { + "default" : 0, + "description" : "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "keyboard" : { + "default" : null, + "description" : "Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "kvm" : { + "default" : 1, + "description" : "Enable/disable KVM hardware virtualization.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "localtime" : { + "description" : "Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ], + "optional" : 1, + "type" : "string" + }, + "machine" : { + "description" : "Specifies the QEMU machine type.", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.", + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - N)" + }, + "migrate_downtime" : { + "default" : 0.1, + "description" : "Set maximum tolerated downtime (in seconds) for migrations.", + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "migrate_speed" : { + "default" : 0, + "description" : "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "name" : { + "description" : "Set a name for the VM. Only used on the configuration web interface.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nameserver" : { + "description" : "cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "format" : "address-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specify network devices.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n", + "format" : "pve-bridge-id", + "format_description" : "bridge", + "optional" : 1, + "type" : "string" + }, + "e1000" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82540em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82544gc" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82545em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000e" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "firewall" : { + "description" : "Whether this interface should be protected by the firewall.", + "optional" : 1, + "type" : "boolean" + }, + "i82551" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82557b" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82559er" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "macaddr" : { + "description" : "MAC address. That address must be unique withing your network. This is automatically generated if not specified.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "model" : { + "default_key" : 1, + "description" : "Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.", + "enum" : [ + "e1000", + "e1000-82540em", + "e1000-82544gc", + "e1000-82545em", + "e1000e", + "i82551", + "i82557b", + "i82559er", + "ne2k_isa", + "ne2k_pci", + "pcnet", + "rtl8139", + "virtio", + "vmxnet3" + ], + "type" : "string" + }, + "mtu" : { + "description" : "Force MTU, for VirtIO only. Set to '1' to use the bridge MTU", + "maximum" : 65520, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "ne2k_isa" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "ne2k_pci" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "pcnet" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "queues" : { + "description" : "Number of packet queues to be used on the device.", + "maximum" : 64, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "rtl8139" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "tag" : { + "description" : "VLAN tag to apply to packets on this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN trunks to pass through this interface.", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "virtio" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "vmxnet3" : { + "alias" : "macaddr", + "keyAlias" : "model" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "numa" : { + "default" : 0, + "description" : "Enable/disable NUMA.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "numa[n]" : { + "description" : "NUMA topology.", + "format" : { + "cpus" : { + "description" : "CPUs accessing this NUMA node.", + "format_description" : "id[-id];...", + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "hostnodes" : { + "description" : "Host NUMA nodes to use.", + "format_description" : "id[-id];...", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "memory" : { + "description" : "Amount of memory this NUMA node provides.", + "optional" : 1, + "type" : "number" + }, + "policy" : { + "description" : "NUMA allocation policy.", + "enum" : [ + "preferred", + "bind", + "interleave" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "cpus= [,hostnodes=] [,memory=] [,policy=]" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostype" : { + "description" : "Specify guest operating system.", + "enum" : [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "win11", + "l24", + "l26", + "solaris" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 6.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n" + }, + "parallel[n]" : { + "description" : "Map host parallel devices (n is 0 to 2).", + "optional" : 1, + "pattern" : "/dev/parport\\d+|/dev/usb/lp\\d+", + "type" : "string", + "verbose_description" : "Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "reboot" : { + "default" : 1, + "description" : "Allow reboot. If set to '0' the VM exit on reboot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "revert" : { + "description" : "Revert a pending change.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rng0" : { + "description" : "Configure a VirtIO-based Random Number Generator.", + "format" : { + "max_bytes" : { + "default" : 1024, + "description" : "Maximum bytes of entropy allowed to get injected into the guest every 'period' milliseconds. Prefer a lower value when using '/dev/random' as source. Use `0` to disable limiting (potentially dangerous!).", + "optional" : 1, + "type" : "integer" + }, + "period" : { + "default" : 1000, + "description" : "Every 'period' milliseconds the entropy-injection quota is reset, allowing the guest to retrieve another 'max_bytes' of entropy.", + "optional" : 1, + "type" : "integer" + }, + "source" : { + "default_key" : 1, + "description" : "The file on the host to gather entropy from. In most cases '/dev/urandom' should be preferred over '/dev/random' to avoid entropy-starvation issues on the host. Using urandom does *not* decrease security in any meaningful way, as it's still seeded from real entropy, and the bytes provided will most likely be mixed with real entropy on the guest as well. '/dev/hwrng' can be used to pass through a hardware RNG from the host.", + "enum" : [ + "/dev/urandom", + "/dev/random", + "/dev/hwrng" + ], + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[source=] [,max_bytes=] [,period=]" + }, + "sata[n]" : { + "description" : "Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "scsi[n]" : { + "description" : "Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "queues" : { + "description" : "Number of queues.", + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "scsiblock" : { + "default" : 0, + "description" : "whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "scsihw" : { + "default" : "lsi", + "description" : "SCSI controller model", + "enum" : [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "serial[n]" : { + "description" : "Create a serial device inside the VM (n is 0 to 3)", + "optional" : 1, + "pattern" : "(/dev/.+|socket)", + "type" : "string", + "verbose_description" : "Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "shares" : { + "default" : 1000, + "description" : "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.", + "maximum" : 50000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 50000)" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "smbios1" : { + "description" : "Specify SMBIOS type 1 fields.", + "format" : "pve-qm-smbios1", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]" + }, + "smp" : { + "default" : 1, + "description" : "The number of CPUs. Please use option -sockets instead.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "sockets" : { + "default" : 1, + "description" : "The number of CPU sockets.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "spice_enhancements" : { + "description" : "Configure additional enhancements for SPICE.", + "format" : { + "foldersharing" : { + "default" : "0", + "description" : "Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.", + "optional" : 1, + "type" : "boolean" + }, + "videostreaming" : { + "default" : "off", + "description" : "Enable video streaming. Uses compression for detected video streams.", + "enum" : [ + "off", + "all", + "filter" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[foldersharing=<1|0>] [,videostreaming=]" + }, + "sshkeys" : { + "description" : "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format" : "urlencoded", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "startdate" : { + "default" : "now", + "description" : "Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.", + "optional" : 1, + "pattern" : "(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)", + "type" : "string", + "typetext" : "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "tablet" : { + "default" : 1, + "description" : "Enable/disable the USB tablet device.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)." + }, + "tags" : { + "description" : "Tags of the VM. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tdf" : { + "default" : 0, + "description" : "Enable/disable time drift fix.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tpmstate0" : { + "description" : "Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "version" : { + "default" : "v2.0", + "description" : "The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.", + "enum" : [ + "v1.2", + "v2.0" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,import-from=] [,size=] [,version=]" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=]" + }, + "usb[n]" : { + "description" : "Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).", + "format" : { + "host" : { + "default_key" : 1, + "description" : "The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadeciaml numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n", + "format" : "pve-qm-usb-device", + "format_description" : "HOSTUSBDEVICE|spice", + "type" : "string" + }, + "usb3" : { + "default" : 0, + "description" : "Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[host=] [,usb3=<1|0>]" + }, + "vcpus" : { + "default" : 0, + "description" : "Number of hotplugged vcpus.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vga" : { + "description" : "Configure the VGA hardware.", + "format" : { + "memory" : { + "description" : "Sets the VGA memory (in MiB). Has no effect with serial display.", + "maximum" : 512, + "minimum" : 4, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "default" : "std", + "default_key" : 1, + "description" : "Select the VGA type.", + "enum" : [ + "cirrus", + "qxl", + "qxl2", + "qxl3", + "qxl4", + "none", + "serial0", + "serial1", + "serial2", + "serial3", + "std", + "virtio", + "virtio-gl", + "vmware" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,memory=]", + "verbose_description" : "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal." + }, + "virtio[n]" : { + "description" : "Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]" + }, + "vmgenid" : { + "default" : "1 (autogenerated)", + "description" : "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "format_description" : "UUID", + "optional" : 1, + "pattern" : "(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])", + "type" : "string", + "verbose_description" : "The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file." + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vmstatestorage" : { + "description" : "Default storage for VM state volumes/files.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "watchdog" : { + "description" : "Create a virtual hardware watchdog device.", + "format" : "pve-qm-watchdog", + "optional" : 1, + "type" : "string", + "typetext" : "[[model=]] [,action=]", + "verbose_description" : "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk", + "VM.Config.CDROM", + "VM.Config.CPU", + "VM.Config.Memory", + "VM.Config.Network", + "VM.Config.HWType", + "VM.Config.Options", + "VM.Config.Cloudinit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "optional" : 1, + "type" : "string" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set virtual machine options (synchrounous API) - You should consider using the POST method instead for any actions involving hotplug or storage allocation.", + "method" : "PUT", + "name" : "update_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acpi" : { + "default" : 1, + "description" : "Enable/disable ACPI.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "affinity" : { + "description" : "List of host cores used to execute guest processes, for example: 0,5,8-11", + "format" : "pve-cpuset", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "agent" : { + "description" : "Enable/disable communication with the QEMU Guest Agent and its properties.", + "format" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.", + "type" : "boolean" + }, + "freeze-fs-on-backup" : { + "default" : 1, + "description" : "Freeze/thaw guest filesystems on backup for consistency.", + "optional" : 1, + "type" : "boolean" + }, + "fstrim_cloned_disks" : { + "default" : 0, + "description" : "Run fstrim after moving a disk or migrating the VM.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default" : "virtio", + "description" : "Select the agent type", + "enum" : [ + "virtio", + "isa" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[enabled=]<1|0> [,freeze-fs-on-backup=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "args" : { + "description" : "Arbitrary arguments passed to kvm.", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -no-hpet\n\nNOTE: this option is for experts only.\n" + }, + "audio0" : { + "description" : "Configure a audio device, useful in combination with QXL/Spice.", + "format" : { + "device" : { + "description" : "Configure an audio device.", + "enum" : [ + "ich9-intel-hda", + "intel-hda", + "AC97" + ], + "type" : "string" + }, + "driver" : { + "default" : "spice", + "description" : "Driver backend for the audio device.", + "enum" : [ + "spice", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "device= [,driver=]" + }, + "autostart" : { + "default" : 0, + "description" : "Automatic restart after crash (currently ignored).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "balloon" : { + "description" : "Amount of target RAM for the VM in MiB. Using zero disables the ballon driver.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "bios" : { + "default" : "seabios", + "description" : "Select BIOS implementation.", + "enum" : [ + "seabios", + "ovmf" + ], + "optional" : 1, + "type" : "string" + }, + "boot" : { + "description" : "Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.", + "format" : "pve-qm-boot", + "optional" : 1, + "type" : "string", + "typetext" : "[[legacy=]<[acdn]{1,4}>] [,order=]" + }, + "bootdisk" : { + "description" : "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format" : "pve-qm-bootdisk", + "optional" : 1, + "pattern" : "(ide|sata|scsi|virtio)\\d+", + "type" : "string" + }, + "cdrom" : { + "description" : "This is an alias for option -ide2", + "format" : "pve-qm-ide", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cicustom" : { + "description" : "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format" : "pve-qm-cicustom", + "optional" : 1, + "type" : "string", + "typetext" : "[meta=] [,network=] [,user=] [,vendor=]" + }, + "cipassword" : { + "description" : "cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "citype" : { + "description" : "Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.", + "enum" : [ + "configdrive2", + "nocloud", + "opennebula" + ], + "optional" : 1, + "type" : "string" + }, + "ciuser" : { + "description" : "cloud-init: User name to change ssh keys and password for instead of the image's configured default user.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cores" : { + "default" : 1, + "description" : "The number of cores per socket.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "cpu" : { + "description" : "Emulated CPU type.", + "format" : "pve-vm-cpu-conf", + "optional" : 1, + "type" : "string", + "typetext" : "[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 128)", + "verbose_description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit." + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 262144, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 262144)", + "verbose_description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs." + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "efidisk0" : { + "description" : "Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "efitype" : { + "default" : "2m", + "description" : "Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarc64 (ARM).", + "enum" : [ + "2m", + "4m" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "pre-enrolled-keys" : { + "default" : 0, + "description" : "Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,pre-enrolled-keys=<1|0>] [,size=]" + }, + "force" : { + "description" : "Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.", + "optional" : 1, + "requires" : "delete", + "type" : "boolean", + "typetext" : "" + }, + "freeze" : { + "description" : "Freeze CPU at startup (use 'c' monitor command to start execution).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the vms lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostpci[n]" : { + "description" : "Map host PCI devices into guest.", + "format" : "pve-qm-hostpci", + "optional" : 1, + "type" : "string", + "typetext" : "[host=] [,device-id=] [,legacy-igd=<1|0>] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]", + "verbose_description" : "Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "hotplug" : { + "default" : "network,disk,usb", + "description" : "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.", + "format" : "pve-hotplug-features", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hugepages" : { + "description" : "Enable/disable hugepages memory.", + "enum" : [ + "any", + "2", + "1024" + ], + "optional" : 1, + "type" : "string" + }, + "ide[n]" : { + "description" : "Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "model" : { + "description" : "The drive's reported model name, url-encoded, up to 40 bytes long.", + "format" : "urlencoded", + "format_description" : "model", + "maxLength" : 120, + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "ipconfig[n]" : { + "description" : "cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n", + "format" : "pve-qm-ipconfig", + "optional" : 1, + "type" : "string", + "typetext" : "[gw=] [,gw6=] [,ip=] [,ip6=]" + }, + "ivshmem" : { + "description" : "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + "format" : { + "name" : { + "description" : "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + "format_description" : "string", + "optional" : 1, + "pattern" : "[a-zA-Z0-9\\-]+", + "type" : "string" + }, + "size" : { + "description" : "The size of the file in MB.", + "minimum" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "size= [,name=]" + }, + "keephugepages" : { + "default" : 0, + "description" : "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "keyboard" : { + "default" : null, + "description" : "Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "kvm" : { + "default" : 1, + "description" : "Enable/disable KVM hardware virtualization.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "localtime" : { + "description" : "Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ], + "optional" : 1, + "type" : "string" + }, + "machine" : { + "description" : "Specifies the QEMU machine type.", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.", + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - N)" + }, + "migrate_downtime" : { + "default" : 0.1, + "description" : "Set maximum tolerated downtime (in seconds) for migrations.", + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "migrate_speed" : { + "default" : 0, + "description" : "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "name" : { + "description" : "Set a name for the VM. Only used on the configuration web interface.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nameserver" : { + "description" : "cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "format" : "address-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specify network devices.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n", + "format" : "pve-bridge-id", + "format_description" : "bridge", + "optional" : 1, + "type" : "string" + }, + "e1000" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82540em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82544gc" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82545em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000e" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "firewall" : { + "description" : "Whether this interface should be protected by the firewall.", + "optional" : 1, + "type" : "boolean" + }, + "i82551" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82557b" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82559er" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "macaddr" : { + "description" : "MAC address. That address must be unique withing your network. This is automatically generated if not specified.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "model" : { + "default_key" : 1, + "description" : "Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.", + "enum" : [ + "e1000", + "e1000-82540em", + "e1000-82544gc", + "e1000-82545em", + "e1000e", + "i82551", + "i82557b", + "i82559er", + "ne2k_isa", + "ne2k_pci", + "pcnet", + "rtl8139", + "virtio", + "vmxnet3" + ], + "type" : "string" + }, + "mtu" : { + "description" : "Force MTU, for VirtIO only. Set to '1' to use the bridge MTU", + "maximum" : 65520, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "ne2k_isa" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "ne2k_pci" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "pcnet" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "queues" : { + "description" : "Number of packet queues to be used on the device.", + "maximum" : 64, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "rtl8139" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "tag" : { + "description" : "VLAN tag to apply to packets on this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN trunks to pass through this interface.", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "virtio" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "vmxnet3" : { + "alias" : "macaddr", + "keyAlias" : "model" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "numa" : { + "default" : 0, + "description" : "Enable/disable NUMA.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "numa[n]" : { + "description" : "NUMA topology.", + "format" : { + "cpus" : { + "description" : "CPUs accessing this NUMA node.", + "format_description" : "id[-id];...", + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "hostnodes" : { + "description" : "Host NUMA nodes to use.", + "format_description" : "id[-id];...", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "memory" : { + "description" : "Amount of memory this NUMA node provides.", + "optional" : 1, + "type" : "number" + }, + "policy" : { + "description" : "NUMA allocation policy.", + "enum" : [ + "preferred", + "bind", + "interleave" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "cpus= [,hostnodes=] [,memory=] [,policy=]" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostype" : { + "description" : "Specify guest operating system.", + "enum" : [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "win11", + "l24", + "l26", + "solaris" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 6.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n" + }, + "parallel[n]" : { + "description" : "Map host parallel devices (n is 0 to 2).", + "optional" : 1, + "pattern" : "/dev/parport\\d+|/dev/usb/lp\\d+", + "type" : "string", + "verbose_description" : "Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "reboot" : { + "default" : 1, + "description" : "Allow reboot. If set to '0' the VM exit on reboot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "revert" : { + "description" : "Revert a pending change.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rng0" : { + "description" : "Configure a VirtIO-based Random Number Generator.", + "format" : { + "max_bytes" : { + "default" : 1024, + "description" : "Maximum bytes of entropy allowed to get injected into the guest every 'period' milliseconds. Prefer a lower value when using '/dev/random' as source. Use `0` to disable limiting (potentially dangerous!).", + "optional" : 1, + "type" : "integer" + }, + "period" : { + "default" : 1000, + "description" : "Every 'period' milliseconds the entropy-injection quota is reset, allowing the guest to retrieve another 'max_bytes' of entropy.", + "optional" : 1, + "type" : "integer" + }, + "source" : { + "default_key" : 1, + "description" : "The file on the host to gather entropy from. In most cases '/dev/urandom' should be preferred over '/dev/random' to avoid entropy-starvation issues on the host. Using urandom does *not* decrease security in any meaningful way, as it's still seeded from real entropy, and the bytes provided will most likely be mixed with real entropy on the guest as well. '/dev/hwrng' can be used to pass through a hardware RNG from the host.", + "enum" : [ + "/dev/urandom", + "/dev/random", + "/dev/hwrng" + ], + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[source=] [,max_bytes=] [,period=]" + }, + "sata[n]" : { + "description" : "Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "scsi[n]" : { + "description" : "Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "queues" : { + "description" : "Number of queues.", + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "scsiblock" : { + "default" : 0, + "description" : "whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "scsihw" : { + "default" : "lsi", + "description" : "SCSI controller model", + "enum" : [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "serial[n]" : { + "description" : "Create a serial device inside the VM (n is 0 to 3)", + "optional" : 1, + "pattern" : "(/dev/.+|socket)", + "type" : "string", + "verbose_description" : "Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "shares" : { + "default" : 1000, + "description" : "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.", + "maximum" : 50000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 50000)" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "smbios1" : { + "description" : "Specify SMBIOS type 1 fields.", + "format" : "pve-qm-smbios1", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]" + }, + "smp" : { + "default" : 1, + "description" : "The number of CPUs. Please use option -sockets instead.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "sockets" : { + "default" : 1, + "description" : "The number of CPU sockets.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "spice_enhancements" : { + "description" : "Configure additional enhancements for SPICE.", + "format" : { + "foldersharing" : { + "default" : "0", + "description" : "Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.", + "optional" : 1, + "type" : "boolean" + }, + "videostreaming" : { + "default" : "off", + "description" : "Enable video streaming. Uses compression for detected video streams.", + "enum" : [ + "off", + "all", + "filter" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[foldersharing=<1|0>] [,videostreaming=]" + }, + "sshkeys" : { + "description" : "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format" : "urlencoded", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "startdate" : { + "default" : "now", + "description" : "Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.", + "optional" : 1, + "pattern" : "(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)", + "type" : "string", + "typetext" : "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "tablet" : { + "default" : 1, + "description" : "Enable/disable the USB tablet device.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)." + }, + "tags" : { + "description" : "Tags of the VM. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tdf" : { + "default" : 0, + "description" : "Enable/disable time drift fix.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tpmstate0" : { + "description" : "Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "version" : { + "default" : "v2.0", + "description" : "The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.", + "enum" : [ + "v1.2", + "v2.0" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,import-from=] [,size=] [,version=]" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=]" + }, + "usb[n]" : { + "description" : "Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).", + "format" : { + "host" : { + "default_key" : 1, + "description" : "The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadeciaml numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n", + "format" : "pve-qm-usb-device", + "format_description" : "HOSTUSBDEVICE|spice", + "type" : "string" + }, + "usb3" : { + "default" : 0, + "description" : "Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[host=] [,usb3=<1|0>]" + }, + "vcpus" : { + "default" : 0, + "description" : "Number of hotplugged vcpus.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vga" : { + "description" : "Configure the VGA hardware.", + "format" : { + "memory" : { + "description" : "Sets the VGA memory (in MiB). Has no effect with serial display.", + "maximum" : 512, + "minimum" : 4, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "default" : "std", + "default_key" : 1, + "description" : "Select the VGA type.", + "enum" : [ + "cirrus", + "qxl", + "qxl2", + "qxl3", + "qxl4", + "none", + "serial0", + "serial1", + "serial2", + "serial3", + "std", + "virtio", + "virtio-gl", + "vmware" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,memory=]", + "verbose_description" : "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal." + }, + "virtio[n]" : { + "description" : "Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]" + }, + "vmgenid" : { + "default" : "1 (autogenerated)", + "description" : "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "format_description" : "UUID", + "optional" : 1, + "pattern" : "(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])", + "type" : "string", + "verbose_description" : "The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file." + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vmstatestorage" : { + "description" : "Default storage for VM state volumes/files.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "watchdog" : { + "description" : "Create a virtual hardware watchdog device.", + "format" : "pve-qm-watchdog", + "optional" : 1, + "type" : "string", + "typetext" : "[[model=]] [,action=]", + "verbose_description" : "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk", + "VM.Config.CDROM", + "VM.Config.CPU", + "VM.Config.Memory", + "VM.Config.Network", + "VM.Config.HWType", + "VM.Config.Options", + "VM.Config.Cloudinit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/config", + "text" : "config" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the virtual machine configuration with both current and pending values.", + "method" : "GET", + "name" : "vm_pending", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "delete" : { + "description" : "Indicates a pending delete request if present and not 0. The value 2 indicates a force-delete request.", + "maximum" : 2, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "key" : { + "description" : "Configuration option name.", + "type" : "string" + }, + "pending" : { + "description" : "Pending value.", + "optional" : 1, + "type" : "string" + }, + "value" : { + "description" : "Current value.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/pending", + "text" : "pending" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get automatically generated cloudinit config.", + "method" : "GET", + "name" : "cloudinit_generated_config_dump", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Config type.", + "enum" : [ + "user", + "network", + "meta" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/cloudinit/dump", + "text" : "dump" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the cloudinit configuration with both current and pending values.", + "method" : "GET", + "name" : "cloudinit_pending", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "key" : { + "description" : "Configuration option name.", + "type" : "string" + }, + "new" : { + "description" : "The new pending value.", + "optional" : 1, + "type" : "string" + }, + "old" : { + "description" : "Value as it was used to generate the current cloudinit image.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Regenerate and change cloudinit config drive.", + "method" : "PUT", + "name" : "cloudinit_update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + "VM.Config.Cloudinit" + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/cloudinit", + "text" : "cloudinit" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Unlink/delete disk images.", + "method" : "PUT", + "name" : "unlink", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "idlist" : { + "description" : "A list of disk IDs you want to delete.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/unlink", + "text" : "unlink" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a TCP VNC proxy connections.", + "method" : "POST", + "name" : "vncproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "generate-password" : { + "default" : 0, + "description" : "Generates a random password to be used as ticket instead of the API ticket.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "websocket" : { + "description" : "starts websockify instead of vncproxy", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "cert" : { + "type" : "string" + }, + "password" : { + "description" : "Returned if requested with 'generate-password' param. Consists of printable ASCII characters ('!' .. '~').", + "optional" : 1, + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/vncproxy", + "text" : "vncproxy" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a TCP proxy connections.", + "method" : "POST", + "name" : "termproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "serial" : { + "description" : "opens a serial terminal (defaults to display)", + "enum" : [ + "serial0", + "serial1", + "serial2", + "serial3" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/termproxy", + "text" : "termproxy" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Opens a weksocket for VNC traffic.", + "method" : "GET", + "name" : "vncwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Port number returned by previous vncproxy call.", + "maximum" : 5999, + "minimum" : 5900, + "type" : "integer", + "typetext" : " (5900 - 5999)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vncticket" : { + "description" : "Ticket from previous call to vncproxy.", + "maxLength" : 512, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ], + "description" : "You also need to pass a valid ticket (vncticket)." + }, + "returns" : { + "properties" : { + "port" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/vncwebsocket", + "text" : "vncwebsocket" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Returns a SPICE configuration to connect to the VM.", + "method" : "POST", + "name" : "spiceproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "proxy" : { + "description" : "SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).", + "format" : "address", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 1, + "description" : "Returned values can be directly passed to the 'remote-viewer' application.", + "properties" : { + "host" : { + "type" : "string" + }, + "password" : { + "type" : "string" + }, + "proxy" : { + "type" : "string" + }, + "tls-port" : { + "type" : "integer" + }, + "type" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/spiceproxy", + "text" : "spiceproxy" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get virtual machine status.", + "method" : "GET", + "name" : "vm_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "agent" : { + "description" : "QEMU Guest Agent is enabled in config.", + "optional" : 1, + "type" : "boolean" + }, + "cpus" : { + "description" : "Maximum usable CPUs.", + "optional" : 1, + "type" : "number" + }, + "ha" : { + "description" : "HA manager service status.", + "type" : "object" + }, + "lock" : { + "description" : "The current config lock, if any.", + "optional" : 1, + "type" : "string" + }, + "maxdisk" : { + "description" : "Root disk size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Maximum memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "VM name.", + "optional" : 1, + "type" : "string" + }, + "pid" : { + "description" : "PID of running qemu process.", + "optional" : 1, + "type" : "integer" + }, + "qmpstatus" : { + "description" : "QEMU QMP agent status.", + "optional" : 1, + "type" : "string" + }, + "running-machine" : { + "description" : "The currently running machine type (if running).", + "optional" : 1, + "type" : "string" + }, + "running-qemu" : { + "description" : "The currently running QEMU version (if running).", + "optional" : 1, + "type" : "string" + }, + "spice" : { + "description" : "QEMU VGA configuration supports spice.", + "optional" : 1, + "type" : "boolean" + }, + "status" : { + "description" : "QEMU process status.", + "enum" : [ + "stopped", + "running" + ], + "type" : "string" + }, + "tags" : { + "description" : "The current configured tags, if any", + "optional" : 1, + "type" : "string" + }, + "uptime" : { + "description" : "Uptime.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/current", + "text" : "current" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start virtual machine.", + "method" : "POST", + "name" : "vm_start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force-cpu" : { + "description" : "Override QEMU's -cpu argument with the given string.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "machine" : { + "description" : "Specifies the QEMU machine type.", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "migratedfrom" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "migration_network" : { + "description" : "CIDR of the (sub) network that is used for migration.", + "format" : "CIDR", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "migration_type" : { + "description" : "Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.", + "enum" : [ + "secure", + "insecure" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stateuri" : { + "description" : "Some command save/restore state from this location.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "targetstorage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storage-pair-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : "max(30, vm memory in GiB)", + "description" : "Wait maximal timeout seconds.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop virtual machine. The qemu process will exit immediately. Thisis akin to pulling the power plug of a running computer and may damage the VM data", + "method" : "POST", + "name" : "vm_stop", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "keepActive" : { + "default" : 0, + "description" : "Do not deactivate storage volumes.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "migratedfrom" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "timeout" : { + "description" : "Wait maximal timeout seconds.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/stop", + "text" : "stop" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Reset virtual machine.", + "method" : "POST", + "name" : "vm_reset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/reset", + "text" : "reset" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Shutdown virtual machine. This is similar to pressing the power button on a physical machine.This will send an ACPI event for the guest OS, which should then proceed to a clean shutdown.", + "method" : "POST", + "name" : "vm_shutdown", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "forceStop" : { + "default" : 0, + "description" : "Make sure the VM stops.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "keepActive" : { + "default" : 0, + "description" : "Do not deactivate storage volumes.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "timeout" : { + "description" : "Wait maximal timeout seconds.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/shutdown", + "text" : "shutdown" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Reboot the VM by shutting it down, and starting it again. Applies pending changes.", + "method" : "POST", + "name" : "vm_reboot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "description" : "Wait maximal timeout seconds for the shutdown.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/reboot", + "text" : "reboot" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Suspend virtual machine.", + "method" : "POST", + "name" : "vm_suspend", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "statestorage" : { + "description" : "The storage for the VM state", + "format" : "pve-storage-id", + "optional" : 1, + "requires" : "todisk", + "type" : "string", + "typetext" : "" + }, + "todisk" : { + "default" : 0, + "description" : "If set, suspends the VM to disk. Will be resumed on next VM start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ], + "description" : "You need 'VM.PowerMgmt' on /vms/{vmid}, and if you have set 'todisk', you need also 'VM.Config.Disk' on /vms/{vmid} and 'Datastore.AllocateSpace' on the storage for the vmstate." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/suspend", + "text" : "suspend" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Resume virtual machine.", + "method" : "POST", + "name" : "vm_resume", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "nocheck" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/resume", + "text" : "resume" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "vmcmdidx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/status", + "text" : "status" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Send key event to virtual machine.", + "method" : "PUT", + "name" : "vm_sendkey", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "key" : { + "description" : "The key (qemu monitor encoding).", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/sendkey", + "text" : "sendkey" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Check if feature for virtual machine is available.", + "method" : "GET", + "name" : "vm_feature", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "feature" : { + "description" : "Feature to check.", + "enum" : [ + "snapshot", + "clone", + "copy" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "hasFeature" : { + "type" : "boolean" + }, + "nodes" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/feature", + "text" : "feature" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a copy of virtual machine/template.", + "method" : "POST", + "name" : "clone_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "clone limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "description" : { + "description" : "Description for the new VM.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "format" : { + "description" : "Target format for file storage. Only valid for full clone.", + "enum" : [ + "raw", + "qcow2", + "vmdk" + ], + "optional" : 1, + "type" : "string" + }, + "full" : { + "description" : "Create a full copy of all disks. This is always done when you clone a normal VM. For VM templates, we try to create a linked clone by default.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "Set a name for the new VM.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "newid" : { + "description" : "VMID for the clone.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Add the new VM to the specified pool.", + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Target storage for full clone.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node. Only allowed if the original VM is on shared storage.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/vms/{vmid}", + [ + "VM.Clone" + ] + ], + [ + "or", + [ + "perm", + "/vms/{newid}", + [ + "VM.Allocate" + ] + ], + [ + "perm", + "/pool/{pool}", + [ + "VM.Allocate" + ], + "require_param", + "pool" + ] + ] + ], + "description" : "You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions on /vms/{newid} (or on the VM pool /pool/{pool}). You also need 'Datastore.AllocateSpace' on any used storage." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/clone", + "text" : "clone" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Move volume to different storage or to a different VM.", + "method" : "POST", + "name" : "move_vm_disk", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "move limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "delete" : { + "default" : 0, + "description" : "Delete the original disk after successful copy. By default the original disk is kept as unused disk.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1\"\n\t\t .\" digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disk" : { + "description" : "The disk you want to move.", + "enum" : [ + "ide0", + "ide1", + "ide2", + "ide3", + "scsi0", + "scsi1", + "scsi2", + "scsi3", + "scsi4", + "scsi5", + "scsi6", + "scsi7", + "scsi8", + "scsi9", + "scsi10", + "scsi11", + "scsi12", + "scsi13", + "scsi14", + "scsi15", + "scsi16", + "scsi17", + "scsi18", + "scsi19", + "scsi20", + "scsi21", + "scsi22", + "scsi23", + "scsi24", + "scsi25", + "scsi26", + "scsi27", + "scsi28", + "scsi29", + "scsi30", + "virtio0", + "virtio1", + "virtio2", + "virtio3", + "virtio4", + "virtio5", + "virtio6", + "virtio7", + "virtio8", + "virtio9", + "virtio10", + "virtio11", + "virtio12", + "virtio13", + "virtio14", + "virtio15", + "sata0", + "sata1", + "sata2", + "sata3", + "sata4", + "sata5", + "efidisk0", + "tpmstate0", + "unused0", + "unused1", + "unused2", + "unused3", + "unused4", + "unused5", + "unused6", + "unused7", + "unused8", + "unused9", + "unused10", + "unused11", + "unused12", + "unused13", + "unused14", + "unused15", + "unused16", + "unused17", + "unused18", + "unused19", + "unused20", + "unused21", + "unused22", + "unused23", + "unused24", + "unused25", + "unused26", + "unused27", + "unused28", + "unused29", + "unused30", + "unused31", + "unused32", + "unused33", + "unused34", + "unused35", + "unused36", + "unused37", + "unused38", + "unused39", + "unused40", + "unused41", + "unused42", + "unused43", + "unused44", + "unused45", + "unused46", + "unused47", + "unused48", + "unused49", + "unused50", + "unused51", + "unused52", + "unused53", + "unused54", + "unused55", + "unused56", + "unused57", + "unused58", + "unused59", + "unused60", + "unused61", + "unused62", + "unused63", + "unused64", + "unused65", + "unused66", + "unused67", + "unused68", + "unused69", + "unused70", + "unused71", + "unused72", + "unused73", + "unused74", + "unused75", + "unused76", + "unused77", + "unused78", + "unused79", + "unused80", + "unused81", + "unused82", + "unused83", + "unused84", + "unused85", + "unused86", + "unused87", + "unused88", + "unused89", + "unused90", + "unused91", + "unused92", + "unused93", + "unused94", + "unused95", + "unused96", + "unused97", + "unused98", + "unused99", + "unused100", + "unused101", + "unused102", + "unused103", + "unused104", + "unused105", + "unused106", + "unused107", + "unused108", + "unused109", + "unused110", + "unused111", + "unused112", + "unused113", + "unused114", + "unused115", + "unused116", + "unused117", + "unused118", + "unused119", + "unused120", + "unused121", + "unused122", + "unused123", + "unused124", + "unused125", + "unused126", + "unused127", + "unused128", + "unused129", + "unused130", + "unused131", + "unused132", + "unused133", + "unused134", + "unused135", + "unused136", + "unused137", + "unused138", + "unused139", + "unused140", + "unused141", + "unused142", + "unused143", + "unused144", + "unused145", + "unused146", + "unused147", + "unused148", + "unused149", + "unused150", + "unused151", + "unused152", + "unused153", + "unused154", + "unused155", + "unused156", + "unused157", + "unused158", + "unused159", + "unused160", + "unused161", + "unused162", + "unused163", + "unused164", + "unused165", + "unused166", + "unused167", + "unused168", + "unused169", + "unused170", + "unused171", + "unused172", + "unused173", + "unused174", + "unused175", + "unused176", + "unused177", + "unused178", + "unused179", + "unused180", + "unused181", + "unused182", + "unused183", + "unused184", + "unused185", + "unused186", + "unused187", + "unused188", + "unused189", + "unused190", + "unused191", + "unused192", + "unused193", + "unused194", + "unused195", + "unused196", + "unused197", + "unused198", + "unused199", + "unused200", + "unused201", + "unused202", + "unused203", + "unused204", + "unused205", + "unused206", + "unused207", + "unused208", + "unused209", + "unused210", + "unused211", + "unused212", + "unused213", + "unused214", + "unused215", + "unused216", + "unused217", + "unused218", + "unused219", + "unused220", + "unused221", + "unused222", + "unused223", + "unused224", + "unused225", + "unused226", + "unused227", + "unused228", + "unused229", + "unused230", + "unused231", + "unused232", + "unused233", + "unused234", + "unused235", + "unused236", + "unused237", + "unused238", + "unused239", + "unused240", + "unused241", + "unused242", + "unused243", + "unused244", + "unused245", + "unused246", + "unused247", + "unused248", + "unused249", + "unused250", + "unused251", + "unused252", + "unused253", + "unused254", + "unused255" + ], + "type" : "string" + }, + "format" : { + "description" : "Target Format.", + "enum" : [ + "raw", + "qcow2", + "vmdk" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Target storage.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target-digest" : { + "description" : "Prevent changes if the current config file of the target VM has a\"\n\t\t .\" different SHA1 digest. This can be used to detect concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target-disk" : { + "description" : "The config key the disk will be moved to on the target VM (for example, ide0 or scsi1). Default is the source disk key.", + "enum" : [ + "ide0", + "ide1", + "ide2", + "ide3", + "scsi0", + "scsi1", + "scsi2", + "scsi3", + "scsi4", + "scsi5", + "scsi6", + "scsi7", + "scsi8", + "scsi9", + "scsi10", + "scsi11", + "scsi12", + "scsi13", + "scsi14", + "scsi15", + "scsi16", + "scsi17", + "scsi18", + "scsi19", + "scsi20", + "scsi21", + "scsi22", + "scsi23", + "scsi24", + "scsi25", + "scsi26", + "scsi27", + "scsi28", + "scsi29", + "scsi30", + "virtio0", + "virtio1", + "virtio2", + "virtio3", + "virtio4", + "virtio5", + "virtio6", + "virtio7", + "virtio8", + "virtio9", + "virtio10", + "virtio11", + "virtio12", + "virtio13", + "virtio14", + "virtio15", + "sata0", + "sata1", + "sata2", + "sata3", + "sata4", + "sata5", + "efidisk0", + "tpmstate0", + "unused0", + "unused1", + "unused2", + "unused3", + "unused4", + "unused5", + "unused6", + "unused7", + "unused8", + "unused9", + "unused10", + "unused11", + "unused12", + "unused13", + "unused14", + "unused15", + "unused16", + "unused17", + "unused18", + "unused19", + "unused20", + "unused21", + "unused22", + "unused23", + "unused24", + "unused25", + "unused26", + "unused27", + "unused28", + "unused29", + "unused30", + "unused31", + "unused32", + "unused33", + "unused34", + "unused35", + "unused36", + "unused37", + "unused38", + "unused39", + "unused40", + "unused41", + "unused42", + "unused43", + "unused44", + "unused45", + "unused46", + "unused47", + "unused48", + "unused49", + "unused50", + "unused51", + "unused52", + "unused53", + "unused54", + "unused55", + "unused56", + "unused57", + "unused58", + "unused59", + "unused60", + "unused61", + "unused62", + "unused63", + "unused64", + "unused65", + "unused66", + "unused67", + "unused68", + "unused69", + "unused70", + "unused71", + "unused72", + "unused73", + "unused74", + "unused75", + "unused76", + "unused77", + "unused78", + "unused79", + "unused80", + "unused81", + "unused82", + "unused83", + "unused84", + "unused85", + "unused86", + "unused87", + "unused88", + "unused89", + "unused90", + "unused91", + "unused92", + "unused93", + "unused94", + "unused95", + "unused96", + "unused97", + "unused98", + "unused99", + "unused100", + "unused101", + "unused102", + "unused103", + "unused104", + "unused105", + "unused106", + "unused107", + "unused108", + "unused109", + "unused110", + "unused111", + "unused112", + "unused113", + "unused114", + "unused115", + "unused116", + "unused117", + "unused118", + "unused119", + "unused120", + "unused121", + "unused122", + "unused123", + "unused124", + "unused125", + "unused126", + "unused127", + "unused128", + "unused129", + "unused130", + "unused131", + "unused132", + "unused133", + "unused134", + "unused135", + "unused136", + "unused137", + "unused138", + "unused139", + "unused140", + "unused141", + "unused142", + "unused143", + "unused144", + "unused145", + "unused146", + "unused147", + "unused148", + "unused149", + "unused150", + "unused151", + "unused152", + "unused153", + "unused154", + "unused155", + "unused156", + "unused157", + "unused158", + "unused159", + "unused160", + "unused161", + "unused162", + "unused163", + "unused164", + "unused165", + "unused166", + "unused167", + "unused168", + "unused169", + "unused170", + "unused171", + "unused172", + "unused173", + "unused174", + "unused175", + "unused176", + "unused177", + "unused178", + "unused179", + "unused180", + "unused181", + "unused182", + "unused183", + "unused184", + "unused185", + "unused186", + "unused187", + "unused188", + "unused189", + "unused190", + "unused191", + "unused192", + "unused193", + "unused194", + "unused195", + "unused196", + "unused197", + "unused198", + "unused199", + "unused200", + "unused201", + "unused202", + "unused203", + "unused204", + "unused205", + "unused206", + "unused207", + "unused208", + "unused209", + "unused210", + "unused211", + "unused212", + "unused213", + "unused214", + "unused215", + "unused216", + "unused217", + "unused218", + "unused219", + "unused220", + "unused221", + "unused222", + "unused223", + "unused224", + "unused225", + "unused226", + "unused227", + "unused228", + "unused229", + "unused230", + "unused231", + "unused232", + "unused233", + "unused234", + "unused235", + "unused236", + "unused237", + "unused238", + "unused239", + "unused240", + "unused241", + "unused242", + "unused243", + "unused244", + "unused245", + "unused246", + "unused247", + "unused248", + "unused249", + "unused250", + "unused251", + "unused252", + "unused253", + "unused254", + "unused255" + ], + "optional" : 1, + "type" : "string" + }, + "target-vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ], + "description" : "You need 'VM.Config.Disk' permissions on /vms/{vmid}, and 'Datastore.AllocateSpace' permissions on the storage. To move a disk to another VM, you need the permissions on the target VM as well." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/move_disk", + "text" : "move_disk" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get preconditions for migration.", + "method" : "GET", + "name" : "migrate_vm_precondition", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "allowed_nodes" : { + "description" : "List nodes allowed for offline migration, only passed if VM is offline", + "optional" : 1, + "type" : "array" + }, + "local_disks" : { + "description" : "List local disks including CD-Rom, unsused and not referenced disks", + "type" : "array" + }, + "local_resources" : { + "description" : "List local resources e.g. pci, usb", + "type" : "array" + }, + "not_allowed_nodes" : { + "description" : "List not allowed nodes with additional informations, only passed if VM is offline", + "optional" : 1, + "type" : "object" + }, + "running" : { + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Migrate virtual machine. Creates a new migration task.", + "method" : "POST", + "name" : "migrate_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "migrate limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "force" : { + "description" : "Allow to migrate VMs which use local devices. Only root may use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "migration_network" : { + "description" : "CIDR of the (sub) network that is used for migration.", + "format" : "CIDR", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "migration_type" : { + "description" : "Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.", + "enum" : [ + "secure", + "insecure" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "online" : { + "description" : "Use online/live migration if VM is running. Ignored if VM is stopped.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "targetstorage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storage-pair-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "with-local-disks" : { + "description" : "Enable live storage migration for local disk", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/migrate", + "text" : "migrate" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migrate virtual machine to a remote cluster. Creates a new migration task. EXPERIMENTAL feature!", + "method" : "POST", + "name" : "remote_migrate_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "migrate limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "delete" : { + "default" : 0, + "description" : "Delete the original VM and related data after successful migration. By default the original VM is kept on the source cluster in a stopped state.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "online" : { + "description" : "Use online/live migration if VM is running. Ignored if VM is stopped.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target-bridge" : { + "description" : "Mapping from source to target bridges. Providing only a single bridge ID maps all source bridges to that bridge. Providing the special value '1' will map each source bridge to itself.", + "format" : "bridge-pair-list", + "type" : "string", + "typetext" : "" + }, + "target-endpoint" : { + "description" : "Remote target endpoint", + "format" : "proxmox-remote", + "type" : "string", + "typetext" : "apitoken= ,host= [,fingerprint=] [,port=]" + }, + "target-storage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storage-pair-list", + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "target-vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/remote_migrate", + "text" : "remote_migrate" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute QEMU monitor commands.", + "method" : "POST", + "name" : "monitor", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "command" : { + "description" : "The monitor command.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ], + "description" : "Sys.Modify is required for (sub)commands which are not read-only ('info *' and 'help')" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/monitor", + "text" : "monitor" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Extend volume size.", + "method" : "PUT", + "name" : "resize_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disk" : { + "description" : "The disk you want to resize.", + "enum" : [ + "ide0", + "ide1", + "ide2", + "ide3", + "scsi0", + "scsi1", + "scsi2", + "scsi3", + "scsi4", + "scsi5", + "scsi6", + "scsi7", + "scsi8", + "scsi9", + "scsi10", + "scsi11", + "scsi12", + "scsi13", + "scsi14", + "scsi15", + "scsi16", + "scsi17", + "scsi18", + "scsi19", + "scsi20", + "scsi21", + "scsi22", + "scsi23", + "scsi24", + "scsi25", + "scsi26", + "scsi27", + "scsi28", + "scsi29", + "scsi30", + "virtio0", + "virtio1", + "virtio2", + "virtio3", + "virtio4", + "virtio5", + "virtio6", + "virtio7", + "virtio8", + "virtio9", + "virtio10", + "virtio11", + "virtio12", + "virtio13", + "virtio14", + "virtio15", + "sata0", + "sata1", + "sata2", + "sata3", + "sata4", + "sata5", + "efidisk0", + "tpmstate0" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "size" : { + "description" : "The new size. With the `+` sign the value is added to the actual size of the volume and without it, the value is taken as an absolute one. Shrinking disk size is not supported.", + "pattern" : "\\+?\\d+(\\.\\d+)?[KMGT]?", + "type" : "string" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/resize", + "text" : "resize" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get snapshot configuration", + "method" : "GET", + "name" : "get_snapshot_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback", + "VM.Audit" + ], + "any", + 1 + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update snapshot metadata.", + "method" : "PUT", + "name" : "update_snapshot_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A textual description or comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "text" : "config" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Rollback VM state to specified snapshot.", + "method" : "POST", + "name" : "rollback", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Whether the VM should get started after rolling back successfully. (Note: VMs will be automatically started if the snapshot includes RAM.)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback", + "text" : "rollback" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete a VM snapshot.", + "method" : "DELETE", + "name" : "delsnapshot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "For removal from config file, even if removing disk snapshots fails.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "snapshot_cmd_idx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{cmd}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "text" : "{snapname}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all snapshots.", + "method" : "GET", + "name" : "snapshot_list", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "description" : { + "description" : "Snapshot description.", + "type" : "string" + }, + "name" : { + "description" : "Snapshot identifier. Value 'current' identifies the current VM.", + "type" : "string" + }, + "parent" : { + "description" : "Parent snapshot identifier.", + "optional" : 1, + "type" : "string" + }, + "snaptime" : { + "description" : "Snapshot creation time", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "vmstate" : { + "description" : "Snapshot includes RAM.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Snapshot a VM.", + "method" : "POST", + "name" : "snapshot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A textual description or comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vmstate" : { + "description" : "Save the vmstate", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/snapshot", + "text" : "snapshot" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a Template.", + "method" : "POST", + "name" : "template", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "disk" : { + "description" : "If you want to convert only 1 disk to base image.", + "enum" : [ + "ide0", + "ide1", + "ide2", + "ide3", + "scsi0", + "scsi1", + "scsi2", + "scsi3", + "scsi4", + "scsi5", + "scsi6", + "scsi7", + "scsi8", + "scsi9", + "scsi10", + "scsi11", + "scsi12", + "scsi13", + "scsi14", + "scsi15", + "scsi16", + "scsi17", + "scsi18", + "scsi19", + "scsi20", + "scsi21", + "scsi22", + "scsi23", + "scsi24", + "scsi25", + "scsi26", + "scsi27", + "scsi28", + "scsi29", + "scsi30", + "virtio0", + "virtio1", + "virtio2", + "virtio3", + "virtio4", + "virtio5", + "virtio6", + "virtio7", + "virtio8", + "virtio9", + "virtio10", + "virtio11", + "virtio12", + "virtio13", + "virtio14", + "virtio15", + "sata0", + "sata1", + "sata2", + "sata3", + "sata4", + "sata5", + "efidisk0", + "tpmstate0" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + "description" : "You need 'VM.Allocate' permissions on /vms/{vmid}" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/template", + "text" : "template" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migration tunnel endpoint - only for internal use by VM migration.", + "method" : "POST", + "name" : "mtunnel", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bridges" : { + "description" : "List of network bridges to check availability. Will be checked again for actually used bridges during migration.", + "format" : "pve-bridge-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storages" : { + "description" : "List of storages to check permission and availability. Will be checked again for all actually used storages during migration.", + "format" : "pve-storage-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + [ + "perm", + "/", + [ + "Sys.Incoming" + ] + ] + ], + "description" : "You need 'VM.Allocate' permissions on '/vms/{vmid}' and Sys.Incoming on '/'. Further permission checks happen during the actual migration." + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "socket" : { + "type" : "string" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/mtunnel", + "text" : "mtunnel" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration.", + "method" : "GET", + "name" : "mtunnelwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "socket" : { + "description" : "unix socket to forward to", + "type" : "string", + "typetext" : "" + }, + "ticket" : { + "description" : "ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "description" : "You need to pass a ticket valid for the selected socket. Tickets can be created via the mtunnel API call, which will check permissions accordingly.", + "user" : "all" + }, + "returns" : { + "properties" : { + "port" : { + "optional" : 1, + "type" : "string" + }, + "socket" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/mtunnelwebsocket", + "text" : "mtunnelwebsocket" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy the VM and all used/owned volumes. Removes any VM specific permissions and firewall rules", + "method" : "DELETE", + "name" : "destroy_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "destroy-unreferenced-disks" : { + "default" : 0, + "description" : "If set, destroy additionally all disks not referenced in the config but with a matching VMID from all enabled storages.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "purge" : { + "description" : "Remove VMID from configurations, like backup & replication jobs and HA.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "vmdiridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}", + "text" : "{vmid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Virtual machine index (per node).", + "method" : "GET", + "name" : "vmlist", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "full" : { + "description" : "Determine the full status of active VMs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list VMs where you have VM.Audit permissons on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "cpus" : { + "description" : "Maximum usable CPUs.", + "optional" : 1, + "type" : "number" + }, + "lock" : { + "description" : "The current config lock, if any.", + "optional" : 1, + "type" : "string" + }, + "maxdisk" : { + "description" : "Root disk size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Maximum memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "VM name.", + "optional" : 1, + "type" : "string" + }, + "pid" : { + "description" : "PID of running qemu process.", + "optional" : 1, + "type" : "integer" + }, + "qmpstatus" : { + "description" : "QEMU QMP agent status.", + "optional" : 1, + "type" : "string" + }, + "running-machine" : { + "description" : "The currently running machine type (if running).", + "optional" : 1, + "type" : "string" + }, + "running-qemu" : { + "description" : "The currently running QEMU version (if running).", + "optional" : 1, + "type" : "string" + }, + "status" : { + "description" : "QEMU process status.", + "enum" : [ + "stopped", + "running" + ], + "type" : "string" + }, + "tags" : { + "description" : "The current configured tags, if any", + "optional" : 1, + "type" : "string" + }, + "uptime" : { + "description" : "Uptime.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{vmid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create or restore a virtual machine.", + "method" : "POST", + "name" : "create_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acpi" : { + "default" : 1, + "description" : "Enable/disable ACPI.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "affinity" : { + "description" : "List of host cores used to execute guest processes, for example: 0,5,8-11", + "format" : "pve-cpuset", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "agent" : { + "description" : "Enable/disable communication with the QEMU Guest Agent and its properties.", + "format" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.", + "type" : "boolean" + }, + "freeze-fs-on-backup" : { + "default" : 1, + "description" : "Freeze/thaw guest filesystems on backup for consistency.", + "optional" : 1, + "type" : "boolean" + }, + "fstrim_cloned_disks" : { + "default" : 0, + "description" : "Run fstrim after moving a disk or migrating the VM.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default" : "virtio", + "description" : "Select the agent type", + "enum" : [ + "virtio", + "isa" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[enabled=]<1|0> [,freeze-fs-on-backup=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "archive" : { + "description" : "The backup archive. Either the file system path to a .tar or .vma file (use '-' to pipe data from stdin) or a proxmox storage backup volume identifier.", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "args" : { + "description" : "Arbitrary arguments passed to kvm.", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -no-hpet\n\nNOTE: this option is for experts only.\n" + }, + "audio0" : { + "description" : "Configure a audio device, useful in combination with QXL/Spice.", + "format" : { + "device" : { + "description" : "Configure an audio device.", + "enum" : [ + "ich9-intel-hda", + "intel-hda", + "AC97" + ], + "type" : "string" + }, + "driver" : { + "default" : "spice", + "description" : "Driver backend for the audio device.", + "enum" : [ + "spice", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "device= [,driver=]" + }, + "autostart" : { + "default" : 0, + "description" : "Automatic restart after crash (currently ignored).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "balloon" : { + "description" : "Amount of target RAM for the VM in MiB. Using zero disables the ballon driver.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "bios" : { + "default" : "seabios", + "description" : "Select BIOS implementation.", + "enum" : [ + "seabios", + "ovmf" + ], + "optional" : 1, + "type" : "string" + }, + "boot" : { + "description" : "Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.", + "format" : "pve-qm-boot", + "optional" : 1, + "type" : "string", + "typetext" : "[[legacy=]<[acdn]{1,4}>] [,order=]" + }, + "bootdisk" : { + "description" : "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format" : "pve-qm-bootdisk", + "optional" : 1, + "pattern" : "(ide|sata|scsi|virtio)\\d+", + "type" : "string" + }, + "bwlimit" : { + "default" : "restore limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "cdrom" : { + "description" : "This is an alias for option -ide2", + "format" : "pve-qm-ide", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cicustom" : { + "description" : "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format" : "pve-qm-cicustom", + "optional" : 1, + "type" : "string", + "typetext" : "[meta=] [,network=] [,user=] [,vendor=]" + }, + "cipassword" : { + "description" : "cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "citype" : { + "description" : "Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.", + "enum" : [ + "configdrive2", + "nocloud", + "opennebula" + ], + "optional" : 1, + "type" : "string" + }, + "ciuser" : { + "description" : "cloud-init: User name to change ssh keys and password for instead of the image's configured default user.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cores" : { + "default" : 1, + "description" : "The number of cores per socket.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "cpu" : { + "description" : "Emulated CPU type.", + "format" : "pve-vm-cpu-conf", + "optional" : 1, + "type" : "string", + "typetext" : "[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 128)", + "verbose_description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit." + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 262144, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 262144)", + "verbose_description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs." + }, + "description" : { + "description" : "Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "efidisk0" : { + "description" : "Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "efitype" : { + "default" : "2m", + "description" : "Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarc64 (ARM).", + "enum" : [ + "2m", + "4m" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "pre-enrolled-keys" : { + "default" : 0, + "description" : "Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,pre-enrolled-keys=<1|0>] [,size=]" + }, + "force" : { + "description" : "Allow to overwrite existing VM.", + "optional" : 1, + "requires" : "archive", + "type" : "boolean", + "typetext" : "" + }, + "freeze" : { + "description" : "Freeze CPU at startup (use 'c' monitor command to start execution).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the vms lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostpci[n]" : { + "description" : "Map host PCI devices into guest.", + "format" : "pve-qm-hostpci", + "optional" : 1, + "type" : "string", + "typetext" : "[host=] [,device-id=] [,legacy-igd=<1|0>] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]", + "verbose_description" : "Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "hotplug" : { + "default" : "network,disk,usb", + "description" : "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.", + "format" : "pve-hotplug-features", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hugepages" : { + "description" : "Enable/disable hugepages memory.", + "enum" : [ + "any", + "2", + "1024" + ], + "optional" : 1, + "type" : "string" + }, + "ide[n]" : { + "description" : "Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "model" : { + "description" : "The drive's reported model name, url-encoded, up to 40 bytes long.", + "format" : "urlencoded", + "format_description" : "model", + "maxLength" : 120, + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "ipconfig[n]" : { + "description" : "cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n", + "format" : "pve-qm-ipconfig", + "optional" : 1, + "type" : "string", + "typetext" : "[gw=] [,gw6=] [,ip=] [,ip6=]" + }, + "ivshmem" : { + "description" : "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + "format" : { + "name" : { + "description" : "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + "format_description" : "string", + "optional" : 1, + "pattern" : "[a-zA-Z0-9\\-]+", + "type" : "string" + }, + "size" : { + "description" : "The size of the file in MB.", + "minimum" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "size= [,name=]" + }, + "keephugepages" : { + "default" : 0, + "description" : "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "keyboard" : { + "default" : null, + "description" : "Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "kvm" : { + "default" : 1, + "description" : "Enable/disable KVM hardware virtualization.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "live-restore" : { + "description" : "Start the VM immediately from the backup and restore in background. PBS only.", + "optional" : 1, + "requires" : "archive", + "type" : "boolean", + "typetext" : "" + }, + "localtime" : { + "description" : "Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ], + "optional" : 1, + "type" : "string" + }, + "machine" : { + "description" : "Specifies the QEMU machine type.", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.", + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - N)" + }, + "migrate_downtime" : { + "default" : 0.1, + "description" : "Set maximum tolerated downtime (in seconds) for migrations.", + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "migrate_speed" : { + "default" : 0, + "description" : "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "name" : { + "description" : "Set a name for the VM. Only used on the configuration web interface.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nameserver" : { + "description" : "cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "format" : "address-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specify network devices.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n", + "format" : "pve-bridge-id", + "format_description" : "bridge", + "optional" : 1, + "type" : "string" + }, + "e1000" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82540em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82544gc" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82545em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000e" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "firewall" : { + "description" : "Whether this interface should be protected by the firewall.", + "optional" : 1, + "type" : "boolean" + }, + "i82551" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82557b" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82559er" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "macaddr" : { + "description" : "MAC address. That address must be unique withing your network. This is automatically generated if not specified.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "model" : { + "default_key" : 1, + "description" : "Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.", + "enum" : [ + "e1000", + "e1000-82540em", + "e1000-82544gc", + "e1000-82545em", + "e1000e", + "i82551", + "i82557b", + "i82559er", + "ne2k_isa", + "ne2k_pci", + "pcnet", + "rtl8139", + "virtio", + "vmxnet3" + ], + "type" : "string" + }, + "mtu" : { + "description" : "Force MTU, for VirtIO only. Set to '1' to use the bridge MTU", + "maximum" : 65520, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "ne2k_isa" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "ne2k_pci" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "pcnet" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "queues" : { + "description" : "Number of packet queues to be used on the device.", + "maximum" : 64, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "rtl8139" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "tag" : { + "description" : "VLAN tag to apply to packets on this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN trunks to pass through this interface.", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "virtio" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "vmxnet3" : { + "alias" : "macaddr", + "keyAlias" : "model" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "numa" : { + "default" : 0, + "description" : "Enable/disable NUMA.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "numa[n]" : { + "description" : "NUMA topology.", + "format" : { + "cpus" : { + "description" : "CPUs accessing this NUMA node.", + "format_description" : "id[-id];...", + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "hostnodes" : { + "description" : "Host NUMA nodes to use.", + "format_description" : "id[-id];...", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "memory" : { + "description" : "Amount of memory this NUMA node provides.", + "optional" : 1, + "type" : "number" + }, + "policy" : { + "description" : "NUMA allocation policy.", + "enum" : [ + "preferred", + "bind", + "interleave" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "cpus= [,hostnodes=] [,memory=] [,policy=]" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostype" : { + "description" : "Specify guest operating system.", + "enum" : [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "win11", + "l24", + "l26", + "solaris" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 6.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n" + }, + "parallel[n]" : { + "description" : "Map host parallel devices (n is 0 to 2).", + "optional" : 1, + "pattern" : "/dev/parport\\d+|/dev/usb/lp\\d+", + "type" : "string", + "verbose_description" : "Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "pool" : { + "description" : "Add the VM to the specified pool.", + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "reboot" : { + "default" : 1, + "description" : "Allow reboot. If set to '0' the VM exit on reboot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "rng0" : { + "description" : "Configure a VirtIO-based Random Number Generator.", + "format" : { + "max_bytes" : { + "default" : 1024, + "description" : "Maximum bytes of entropy allowed to get injected into the guest every 'period' milliseconds. Prefer a lower value when using '/dev/random' as source. Use `0` to disable limiting (potentially dangerous!).", + "optional" : 1, + "type" : "integer" + }, + "period" : { + "default" : 1000, + "description" : "Every 'period' milliseconds the entropy-injection quota is reset, allowing the guest to retrieve another 'max_bytes' of entropy.", + "optional" : 1, + "type" : "integer" + }, + "source" : { + "default_key" : 1, + "description" : "The file on the host to gather entropy from. In most cases '/dev/urandom' should be preferred over '/dev/random' to avoid entropy-starvation issues on the host. Using urandom does *not* decrease security in any meaningful way, as it's still seeded from real entropy, and the bytes provided will most likely be mixed with real entropy on the guest as well. '/dev/hwrng' can be used to pass through a hardware RNG from the host.", + "enum" : [ + "/dev/urandom", + "/dev/random", + "/dev/hwrng" + ], + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[source=] [,max_bytes=] [,period=]" + }, + "sata[n]" : { + "description" : "Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "scsi[n]" : { + "description" : "Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "queues" : { + "description" : "Number of queues.", + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "scsiblock" : { + "default" : 0, + "description" : "whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "scsihw" : { + "default" : "lsi", + "description" : "SCSI controller model", + "enum" : [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "serial[n]" : { + "description" : "Create a serial device inside the VM (n is 0 to 3)", + "optional" : 1, + "pattern" : "(/dev/.+|socket)", + "type" : "string", + "verbose_description" : "Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "shares" : { + "default" : 1000, + "description" : "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.", + "maximum" : 50000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 50000)" + }, + "smbios1" : { + "description" : "Specify SMBIOS type 1 fields.", + "format" : "pve-qm-smbios1", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]" + }, + "smp" : { + "default" : 1, + "description" : "The number of CPUs. Please use option -sockets instead.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "sockets" : { + "default" : 1, + "description" : "The number of CPU sockets.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "spice_enhancements" : { + "description" : "Configure additional enhancements for SPICE.", + "format" : { + "foldersharing" : { + "default" : "0", + "description" : "Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.", + "optional" : 1, + "type" : "boolean" + }, + "videostreaming" : { + "default" : "off", + "description" : "Enable video streaming. Uses compression for detected video streams.", + "enum" : [ + "off", + "all", + "filter" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[foldersharing=<1|0>] [,videostreaming=]" + }, + "sshkeys" : { + "description" : "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format" : "urlencoded", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Start VM after it was created successfully.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "startdate" : { + "default" : "now", + "description" : "Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.", + "optional" : 1, + "pattern" : "(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)", + "type" : "string", + "typetext" : "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "storage" : { + "description" : "Default storage.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tablet" : { + "default" : 1, + "description" : "Enable/disable the USB tablet device.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)." + }, + "tags" : { + "description" : "Tags of the VM. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tdf" : { + "default" : 0, + "description" : "Enable/disable time drift fix.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tpmstate0" : { + "description" : "Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "version" : { + "default" : "v2.0", + "description" : "The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.", + "enum" : [ + "v1.2", + "v2.0" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,import-from=] [,size=] [,version=]" + }, + "unique" : { + "description" : "Assign a unique random ethernet address.", + "optional" : 1, + "requires" : "archive", + "type" : "boolean", + "typetext" : "" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=]" + }, + "usb[n]" : { + "description" : "Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).", + "format" : { + "host" : { + "default_key" : 1, + "description" : "The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadeciaml numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n", + "format" : "pve-qm-usb-device", + "format_description" : "HOSTUSBDEVICE|spice", + "type" : "string" + }, + "usb3" : { + "default" : 0, + "description" : "Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[host=] [,usb3=<1|0>]" + }, + "vcpus" : { + "default" : 0, + "description" : "Number of hotplugged vcpus.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vga" : { + "description" : "Configure the VGA hardware.", + "format" : { + "memory" : { + "description" : "Sets the VGA memory (in MiB). Has no effect with serial display.", + "maximum" : 512, + "minimum" : 4, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "default" : "std", + "default_key" : 1, + "description" : "Select the VGA type.", + "enum" : [ + "cirrus", + "qxl", + "qxl2", + "qxl3", + "qxl4", + "none", + "serial0", + "serial1", + "serial2", + "serial3", + "std", + "virtio", + "virtio-gl", + "vmware" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,memory=]", + "verbose_description" : "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal." + }, + "virtio[n]" : { + "description" : "Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]" + }, + "vmgenid" : { + "default" : "1 (autogenerated)", + "description" : "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "format_description" : "UUID", + "optional" : 1, + "pattern" : "(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])", + "type" : "string", + "verbose_description" : "The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file." + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vmstatestorage" : { + "description" : "Default storage for VM state volumes/files.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "watchdog" : { + "description" : "Create a virtual hardware watchdog device.", + "format" : "pve-qm-watchdog", + "optional" : 1, + "type" : "string", + "typetext" : "[[model=]] [,action=]", + "verbose_description" : "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)" + } + } + }, + "permissions" : { + "description" : "You need 'VM.Allocate' permissions on /vms/{vmid} or on the VM pool /pool/{pool}. For restore (option 'archive'), it is enough if the user has 'VM.Backup' permission and the VM already exists. If you create disks you need 'Datastore.AllocateSpace' on any used storage.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu", + "text" : "qemu" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get container configuration.", + "method" : "GET", + "name" : "vm_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "current" : { + "default" : 0, + "description" : "Get current values (instead of pending values).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapshot" : { + "description" : "Fetch config values from given snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "arch" : { + "default" : "amd64", + "description" : "OS architecture type.", + "enum" : [ + "amd64", + "i386", + "arm64", + "armhf", + "riscv32", + "riscv64" + ], + "optional" : 1, + "type" : "string" + }, + "cmode" : { + "default" : "tty", + "description" : "Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).", + "enum" : [ + "shell", + "console", + "tty" + ], + "optional" : 1, + "type" : "string" + }, + "console" : { + "default" : 1, + "description" : "Attach a console device (/dev/console) to the container.", + "optional" : 1, + "type" : "boolean" + }, + "cores" : { + "description" : "The number of cores assigned to the container. A container can use all available cores by default.", + "maximum" : 8192, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.", + "maximum" : 8192, + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 500000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "verbose_description" : "CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests." + }, + "debug" : { + "default" : 0, + "description" : "Try to be more verbose. For now this only enables debug log-level on start.", + "optional" : 1, + "type" : "boolean" + }, + "description" : { + "description" : "Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "SHA1 digest of configuration file. This can be used to prevent concurrent modifications.", + "type" : "string" + }, + "features" : { + "description" : "Allow containers access to advanced features.", + "format" : { + "force_rw_sys" : { + "default" : 0, + "description" : "Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.", + "optional" : 1, + "type" : "boolean" + }, + "fuse" : { + "default" : 0, + "description" : "Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.", + "optional" : 1, + "type" : "boolean" + }, + "keyctl" : { + "default" : 0, + "description" : "For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.", + "optional" : 1, + "type" : "boolean" + }, + "mknod" : { + "default" : 0, + "description" : "Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.", + "optional" : 1, + "type" : "boolean" + }, + "mount" : { + "description" : "Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.", + "format_description" : "fstype;fstype;...", + "optional" : 1, + "pattern" : "(?^:[a-zA-Z0-9_; ]+)", + "type" : "string" + }, + "nesting" : { + "default" : 0, + "description" : "Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string" + }, + "hookscript" : { + "description" : "Script that will be exectued during various steps in the containers lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string" + }, + "hostname" : { + "description" : "Set a host name for the container.", + "format" : "dns-name", + "maxLength" : 255, + "optional" : 1, + "type" : "string" + }, + "lock" : { + "description" : "Lock/unlock the container.", + "enum" : [ + "backup", + "create", + "destroyed", + "disk", + "fstrim", + "migrate", + "mounted", + "rollback", + "snapshot", + "snapshot-delete" + ], + "optional" : 1, + "type" : "string" + }, + "lxc" : { + "description" : "Array of lxc low-level configurations ([[key1, value1], [key2, value2] ...]).", + "items" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "optional" : 1, + "type" : "array" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the container in MB.", + "minimum" : 16, + "optional" : 1, + "type" : "integer" + }, + "mp[n]" : { + "description" : "Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "backup" : { + "description" : "Whether to include the mount point in backups.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Whether to include the mount point in backups (only used for volume mount points)." + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(noatime|lazytime|nodev|nosuid|noexec))(;(?^:(noatime|lazytime|nodev|nosuid|noexec)))*)", + "type" : "string" + }, + "mp" : { + "description" : "Path to the mount point as seen from inside the container (must not contain symlinks).", + "format" : "pve-lxc-mp-string", + "format_description" : "Path", + "type" : "string", + "verbose_description" : "Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons." + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "nameserver" : { + "description" : "Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "lxc-ip-with-ll-iface-list", + "optional" : 1, + "type" : "string" + }, + "net[n]" : { + "description" : "Specifies network interfaces for the container.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to.", + "format_description" : "bridge", + "optional" : 1, + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "firewall" : { + "description" : "Controls whether this interface's firewall rules should be used.", + "optional" : 1, + "type" : "boolean" + }, + "gw" : { + "description" : "Default gateway for IPv4 traffic.", + "format" : "ipv4", + "format_description" : "GatewayIPv4", + "optional" : 1, + "type" : "string" + }, + "gw6" : { + "description" : "Default gateway for IPv6 traffic.", + "format" : "ipv6", + "format_description" : "GatewayIPv6", + "optional" : 1, + "type" : "string" + }, + "hwaddr" : { + "description" : "The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "ip" : { + "description" : "IPv4 address in CIDR format.", + "format" : "pve-ipv4-config", + "format_description" : "(IPv4/CIDR|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address in CIDR format.", + "format" : "pve-ipv6-config", + "format_description" : "(IPv6/CIDR|auto|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "mtu" : { + "description" : "Maximum transfer unit of the interface. (lxc.network.mtu)", + "maximum" : 65535, + "minimum" : 64, + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "Name of the network device as seen from inside the container. (lxc.network.name)", + "format_description" : "string", + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "rate" : { + "description" : "Apply rate limiting to the interface", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "tag" : { + "description" : "VLAN tag for this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN ids to pass through the interface", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:;\\d+)*)", + "type" : "string" + }, + "type" : { + "description" : "Network interface type.", + "enum" : [ + "veth" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a container will be started during system bootup.", + "optional" : 1, + "type" : "boolean" + }, + "ostype" : { + "description" : "OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.", + "enum" : [ + "debian", + "devuan", + "ubuntu", + "centos", + "fedora", + "opensuse", + "archlinux", + "alpine", + "gentoo", + "nixos", + "unmanaged" + ], + "optional" : 1, + "type" : "string" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.", + "optional" : 1, + "type" : "boolean" + }, + "rootfs" : { + "description" : "Use volume as container root.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(noatime|lazytime|nodev|nosuid|noexec))(;(?^:(noatime|lazytime|nodev|nosuid|noexec)))*)", + "type" : "string" + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "dns-name-list", + "optional" : 1, + "type" : "string" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "swap" : { + "default" : 512, + "description" : "Amount of SWAP for the container in MB.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "tags" : { + "description" : "Tags of the Container. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean" + }, + "timezone" : { + "description" : "Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab", + "format" : "pve-ct-timezone", + "optional" : 1, + "type" : "string" + }, + "tty" : { + "default" : 2, + "description" : "Specify the number of tty available to the container", + "maximum" : 6, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "unprivileged" : { + "default" : 0, + "description" : "Makes the container run as unprivileged user. (Should not be modified manually.)", + "optional" : 1, + "type" : "boolean" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "volume" : { + "default_key" : 1, + "description" : "The volume that is not used currently.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set container options.", + "method" : "PUT", + "name" : "update_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "arch" : { + "default" : "amd64", + "description" : "OS architecture type.", + "enum" : [ + "amd64", + "i386", + "arm64", + "armhf", + "riscv32", + "riscv64" + ], + "optional" : 1, + "type" : "string" + }, + "cmode" : { + "default" : "tty", + "description" : "Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).", + "enum" : [ + "shell", + "console", + "tty" + ], + "optional" : 1, + "type" : "string" + }, + "console" : { + "default" : 1, + "description" : "Attach a console device (/dev/console) to the container.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cores" : { + "description" : "The number of cores assigned to the container. A container can use all available cores by default.", + "maximum" : 8192, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 8192)" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.", + "maximum" : 8192, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 8192)" + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 500000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 500000)", + "verbose_description" : "CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests." + }, + "debug" : { + "default" : 0, + "description" : "Try to be more verbose. For now this only enables debug log-level on start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "features" : { + "description" : "Allow containers access to advanced features.", + "format" : { + "force_rw_sys" : { + "default" : 0, + "description" : "Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.", + "optional" : 1, + "type" : "boolean" + }, + "fuse" : { + "default" : 0, + "description" : "Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.", + "optional" : 1, + "type" : "boolean" + }, + "keyctl" : { + "default" : 0, + "description" : "For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.", + "optional" : 1, + "type" : "boolean" + }, + "mknod" : { + "default" : 0, + "description" : "Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.", + "optional" : 1, + "type" : "boolean" + }, + "mount" : { + "description" : "Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.", + "format_description" : "fstype;fstype;...", + "optional" : 1, + "pattern" : "(?^:[a-zA-Z0-9_; ]+)", + "type" : "string" + }, + "nesting" : { + "default" : 0, + "description" : "Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[force_rw_sys=<1|0>] [,fuse=<1|0>] [,keyctl=<1|0>] [,mknod=<1|0>] [,mount=] [,nesting=<1|0>]" + }, + "hookscript" : { + "description" : "Script that will be exectued during various steps in the containers lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostname" : { + "description" : "Set a host name for the container.", + "format" : "dns-name", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the container.", + "enum" : [ + "backup", + "create", + "destroyed", + "disk", + "fstrim", + "migrate", + "mounted", + "rollback", + "snapshot", + "snapshot-delete" + ], + "optional" : 1, + "type" : "string" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the container in MB.", + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - N)" + }, + "mp[n]" : { + "description" : "Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "backup" : { + "description" : "Whether to include the mount point in backups.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Whether to include the mount point in backups (only used for volume mount points)." + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(noatime|lazytime|nodev|nosuid|noexec))(;(?^:(noatime|lazytime|nodev|nosuid|noexec)))*)", + "type" : "string" + }, + "mp" : { + "description" : "Path to the mount point as seen from inside the container (must not contain symlinks).", + "format" : "pve-lxc-mp-string", + "format_description" : "Path", + "type" : "string", + "verbose_description" : "Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons." + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=] ,mp= [,acl=<1|0>] [,backup=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]" + }, + "nameserver" : { + "description" : "Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "lxc-ip-with-ll-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specifies network interfaces for the container.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to.", + "format_description" : "bridge", + "optional" : 1, + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "firewall" : { + "description" : "Controls whether this interface's firewall rules should be used.", + "optional" : 1, + "type" : "boolean" + }, + "gw" : { + "description" : "Default gateway for IPv4 traffic.", + "format" : "ipv4", + "format_description" : "GatewayIPv4", + "optional" : 1, + "type" : "string" + }, + "gw6" : { + "description" : "Default gateway for IPv6 traffic.", + "format" : "ipv6", + "format_description" : "GatewayIPv6", + "optional" : 1, + "type" : "string" + }, + "hwaddr" : { + "description" : "The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "ip" : { + "description" : "IPv4 address in CIDR format.", + "format" : "pve-ipv4-config", + "format_description" : "(IPv4/CIDR|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address in CIDR format.", + "format" : "pve-ipv6-config", + "format_description" : "(IPv6/CIDR|auto|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "mtu" : { + "description" : "Maximum transfer unit of the interface. (lxc.network.mtu)", + "maximum" : 65535, + "minimum" : 64, + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "Name of the network device as seen from inside the container. (lxc.network.name)", + "format_description" : "string", + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "rate" : { + "description" : "Apply rate limiting to the interface", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "tag" : { + "description" : "VLAN tag for this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN ids to pass through the interface", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:;\\d+)*)", + "type" : "string" + }, + "type" : { + "description" : "Network interface type.", + "enum" : [ + "veth" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "name= [,bridge=] [,firewall=<1|0>] [,gw=] [,gw6=] [,hwaddr=] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=<(IPv6/CIDR|auto|dhcp|manual)>] [,link_down=<1|0>] [,mtu=] [,rate=] [,tag=] [,trunks=] [,type=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a container will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostype" : { + "description" : "OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.", + "enum" : [ + "debian", + "devuan", + "ubuntu", + "centos", + "fedora", + "opensuse", + "archlinux", + "alpine", + "gentoo", + "nixos", + "unmanaged" + ], + "optional" : 1, + "type" : "string" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "revert" : { + "description" : "Revert a pending change.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rootfs" : { + "description" : "Use volume as container root.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(noatime|lazytime|nodev|nosuid|noexec))(;(?^:(noatime|lazytime|nodev|nosuid|noexec)))*)", + "type" : "string" + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=] [,acl=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]" + }, + "searchdomain" : { + "description" : "Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "dns-name-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "swap" : { + "default" : 512, + "description" : "Amount of SWAP for the container in MB.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "tags" : { + "description" : "Tags of the Container. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "timezone" : { + "description" : "Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab", + "format" : "pve-ct-timezone", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tty" : { + "default" : 2, + "description" : "Specify the number of tty available to the container", + "maximum" : 6, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 6)" + }, + "unprivileged" : { + "default" : 0, + "description" : "Makes the container run as unprivileged user. (Should not be modified manually.)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "volume" : { + "default_key" : 1, + "description" : "The volume that is not used currently.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=]" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk", + "VM.Config.CPU", + "VM.Config.Memory", + "VM.Config.Network", + "VM.Config.Options" + ], + "any", + 1 + ], + "description" : "non-volume mount points in rootfs and mp[n] are restricted to root@pam" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/config", + "text" : "config" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get virtual machine status.", + "method" : "GET", + "name" : "vm_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "cpus" : { + "description" : "Maximum usable CPUs.", + "optional" : 1, + "type" : "number" + }, + "ha" : { + "description" : "HA manager service status.", + "type" : "object" + }, + "lock" : { + "description" : "The current config lock, if any.", + "optional" : 1, + "type" : "string" + }, + "maxdisk" : { + "description" : "Root disk size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Maximum memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxswap" : { + "description" : "Maximum SWAP memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "Container name.", + "optional" : 1, + "type" : "string" + }, + "status" : { + "description" : "LXC Container status.", + "enum" : [ + "stopped", + "running" + ], + "type" : "string" + }, + "tags" : { + "description" : "The current configured tags, if any.", + "optional" : 1, + "type" : "string" + }, + "uptime" : { + "description" : "Uptime.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/current", + "text" : "current" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start the container.", + "method" : "POST", + "name" : "vm_start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "debug" : { + "default" : 0, + "description" : "If set, enables very verbose debug log-level on start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop the container. This will abruptly stop all processes running in the container.", + "method" : "POST", + "name" : "vm_stop", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/stop", + "text" : "stop" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Shutdown the container. This will trigger a clean shutdown of the container, see lxc-stop(1) for details.", + "method" : "POST", + "name" : "vm_shutdown", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "forceStop" : { + "default" : 0, + "description" : "Make sure the Container stops.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 60, + "description" : "Wait maximal timeout seconds.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/shutdown", + "text" : "shutdown" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Suspend the container. This is experimental.", + "method" : "POST", + "name" : "vm_suspend", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/suspend", + "text" : "suspend" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Resume the container.", + "method" : "POST", + "name" : "vm_resume", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/resume", + "text" : "resume" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Reboot the container by shutting it down, and starting it again. Applies pending changes.", + "method" : "POST", + "name" : "vm_reboot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "description" : "Wait maximal timeout seconds for the shutdown.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/reboot", + "text" : "reboot" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "vmcmdidx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/status", + "text" : "status" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Rollback LXC state to specified snapshot.", + "method" : "POST", + "name" : "rollback", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Whether the container should get started after rolling back successfully", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback", + "text" : "rollback" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get snapshot configuration", + "method" : "GET", + "name" : "get_snapshot_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback", + "VM.Audit" + ], + "any", + 1 + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update snapshot metadata.", + "method" : "PUT", + "name" : "update_snapshot_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A textual description or comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "text" : "config" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete a LXC snapshot.", + "method" : "DELETE", + "name" : "delsnapshot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "For removal from config file, even if removing disk snapshots fails.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "snapshot_cmd_idx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{cmd}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "text" : "{snapname}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all snapshots.", + "method" : "GET", + "name" : "list", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "description" : { + "description" : "Snapshot description.", + "type" : "string" + }, + "name" : { + "description" : "Snapshot identifier. Value 'current' identifies the current VM.", + "type" : "string" + }, + "parent" : { + "description" : "Parent snapshot identifier.", + "optional" : 1, + "type" : "string" + }, + "snaptime" : { + "description" : "Snapshot creation time", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Snapshot a container.", + "method" : "POST", + "name" : "snapshot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A textual description or comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/snapshot", + "text" : "snapshot" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "dest" : { + "optional" : 1, + "type" : "string" + }, + "dport" : { + "optional" : 1, + "type" : "string" + }, + "enable" : { + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "optional" : 1, + "type" : "string" + }, + "iface" : { + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "optional" : 1, + "type" : "string" + }, + "pos" : { + "type" : "integer" + }, + "proto" : { + "optional" : 1, + "type" : "string" + }, + "source" : { + "optional" : 1, + "type" : "string" + }, + "sport" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "pos" : { + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 0, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/rules", + "text" : "rules" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network alias.", + "method" : "DELETE", + "name" : "remove_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read alias.", + "method" : "GET", + "name" : "read_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network alias.", + "method" : "PUT", + "name" : "update_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "rename" : { + "description" : "Rename an existing alias.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List aliases", + "method" : "GET", + "name" : "get_aliases", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create IP or Network Alias.", + "method" : "POST", + "name" : "create_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/aliases", + "text" : "aliases" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network from IPSet.", + "method" : "DELETE", + "name" : "remove_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read IP or Network settings from IPSet.", + "method" : "GET", + "name" : "read_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network settings", + "method" : "PUT", + "name" : "update_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "text" : "{cidr}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete IPSet", + "method" : "DELETE", + "name" : "delete_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "Delete all members of the IPSet, if there are any.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List IPSet content", + "method" : "GET", + "name" : "get_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{cidr}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add IP or Network to IPSet.", + "method" : "POST", + "name" : "create_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List IPSets", + "method" : "GET", + "name" : "ipset_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new IPSet", + "method" : "POST", + "name" : "create_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "rename" : { + "description" : "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/ipset", + "text" : "ipset" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get VM firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "dhcp" : { + "default" : 0, + "description" : "Enable DHCP.", + "optional" : 1, + "type" : "boolean" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean" + }, + "ipfilter" : { + "description" : "Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.", + "optional" : 1, + "type" : "boolean" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macfilter" : { + "default" : 1, + "description" : "Enable/disable MAC address filter.", + "optional" : 1, + "type" : "boolean" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "radv" : { + "description" : "Allow sending Router Advertisement.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp" : { + "default" : 0, + "description" : "Enable DHCP.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ipfilter" : { + "description" : "Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macfilter" : { + "default" : 1, + "description" : "Enable/disable MAC address filter.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "radv" : { + "description" : "Allow sending Router Advertisement.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read firewall log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display log since this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "until" : { + "description" : "Display log until this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Lists possible IPSet/Alias reference which are allowed in source/dest properties.", + "method" : "GET", + "name" : "refs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Only list references of specified type.", + "enum" : [ + "alias", + "ipset" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "alias", + "ipset" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/refs", + "text" : "refs" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall", + "text" : "firewall" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read VM RRD statistics (returns PNG)", + "method" : "GET", + "name" : "rrd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "ds" : { + "description" : "The list of datasources you want to display.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "filename" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/rrd", + "text" : "rrd" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read VM RRD statistics", + "method" : "GET", + "name" : "rrddata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/rrddata", + "text" : "rrddata" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a TCP VNC proxy connections.", + "method" : "POST", + "name" : "vncproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "height" : { + "description" : "sets the height of the console in pixels.", + "maximum" : 2160, + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - 2160)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "websocket" : { + "description" : "use websocket instead of standard VNC.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "width" : { + "description" : "sets the width of the console in pixels.", + "maximum" : 4096, + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - 4096)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "cert" : { + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/vncproxy", + "text" : "vncproxy" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a TCP proxy connection.", + "method" : "POST", + "name" : "termproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/termproxy", + "text" : "termproxy" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Opens a weksocket for VNC traffic.", + "method" : "GET", + "name" : "vncwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Port number returned by previous vncproxy call.", + "maximum" : 5999, + "minimum" : 5900, + "type" : "integer", + "typetext" : " (5900 - 5999)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vncticket" : { + "description" : "Ticket from previous call to vncproxy.", + "maxLength" : 512, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ], + "description" : "You also need to pass a valid ticket (vncticket)." + }, + "returns" : { + "properties" : { + "port" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/vncwebsocket", + "text" : "vncwebsocket" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Returns a SPICE configuration to connect to the CT.", + "method" : "POST", + "name" : "spiceproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "proxy" : { + "description" : "SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).", + "format" : "address", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 1, + "description" : "Returned values can be directly passed to the 'remote-viewer' application.", + "properties" : { + "host" : { + "type" : "string" + }, + "password" : { + "type" : "string" + }, + "proxy" : { + "type" : "string" + }, + "tls-port" : { + "type" : "integer" + }, + "type" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/spiceproxy", + "text" : "spiceproxy" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migrate the container to another cluster. Creates a new migration task. EXPERIMENTAL feature!", + "method" : "POST", + "name" : "remote_migrate_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "migrate limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "delete" : { + "default" : 0, + "description" : "Delete the original CT and related data after successful migration. By default the original CT is kept on the source cluster in a stopped state.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "online" : { + "description" : "Use online/live migration.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restart" : { + "description" : "Use restart migration", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target-bridge" : { + "description" : "Mapping from source to target bridges. Providing only a single bridge ID maps all source bridges to that bridge. Providing the special value '1' will map each source bridge to itself.", + "format" : "bridge-pair-list", + "type" : "string", + "typetext" : "" + }, + "target-endpoint" : { + "description" : "Remote target endpoint", + "format" : "proxmox-remote", + "type" : "string", + "typetext" : "apitoken= ,host= [,fingerprint=] [,port=]" + }, + "target-storage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storage-pair-list", + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "target-vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "timeout" : { + "default" : 180, + "description" : "Timeout in seconds for shutdown for restart migration", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/remote_migrate", + "text" : "remote_migrate" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migrate the container to another node. Creates a new migration task.", + "method" : "POST", + "name" : "migrate_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "migrate limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "online" : { + "description" : "Use online/live migration.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restart" : { + "description" : "Use restart migration", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "target-storage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storage-pair-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 180, + "description" : "Timeout in seconds for shutdown for restart migration", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/migrate", + "text" : "migrate" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Check if feature for virtual machine is available.", + "method" : "GET", + "name" : "vm_feature", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "feature" : { + "description" : "Feature to check.", + "enum" : [ + "snapshot", + "clone", + "copy" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "hasFeature" : { + "type" : "boolean" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/feature", + "text" : "feature" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a Template.", + "method" : "POST", + "name" : "template", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + "description" : "You need 'VM.Allocate' permissions on /vms/{vmid}" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/template", + "text" : "template" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a container clone/copy", + "method" : "POST", + "name" : "clone_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "clone limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "description" : { + "description" : "Description for the new CT.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "full" : { + "description" : "Create a full copy of all disks. This is always done when you clone a normal CT. For CT templates, we try to create a linked clone by default.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hostname" : { + "description" : "Set a hostname for the new CT.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "newid" : { + "description" : "VMID for the clone.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Add the new CT to the specified pool.", + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Target storage for full clone.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node. Only allowed if the original VM is on shared storage.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/vms/{vmid}", + [ + "VM.Clone" + ] + ], + [ + "or", + [ + "perm", + "/vms/{newid}", + [ + "VM.Allocate" + ] + ], + [ + "perm", + "/pool/{pool}", + [ + "VM.Allocate" + ], + "require_param", + "pool" + ] + ] + ], + "description" : "You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions on /vms/{newid} (or on the VM pool /pool/{pool}). You also need 'Datastore.AllocateSpace' on any used storage." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/clone", + "text" : "clone" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Resize a container mount point.", + "method" : "PUT", + "name" : "resize_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disk" : { + "description" : "The disk you want to resize.", + "enum" : [ + "rootfs", + "mp0", + "mp1", + "mp2", + "mp3", + "mp4", + "mp5", + "mp6", + "mp7", + "mp8", + "mp9", + "mp10", + "mp11", + "mp12", + "mp13", + "mp14", + "mp15", + "mp16", + "mp17", + "mp18", + "mp19", + "mp20", + "mp21", + "mp22", + "mp23", + "mp24", + "mp25", + "mp26", + "mp27", + "mp28", + "mp29", + "mp30", + "mp31", + "mp32", + "mp33", + "mp34", + "mp35", + "mp36", + "mp37", + "mp38", + "mp39", + "mp40", + "mp41", + "mp42", + "mp43", + "mp44", + "mp45", + "mp46", + "mp47", + "mp48", + "mp49", + "mp50", + "mp51", + "mp52", + "mp53", + "mp54", + "mp55", + "mp56", + "mp57", + "mp58", + "mp59", + "mp60", + "mp61", + "mp62", + "mp63", + "mp64", + "mp65", + "mp66", + "mp67", + "mp68", + "mp69", + "mp70", + "mp71", + "mp72", + "mp73", + "mp74", + "mp75", + "mp76", + "mp77", + "mp78", + "mp79", + "mp80", + "mp81", + "mp82", + "mp83", + "mp84", + "mp85", + "mp86", + "mp87", + "mp88", + "mp89", + "mp90", + "mp91", + "mp92", + "mp93", + "mp94", + "mp95", + "mp96", + "mp97", + "mp98", + "mp99", + "mp100", + "mp101", + "mp102", + "mp103", + "mp104", + "mp105", + "mp106", + "mp107", + "mp108", + "mp109", + "mp110", + "mp111", + "mp112", + "mp113", + "mp114", + "mp115", + "mp116", + "mp117", + "mp118", + "mp119", + "mp120", + "mp121", + "mp122", + "mp123", + "mp124", + "mp125", + "mp126", + "mp127", + "mp128", + "mp129", + "mp130", + "mp131", + "mp132", + "mp133", + "mp134", + "mp135", + "mp136", + "mp137", + "mp138", + "mp139", + "mp140", + "mp141", + "mp142", + "mp143", + "mp144", + "mp145", + "mp146", + "mp147", + "mp148", + "mp149", + "mp150", + "mp151", + "mp152", + "mp153", + "mp154", + "mp155", + "mp156", + "mp157", + "mp158", + "mp159", + "mp160", + "mp161", + "mp162", + "mp163", + "mp164", + "mp165", + "mp166", + "mp167", + "mp168", + "mp169", + "mp170", + "mp171", + "mp172", + "mp173", + "mp174", + "mp175", + "mp176", + "mp177", + "mp178", + "mp179", + "mp180", + "mp181", + "mp182", + "mp183", + "mp184", + "mp185", + "mp186", + "mp187", + "mp188", + "mp189", + "mp190", + "mp191", + "mp192", + "mp193", + "mp194", + "mp195", + "mp196", + "mp197", + "mp198", + "mp199", + "mp200", + "mp201", + "mp202", + "mp203", + "mp204", + "mp205", + "mp206", + "mp207", + "mp208", + "mp209", + "mp210", + "mp211", + "mp212", + "mp213", + "mp214", + "mp215", + "mp216", + "mp217", + "mp218", + "mp219", + "mp220", + "mp221", + "mp222", + "mp223", + "mp224", + "mp225", + "mp226", + "mp227", + "mp228", + "mp229", + "mp230", + "mp231", + "mp232", + "mp233", + "mp234", + "mp235", + "mp236", + "mp237", + "mp238", + "mp239", + "mp240", + "mp241", + "mp242", + "mp243", + "mp244", + "mp245", + "mp246", + "mp247", + "mp248", + "mp249", + "mp250", + "mp251", + "mp252", + "mp253", + "mp254", + "mp255" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "size" : { + "description" : "The new size. With the '+' sign the value is added to the actual size of the volume and without it, the value is taken as an absolute one. Shrinking disk size is not supported.", + "pattern" : "\\+?\\d+(\\.\\d+)?[KMGT]?", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/resize", + "text" : "resize" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Move a rootfs-/mp-volume to a different storage or to a different container.", + "method" : "POST", + "name" : "move_volume", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "clone limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "delete" : { + "default" : 0, + "description" : "Delete the original volume after successful copy. By default the original is kept as an unused volume entry.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 \" .\n\t\t \"digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Target Storage.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target-digest" : { + "description" : "Prevent changes if current configuration file of the target \" .\n\t\t \"container has a different SHA1 digest. This can be used to prevent \" .\n\t\t \"concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target-vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "target-volume" : { + "description" : "The config key the volume will be moved to. Default is the source volume key.", + "enum" : [ + "rootfs", + "mp0", + "mp1", + "mp2", + "mp3", + "mp4", + "mp5", + "mp6", + "mp7", + "mp8", + "mp9", + "mp10", + "mp11", + "mp12", + "mp13", + "mp14", + "mp15", + "mp16", + "mp17", + "mp18", + "mp19", + "mp20", + "mp21", + "mp22", + "mp23", + "mp24", + "mp25", + "mp26", + "mp27", + "mp28", + "mp29", + "mp30", + "mp31", + "mp32", + "mp33", + "mp34", + "mp35", + "mp36", + "mp37", + "mp38", + "mp39", + "mp40", + "mp41", + "mp42", + "mp43", + "mp44", + "mp45", + "mp46", + "mp47", + "mp48", + "mp49", + "mp50", + "mp51", + "mp52", + "mp53", + "mp54", + "mp55", + "mp56", + "mp57", + "mp58", + "mp59", + "mp60", + "mp61", + "mp62", + "mp63", + "mp64", + "mp65", + "mp66", + "mp67", + "mp68", + "mp69", + "mp70", + "mp71", + "mp72", + "mp73", + "mp74", + "mp75", + "mp76", + "mp77", + "mp78", + "mp79", + "mp80", + "mp81", + "mp82", + "mp83", + "mp84", + "mp85", + "mp86", + "mp87", + "mp88", + "mp89", + "mp90", + "mp91", + "mp92", + "mp93", + "mp94", + "mp95", + "mp96", + "mp97", + "mp98", + "mp99", + "mp100", + "mp101", + "mp102", + "mp103", + "mp104", + "mp105", + "mp106", + "mp107", + "mp108", + "mp109", + "mp110", + "mp111", + "mp112", + "mp113", + "mp114", + "mp115", + "mp116", + "mp117", + "mp118", + "mp119", + "mp120", + "mp121", + "mp122", + "mp123", + "mp124", + "mp125", + "mp126", + "mp127", + "mp128", + "mp129", + "mp130", + "mp131", + "mp132", + "mp133", + "mp134", + "mp135", + "mp136", + "mp137", + "mp138", + "mp139", + "mp140", + "mp141", + "mp142", + "mp143", + "mp144", + "mp145", + "mp146", + "mp147", + "mp148", + "mp149", + "mp150", + "mp151", + "mp152", + "mp153", + "mp154", + "mp155", + "mp156", + "mp157", + "mp158", + "mp159", + "mp160", + "mp161", + "mp162", + "mp163", + "mp164", + "mp165", + "mp166", + "mp167", + "mp168", + "mp169", + "mp170", + "mp171", + "mp172", + "mp173", + "mp174", + "mp175", + "mp176", + "mp177", + "mp178", + "mp179", + "mp180", + "mp181", + "mp182", + "mp183", + "mp184", + "mp185", + "mp186", + "mp187", + "mp188", + "mp189", + "mp190", + "mp191", + "mp192", + "mp193", + "mp194", + "mp195", + "mp196", + "mp197", + "mp198", + "mp199", + "mp200", + "mp201", + "mp202", + "mp203", + "mp204", + "mp205", + "mp206", + "mp207", + "mp208", + "mp209", + "mp210", + "mp211", + "mp212", + "mp213", + "mp214", + "mp215", + "mp216", + "mp217", + "mp218", + "mp219", + "mp220", + "mp221", + "mp222", + "mp223", + "mp224", + "mp225", + "mp226", + "mp227", + "mp228", + "mp229", + "mp230", + "mp231", + "mp232", + "mp233", + "mp234", + "mp235", + "mp236", + "mp237", + "mp238", + "mp239", + "mp240", + "mp241", + "mp242", + "mp243", + "mp244", + "mp245", + "mp246", + "mp247", + "mp248", + "mp249", + "mp250", + "mp251", + "mp252", + "mp253", + "mp254", + "mp255", + "unused0", + "unused1", + "unused2", + "unused3", + "unused4", + "unused5", + "unused6", + "unused7", + "unused8", + "unused9", + "unused10", + "unused11", + "unused12", + "unused13", + "unused14", + "unused15", + "unused16", + "unused17", + "unused18", + "unused19", + "unused20", + "unused21", + "unused22", + "unused23", + "unused24", + "unused25", + "unused26", + "unused27", + "unused28", + "unused29", + "unused30", + "unused31", + "unused32", + "unused33", + "unused34", + "unused35", + "unused36", + "unused37", + "unused38", + "unused39", + "unused40", + "unused41", + "unused42", + "unused43", + "unused44", + "unused45", + "unused46", + "unused47", + "unused48", + "unused49", + "unused50", + "unused51", + "unused52", + "unused53", + "unused54", + "unused55", + "unused56", + "unused57", + "unused58", + "unused59", + "unused60", + "unused61", + "unused62", + "unused63", + "unused64", + "unused65", + "unused66", + "unused67", + "unused68", + "unused69", + "unused70", + "unused71", + "unused72", + "unused73", + "unused74", + "unused75", + "unused76", + "unused77", + "unused78", + "unused79", + "unused80", + "unused81", + "unused82", + "unused83", + "unused84", + "unused85", + "unused86", + "unused87", + "unused88", + "unused89", + "unused90", + "unused91", + "unused92", + "unused93", + "unused94", + "unused95", + "unused96", + "unused97", + "unused98", + "unused99", + "unused100", + "unused101", + "unused102", + "unused103", + "unused104", + "unused105", + "unused106", + "unused107", + "unused108", + "unused109", + "unused110", + "unused111", + "unused112", + "unused113", + "unused114", + "unused115", + "unused116", + "unused117", + "unused118", + "unused119", + "unused120", + "unused121", + "unused122", + "unused123", + "unused124", + "unused125", + "unused126", + "unused127", + "unused128", + "unused129", + "unused130", + "unused131", + "unused132", + "unused133", + "unused134", + "unused135", + "unused136", + "unused137", + "unused138", + "unused139", + "unused140", + "unused141", + "unused142", + "unused143", + "unused144", + "unused145", + "unused146", + "unused147", + "unused148", + "unused149", + "unused150", + "unused151", + "unused152", + "unused153", + "unused154", + "unused155", + "unused156", + "unused157", + "unused158", + "unused159", + "unused160", + "unused161", + "unused162", + "unused163", + "unused164", + "unused165", + "unused166", + "unused167", + "unused168", + "unused169", + "unused170", + "unused171", + "unused172", + "unused173", + "unused174", + "unused175", + "unused176", + "unused177", + "unused178", + "unused179", + "unused180", + "unused181", + "unused182", + "unused183", + "unused184", + "unused185", + "unused186", + "unused187", + "unused188", + "unused189", + "unused190", + "unused191", + "unused192", + "unused193", + "unused194", + "unused195", + "unused196", + "unused197", + "unused198", + "unused199", + "unused200", + "unused201", + "unused202", + "unused203", + "unused204", + "unused205", + "unused206", + "unused207", + "unused208", + "unused209", + "unused210", + "unused211", + "unused212", + "unused213", + "unused214", + "unused215", + "unused216", + "unused217", + "unused218", + "unused219", + "unused220", + "unused221", + "unused222", + "unused223", + "unused224", + "unused225", + "unused226", + "unused227", + "unused228", + "unused229", + "unused230", + "unused231", + "unused232", + "unused233", + "unused234", + "unused235", + "unused236", + "unused237", + "unused238", + "unused239", + "unused240", + "unused241", + "unused242", + "unused243", + "unused244", + "unused245", + "unused246", + "unused247", + "unused248", + "unused249", + "unused250", + "unused251", + "unused252", + "unused253", + "unused254", + "unused255" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "volume" : { + "description" : "Volume which will be moved.", + "enum" : [ + "rootfs", + "mp0", + "mp1", + "mp2", + "mp3", + "mp4", + "mp5", + "mp6", + "mp7", + "mp8", + "mp9", + "mp10", + "mp11", + "mp12", + "mp13", + "mp14", + "mp15", + "mp16", + "mp17", + "mp18", + "mp19", + "mp20", + "mp21", + "mp22", + "mp23", + "mp24", + "mp25", + "mp26", + "mp27", + "mp28", + "mp29", + "mp30", + "mp31", + "mp32", + "mp33", + "mp34", + "mp35", + "mp36", + "mp37", + "mp38", + "mp39", + "mp40", + "mp41", + "mp42", + "mp43", + "mp44", + "mp45", + "mp46", + "mp47", + "mp48", + "mp49", + "mp50", + "mp51", + "mp52", + "mp53", + "mp54", + "mp55", + "mp56", + "mp57", + "mp58", + "mp59", + "mp60", + "mp61", + "mp62", + "mp63", + "mp64", + "mp65", + "mp66", + "mp67", + "mp68", + "mp69", + "mp70", + "mp71", + "mp72", + "mp73", + "mp74", + "mp75", + "mp76", + "mp77", + "mp78", + "mp79", + "mp80", + "mp81", + "mp82", + "mp83", + "mp84", + "mp85", + "mp86", + "mp87", + "mp88", + "mp89", + "mp90", + "mp91", + "mp92", + "mp93", + "mp94", + "mp95", + "mp96", + "mp97", + "mp98", + "mp99", + "mp100", + "mp101", + "mp102", + "mp103", + "mp104", + "mp105", + "mp106", + "mp107", + "mp108", + "mp109", + "mp110", + "mp111", + "mp112", + "mp113", + "mp114", + "mp115", + "mp116", + "mp117", + "mp118", + "mp119", + "mp120", + "mp121", + "mp122", + "mp123", + "mp124", + "mp125", + "mp126", + "mp127", + "mp128", + "mp129", + "mp130", + "mp131", + "mp132", + "mp133", + "mp134", + "mp135", + "mp136", + "mp137", + "mp138", + "mp139", + "mp140", + "mp141", + "mp142", + "mp143", + "mp144", + "mp145", + "mp146", + "mp147", + "mp148", + "mp149", + "mp150", + "mp151", + "mp152", + "mp153", + "mp154", + "mp155", + "mp156", + "mp157", + "mp158", + "mp159", + "mp160", + "mp161", + "mp162", + "mp163", + "mp164", + "mp165", + "mp166", + "mp167", + "mp168", + "mp169", + "mp170", + "mp171", + "mp172", + "mp173", + "mp174", + "mp175", + "mp176", + "mp177", + "mp178", + "mp179", + "mp180", + "mp181", + "mp182", + "mp183", + "mp184", + "mp185", + "mp186", + "mp187", + "mp188", + "mp189", + "mp190", + "mp191", + "mp192", + "mp193", + "mp194", + "mp195", + "mp196", + "mp197", + "mp198", + "mp199", + "mp200", + "mp201", + "mp202", + "mp203", + "mp204", + "mp205", + "mp206", + "mp207", + "mp208", + "mp209", + "mp210", + "mp211", + "mp212", + "mp213", + "mp214", + "mp215", + "mp216", + "mp217", + "mp218", + "mp219", + "mp220", + "mp221", + "mp222", + "mp223", + "mp224", + "mp225", + "mp226", + "mp227", + "mp228", + "mp229", + "mp230", + "mp231", + "mp232", + "mp233", + "mp234", + "mp235", + "mp236", + "mp237", + "mp238", + "mp239", + "mp240", + "mp241", + "mp242", + "mp243", + "mp244", + "mp245", + "mp246", + "mp247", + "mp248", + "mp249", + "mp250", + "mp251", + "mp252", + "mp253", + "mp254", + "mp255", + "unused0", + "unused1", + "unused2", + "unused3", + "unused4", + "unused5", + "unused6", + "unused7", + "unused8", + "unused9", + "unused10", + "unused11", + "unused12", + "unused13", + "unused14", + "unused15", + "unused16", + "unused17", + "unused18", + "unused19", + "unused20", + "unused21", + "unused22", + "unused23", + "unused24", + "unused25", + "unused26", + "unused27", + "unused28", + "unused29", + "unused30", + "unused31", + "unused32", + "unused33", + "unused34", + "unused35", + "unused36", + "unused37", + "unused38", + "unused39", + "unused40", + "unused41", + "unused42", + "unused43", + "unused44", + "unused45", + "unused46", + "unused47", + "unused48", + "unused49", + "unused50", + "unused51", + "unused52", + "unused53", + "unused54", + "unused55", + "unused56", + "unused57", + "unused58", + "unused59", + "unused60", + "unused61", + "unused62", + "unused63", + "unused64", + "unused65", + "unused66", + "unused67", + "unused68", + "unused69", + "unused70", + "unused71", + "unused72", + "unused73", + "unused74", + "unused75", + "unused76", + "unused77", + "unused78", + "unused79", + "unused80", + "unused81", + "unused82", + "unused83", + "unused84", + "unused85", + "unused86", + "unused87", + "unused88", + "unused89", + "unused90", + "unused91", + "unused92", + "unused93", + "unused94", + "unused95", + "unused96", + "unused97", + "unused98", + "unused99", + "unused100", + "unused101", + "unused102", + "unused103", + "unused104", + "unused105", + "unused106", + "unused107", + "unused108", + "unused109", + "unused110", + "unused111", + "unused112", + "unused113", + "unused114", + "unused115", + "unused116", + "unused117", + "unused118", + "unused119", + "unused120", + "unused121", + "unused122", + "unused123", + "unused124", + "unused125", + "unused126", + "unused127", + "unused128", + "unused129", + "unused130", + "unused131", + "unused132", + "unused133", + "unused134", + "unused135", + "unused136", + "unused137", + "unused138", + "unused139", + "unused140", + "unused141", + "unused142", + "unused143", + "unused144", + "unused145", + "unused146", + "unused147", + "unused148", + "unused149", + "unused150", + "unused151", + "unused152", + "unused153", + "unused154", + "unused155", + "unused156", + "unused157", + "unused158", + "unused159", + "unused160", + "unused161", + "unused162", + "unused163", + "unused164", + "unused165", + "unused166", + "unused167", + "unused168", + "unused169", + "unused170", + "unused171", + "unused172", + "unused173", + "unused174", + "unused175", + "unused176", + "unused177", + "unused178", + "unused179", + "unused180", + "unused181", + "unused182", + "unused183", + "unused184", + "unused185", + "unused186", + "unused187", + "unused188", + "unused189", + "unused190", + "unused191", + "unused192", + "unused193", + "unused194", + "unused195", + "unused196", + "unused197", + "unused198", + "unused199", + "unused200", + "unused201", + "unused202", + "unused203", + "unused204", + "unused205", + "unused206", + "unused207", + "unused208", + "unused209", + "unused210", + "unused211", + "unused212", + "unused213", + "unused214", + "unused215", + "unused216", + "unused217", + "unused218", + "unused219", + "unused220", + "unused221", + "unused222", + "unused223", + "unused224", + "unused225", + "unused226", + "unused227", + "unused228", + "unused229", + "unused230", + "unused231", + "unused232", + "unused233", + "unused234", + "unused235", + "unused236", + "unused237", + "unused238", + "unused239", + "unused240", + "unused241", + "unused242", + "unused243", + "unused244", + "unused245", + "unused246", + "unused247", + "unused248", + "unused249", + "unused250", + "unused251", + "unused252", + "unused253", + "unused254", + "unused255" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ], + "description" : "You need 'VM.Config.Disk' permissions on /vms/{vmid}, and 'Datastore.AllocateSpace' permissions on the storage. To move a volume to another container, you need the permissions on the target container as well." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/move_volume", + "text" : "move_volume" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get container configuration, including pending changes.", + "method" : "GET", + "name" : "vm_pending", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "delete" : { + "description" : "Indicates a pending delete request if present and not 0.", + "maximum" : 2, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "key" : { + "description" : "Configuration option name.", + "type" : "string" + }, + "pending" : { + "description" : "Pending value.", + "optional" : 1, + "type" : "string" + }, + "value" : { + "description" : "Current value.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/pending", + "text" : "pending" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migration tunnel endpoint - only for internal use by CT migration.", + "method" : "POST", + "name" : "mtunnel", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bridges" : { + "description" : "List of network bridges to check availability. Will be checked again for actually used bridges during migration.", + "format" : "pve-bridge-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storages" : { + "description" : "List of storages to check permission and availability. Will be checked again for all actually used storages during migration.", + "format" : "pve-storage-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + [ + "perm", + "/", + [ + "Sys.Incoming" + ] + ] + ], + "description" : "You need 'VM.Allocate' permissions on '/vms/{vmid}' and Sys.Incoming on '/'. Further permission checks happen during the actual migration." + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "socket" : { + "type" : "string" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/mtunnel", + "text" : "mtunnel" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration.", + "method" : "GET", + "name" : "mtunnelwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "socket" : { + "description" : "unix socket to forward to", + "type" : "string", + "typetext" : "" + }, + "ticket" : { + "description" : "ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "description" : "You need to pass a ticket valid for the selected socket. Tickets can be created via the mtunnel API call, which will check permissions accordingly.", + "user" : "all" + }, + "returns" : { + "properties" : { + "port" : { + "optional" : 1, + "type" : "string" + }, + "socket" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/mtunnelwebsocket", + "text" : "mtunnelwebsocket" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy the container (also delete all uses files).", + "method" : "DELETE", + "name" : "destroy_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "destroy-unreferenced-disks" : { + "description" : "If set, destroy additionally all disks with the VMID from all enabled storages which are not referenced in the config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "force" : { + "default" : 0, + "description" : "Force destroy, even if running.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "purge" : { + "default" : 0, + "description" : "Remove container from all related configurations. For example, backup jobs, replication jobs or HA. Related ACLs and Firewall entries will *always* be removed.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "vmdiridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}", + "text" : "{vmid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "LXC container index (per node).", + "method" : "GET", + "name" : "vmlist", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list CTs where you have VM.Audit permissons on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "cpus" : { + "description" : "Maximum usable CPUs.", + "optional" : 1, + "type" : "number" + }, + "lock" : { + "description" : "The current config lock, if any.", + "optional" : 1, + "type" : "string" + }, + "maxdisk" : { + "description" : "Root disk size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Maximum memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxswap" : { + "description" : "Maximum SWAP memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "Container name.", + "optional" : 1, + "type" : "string" + }, + "status" : { + "description" : "LXC Container status.", + "enum" : [ + "stopped", + "running" + ], + "type" : "string" + }, + "tags" : { + "description" : "The current configured tags, if any.", + "optional" : 1, + "type" : "string" + }, + "uptime" : { + "description" : "Uptime.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{vmid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create or restore a container.", + "method" : "POST", + "name" : "create_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "arch" : { + "default" : "amd64", + "description" : "OS architecture type.", + "enum" : [ + "amd64", + "i386", + "arm64", + "armhf", + "riscv32", + "riscv64" + ], + "optional" : 1, + "type" : "string" + }, + "bwlimit" : { + "default" : "restore limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "cmode" : { + "default" : "tty", + "description" : "Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).", + "enum" : [ + "shell", + "console", + "tty" + ], + "optional" : 1, + "type" : "string" + }, + "console" : { + "default" : 1, + "description" : "Attach a console device (/dev/console) to the container.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cores" : { + "description" : "The number of cores assigned to the container. A container can use all available cores by default.", + "maximum" : 8192, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 8192)" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.", + "maximum" : 8192, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 8192)" + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 500000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 500000)", + "verbose_description" : "CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests." + }, + "debug" : { + "default" : 0, + "description" : "Try to be more verbose. For now this only enables debug log-level on start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "description" : { + "description" : "Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "features" : { + "description" : "Allow containers access to advanced features.", + "format" : { + "force_rw_sys" : { + "default" : 0, + "description" : "Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.", + "optional" : 1, + "type" : "boolean" + }, + "fuse" : { + "default" : 0, + "description" : "Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.", + "optional" : 1, + "type" : "boolean" + }, + "keyctl" : { + "default" : 0, + "description" : "For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.", + "optional" : 1, + "type" : "boolean" + }, + "mknod" : { + "default" : 0, + "description" : "Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.", + "optional" : 1, + "type" : "boolean" + }, + "mount" : { + "description" : "Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.", + "format_description" : "fstype;fstype;...", + "optional" : 1, + "pattern" : "(?^:[a-zA-Z0-9_; ]+)", + "type" : "string" + }, + "nesting" : { + "default" : 0, + "description" : "Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[force_rw_sys=<1|0>] [,fuse=<1|0>] [,keyctl=<1|0>] [,mknod=<1|0>] [,mount=] [,nesting=<1|0>]" + }, + "force" : { + "description" : "Allow to overwrite existing container.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hookscript" : { + "description" : "Script that will be exectued during various steps in the containers lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostname" : { + "description" : "Set a host name for the container.", + "format" : "dns-name", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ignore-unpack-errors" : { + "description" : "Ignore errors when extracting the template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the container.", + "enum" : [ + "backup", + "create", + "destroyed", + "disk", + "fstrim", + "migrate", + "mounted", + "rollback", + "snapshot", + "snapshot-delete" + ], + "optional" : 1, + "type" : "string" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the container in MB.", + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - N)" + }, + "mp[n]" : { + "description" : "Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "backup" : { + "description" : "Whether to include the mount point in backups.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Whether to include the mount point in backups (only used for volume mount points)." + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(noatime|lazytime|nodev|nosuid|noexec))(;(?^:(noatime|lazytime|nodev|nosuid|noexec)))*)", + "type" : "string" + }, + "mp" : { + "description" : "Path to the mount point as seen from inside the container (must not contain symlinks).", + "format" : "pve-lxc-mp-string", + "format_description" : "Path", + "type" : "string", + "verbose_description" : "Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons." + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=] ,mp= [,acl=<1|0>] [,backup=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]" + }, + "nameserver" : { + "description" : "Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "lxc-ip-with-ll-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specifies network interfaces for the container.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to.", + "format_description" : "bridge", + "optional" : 1, + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "firewall" : { + "description" : "Controls whether this interface's firewall rules should be used.", + "optional" : 1, + "type" : "boolean" + }, + "gw" : { + "description" : "Default gateway for IPv4 traffic.", + "format" : "ipv4", + "format_description" : "GatewayIPv4", + "optional" : 1, + "type" : "string" + }, + "gw6" : { + "description" : "Default gateway for IPv6 traffic.", + "format" : "ipv6", + "format_description" : "GatewayIPv6", + "optional" : 1, + "type" : "string" + }, + "hwaddr" : { + "description" : "The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "ip" : { + "description" : "IPv4 address in CIDR format.", + "format" : "pve-ipv4-config", + "format_description" : "(IPv4/CIDR|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address in CIDR format.", + "format" : "pve-ipv6-config", + "format_description" : "(IPv6/CIDR|auto|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "mtu" : { + "description" : "Maximum transfer unit of the interface. (lxc.network.mtu)", + "maximum" : 65535, + "minimum" : 64, + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "Name of the network device as seen from inside the container. (lxc.network.name)", + "format_description" : "string", + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "rate" : { + "description" : "Apply rate limiting to the interface", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "tag" : { + "description" : "VLAN tag for this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN ids to pass through the interface", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:;\\d+)*)", + "type" : "string" + }, + "type" : { + "description" : "Network interface type.", + "enum" : [ + "veth" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "name= [,bridge=] [,firewall=<1|0>] [,gw=] [,gw6=] [,hwaddr=] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=<(IPv6/CIDR|auto|dhcp|manual)>] [,link_down=<1|0>] [,mtu=] [,rate=] [,tag=] [,trunks=] [,type=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a container will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostemplate" : { + "description" : "The OS template or backup file.", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + }, + "ostype" : { + "description" : "OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.", + "enum" : [ + "debian", + "devuan", + "ubuntu", + "centos", + "fedora", + "opensuse", + "archlinux", + "alpine", + "gentoo", + "nixos", + "unmanaged" + ], + "optional" : 1, + "type" : "string" + }, + "password" : { + "description" : "Sets root password inside container.", + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Add the VM to the specified pool.", + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restore" : { + "description" : "Mark this as restore task.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "rootfs" : { + "description" : "Use volume as container root.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(noatime|lazytime|nodev|nosuid|noexec))(;(?^:(noatime|lazytime|nodev|nosuid|noexec)))*)", + "type" : "string" + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=] [,acl=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]" + }, + "searchdomain" : { + "description" : "Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "dns-name-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ssh-public-keys" : { + "description" : "Setup public SSH keys (one key per line, OpenSSH format).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Start the CT after its creation finished successfully.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "storage" : { + "default" : "local", + "description" : "Default Storage.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "swap" : { + "default" : 512, + "description" : "Amount of SWAP for the container in MB.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "tags" : { + "description" : "Tags of the Container. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "timezone" : { + "description" : "Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab", + "format" : "pve-ct-timezone", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tty" : { + "default" : 2, + "description" : "Specify the number of tty available to the container", + "maximum" : 6, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 6)" + }, + "unique" : { + "description" : "Assign a unique random ethernet address.", + "optional" : 1, + "requires" : "restore", + "type" : "boolean", + "typetext" : "" + }, + "unprivileged" : { + "default" : 0, + "description" : "Makes the container run as unprivileged user. (Should not be modified manually.)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "volume" : { + "default_key" : 1, + "description" : "The volume that is not used currently.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=]" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "description" : "You need 'VM.Allocate' permissions on /vms/{vmid} or on the VM pool /pool/{pool}. For restore, it is enough if the user has 'VM.Backup' permission and the VM already exists. You also need 'Datastore.AllocateSpace' permissions on the storage.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc", + "text" : "lxc" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the Ceph configuration file.", + "method" : "GET", + "name" : "raw", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/cfg/raw", + "text" : "raw" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the Ceph configuration database.", + "method" : "GET", + "name" : "db", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "can_update_at_runtime" : { + "type" : "boolean" + }, + "level" : { + "type" : "string" + }, + "mask" : { + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "section" : { + "type" : "string" + }, + "value" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/cfg/db", + "text" : "db" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/cfg", + "text" : "cfg" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get OSD details", + "method" : "GET", + "name" : "osddetails", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "devices" : { + "description" : "Array containing data about devices", + "items" : { + "properties" : { + "dev_node" : { + "description" : "Device node", + "type" : "string" + }, + "device" : { + "description" : "Kind of OSD device", + "enum" : [ + "block", + "db", + "wal" + ], + "type" : "string" + }, + "devices" : { + "description" : "Physical disks used", + "type" : "string" + }, + "size" : { + "description" : "Size in bytes", + "type" : "integer" + }, + "support_discard" : { + "description" : "Discard support of the physical device", + "type" : "boolean" + }, + "type" : { + "description" : "Type of device. For example, hdd or ssd", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "osd" : { + "description" : "General information about the OSD", + "properties" : { + "back_addr" : { + "description" : "Address and port used to talk to other OSDs.", + "type" : "string" + }, + "front_addr" : { + "description" : "Address and port used to talk to clients and monitors.", + "type" : "string" + }, + "hb_back_addr" : { + "description" : "Heartbeat address and port for other OSDs.", + "type" : "string" + }, + "hb_front_addr" : { + "description" : "Heartbeat address and port for clients and monitors.", + "type" : "string" + }, + "hostname" : { + "description" : "Name of the host containing the OSD.", + "type" : "string" + }, + "id" : { + "description" : "ID of the OSD.", + "type" : "integer" + }, + "mem_usage" : { + "description" : "Memory usage of the OSD service.", + "type" : "integer" + }, + "osd_data" : { + "description" : "Path to the OSD's data directory.", + "type" : "string" + }, + "osd_objectstore" : { + "description" : "The type of object store used.", + "type" : "string" + }, + "pid" : { + "description" : "OSD process ID.", + "type" : "integer" + }, + "version" : { + "description" : "Ceph version of the OSD service.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/metadata", + "text" : "metadata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get OSD volume details", + "method" : "GET", + "name" : "osdvolume", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + }, + "type" : { + "default" : "block", + "description" : "OSD device type", + "enum" : [ + "block", + "db", + "wal" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "creation_time" : { + "description" : "Creation time as reported by `lvs`.", + "type" : "string" + }, + "lv_name" : { + "description" : "Name of the logical volume (LV).", + "type" : "string" + }, + "lv_path" : { + "description" : "Path to the logical volume (LV).", + "type" : "string" + }, + "lv_size" : { + "description" : "Size of the logical volume (LV).", + "type" : "integer" + }, + "lv_uuid" : { + "description" : "UUID of the logical volume (LV).", + "type" : "string" + }, + "vg_name" : { + "description" : "Name of the volume group (VG).", + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/lv-info", + "text" : "lv-info" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "ceph osd in", + "method" : "POST", + "name" : "in", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/in", + "text" : "in" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "ceph osd out", + "method" : "POST", + "name" : "out", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/out", + "text" : "out" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Instruct the OSD to scrub.", + "method" : "POST", + "name" : "scrub", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "deep" : { + "default" : 0, + "description" : "If set, instructs a deep scrub instead of a normal one.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/scrub", + "text" : "scrub" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy OSD", + "method" : "DELETE", + "name" : "destroyosd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cleanup" : { + "default" : 0, + "description" : "If set, we remove partition table entries.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "OSD index.", + "method" : "GET", + "name" : "osdindex", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/osd/{osdid}", + "text" : "{osdid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Ceph osd list/tree.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "flags" : { + "type" : "string" + }, + "root" : { + "description" : "Tree with OSDs in the CRUSH map structure.", + "type" : "object" + } + }, + "type" : "object" + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create OSD", + "method" : "POST", + "name" : "createosd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "crush-device-class" : { + "description" : "Set the device class of the OSD in crush.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "db_dev" : { + "description" : "Block device name for block.db.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "db_dev_size" : { + "default" : "bluestore_block_db_size or 10% of OSD size", + "description" : "Size in GiB for block.db.", + "minimum" : 1, + "optional" : 1, + "requires" : "db_dev", + "type" : "number", + "typetext" : " (1 - N)", + "verbose_description" : "If a block.db is requested but the size is not given, will be automatically selected by: bluestore_block_db_size from the ceph database (osd or global section) or config (osd or global section)in that order. If this is not available, it will be sized 10% of the size of the OSD device. Fails if the available size is not enough." + }, + "dev" : { + "description" : "Block device name.", + "type" : "string", + "typetext" : "" + }, + "encrypted" : { + "default" : 0, + "description" : "Enables encryption of the OSD.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "wal_dev" : { + "description" : "Block device name for block.wal.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "wal_dev_size" : { + "default" : "bluestore_block_wal_size or 1% of OSD size", + "description" : "Size in GiB for block.wal.", + "minimum" : 0.5, + "optional" : 1, + "requires" : "wal_dev", + "type" : "number", + "typetext" : " (0.5 - N)", + "verbose_description" : "If a block.wal is requested but the size is not given, will be automatically selected by: bluestore_block_wal_size from the ceph database (osd or global section) or config (osd or global section)in that order. If this is not available, it will be sized 1% of the size of the OSD device. Fails if the available size is not enough." + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/osd", + "text" : "osd" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy Ceph Metadata Server", + "method" : "DELETE", + "name" : "destroymds", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The name (ID) of the mds", + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Ceph Metadata Server (MDS)", + "method" : "POST", + "name" : "createmds", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "hotstandby" : { + "default" : "0", + "description" : "Determines whether a ceph-mds daemon should poll and replay the log of an active MDS. Faster switch on MDS failure, but needs more idle resources.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "default" : "nodename", + "description" : "The ID for the mds, when omitted the same as the nodename", + "maxLength" : 200, + "optional" : 1, + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/mds/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "MDS directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "addr" : { + "optional" : 1, + "type" : "string" + }, + "host" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name (ID) for the MDS" + }, + "rank" : { + "optional" : 1, + "type" : "integer" + }, + "standby_replay" : { + "description" : "If true, the standby MDS is polling the active MDS for faster recovery (hot standby).", + "optional" : 1, + "type" : "boolean" + }, + "state" : { + "description" : "State of the MDS", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/mds", + "text" : "mds" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy Ceph Manager.", + "method" : "DELETE", + "name" : "destroymgr", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The ID of the manager", + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Ceph Manager", + "method" : "POST", + "name" : "createmgr", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The ID for the manager, when omitted the same as the nodename", + "maxLength" : 200, + "optional" : 1, + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/mgr/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "MGR directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "addr" : { + "optional" : 1, + "type" : "string" + }, + "host" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name (ID) for the MGR" + }, + "state" : { + "description" : "State of the MGR", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/mgr", + "text" : "mgr" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy Ceph Monitor and Manager.", + "method" : "DELETE", + "name" : "destroymon", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "monid" : { + "description" : "Monitor ID", + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Ceph Monitor and Manager", + "method" : "POST", + "name" : "createmon", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "mon-address" : { + "description" : "Overwrites autodetected monitor IP address(es). Must be in the public network(s) of Ceph.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "monid" : { + "description" : "The ID for the monitor, when omitted the same as the nodename", + "maxLength" : 200, + "optional" : 1, + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/mon/{monid}", + "text" : "{monid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Ceph monitor list.", + "method" : "GET", + "name" : "listmon", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "addr" : { + "optional" : 1, + "type" : "string" + }, + "ceph_version" : { + "optional" : 1, + "type" : "string" + }, + "ceph_version_short" : { + "optional" : 1, + "type" : "string" + }, + "direxists" : { + "optional" : 1, + "type" : "string" + }, + "host" : { + "optional" : 1, + "type" : "boolean" + }, + "name" : { + "type" : "string" + }, + "quorum" : { + "optional" : 1, + "type" : "boolean" + }, + "rank" : { + "optional" : 1, + "type" : "integer" + }, + "service" : { + "optional" : 1, + "type" : "integer" + }, + "state" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/mon", + "text" : "mon" + }, + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a Ceph filesystem", + "method" : "POST", + "name" : "createfs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add-storage" : { + "default" : 0, + "description" : "Configure the created CephFS as storage for this cluster.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "default" : "cephfs", + "description" : "The ceph filesystem name.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_num" : { + "default" : 128, + "description" : "Number of placement groups for the backing data pool. The metadata pool will use a quarter of this.", + "maximum" : 32768, + "minimum" : 8, + "optional" : 1, + "type" : "integer", + "typetext" : " (8 - 32768)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/fs/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "data_pool" : { + "description" : "The name of the data pool.", + "type" : "string" + }, + "metadata_pool" : { + "description" : "The name of the metadata pool.", + "type" : "string" + }, + "name" : { + "description" : "The ceph filesystem name.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/fs", + "text" : "fs" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Show the current pool status.", + "method" : "GET", + "name" : "getpool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The name of the pool. It must be unique.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "verbose" : { + "default" : 0, + "description" : "If enabled, will display additional data(eg. statistics).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "application" : { + "default" : "rbd", + "description" : "The application of the pool.", + "enum" : [ + "rbd", + "cephfs", + "rgw" + ], + "optional" : 1, + "title" : "Application", + "type" : "string" + }, + "application_list" : { + "optional" : 1, + "title" : "Application", + "type" : "array" + }, + "autoscale_status" : { + "optional" : 1, + "title" : "Autoscale Status", + "type" : "object" + }, + "crush_rule" : { + "description" : "The rule to use for mapping object placement in the cluster.", + "optional" : 1, + "title" : "Crush Rule Name", + "type" : "string" + }, + "fast_read" : { + "title" : "Fast Read", + "type" : "boolean" + }, + "hashpspool" : { + "title" : "hashpspool", + "type" : "boolean" + }, + "id" : { + "title" : "ID", + "type" : "integer" + }, + "min_size" : { + "default" : 2, + "description" : "Minimum number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Min Size", + "type" : "integer" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "title" : "Name", + "type" : "string" + }, + "nodeep-scrub" : { + "title" : "nodeep-scrub", + "type" : "boolean" + }, + "nodelete" : { + "title" : "nodelete", + "type" : "boolean" + }, + "nopgchange" : { + "title" : "nopgchange", + "type" : "boolean" + }, + "noscrub" : { + "title" : "noscrub", + "type" : "boolean" + }, + "nosizechange" : { + "title" : "nosizechange", + "type" : "boolean" + }, + "pg_autoscale_mode" : { + "default" : "warn", + "description" : "The automatic PG scaling mode of the pool.", + "enum" : [ + "on", + "off", + "warn" + ], + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "default" : 128, + "description" : "Number of placement groups.", + "maximum" : 32768, + "minimum" : 1, + "optional" : 1, + "title" : "PG Num", + "type" : "integer" + }, + "pg_num_min" : { + "description" : "Minimal number of placement groups.", + "maximum" : 32768, + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer" + }, + "pgp_num" : { + "title" : "PGP num", + "type" : "integer" + }, + "size" : { + "default" : 3, + "description" : "Number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Size", + "type" : "integer" + }, + "statistics" : { + "optional" : 1, + "title" : "Statistics", + "type" : "object" + }, + "target_size" : { + "description" : "The estimated target size of the pool for the PG autoscaler.", + "optional" : 1, + "pattern" : "^(\\d+(\\.\\d+)?)([KMGT])?$", + "title" : "PG Autoscale Target Size", + "type" : "string" + }, + "target_size_ratio" : { + "description" : "The estimated target ratio of the pool for the PG autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number" + }, + "use_gmt_hitset" : { + "title" : "use_gmt_hitset", + "type" : "boolean" + }, + "write_fadvise_dontneed" : { + "title" : "write_fadvise_dontneed", + "type" : "boolean" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/pool/{name}/status", + "text" : "status" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy pool", + "method" : "DELETE", + "name" : "destroypool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "If true, destroys pool even if in use", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "remove_ecprofile" : { + "default" : 1, + "description" : "Remove the erasure code profile. Defaults to true, if applicable.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove_storages" : { + "default" : 0, + "description" : "Remove all pveceph-managed storages configured for this pool", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Pool index.", + "method" : "GET", + "name" : "poolindex", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The name of the pool.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Change POOL settings", + "method" : "PUT", + "name" : "setpool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "application" : { + "description" : "The application of the pool.", + "enum" : [ + "rbd", + "cephfs", + "rgw" + ], + "optional" : 1, + "title" : "Application", + "type" : "string" + }, + "crush_rule" : { + "description" : "The rule to use for mapping object placement in the cluster.", + "optional" : 1, + "title" : "Crush Rule Name", + "type" : "string", + "typetext" : "" + }, + "min_size" : { + "description" : "Minimum number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Min Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "title" : "Name", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_autoscale_mode" : { + "description" : "The automatic PG scaling mode of the pool.", + "enum" : [ + "on", + "off", + "warn" + ], + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "description" : "Number of placement groups.", + "maximum" : 32768, + "minimum" : 1, + "optional" : 1, + "title" : "PG Num", + "type" : "integer", + "typetext" : " (1 - 32768)" + }, + "pg_num_min" : { + "description" : "Minimal number of placement groups.", + "maximum" : 32768, + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer", + "typetext" : " (-N - 32768)" + }, + "size" : { + "description" : "Number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "target_size" : { + "description" : "The estimated target size of the pool for the PG autoscaler.", + "optional" : 1, + "pattern" : "^(\\d+(\\.\\d+)?)([KMGT])?$", + "title" : "PG Autoscale Target Size", + "type" : "string" + }, + "target_size_ratio" : { + "description" : "The estimated target ratio of the pool for the PG autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/pool/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all pools and their settings (which are settable by the POST/PUT endpoints).", + "method" : "GET", + "name" : "lspools", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "application_metadata" : { + "optional" : 1, + "title" : "Associated Applications", + "type" : "object" + }, + "autoscale_status" : { + "optional" : 1, + "title" : "Autoscale Status", + "type" : "object" + }, + "bytes_used" : { + "title" : "Used", + "type" : "integer" + }, + "crush_rule" : { + "title" : "Crush Rule", + "type" : "integer" + }, + "crush_rule_name" : { + "title" : "Crush Rule Name", + "type" : "string" + }, + "min_size" : { + "title" : "Min Size", + "type" : "integer" + }, + "percent_used" : { + "title" : "%-Used", + "type" : "number" + }, + "pg_autoscale_mode" : { + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "title" : "PG Num", + "type" : "integer" + }, + "pg_num_final" : { + "optional" : 1, + "title" : "Optimal PG Num", + "type" : "integer" + }, + "pg_num_min" : { + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer" + }, + "pool" : { + "title" : "ID", + "type" : "integer" + }, + "pool_name" : { + "title" : "Name", + "type" : "string" + }, + "size" : { + "title" : "Size", + "type" : "integer" + }, + "target_size" : { + "optional" : 1, + "title" : "PG Autoscale Target Size", + "type" : "integer" + }, + "target_size_ratio" : { + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number" + }, + "type" : { + "enum" : [ + "replicated", + "erasure", + "unknown" + ], + "title" : "Type", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pool_name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Ceph pool", + "method" : "POST", + "name" : "createpool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storages" : { + "default" : "0; for erasure coded pools: 1", + "description" : "Configure VM and CT storage using the new pool.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "application" : { + "default" : "rbd", + "description" : "The application of the pool.", + "enum" : [ + "rbd", + "cephfs", + "rgw" + ], + "optional" : 1, + "title" : "Application", + "type" : "string" + }, + "crush_rule" : { + "description" : "The rule to use for mapping object placement in the cluster.", + "optional" : 1, + "title" : "Crush Rule Name", + "type" : "string", + "typetext" : "" + }, + "erasure-coding" : { + "description" : "Create an erasure coded pool for RBD with an accompaning replicated pool for metadata storage. With EC, the common ceph options 'size', 'min_size' and 'crush_rule' parameters will be applied to the metadata pool.", + "format" : { + "device-class" : { + "description" : "CRUSH device class. Will create an erasure coded pool plus a replicated pool for metadata.", + "format_description" : "class", + "optional" : 1, + "type" : "string" + }, + "failure-domain" : { + "default" : "host", + "description" : "CRUSH failure domain. Default is 'host'. Will create an erasure coded pool plus a replicated pool for metadata.", + "format_description" : "domain", + "optional" : 1, + "type" : "string" + }, + "k" : { + "description" : "Number of data chunks. Will create an erasure coded pool plus a replicated pool for metadata.", + "minimum" : 2, + "type" : "integer" + }, + "m" : { + "description" : "Number of coding chunks. Will create an erasure coded pool plus a replicated pool for metadata.", + "minimum" : 1, + "type" : "integer" + }, + "profile" : { + "description" : "Override the erasure code (EC) profile to use. Will create an erasure coded pool plus a replicated pool for metadata.", + "format_description" : "profile", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "k= ,m= [,device-class=] [,failure-domain=] [,profile=]" + }, + "min_size" : { + "default" : 2, + "description" : "Minimum number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Min Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "title" : "Name", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_autoscale_mode" : { + "default" : "warn", + "description" : "The automatic PG scaling mode of the pool.", + "enum" : [ + "on", + "off", + "warn" + ], + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "default" : 128, + "description" : "Number of placement groups.", + "maximum" : 32768, + "minimum" : 1, + "optional" : 1, + "title" : "PG Num", + "type" : "integer", + "typetext" : " (1 - 32768)" + }, + "pg_num_min" : { + "description" : "Minimal number of placement groups.", + "maximum" : 32768, + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer", + "typetext" : " (-N - 32768)" + }, + "size" : { + "default" : 3, + "description" : "Number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "target_size" : { + "description" : "The estimated target size of the pool for the PG autoscaler.", + "optional" : 1, + "pattern" : "^(\\d+(\\.\\d+)?)([KMGT])?$", + "title" : "PG Autoscale Target Size", + "type" : "string" + }, + "target_size_ratio" : { + "description" : "The estimated target ratio of the pool for the PG autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/pool", + "text" : "pool" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy pool. Deprecated, please use `/nodes/{node}/ceph/pool/{name}`.", + "method" : "DELETE", + "name" : "destroypool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "If true, destroys pool even if in use", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "remove_ecprofile" : { + "default" : 1, + "description" : "Remove the erasure code profile. Defaults to true, if applicable.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove_storages" : { + "default" : 0, + "description" : "Remove all pveceph-managed storages configured for this pool", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List pool settings. Deprecated, please use `/nodes/{node}/ceph/pool/{pool}/status`.", + "method" : "GET", + "name" : "getpool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The name of the pool. It must be unique.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "verbose" : { + "default" : 0, + "description" : "If enabled, will display additional data(eg. statistics).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "application" : { + "default" : "rbd", + "description" : "The application of the pool.", + "enum" : [ + "rbd", + "cephfs", + "rgw" + ], + "optional" : 1, + "title" : "Application", + "type" : "string" + }, + "application_list" : { + "optional" : 1, + "title" : "Application", + "type" : "array" + }, + "autoscale_status" : { + "optional" : 1, + "title" : "Autoscale Status", + "type" : "object" + }, + "crush_rule" : { + "description" : "The rule to use for mapping object placement in the cluster.", + "optional" : 1, + "title" : "Crush Rule Name", + "type" : "string" + }, + "fast_read" : { + "title" : "Fast Read", + "type" : "boolean" + }, + "hashpspool" : { + "title" : "hashpspool", + "type" : "boolean" + }, + "id" : { + "title" : "ID", + "type" : "integer" + }, + "min_size" : { + "default" : 2, + "description" : "Minimum number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Min Size", + "type" : "integer" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "title" : "Name", + "type" : "string" + }, + "nodeep-scrub" : { + "title" : "nodeep-scrub", + "type" : "boolean" + }, + "nodelete" : { + "title" : "nodelete", + "type" : "boolean" + }, + "nopgchange" : { + "title" : "nopgchange", + "type" : "boolean" + }, + "noscrub" : { + "title" : "noscrub", + "type" : "boolean" + }, + "nosizechange" : { + "title" : "nosizechange", + "type" : "boolean" + }, + "pg_autoscale_mode" : { + "default" : "warn", + "description" : "The automatic PG scaling mode of the pool.", + "enum" : [ + "on", + "off", + "warn" + ], + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "default" : 128, + "description" : "Number of placement groups.", + "maximum" : 32768, + "minimum" : 1, + "optional" : 1, + "title" : "PG Num", + "type" : "integer" + }, + "pg_num_min" : { + "description" : "Minimal number of placement groups.", + "maximum" : 32768, + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer" + }, + "pgp_num" : { + "title" : "PGP num", + "type" : "integer" + }, + "size" : { + "default" : 3, + "description" : "Number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Size", + "type" : "integer" + }, + "statistics" : { + "optional" : 1, + "title" : "Statistics", + "type" : "object" + }, + "target_size" : { + "description" : "The estimated target size of the pool for the PG autoscaler.", + "optional" : 1, + "pattern" : "^(\\d+(\\.\\d+)?)([KMGT])?$", + "title" : "PG Autoscale Target Size", + "type" : "string" + }, + "target_size_ratio" : { + "description" : "The estimated target ratio of the pool for the PG autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number" + }, + "use_gmt_hitset" : { + "title" : "use_gmt_hitset", + "type" : "boolean" + }, + "write_fadvise_dontneed" : { + "title" : "write_fadvise_dontneed", + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Change POOL settings. Deprecated, please use `/nodes/{node}/ceph/pool/{name}`.", + "method" : "PUT", + "name" : "setpool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "application" : { + "description" : "The application of the pool.", + "enum" : [ + "rbd", + "cephfs", + "rgw" + ], + "optional" : 1, + "title" : "Application", + "type" : "string" + }, + "crush_rule" : { + "description" : "The rule to use for mapping object placement in the cluster.", + "optional" : 1, + "title" : "Crush Rule Name", + "type" : "string", + "typetext" : "" + }, + "min_size" : { + "description" : "Minimum number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Min Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "title" : "Name", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_autoscale_mode" : { + "description" : "The automatic PG scaling mode of the pool.", + "enum" : [ + "on", + "off", + "warn" + ], + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "description" : "Number of placement groups.", + "maximum" : 32768, + "minimum" : 1, + "optional" : 1, + "title" : "PG Num", + "type" : "integer", + "typetext" : " (1 - 32768)" + }, + "pg_num_min" : { + "description" : "Minimal number of placement groups.", + "maximum" : 32768, + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer", + "typetext" : " (-N - 32768)" + }, + "size" : { + "description" : "Number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "target_size" : { + "description" : "The estimated target size of the pool for the PG autoscaler.", + "optional" : 1, + "pattern" : "^(\\d+(\\.\\d+)?)([KMGT])?$", + "title" : "PG Autoscale Target Size", + "type" : "string" + }, + "target_size_ratio" : { + "description" : "The estimated target ratio of the pool for the PG autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/pools/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all pools. Deprecated, please use `/nodes/{node}/ceph/pool`.", + "method" : "GET", + "name" : "lspools", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "application_metadata" : { + "optional" : 1, + "title" : "Associated Applications", + "type" : "object" + }, + "autoscale_status" : { + "optional" : 1, + "title" : "Autoscale Status", + "type" : "object" + }, + "bytes_used" : { + "title" : "Used", + "type" : "integer" + }, + "crush_rule" : { + "title" : "Crush Rule", + "type" : "integer" + }, + "crush_rule_name" : { + "title" : "Crush Rule Name", + "type" : "string" + }, + "min_size" : { + "title" : "Min Size", + "type" : "integer" + }, + "percent_used" : { + "title" : "%-Used", + "type" : "number" + }, + "pg_autoscale_mode" : { + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "title" : "PG Num", + "type" : "integer" + }, + "pg_num_final" : { + "optional" : 1, + "title" : "Optimal PG Num", + "type" : "integer" + }, + "pg_num_min" : { + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer" + }, + "pool" : { + "title" : "ID", + "type" : "integer" + }, + "pool_name" : { + "title" : "Name", + "type" : "string" + }, + "size" : { + "title" : "Size", + "type" : "integer" + }, + "target_size" : { + "optional" : 1, + "title" : "PG Autoscale Target Size", + "type" : "integer" + }, + "target_size_ratio" : { + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number" + }, + "type" : { + "enum" : [ + "replicated", + "erasure", + "unknown" + ], + "title" : "Type", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pool_name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Ceph pool. Deprecated, please use `/nodes/{node}/ceph/pool`.", + "method" : "POST", + "name" : "createpool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storages" : { + "default" : "0; for erasure coded pools: 1", + "description" : "Configure VM and CT storage using the new pool.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "application" : { + "default" : "rbd", + "description" : "The application of the pool.", + "enum" : [ + "rbd", + "cephfs", + "rgw" + ], + "optional" : 1, + "title" : "Application", + "type" : "string" + }, + "crush_rule" : { + "description" : "The rule to use for mapping object placement in the cluster.", + "optional" : 1, + "title" : "Crush Rule Name", + "type" : "string", + "typetext" : "" + }, + "erasure-coding" : { + "description" : "Create an erasure coded pool for RBD with an accompaning replicated pool for metadata storage. With EC, the common ceph options 'size', 'min_size' and 'crush_rule' parameters will be applied to the metadata pool.", + "format" : { + "device-class" : { + "description" : "CRUSH device class. Will create an erasure coded pool plus a replicated pool for metadata.", + "format_description" : "class", + "optional" : 1, + "type" : "string" + }, + "failure-domain" : { + "default" : "host", + "description" : "CRUSH failure domain. Default is 'host'. Will create an erasure coded pool plus a replicated pool for metadata.", + "format_description" : "domain", + "optional" : 1, + "type" : "string" + }, + "k" : { + "description" : "Number of data chunks. Will create an erasure coded pool plus a replicated pool for metadata.", + "minimum" : 2, + "type" : "integer" + }, + "m" : { + "description" : "Number of coding chunks. Will create an erasure coded pool plus a replicated pool for metadata.", + "minimum" : 1, + "type" : "integer" + }, + "profile" : { + "description" : "Override the erasure code (EC) profile to use. Will create an erasure coded pool plus a replicated pool for metadata.", + "format_description" : "profile", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "k= ,m= [,device-class=] [,failure-domain=] [,profile=]" + }, + "min_size" : { + "default" : 2, + "description" : "Minimum number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Min Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "title" : "Name", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_autoscale_mode" : { + "default" : "warn", + "description" : "The automatic PG scaling mode of the pool.", + "enum" : [ + "on", + "off", + "warn" + ], + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "default" : 128, + "description" : "Number of placement groups.", + "maximum" : 32768, + "minimum" : 1, + "optional" : 1, + "title" : "PG Num", + "type" : "integer", + "typetext" : " (1 - 32768)" + }, + "pg_num_min" : { + "description" : "Minimal number of placement groups.", + "maximum" : 32768, + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer", + "typetext" : " (-N - 32768)" + }, + "size" : { + "default" : 3, + "description" : "Number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "target_size" : { + "description" : "The estimated target size of the pool for the PG autoscaler.", + "optional" : 1, + "pattern" : "^(\\d+(\\.\\d+)?)([KMGT])?$", + "title" : "PG Autoscale Target Size", + "type" : "string" + }, + "target_size_ratio" : { + "description" : "The estimated target ratio of the pool for the PG autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/pools", + "text" : "pools" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the Ceph configuration file. Deprecated, please use `/nodes/{node}/ceph/cfg/raw.", + "method" : "GET", + "name" : "config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/config", + "text" : "config" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the Ceph configuration database. Deprecated, please use `/nodes/{node}/ceph/cfg/db.", + "method" : "GET", + "name" : "configdb", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "can_update_at_runtime" : { + "type" : "boolean" + }, + "level" : { + "type" : "string" + }, + "mask" : { + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "section" : { + "type" : "string" + }, + "value" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/configdb", + "text" : "configdb" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create initial ceph default configuration and setup symlinks.", + "method" : "POST", + "name" : "init", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cluster-network" : { + "description" : "Declare a separate cluster network, OSDs will routeheartbeat, object replication and recovery traffic over it", + "format" : "CIDR", + "maxLength" : 128, + "optional" : 1, + "requires" : "network", + "type" : "string", + "typetext" : "" + }, + "disable_cephx" : { + "default" : 0, + "description" : "Disable cephx authentication.\n\nWARNING: cephx is a security feature protecting against man-in-the-middle attacks. Only consider disabling cephx if your network is private!", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "min_size" : { + "default" : 2, + "description" : "Minimum number of available replicas per object to allow I/O", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "network" : { + "description" : "Use specific network for all ceph related traffic", + "format" : "CIDR", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_bits" : { + "default" : 6, + "description" : "Placement group bits, used to specify the default number of placement groups.\n\nNOTE: 'osd pool default pg num' does not work for default pools.", + "maximum" : 14, + "minimum" : 6, + "optional" : 1, + "type" : "integer", + "typetext" : " (6 - 14)" + }, + "size" : { + "default" : 3, + "description" : "Targeted number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 7)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/init", + "text" : "init" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop ceph services.", + "method" : "POST", + "name" : "stop", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "default" : "ceph.target", + "description" : "Ceph service name.", + "optional" : 1, + "pattern" : "(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/stop", + "text" : "stop" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start ceph services.", + "method" : "POST", + "name" : "start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "default" : "ceph.target", + "description" : "Ceph service name.", + "optional" : 1, + "pattern" : "(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Restart ceph services.", + "method" : "POST", + "name" : "restart", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "default" : "ceph.target", + "description" : "Ceph service name.", + "optional" : 1, + "pattern" : "(mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/restart", + "text" : "restart" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get ceph status.", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get OSD crush map", + "method" : "GET", + "name" : "crush", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/crush", + "text" : "crush" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read ceph log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List ceph rules.", + "method" : "GET", + "name" : "rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "name" : { + "description" : "Name of the CRUSH rule.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/rules", + "text" : "rules" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Heuristical check if it is safe to perform an action.", + "method" : "GET", + "name" : "cmd_safety", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Action to check", + "enum" : [ + "stop", + "destroy" + ], + "type" : "string" + }, + "id" : { + "description" : "ID of the service", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service type", + "enum" : [ + "osd", + "mon", + "mds" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "safe" : { + "description" : "If it is safe to run the command.", + "type" : "boolean" + }, + "status" : { + "description" : "Status message given by Ceph.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/cmd-safety", + "text" : "cmd-safety" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph", + "text" : "ceph" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the currently configured vzdump defaults.", + "method" : "GET", + "name" : "defaults", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions for the specified storage (or default storage if none specified). Some properties are only returned when the user has 'Sys.Audit' permissions for the node.", + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (KBytes per second).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "format" : "string-alist", + "optional" : 1, + "type" : "string" + }, + "ionice" : { + "default" : 7, + "description" : "Set CFQ ionice priority.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "mailnotification" : { + "default" : "always", + "description" : "Specify when to send an email", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string" + }, + "maxfiles" : { + "description" : "Deprecated: use 'prune-backups' instead. Maximal number of backup files per guest system.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string" + }, + "notes-template" : { + "description" : "Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.", + "maxLength" : 1024, + "optional" : 1, + "requires" : "storage", + "type" : "string" + }, + "performance" : { + "description" : "Other performance-related settings.", + "format" : "backup-performance", + "optional" : 1, + "type" : "string" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string" + }, + "protected" : { + "description" : "If true, mark backup(s) as protected.", + "optional" : 1, + "requires" : "storage", + "type" : "boolean" + }, + "prune-backups" : { + "default" : "keep-all=1", + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean" + }, + "remove" : { + "default" : 1, + "description" : "Prune older backups according to 'prune-backups'.", + "optional" : 1, + "type" : "boolean" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, N>0 uses N as thread count.", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/vzdump/defaults", + "text" : "defaults" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Extract configuration from vzdump backup archive.", + "method" : "GET", + "name" : "extractconfig", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'VM.Backup' permissions on the backed up guest ID, and 'Datastore.AllocateSpace' on the backup storage.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/vzdump/extractconfig", + "text" : "extractconfig" + } + ], + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create backup.", + "method" : "POST", + "name" : "vzdump", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (KBytes per second).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "format" : "string-alist", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ionice" : { + "default" : 7, + "description" : "Set CFQ ionice priority.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 8)" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mailnotification" : { + "default" : "always", + "description" : "Specify when to send an email", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "maxfiles" : { + "description" : "Deprecated: use 'prune-backups' instead. Maximal number of backup files per guest system.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "notes-template" : { + "description" : "Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.", + "maxLength" : 1024, + "optional" : 1, + "requires" : "storage", + "type" : "string", + "typetext" : "" + }, + "performance" : { + "description" : "Other performance-related settings.", + "format" : "backup-performance", + "optional" : 1, + "type" : "string", + "typetext" : "[max-workers=]" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protected" : { + "description" : "If true, mark backup(s) as protected.", + "optional" : 1, + "requires" : "storage", + "type" : "boolean", + "typetext" : "" + }, + "prune-backups" : { + "default" : "keep-all=1", + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove" : { + "default" : 1, + "description" : "Prune older backups according to 'prune-backups'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stdout" : { + "description" : "Write tar to stdout, not to a file.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, N>0 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'VM.Backup' permissions on any VM, and 'Datastore.AllocateSpace' on the backup storage. The 'tmpdir', 'dumpdir' and 'script' parameters are restricted to the 'root@pam' user. The 'maxfiles' and 'prune-backups' settings require 'Datastore.Allocate' on the backup storage. The 'bwlimit', 'performance' and 'ionice' parameters require 'Sys.Modify' on '/'.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/vzdump", + "text" : "vzdump" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read service properties", + "method" : "GET", + "name" : "service_state", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "postfix", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/state", + "text" : "state" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start service.", + "method" : "POST", + "name" : "service_start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "postfix", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop service.", + "method" : "POST", + "name" : "service_stop", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "postfix", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/stop", + "text" : "stop" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Hard restart service. Use reload if you want to reduce interruptions.", + "method" : "POST", + "name" : "service_restart", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "postfix", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/restart", + "text" : "restart" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Reload service. Falls back to restart if service cannot be reloaded.", + "method" : "POST", + "name" : "service_reload", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "postfix", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/reload", + "text" : "reload" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "srvcmdidx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "postfix", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/services/{service}", + "text" : "{service}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Service list.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{service}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/services", + "text" : "services" + }, + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete subscription key of this node.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read subscription info.", + "method" : "GET", + "name" : "get", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Update subscription info.", + "method" : "POST", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "Always connect to server, even if we have up to date info inside local cache.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set subscription key.", + "method" : "PUT", + "name" : "set", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "key" : { + "description" : "Proxmox VE subscription key", + "maxLength" : 32, + "pattern" : "pve([1248])([cbsp])-[0-9a-f]{10}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/subscription", + "text" : "subscription" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete network device configuration", + "method" : "DELETE", + "name" : "delete_network", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read network device configuration", + "method" : "GET", + "name" : "network_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "method" : { + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update network device configuration", + "method" : "PUT", + "name" : "update_network", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "address" : { + "description" : "IP address.", + "format" : "ipv4", + "optional" : 1, + "requires" : "netmask", + "type" : "string", + "typetext" : "" + }, + "address6" : { + "description" : "IP address.", + "format" : "ipv6", + "optional" : 1, + "requires" : "netmask6", + "type" : "string", + "typetext" : "" + }, + "autostart" : { + "description" : "Automatically start interface on boot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bond-primary" : { + "description" : "Specify the primary interface for active-backup bond.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bond_mode" : { + "description" : "Bonding mode.", + "enum" : [ + "balance-rr", + "active-backup", + "balance-xor", + "broadcast", + "802.3ad", + "balance-tlb", + "balance-alb", + "balance-slb", + "lacp-balance-slb", + "lacp-balance-tcp" + ], + "optional" : 1, + "type" : "string" + }, + "bond_xmit_hash_policy" : { + "description" : "Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.", + "enum" : [ + "layer2", + "layer2+3", + "layer3+4" + ], + "optional" : 1, + "type" : "string" + }, + "bridge_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge_vlan_aware" : { + "description" : "Enable bridge vlan support.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cidr" : { + "description" : "IPv4 CIDR.", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cidr6" : { + "description" : "IPv6 CIDR.", + "format" : "CIDRv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comments" : { + "description" : "Comments", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comments6" : { + "description" : "Comments", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway" : { + "description" : "Default gateway address.", + "format" : "ipv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway6" : { + "description" : "Default ipv6 gateway address.", + "format" : "ipv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string", + "typetext" : "" + }, + "mtu" : { + "description" : "MTU.", + "maximum" : 65520, + "minimum" : 1280, + "optional" : 1, + "type" : "integer", + "typetext" : " (1280 - 65520)" + }, + "netmask" : { + "description" : "Network mask.", + "format" : "ipv4mask", + "optional" : 1, + "requires" : "address", + "type" : "string", + "typetext" : "" + }, + "netmask6" : { + "description" : "Network mask.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "requires" : "address6", + "type" : "integer", + "typetext" : " (0 - 128)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "ovs_bonds" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_bridge" : { + "description" : "The OVS bridge associated with a OVS port. This is required when you create an OVS port.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_options" : { + "description" : "OVS interface options.", + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_tag" : { + "description" : "Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4094)" + }, + "slaves" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Network interface type", + "enum" : [ + "bridge", + "bond", + "eth", + "alias", + "vlan", + "OVSBridge", + "OVSBond", + "OVSPort", + "OVSIntPort", + "unknown" + ], + "type" : "string" + }, + "vlan-id" : { + "description" : "vlan-id for a custom named vlan interface (ifupdown2 only).", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4094)" + }, + "vlan-raw-device" : { + "description" : "Specify the raw interface for the vlan interface.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/network/{iface}", + "text" : "{iface}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Revert network configuration changes.", + "method" : "DELETE", + "name" : "revert_network_changes", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List available networks", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Only list specific interface types.", + "enum" : [ + "bridge", + "bond", + "eth", + "alias", + "vlan", + "OVSBridge", + "OVSBond", + "OVSPort", + "OVSIntPort", + "any_bridge" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{iface}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create network device configuration", + "method" : "POST", + "name" : "create_network", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "address" : { + "description" : "IP address.", + "format" : "ipv4", + "optional" : 1, + "requires" : "netmask", + "type" : "string", + "typetext" : "" + }, + "address6" : { + "description" : "IP address.", + "format" : "ipv6", + "optional" : 1, + "requires" : "netmask6", + "type" : "string", + "typetext" : "" + }, + "autostart" : { + "description" : "Automatically start interface on boot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bond-primary" : { + "description" : "Specify the primary interface for active-backup bond.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bond_mode" : { + "description" : "Bonding mode.", + "enum" : [ + "balance-rr", + "active-backup", + "balance-xor", + "broadcast", + "802.3ad", + "balance-tlb", + "balance-alb", + "balance-slb", + "lacp-balance-slb", + "lacp-balance-tcp" + ], + "optional" : 1, + "type" : "string" + }, + "bond_xmit_hash_policy" : { + "description" : "Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.", + "enum" : [ + "layer2", + "layer2+3", + "layer3+4" + ], + "optional" : 1, + "type" : "string" + }, + "bridge_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge_vlan_aware" : { + "description" : "Enable bridge vlan support.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cidr" : { + "description" : "IPv4 CIDR.", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cidr6" : { + "description" : "IPv6 CIDR.", + "format" : "CIDRv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comments" : { + "description" : "Comments", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comments6" : { + "description" : "Comments", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway" : { + "description" : "Default gateway address.", + "format" : "ipv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway6" : { + "description" : "Default ipv6 gateway address.", + "format" : "ipv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string", + "typetext" : "" + }, + "mtu" : { + "description" : "MTU.", + "maximum" : 65520, + "minimum" : 1280, + "optional" : 1, + "type" : "integer", + "typetext" : " (1280 - 65520)" + }, + "netmask" : { + "description" : "Network mask.", + "format" : "ipv4mask", + "optional" : 1, + "requires" : "address", + "type" : "string", + "typetext" : "" + }, + "netmask6" : { + "description" : "Network mask.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "requires" : "address6", + "type" : "integer", + "typetext" : " (0 - 128)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "ovs_bonds" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_bridge" : { + "description" : "The OVS bridge associated with a OVS port. This is required when you create an OVS port.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_options" : { + "description" : "OVS interface options.", + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_tag" : { + "description" : "Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4094)" + }, + "slaves" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Network interface type", + "enum" : [ + "bridge", + "bond", + "eth", + "alias", + "vlan", + "OVSBridge", + "OVSBond", + "OVSPort", + "OVSIntPort", + "unknown" + ], + "type" : "string" + }, + "vlan-id" : { + "description" : "vlan-id for a custom named vlan interface (ifupdown2 only).", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4094)" + }, + "vlan-raw-device" : { + "description" : "Specify the raw interface for the vlan interface.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Reload network configuration", + "method" : "PUT", + "name" : "reload_network_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/network", + "text" : "network" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read task log.", + "method" : "GET", + "name" : "read_task_log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "download" : { + "description" : "Whether the tasklog file should be downloaded. This parameter can't be used in conjunction with other parameters", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "limit" : { + "default" : 50, + "description" : "The amount of lines to read from the tasklog.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Start at this line when reading the tasklog", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "upid" : { + "description" : "The task's unique ID.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'Sys.Audit' permissions on '/nodes/' if they aren't the owner of the task.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/tasks/{upid}/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read task status.", + "method" : "GET", + "name" : "read_task_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "upid" : { + "description" : "The task's unique ID.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'Sys.Audit' permissions on '/nodes/' if they are not the owner of the task.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "exitstatus" : { + "optional" : 1, + "type" : "string" + }, + "id" : { + "type" : "string" + }, + "node" : { + "type" : "string" + }, + "pid" : { + "type" : "integer" + }, + "starttime" : { + "type" : "number" + }, + "status" : { + "enum" : [ + "running", + "stopped" + ], + "type" : "string" + }, + "type" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/tasks/{upid}/status", + "text" : "status" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Stop a task.", + "method" : "DELETE", + "name" : "stop_task", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "upid" : { + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'Sys.Modify' permissions on '/nodes/' if they aren't the owner of the task.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "upid_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "upid" : { + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/tasks/{upid}", + "text" : "{upid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read task list for one node (finished tasks).", + "method" : "GET", + "name" : "node_tasks", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "errors" : { + "default" : 0, + "description" : "Only list tasks with a status of ERROR.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "limit" : { + "default" : 50, + "description" : "Only list this amount of tasks.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Only list tasks since this UNIX epoch.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "source" : { + "default" : "archive", + "description" : "List archived, active or all tasks.", + "enum" : [ + "archive", + "active", + "all" + ], + "optional" : 1, + "type" : "string" + }, + "start" : { + "default" : 0, + "description" : "List tasks beginning from this offset.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "statusfilter" : { + "description" : "List of Task States that should be returned.", + "format" : "pve-task-status-type-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "typefilter" : { + "description" : "Only list tasks of this type (e.g., vzstart, vzdump).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "until" : { + "description" : "Only list tasks until this UNIX epoch.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "userfilter" : { + "description" : "Only list tasks from this user.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "Only list tasks for this VM.", + "format" : "pve-vmid", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "description" : "List task associated with the current user, or all task the user has 'Sys.Audit' permissions on /nodes/ (the the task runs on).", + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "endtime" : { + "optional" : 1, + "title" : "Endtime", + "type" : "integer" + }, + "id" : { + "title" : "ID", + "type" : "string" + }, + "node" : { + "title" : "Node", + "type" : "string" + }, + "pid" : { + "title" : "PID", + "type" : "integer" + }, + "pstart" : { + "type" : "integer" + }, + "starttime" : { + "title" : "Starttime", + "type" : "integer" + }, + "status" : { + "optional" : 1, + "title" : "Status", + "type" : "string" + }, + "type" : { + "title" : "Type", + "type" : "string" + }, + "upid" : { + "title" : "UPID", + "type" : "string" + }, + "user" : { + "title" : "User", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{upid}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/tasks", + "text" : "tasks" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote NFS server.", + "method" : "GET", + "name" : "nfsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "The server address (name or IP).", + "format" : "pve-storage-server", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "options" : { + "description" : "NFS export options.", + "type" : "string" + }, + "path" : { + "description" : "The exported path.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/nfs", + "text" : "nfs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote CIFS server.", + "method" : "GET", + "name" : "cifsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "domain" : { + "description" : "SMB domain (Workgroup).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "User password.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "The server address (name or IP).", + "format" : "pve-storage-server", + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "User name.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "description" : { + "description" : "Descriptive text from server.", + "type" : "string" + }, + "share" : { + "description" : "The cifs share name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/cifs", + "text" : "cifs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote Proxmox Backup Server.", + "method" : "GET", + "name" : "pbsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "User password or API token secret.", + "type" : "string", + "typetext" : "" + }, + "port" : { + "default" : 8007, + "description" : "Optional port.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "server" : { + "description" : "The server address (name or IP).", + "format" : "pve-storage-server", + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "User-name or API token-ID.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "Comment from server.", + "optional" : 1, + "type" : "string" + }, + "store" : { + "description" : "The datastore name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/pbs", + "text" : "pbs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote GlusterFS server.", + "method" : "GET", + "name" : "glusterfsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "The server address (name or IP).", + "format" : "pve-storage-server", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "volname" : { + "description" : "The volume name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/glusterfs", + "text" : "glusterfs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote iSCSI server.", + "method" : "GET", + "name" : "iscsiscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "portal" : { + "description" : "The iSCSI portal (IP or DNS name with optional port).", + "format" : "pve-storage-portal-dns", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "portal" : { + "description" : "The iSCSI portal name.", + "type" : "string" + }, + "target" : { + "description" : "The iSCSI target name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/iscsi", + "text" : "iscsi" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local LVM volume groups.", + "method" : "GET", + "name" : "lvmscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "vg" : { + "description" : "The LVM logical volume group name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/lvm", + "text" : "lvm" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local LVM Thin Pools.", + "method" : "GET", + "name" : "lvmthinscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vg" : { + "maxLength" : 100, + "pattern" : "[a-zA-Z0-9\\.\\+\\_][a-zA-Z0-9\\.\\+\\_\\-]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "lv" : { + "description" : "The LVM Thin Pool name (LVM logical volume).", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/lvmthin", + "text" : "lvmthin" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan zfs pool list on local node.", + "method" : "GET", + "name" : "zfsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "pool" : { + "description" : "ZFS pool name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/zfs", + "text" : "zfs" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index of available scan methods", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "method" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{method}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/scan", + "text" : "scan" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List mediated device types for given PCI device.", + "method" : "GET", + "name" : "mdevscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pciid" : { + "description" : "The PCI ID to list the mdev types for.", + "pattern" : "(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\\.[0-9a-fA-F]", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "available" : { + "description" : "The number of still available instances of this type.", + "type" : "integer" + }, + "description" : { + "type" : "string" + }, + "type" : { + "description" : "The name of the mdev type.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/hardware/pci/{pciid}/mdev", + "text" : "mdev" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index of available pci methods", + "method" : "GET", + "name" : "pciindex", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pciid" : { + "pattern" : "(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\\.[0-9a-fA-F]", + "type" : "string" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "method" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{method}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/hardware/pci/{pciid}", + "text" : "{pciid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local PCI devices.", + "method" : "GET", + "name" : "pciscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pci-class-blacklist" : { + "default" : "05;06;0b", + "description" : "A list of blacklisted PCI classes, which will not be returned. Following are filtered by default: Memory Controller (05), Bridge (06) and Processor (0b).", + "format" : "string-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "verbose" : { + "default" : 1, + "description" : "If disabled, does only print the PCI IDs. Otherwise, additional information like vendor and device will be returned.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "class" : { + "description" : "The PCI Class of the device.", + "type" : "string" + }, + "device" : { + "description" : "The Device ID.", + "type" : "string" + }, + "device_name" : { + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "The PCI ID.", + "type" : "string" + }, + "iommugroup" : { + "description" : "The IOMMU group in which the device is in. If no IOMMU group is detected, it is set to -1.", + "type" : "integer" + }, + "mdev" : { + "description" : "If set, marks that the device is capable of creating mediated devices.", + "optional" : 1, + "type" : "boolean" + }, + "subsystem_device" : { + "description" : "The Subsystem Device ID.", + "optional" : 1, + "type" : "string" + }, + "subsystem_device_name" : { + "optional" : 1, + "type" : "string" + }, + "subsystem_vendor" : { + "description" : "The Subsystem Vendor ID.", + "optional" : 1, + "type" : "string" + }, + "subsystem_vendor_name" : { + "optional" : 1, + "type" : "string" + }, + "vendor" : { + "description" : "The Vendor ID.", + "type" : "string" + }, + "vendor_name" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/hardware/pci", + "text" : "pci" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local USB devices.", + "method" : "GET", + "name" : "usbscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "busnum" : { + "type" : "integer" + }, + "class" : { + "type" : "integer" + }, + "devnum" : { + "type" : "integer" + }, + "level" : { + "type" : "integer" + }, + "manufacturer" : { + "optional" : 1, + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "prodid" : { + "type" : "string" + }, + "product" : { + "optional" : 1, + "type" : "string" + }, + "serial" : { + "optional" : 1, + "type" : "string" + }, + "speed" : { + "type" : "string" + }, + "usbpath" : { + "optional" : 1, + "type" : "string" + }, + "vendid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/hardware/usb", + "text" : "usb" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index of hardware types", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{type}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/hardware", + "text" : "hardware" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all custom and default CPU models.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only returns custom models when the current user has Sys.Audit on /nodes.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "custom" : { + "description" : "True if this is a custom CPU model.", + "type" : "boolean" + }, + "name" : { + "description" : "Name of the CPU model. Identifies it for subsequent API calls. Prefixed with 'custom-' for custom models.", + "type" : "string" + }, + "vendor" : { + "description" : "CPU vendor visible to the guest when this model is selected. Vendor of 'reported-model' in case of custom models.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/capabilities/qemu/cpu", + "text" : "cpu" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get available QEMU/KVM machine types.", + "method" : "GET", + "name" : "types", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "id" : { + "description" : "Full name of machine type and version.", + "type" : "string" + }, + "type" : { + "description" : "The machine type.", + "enum" : [ + "q35", + "i440fx" + ], + "type" : "string" + }, + "version" : { + "description" : "The machine version.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/capabilities/qemu/machines", + "text" : "machines" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "QEMU capabilities index.", + "method" : "GET", + "name" : "qemu_caps_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/capabilities/qemu", + "text" : "qemu" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Node capabilities index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/capabilities", + "text" : "capabilities" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Prune backups. Only those using the standard naming scheme are considered.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "prune-backups" : { + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Either 'qemu' or 'lxc'. Only consider backups for guests of this type.", + "enum" : [ + "qemu", + "lxc" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "Only prune backups for this VM.", + "format" : "pve-vmid", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "description" : "You need the 'Datastore.Allocate' privilege on the storage (or if a VM ID is specified, 'Datastore.AllocateSpace' and 'VM.Backup' for the VM).", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get prune information for backups. NOTE: this is only a preview and might not be what a subsequent prune call does if backups are removed/added in the meantime.", + "method" : "GET", + "name" : "dryrun", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "prune-backups" : { + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Either 'qemu' or 'lxc'. Only consider backups for guests of this type.", + "enum" : [ + "qemu", + "lxc" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "Only consider backups for this guest.", + "format" : "pve-vmid", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "ctime" : { + "description" : "Creation time of the backup (seconds since the UNIX epoch).", + "type" : "integer" + }, + "mark" : { + "description" : "Whether the backup would be kept or removed. Backups that are protected or don't use the standard naming scheme are not removed.", + "enum" : [ + "keep", + "remove", + "protected", + "renamed" + ], + "type" : "string" + }, + "type" : { + "description" : "One of 'qemu', 'lxc', 'openvz' or 'unknown'.", + "type" : "string" + }, + "vmid" : { + "description" : "The VM the backup belongs to.", + "optional" : 1, + "type" : "integer" + }, + "volid" : { + "description" : "Backup volume ID.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/prunebackups", + "text" : "prunebackups" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete volume", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delay" : { + "description" : "Time to wait for the task to finish. We return 'null' if the task finish within that time.", + "maximum" : 30, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 30)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need 'Datastore.Allocate' privilege on the storage (or 'Datastore.AllocateSpace' for backup volumes if you have VM.Backup privilege on the VM).", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "optional" : 1, + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get volume attributes", + "method" : "GET", + "name" : "info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "format" : { + "description" : "Format identifier ('raw', 'qcow2', 'subvol', 'iso', 'tgz' ...)", + "type" : "string" + }, + "notes" : { + "description" : "Optional notes.", + "optional" : 1, + "type" : "string" + }, + "path" : { + "description" : "The Path", + "type" : "string" + }, + "protected" : { + "description" : "Protection status. Currently only supported for backups.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Volume size in bytes.", + "renderer" : "bytes", + "type" : "integer" + }, + "used" : { + "description" : "Used space. Please note that most storage plugins do not report anything useful here.", + "renderer" : "bytes", + "type" : "integer" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Copy a volume. This is experimental code - do not use.", + "method" : "POST", + "name" : "copy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target volume identifier", + "type" : "string", + "typetext" : "" + }, + "target_node" : { + "description" : "Target node. Default is local node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Source volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update volume attributes", + "method" : "PUT", + "name" : "updateattributes", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "notes" : { + "description" : "The new notes.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protected" : { + "description" : "Protection status. Currently only supported for backups.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/content/{volume}", + "text" : "{volume}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List storage content.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "content" : { + "description" : "Only list content of this type.", + "format" : "pve-storage-content", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "Only list images for this VM", + "format" : "pve-vmid", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "ctime" : { + "description" : "Creation time (seconds since the UNIX Epoch).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "encrypted" : { + "description" : "If whole backup is encrypted, value is the fingerprint or '1' if encrypted. Only useful for the Proxmox Backup Server storage type.", + "optional" : 1, + "type" : "string" + }, + "format" : { + "description" : "Format identifier ('raw', 'qcow2', 'subvol', 'iso', 'tgz' ...)", + "type" : "string" + }, + "notes" : { + "description" : "Optional notes. If they contain multiple lines, only the first one is returned here.", + "optional" : 1, + "type" : "string" + }, + "parent" : { + "description" : "Volume identifier of parent (for linked cloned).", + "optional" : 1, + "type" : "string" + }, + "protected" : { + "description" : "Protection status. Currently only supported for backups.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Volume size in bytes.", + "renderer" : "bytes", + "type" : "integer" + }, + "used" : { + "description" : "Used space. Please note that most storage plugins do not report anything useful here.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "verification" : { + "description" : "Last backup verification result, only useful for PBS storages.", + "optional" : 1, + "properties" : { + "state" : { + "description" : "Last backup verification state.", + "type" : "string" + }, + "upid" : { + "description" : "Last backup verification UPID.", + "type" : "string" + } + }, + "type" : "object" + }, + "vmid" : { + "description" : "Associated Owner VMID.", + "optional" : 1, + "type" : "integer" + }, + "volid" : { + "description" : "Volume identifier.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{volid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Allocate disk images.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "filename" : { + "description" : "The name of the file to create.", + "type" : "string", + "typetext" : "" + }, + "format" : { + "enum" : [ + "raw", + "qcow2", + "subvol" + ], + "optional" : 1, + "requires" : "size", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "size" : { + "description" : "Size in kilobyte (1024 bytes). Optional suffixes 'M' (megabyte, 1024K) and 'G' (gigabyte, 1024M)", + "pattern" : "\\d+[MG]?", + "type" : "string" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "Specify owner VM", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateSpace" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Volume identifier", + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/storage/{storage}/content", + "text" : "content" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List files and directories for single file restore under the given path.", + "method" : "GET", + "name" : "list", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "filepath" : { + "description" : "base64-path to the directory or file being listed, or \"/\".", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Backup volume ID or name. Currently only PBS snapshots are supported.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "filepath" : { + "description" : "base64 path of the current entry", + "type" : "string" + }, + "leaf" : { + "description" : "If this entry is a leaf in the directory graph.", + "type" : "boolean" + }, + "mtime" : { + "description" : "Entry last-modified time (unix timestamp).", + "optional" : 1, + "type" : "integer" + }, + "size" : { + "description" : "Entry file size.", + "optional" : 1, + "type" : "integer" + }, + "text" : { + "description" : "Entry display text.", + "type" : "string" + }, + "type" : { + "description" : "Entry type.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/file-restore/list", + "text" : "list" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Extract a file or directory (as zip archive) from a PBS backup.", + "method" : "GET", + "name" : "download", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "filepath" : { + "description" : "base64-path to the directory or file to download.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Backup volume ID or name. Currently only PBS snapshots are supported.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "any" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/file-restore/download", + "text" : "download" + } + ], + "leaf" : 0, + "path" : "/nodes/{node}/storage/{storage}/file-restore", + "text" : "file-restore" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read storage status.", + "method" : "GET", + "name" : "read_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read storage RRD statistics (returns PNG).", + "method" : "GET", + "name" : "rrd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "ds" : { + "description" : "The list of datasources you want to display.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "filename" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/rrd", + "text" : "rrd" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read storage RRD statistics.", + "method" : "GET", + "name" : "rrddata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/rrddata", + "text" : "rrddata" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Upload templates and ISO images.", + "method" : "POST", + "name" : "upload", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "checksum" : { + "description" : "The expected checksum of the file.", + "optional" : 1, + "requires" : "checksum-algorithm", + "type" : "string", + "typetext" : "" + }, + "checksum-algorithm" : { + "description" : "The algorithm to calculate the checksum of the file.", + "enum" : [ + "md5", + "sha1", + "sha224", + "sha256", + "sha384", + "sha512" + ], + "optional" : 1, + "requires" : "checksum", + "type" : "string" + }, + "content" : { + "description" : "Content type.", + "enum" : [ + "iso", + "vztmpl" + ], + "format" : "pve-storage-content", + "type" : "string" + }, + "filename" : { + "description" : "The name of the file to create. Caution: This will be normalized!", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "tmpfilename" : { + "description" : "The source file name. This parameter is usually set by the REST handler. You can only overwrite it when connecting to the trusted port on localhost.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/upload", + "text" : "upload" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Download templates and ISO images by using an URL.", + "method" : "POST", + "name" : "download_url", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "checksum" : { + "description" : "The expected checksum of the file.", + "optional" : 1, + "requires" : "checksum-algorithm", + "type" : "string", + "typetext" : "" + }, + "checksum-algorithm" : { + "description" : "The algorithm to calculate the checksum of the file.", + "enum" : [ + "md5", + "sha1", + "sha224", + "sha256", + "sha384", + "sha512" + ], + "optional" : 1, + "requires" : "checksum", + "type" : "string" + }, + "content" : { + "description" : "Content type.", + "enum" : [ + "iso", + "vztmpl" + ], + "format" : "pve-storage-content", + "type" : "string" + }, + "filename" : { + "description" : "The name of the file to create. Caution: This will be normalized!", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "url" : { + "description" : "The URL to download the file from.", + "pattern" : "https?://.*", + "type" : "string" + }, + "verify-certificates" : { + "default" : 1, + "description" : "If false, no SSL/TLS certificates will be verified.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ], + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/download-url", + "text" : "download-url" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "diridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/storage/{storage}", + "text" : "{storage}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get status for all datastores.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "content" : { + "description" : "Only list stores which support this content type.", + "format" : "pve-storage-content-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enabled" : { + "default" : 0, + "description" : "Only list stores which are enabled (not disabled in config).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "format" : { + "default" : 0, + "description" : "Include information about formats", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Only list status for specified storage", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "If target is different to 'node', we only lists shared storages which content is accessible on this 'node' and the specified 'target' node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "active" : { + "description" : "Set when storage is accessible.", + "optional" : 1, + "type" : "boolean" + }, + "avail" : { + "description" : "Available storage space in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "content" : { + "description" : "Allowed storage content types.", + "format" : "pve-storage-content-list", + "type" : "string" + }, + "enabled" : { + "description" : "Set when storage is enabled (not disabled).", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "description" : "Shared flag from storage configuration.", + "optional" : 1, + "type" : "boolean" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string" + }, + "total" : { + "description" : "Total storage space in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "type" : { + "description" : "Storage type.", + "type" : "string" + }, + "used" : { + "description" : "Used storage space in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "used_fraction" : { + "description" : "Used fraction (used/total).", + "optional" : 1, + "renderer" : "fraction_as_percentage", + "type" : "number" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{storage}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/storage", + "text" : "storage" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove an LVM Volume Group.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cleanup-config" : { + "default" : 0, + "description" : "Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cleanup-disks" : { + "default" : 0, + "description" : "Also wipe disks so they can be repurposed afterwards.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify", + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/lvm/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List LVM Volume Groups", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "children" : { + "items" : { + "properties" : { + "children" : { + "description" : "The underlying physical volumes", + "items" : { + "properties" : { + "free" : { + "description" : "The free bytes in the physical volume", + "type" : "integer" + }, + "leaf" : { + "type" : "boolean" + }, + "name" : { + "description" : "The name of the physical volume", + "type" : "string" + }, + "size" : { + "description" : "The size of the physical volume in bytes", + "type" : "integer" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "free" : { + "description" : "The free bytes in the volume group", + "type" : "integer" + }, + "leaf" : { + "type" : "boolean" + }, + "name" : { + "description" : "The name of the volume group", + "type" : "string" + }, + "size" : { + "description" : "The size of the volume group in bytes", + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "leaf" : { + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create an LVM Volume Group", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storage" : { + "default" : 0, + "description" : "Configure storage using the Volume Group", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "device" : { + "description" : "The block device you want to create the volume group on", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify", + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks/lvm", + "text" : "lvm" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove an LVM thin pool.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cleanup-config" : { + "default" : 0, + "description" : "Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cleanup-disks" : { + "default" : 0, + "description" : "Also wipe disks so they can be repurposed afterwards.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "volume-group" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify", + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/lvmthin/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List LVM thinpools", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "lv" : { + "description" : "The name of the thinpool.", + "type" : "string" + }, + "lv_size" : { + "description" : "The size of the thinpool in bytes.", + "type" : "integer" + }, + "metadata_size" : { + "description" : "The size of the metadata lv in bytes.", + "type" : "integer" + }, + "metadata_used" : { + "description" : "The used bytes of the metadata lv.", + "type" : "integer" + }, + "used" : { + "description" : "The used bytes of the thinpool.", + "type" : "integer" + }, + "vg" : { + "description" : "The associated volume group.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create an LVM thinpool", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storage" : { + "default" : 0, + "description" : "Configure storage using the thinpool.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "device" : { + "description" : "The block device you want to create the thinpool on.", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify", + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks/lvmthin", + "text" : "lvmthin" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Unmounts the storage and removes the mount unit.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cleanup-config" : { + "default" : 0, + "description" : "Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cleanup-disks" : { + "default" : 0, + "description" : "Also wipe disk so it can be repurposed afterwards.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify", + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/directory/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "PVE Managed Directory storages.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "device" : { + "description" : "The mounted device.", + "type" : "string" + }, + "options" : { + "description" : "The mount options.", + "type" : "string" + }, + "path" : { + "description" : "The mount path.", + "type" : "string" + }, + "type" : { + "description" : "The filesystem type.", + "type" : "string" + }, + "unitfile" : { + "description" : "The path of the mount unit.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a Filesystem on an unused disk. Will be mounted under '/mnt/pve/NAME'.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storage" : { + "default" : 0, + "description" : "Configure storage using the directory.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "device" : { + "description" : "The block device you want to create the filesystem on.", + "type" : "string", + "typetext" : "" + }, + "filesystem" : { + "default" : "ext4", + "description" : "The desired filesystem.", + "enum" : [ + "ext4", + "xfs" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify", + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks/directory", + "text" : "directory" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy a ZFS pool.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cleanup-config" : { + "default" : 0, + "description" : "Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cleanup-disks" : { + "default" : 0, + "description" : "Also wipe disks so they can be repurposed afterwards.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify", + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get details about a zpool.", + "method" : "GET", + "name" : "detail", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "action" : { + "description" : "Information about the recommended action to fix the state.", + "optional" : 1, + "type" : "string" + }, + "children" : { + "description" : "The pool configuration information, including the vdevs for each section (e.g. spares, cache), may be nested.", + "items" : { + "properties" : { + "cksum" : { + "optional" : 1, + "type" : "number" + }, + "msg" : { + "description" : "An optional message about the vdev.", + "type" : "string" + }, + "name" : { + "description" : "The name of the vdev or section.", + "type" : "string" + }, + "read" : { + "optional" : 1, + "type" : "number" + }, + "state" : { + "description" : "The state of the vdev.", + "optional" : 1, + "type" : "string" + }, + "write" : { + "optional" : 1, + "type" : "number" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "errors" : { + "description" : "Information about the errors on the zpool.", + "type" : "string" + }, + "name" : { + "description" : "The name of the zpool.", + "type" : "string" + }, + "scan" : { + "description" : "Information about the last/current scrub.", + "optional" : 1, + "type" : "string" + }, + "state" : { + "description" : "The state of the zpool.", + "type" : "string" + }, + "status" : { + "description" : "Information about the state of the zpool.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/zfs/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List Zpools.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "alloc" : { + "description" : "", + "type" : "integer" + }, + "dedup" : { + "description" : "", + "type" : "number" + }, + "frag" : { + "description" : "", + "type" : "integer" + }, + "free" : { + "description" : "", + "type" : "integer" + }, + "health" : { + "description" : "", + "type" : "string" + }, + "name" : { + "description" : "", + "type" : "string" + }, + "size" : { + "description" : "", + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a ZFS pool.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storage" : { + "default" : 0, + "description" : "Configure storage using the zpool.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ashift" : { + "default" : 12, + "description" : "Pool sector size exponent.", + "maximum" : 16, + "minimum" : 9, + "optional" : 1, + "type" : "integer", + "typetext" : " (9 - 16)" + }, + "compression" : { + "default" : "on", + "description" : "The compression algorithm to use.", + "enum" : [ + "on", + "off", + "gzip", + "lz4", + "lzjb", + "zle", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "devices" : { + "description" : "The block devices you want to create the zpool on.", + "format" : "string-list", + "type" : "string", + "typetext" : "" + }, + "draid-config" : { + "format" : { + "data" : { + "description" : "The number of data devices per redundancy group. (dRAID)", + "minimum" : 1, + "type" : "integer" + }, + "spares" : { + "description" : "Number of dRAID spares.", + "minimum" : 0, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "data= ,spares=" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "raidlevel" : { + "description" : "The RAID level to use.", + "enum" : [ + "single", + "mirror", + "raid10", + "raidz", + "raidz2", + "raidz3", + "draid", + "draid2", + "draid3" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify", + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks/zfs", + "text" : "zfs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local disks.", + "method" : "GET", + "name" : "list", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "include-partitions" : { + "default" : 0, + "description" : "Also include partitions.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skipsmart" : { + "default" : 0, + "description" : "Skip smart checks.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "type" : { + "description" : "Only list specific types of disks.", + "enum" : [ + "unused", + "journal_disks" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "devpath" : { + "description" : "The device path", + "type" : "string" + }, + "gpt" : { + "type" : "boolean" + }, + "health" : { + "optional" : 1, + "type" : "string" + }, + "model" : { + "optional" : 1, + "type" : "string" + }, + "mounted" : { + "type" : "boolean" + }, + "osdid" : { + "type" : "integer" + }, + "parent" : { + "description" : "For partitions only. The device path of the disk the partition resides on.", + "optional" : 1, + "type" : "string" + }, + "serial" : { + "optional" : 1, + "type" : "string" + }, + "size" : { + "type" : "integer" + }, + "used" : { + "optional" : 1, + "type" : "string" + }, + "vendor" : { + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/list", + "text" : "list" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get SMART Health of a disk.", + "method" : "GET", + "name" : "smart", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "disk" : { + "description" : "Block device name", + "pattern" : "^/dev/[a-zA-Z0-9\\/]+$", + "type" : "string" + }, + "healthonly" : { + "description" : "If true returns only the health status", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "attributes" : { + "optional" : 1, + "type" : "array" + }, + "health" : { + "type" : "string" + }, + "text" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/smart", + "text" : "smart" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Initialize Disk with GPT", + "method" : "POST", + "name" : "initgpt", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "disk" : { + "description" : "Block device name", + "pattern" : "^/dev/[a-zA-Z0-9\\/]+$", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "uuid" : { + "description" : "UUID for the GPT table", + "maxLength" : 36, + "optional" : 1, + "pattern" : "[a-fA-F0-9\\-]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/initgpt", + "text" : "initgpt" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Wipe a disk or partition.", + "method" : "PUT", + "name" : "wipe_disk", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "disk" : { + "description" : "Block device name", + "pattern" : "^/dev/[a-zA-Z0-9\\/]+$", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/wipedisk", + "text" : "wipedisk" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Node index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks", + "text" : "disks" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List available updates.", + "method" : "GET", + "name" : "list_updates", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "This is used to resynchronize the package index files from their sources (apt-get update).", + "method" : "POST", + "name" : "update_database", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "notify" : { + "default" : 0, + "description" : "Send notification mail about new packages (to email address specified for user 'root@pam').", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "quiet" : { + "default" : 0, + "description" : "Only produces output suitable for logging, omitting progress indicators.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/apt/update", + "text" : "update" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get package changelogs.", + "method" : "GET", + "name" : "changelog", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Package name.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "version" : { + "description" : "Package version.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/apt/changelog", + "text" : "changelog" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get APT repository information.", + "method" : "GET", + "name" : "repositories", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "description" : "Result from parsing the APT repository files in /etc/apt/.", + "properties" : { + "digest" : { + "description" : "Common digest of all files.", + "type" : "string" + }, + "errors" : { + "description" : "List of problematic repository files.", + "items" : { + "properties" : { + "error" : { + "description" : "The error message", + "type" : "string" + }, + "path" : { + "description" : "Path to the problematic file.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "files" : { + "description" : "List of parsed repository files.", + "items" : { + "properties" : { + "digest" : { + "description" : "Digest of the file as bytes.", + "items" : { + "type" : "integer" + }, + "type" : "array" + }, + "file-type" : { + "description" : "Format of the file.", + "enum" : [ + "list", + "sources" + ], + "type" : "string" + }, + "path" : { + "description" : "Path to the problematic file.", + "type" : "string" + }, + "repositories" : { + "description" : "The parsed repositories.", + "items" : { + "properties" : { + "Comment" : { + "description" : "Associated comment", + "optional" : 1, + "type" : "string" + }, + "Components" : { + "description" : "List of repository components", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "Enabled" : { + "description" : "Whether the repository is enabled or not", + "type" : "boolean" + }, + "FileType" : { + "description" : "Format of the defining file.", + "enum" : [ + "list", + "sources" + ], + "type" : "string" + }, + "Options" : { + "description" : "Additional options", + "items" : { + "properties" : { + "Key" : { + "type" : "string" + }, + "Values" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "Suites" : { + "description" : "List of package distribuitions", + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "Types" : { + "description" : "List of package types.", + "items" : { + "enum" : [ + "deb", + "deb-src" + ], + "type" : "string" + }, + "type" : "array" + }, + "URIs" : { + "description" : "List of repository URIs.", + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "infos" : { + "description" : "Additional information/warnings for APT repositories.", + "items" : { + "properties" : { + "index" : { + "description" : "Index of the associated repository within the file.", + "type" : "string" + }, + "kind" : { + "description" : "Kind of the information (e.g. warning).", + "type" : "string" + }, + "message" : { + "description" : "Information message.", + "type" : "string" + }, + "path" : { + "description" : "Path to the associated file.", + "type" : "string" + }, + "property" : { + "description" : "Property from which the info originates.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "standard-repos" : { + "description" : "List of standard repositories and their configuration status", + "items" : { + "properties" : { + "handle" : { + "description" : "Handle to identify the repository.", + "type" : "string" + }, + "name" : { + "description" : "Full name of the repository.", + "type" : "string" + }, + "status" : { + "description" : "Indicating enabled/disabled status, if the repository is configured.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Change the properties of a repository. Currently only allows enabling/disabling.", + "method" : "POST", + "name" : "change_repository", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Digest to detect modifications.", + "maxLength" : 80, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enabled" : { + "description" : "Whether the repository should be enabled or not.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "index" : { + "description" : "Index within the file (starting from 0).", + "type" : "integer", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "Path to the containing file.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Add a standard repository to the configuration", + "method" : "PUT", + "name" : "add_repository", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Digest to detect modifications.", + "maxLength" : 80, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "handle" : { + "description" : "Handle that identifies a repository.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/apt/repositories", + "text" : "repositories" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get package information for important Proxmox packages.", + "method" : "GET", + "name" : "versions", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/apt/versions", + "text" : "versions" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index for apt (Advanced Package Tool).", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/apt", + "text" : "apt" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "action" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "dest" : { + "optional" : 1, + "type" : "string" + }, + "dport" : { + "optional" : 1, + "type" : "string" + }, + "enable" : { + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "optional" : 1, + "type" : "string" + }, + "iface" : { + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "optional" : 1, + "type" : "string" + }, + "pos" : { + "type" : "integer" + }, + "proto" : { + "optional" : 1, + "type" : "string" + }, + "source" : { + "optional" : 1, + "type" : "string" + }, + "sport" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "pos" : { + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 0, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/firewall/rules", + "text" : "rules" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get host firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "enable" : { + "description" : "Enable host firewall rules.", + "optional" : 1, + "type" : "boolean" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_nf_conntrack" : { + "default" : 0, + "description" : "Enable logging of conntrack information.", + "optional" : 1, + "type" : "boolean" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean" + }, + "nf_conntrack_allow_invalid" : { + "default" : 0, + "description" : "Allow invalid packets on connection tracking.", + "optional" : 1, + "type" : "boolean" + }, + "nf_conntrack_helpers" : { + "default" : "", + "description" : "Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp", + "format" : "pve-fw-conntrack-helper", + "optional" : 1, + "type" : "string" + }, + "nf_conntrack_max" : { + "default" : 262144, + "description" : "Maximum number of tracked connections.", + "minimum" : 32768, + "optional" : 1, + "type" : "integer" + }, + "nf_conntrack_tcp_timeout_established" : { + "default" : 432000, + "description" : "Conntrack established timeout.", + "minimum" : 7875, + "optional" : 1, + "type" : "integer" + }, + "nf_conntrack_tcp_timeout_syn_recv" : { + "default" : 60, + "description" : "Conntrack syn recv timeout.", + "maximum" : 60, + "minimum" : 30, + "optional" : 1, + "type" : "integer" + }, + "nosmurfs" : { + "description" : "Enable SMURFS filter.", + "optional" : 1, + "type" : "boolean" + }, + "protection_synflood" : { + "default" : 0, + "description" : "Enable synflood protection", + "optional" : 1, + "type" : "boolean" + }, + "protection_synflood_burst" : { + "default" : 1000, + "description" : "Synflood protection rate burst by ip src.", + "optional" : 1, + "type" : "integer" + }, + "protection_synflood_rate" : { + "default" : 200, + "description" : "Synflood protection rate syn/sec by ip src.", + "optional" : 1, + "type" : "integer" + }, + "smurf_log_level" : { + "description" : "Log level for SMURFS filter.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "tcp_flags_log_level" : { + "description" : "Log level for illegal tcp flags filter.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "tcpflags" : { + "default" : 0, + "description" : "Filter illegal combinations of TCP flags.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Enable host firewall rules.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_nf_conntrack" : { + "default" : 0, + "description" : "Enable logging of conntrack information.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nf_conntrack_allow_invalid" : { + "default" : 0, + "description" : "Allow invalid packets on connection tracking.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nf_conntrack_helpers" : { + "default" : "", + "description" : "Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp", + "format" : "pve-fw-conntrack-helper", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nf_conntrack_max" : { + "default" : 262144, + "description" : "Maximum number of tracked connections.", + "minimum" : 32768, + "optional" : 1, + "type" : "integer", + "typetext" : " (32768 - N)" + }, + "nf_conntrack_tcp_timeout_established" : { + "default" : 432000, + "description" : "Conntrack established timeout.", + "minimum" : 7875, + "optional" : 1, + "type" : "integer", + "typetext" : " (7875 - N)" + }, + "nf_conntrack_tcp_timeout_syn_recv" : { + "default" : 60, + "description" : "Conntrack syn recv timeout.", + "maximum" : 60, + "minimum" : 30, + "optional" : 1, + "type" : "integer", + "typetext" : " (30 - 60)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nosmurfs" : { + "description" : "Enable SMURFS filter.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "protection_synflood" : { + "default" : 0, + "description" : "Enable synflood protection", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "protection_synflood_burst" : { + "default" : 1000, + "description" : "Synflood protection rate burst by ip src.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "protection_synflood_rate" : { + "default" : 200, + "description" : "Synflood protection rate syn/sec by ip src.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "smurf_log_level" : { + "description" : "Log level for SMURFS filter.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "tcp_flags_log_level" : { + "description" : "Log level for illegal tcp flags filter.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "tcpflags" : { + "default" : 0, + "description" : "Filter illegal combinations of TCP flags.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/firewall/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read firewall log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display log since this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "until" : { + "description" : "Display log until this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/firewall/log", + "text" : "log" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/firewall", + "text" : "firewall" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get replication job status.", + "method" : "GET", + "name" : "job_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/replication/{id}/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read replication job log.", + "method" : "GET", + "name" : "read_job_log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/, or 'Sys.Audit' on '/nodes/'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/replication/{id}/log", + "text" : "log" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Schedule replication job to start as soon as possible.", + "method" : "POST", + "name" : "schedule_now", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/replication/{id}/schedule_now", + "text" : "schedule_now" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/replication/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List status of all replication jobs on this node.", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "guest" : { + "description" : "Only list replication jobs for this guest.", + "format" : "pve-vmid", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/replication", + "text" : "replication" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Revoke existing certificate from CA.", + "method" : "DELETE", + "name" : "revoke_certificate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Order a new certificate from ACME-compatible CA.", + "method" : "POST", + "name" : "new_certificate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "Overwrite existing custom certificate.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Renew existing certificate from CA.", + "method" : "PUT", + "name" : "renew_certificate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "Force renewal even if expiry is more than 30 days away.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/certificates/acme/certificate", + "text" : "certificate" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "ACME index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/certificates/acme", + "text" : "acme" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get information about node's certificates.", + "method" : "GET", + "name" : "info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "filename" : { + "optional" : 1, + "type" : "string" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "issuer" : { + "description" : "Certificate issuer name.", + "optional" : 1, + "type" : "string" + }, + "notafter" : { + "description" : "Certificate's notAfter timestamp (UNIX epoch).", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "notbefore" : { + "description" : "Certificate's notBefore timestamp (UNIX epoch).", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "pem" : { + "description" : "Certificate in PEM format", + "format" : "pem-certificate", + "optional" : 1, + "type" : "string" + }, + "public-key-bits" : { + "description" : "Certificate's public key size", + "optional" : 1, + "type" : "integer" + }, + "public-key-type" : { + "description" : "Certificate's public key algorithm", + "optional" : 1, + "type" : "string" + }, + "san" : { + "description" : "List of Certificate's SubjectAlternativeName entries.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "renderer" : "yaml", + "type" : "array" + }, + "subject" : { + "description" : "Certificate subject name.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/certificates/info", + "text" : "info" + }, + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "DELETE custom certificate chain and key.", + "method" : "DELETE", + "name" : "remove_custom_cert", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "restart" : { + "default" : 0, + "description" : "Restart pveproxy.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Upload or update custom certificate chain and key.", + "method" : "POST", + "name" : "upload_custom_cert", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "certificates" : { + "description" : "PEM encoded certificate (chain).", + "format" : "pem-certificate-chain", + "type" : "string", + "typetext" : "" + }, + "force" : { + "default" : 0, + "description" : "Overwrite existing custom or ACME certificate files.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "key" : { + "description" : "PEM encoded private key.", + "format" : "pem-string", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "restart" : { + "default" : 0, + "description" : "Restart pveproxy.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "filename" : { + "optional" : 1, + "type" : "string" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "issuer" : { + "description" : "Certificate issuer name.", + "optional" : 1, + "type" : "string" + }, + "notafter" : { + "description" : "Certificate's notAfter timestamp (UNIX epoch).", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "notbefore" : { + "description" : "Certificate's notBefore timestamp (UNIX epoch).", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "pem" : { + "description" : "Certificate in PEM format", + "format" : "pem-certificate", + "optional" : 1, + "type" : "string" + }, + "public-key-bits" : { + "description" : "Certificate's public key size", + "optional" : 1, + "type" : "integer" + }, + "public-key-type" : { + "description" : "Certificate's public key algorithm", + "optional" : 1, + "type" : "string" + }, + "san" : { + "description" : "List of Certificate's SubjectAlternativeName entries.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "renderer" : "yaml", + "type" : "array" + }, + "subject" : { + "description" : "Certificate subject name.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/certificates/custom", + "text" : "custom" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Node index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/certificates", + "text" : "certificates" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get node configuration options.", + "method" : "GET", + "name" : "get_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "property" : { + "default" : "all", + "description" : "Return only a specific property from the node configuration.", + "enum" : [ + "acme", + "acmedomain0", + "acmedomain1", + "acmedomain2", + "acmedomain3", + "acmedomain4", + "acmedomain5", + "description", + "startall-onboot-delay", + "wakeonlan" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "acme" : { + "description" : "Node specific ACME settings.", + "format" : { + "account" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string" + }, + "domains" : { + "description" : "List of domains for this node's ACME certificate", + "format" : "pve-acme-domain-list", + "format_description" : "domain[;domain;...]", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "acmedomain[n]" : { + "description" : "ACME domain and validation plugin", + "format" : { + "alias" : { + "description" : "Alias for the Domain to verify ACME Challenge over DNS", + "format" : "pve-acme-alias", + "format_description" : "domain", + "optional" : 1, + "type" : "string" + }, + "domain" : { + "default_key" : 1, + "description" : "domain for this node's ACME certificate", + "format" : "pve-acme-domain", + "format_description" : "domain", + "type" : "string" + }, + "plugin" : { + "default" : "standalone", + "description" : "The ACME plugin ID", + "format" : "pve-configid", + "format_description" : "name of the plugin configuration", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "description" : { + "description" : "Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.", + "maxLength" : 65536, + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string" + }, + "startall-onboot-delay" : { + "default" : 0, + "description" : "Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.", + "maximum" : 300, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "wakeonlan" : { + "description" : "MAC address for wake on LAN", + "format" : "mac-addr", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set node configuration options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acme" : { + "description" : "Node specific ACME settings.", + "format" : { + "account" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string" + }, + "domains" : { + "description" : "List of domains for this node's ACME certificate", + "format" : "pve-acme-domain-list", + "format_description" : "domain[;domain;...]", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[account=] [,domains=]" + }, + "acmedomain[n]" : { + "description" : "ACME domain and validation plugin", + "format" : { + "alias" : { + "description" : "Alias for the Domain to verify ACME Challenge over DNS", + "format" : "pve-acme-alias", + "format_description" : "domain", + "optional" : 1, + "type" : "string" + }, + "domain" : { + "default_key" : 1, + "description" : "domain for this node's ACME certificate", + "format" : "pve-acme-domain", + "format_description" : "domain", + "type" : "string" + }, + "plugin" : { + "default" : "standalone", + "description" : "The ACME plugin ID", + "format" : "pve-configid", + "format_description" : "name of the plugin configuration", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[domain=] [,alias=] [,plugin=]" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.", + "maxLength" : 65536, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "startall-onboot-delay" : { + "default" : 0, + "description" : "Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.", + "maximum" : 300, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 300)" + }, + "wakeonlan" : { + "description" : "MAC address for wake on LAN", + "format" : "mac-addr", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/config", + "text" : "config" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List zone content.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "status" : { + "description" : "Status.", + "optional" : 1, + "type" : "string" + }, + "statusmsg" : { + "description" : "Status details", + "optional" : 1, + "type" : "string" + }, + "vnet" : { + "description" : "Vnet identifier.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{vnet}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/sdn/zones/{zone}/content", + "text" : "content" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "diridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ], + "any", + 1 + ] + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/sdn/zones/{zone}", + "text" : "{zone}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get status for all zones.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "status" : { + "description" : "Status of zone", + "enum" : [ + "available", + "pending", + "error" + ], + "type" : "string" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{zone}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/sdn/zones", + "text" : "zones" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN index.", + "method" : "GET", + "name" : "sdnindex", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/sdn", + "text" : "sdn" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "API version details", + "method" : "GET", + "name" : "version", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "release" : { + "description" : "The current installed Proxmox VE Release", + "type" : "string" + }, + "repoid" : { + "description" : "The short git commit hash ID from which this version was build", + "type" : "string" + }, + "version" : { + "description" : "The current installed pve-manager package version", + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/version", + "text" : "version" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read node status", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Reboot or shutdown a node.", + "method" : "POST", + "name" : "node_cmd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "command" : { + "description" : "Specify the command.", + "enum" : [ + "reboot", + "shutdown" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read tap/vm network device interface counters", + "method" : "GET", + "name" : "netstat", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/netstat", + "text" : "netstat" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute multiple commands in order.", + "method" : "POST", + "name" : "execute", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "commands" : { + "description" : "JSON encoded array of commands.", + "format" : "pve-command-batch", + "type" : "string", + "typetext" : "", + "verbose_description" : "JSON encoded array of commands, where each command is an object with the following properties:\n args: \n\n\t A set of parameter names and their values.\n\n method: (GET|POST|PUT|DELETE)\n\n\t A method related to the API endpoint (GET, POST etc.).\n\n path: \n\n\t A relative path to an API endpoint on this node.\n\n" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/execute", + "text" : "execute" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Try to wake a node via 'wake on LAN' network packet.", + "method" : "POST", + "name" : "wakeonlan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "target node for wake on LAN packet", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.PowerMgmt" + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "MAC address used to assemble the WoL magic packet.", + "format" : "mac-addr", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/wakeonlan", + "text" : "wakeonlan" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read node RRD statistics (returns PNG)", + "method" : "GET", + "name" : "rrd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "ds" : { + "description" : "The list of datasources you want to display.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "filename" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/rrd", + "text" : "rrd" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read node RRD statistics", + "method" : "GET", + "name" : "rrddata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/rrddata", + "text" : "rrddata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read system log", + "method" : "GET", + "name" : "syslog", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display all log since this date-time string.", + "optional" : 1, + "pattern" : "^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$", + "type" : "string" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "until" : { + "description" : "Display all log until this date-time string.", + "optional" : 1, + "pattern" : "^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/syslog", + "text" : "syslog" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read Journal", + "method" : "GET", + "name" : "journal", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "endcursor" : { + "description" : "End before the given Cursor. Conflicts with 'until'", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lastentries" : { + "description" : "Limit to the last X lines. Conflicts with a range.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display all log since this UNIX epoch. Conflicts with 'startcursor'.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "startcursor" : { + "description" : "Start after the given Cursor. Conflicts with 'since'", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "until" : { + "description" : "Display all log until this UNIX epoch. Conflicts with 'endcursor'.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/journal", + "text" : "journal" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a VNC Shell proxy.", + "method" : "POST", + "name" : "vncshell", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cmd" : { + "default" : "login", + "description" : "Run specific command or default to login.", + "enum" : [ + "ceph_install", + "upgrade", + "login" + ], + "optional" : 1, + "type" : "string" + }, + "cmd-opts" : { + "default" : "", + "description" : "Add parameters to a command. Encoded as null terminated strings.", + "optional" : 1, + "requires" : "cmd", + "type" : "string", + "typetext" : "" + }, + "height" : { + "description" : "sets the height of the console in pixels.", + "maximum" : 2160, + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - 2160)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "websocket" : { + "description" : "use websocket instead of standard vnc.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "width" : { + "description" : "sets the width of the console in pixels.", + "maximum" : 4096, + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - 4096)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ], + "description" : "Restricted to users on realm 'pam'" + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "cert" : { + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/vncshell", + "text" : "vncshell" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a VNC Shell proxy.", + "method" : "POST", + "name" : "termproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cmd" : { + "default" : "login", + "description" : "Run specific command or default to login.", + "enum" : [ + "ceph_install", + "upgrade", + "login" + ], + "optional" : 1, + "type" : "string" + }, + "cmd-opts" : { + "default" : "", + "description" : "Add parameters to a command. Encoded as null terminated strings.", + "optional" : 1, + "requires" : "cmd", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ], + "description" : "Restricted to users on realm 'pam'" + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/termproxy", + "text" : "termproxy" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Opens a websocket for VNC traffic.", + "method" : "GET", + "name" : "vncwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Port number returned by previous vncproxy call.", + "maximum" : 5999, + "minimum" : 5900, + "type" : "integer", + "typetext" : " (5900 - 5999)" + }, + "vncticket" : { + "description" : "Ticket from previous call to vncproxy.", + "maxLength" : 512, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ], + "description" : "Restricted to users on realm 'pam'. You also need to pass a valid ticket (vncticket)." + }, + "returns" : { + "properties" : { + "port" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/vncwebsocket", + "text" : "vncwebsocket" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a SPICE shell.", + "method" : "POST", + "name" : "spiceshell", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cmd" : { + "default" : "login", + "description" : "Run specific command or default to login.", + "enum" : [ + "ceph_install", + "upgrade", + "login" + ], + "optional" : 1, + "type" : "string" + }, + "cmd-opts" : { + "default" : "", + "description" : "Add parameters to a command. Encoded as null terminated strings.", + "optional" : 1, + "requires" : "cmd", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "proxy" : { + "description" : "SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).", + "format" : "address", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ], + "description" : "Restricted to users on realm 'pam'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 1, + "description" : "Returned values can be directly passed to the 'remote-viewer' application.", + "properties" : { + "host" : { + "type" : "string" + }, + "password" : { + "type" : "string" + }, + "proxy" : { + "type" : "string" + }, + "tls-port" : { + "type" : "integer" + }, + "type" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/spiceshell", + "text" : "spiceshell" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read DNS settings.", + "method" : "GET", + "name" : "dns", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "properties" : { + "dns1" : { + "description" : "First name server IP address.", + "optional" : 1, + "type" : "string" + }, + "dns2" : { + "description" : "Second name server IP address.", + "optional" : 1, + "type" : "string" + }, + "dns3" : { + "description" : "Third name server IP address.", + "optional" : 1, + "type" : "string" + }, + "search" : { + "description" : "Search domain for host-name lookup.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Write DNS settings.", + "method" : "PUT", + "name" : "update_dns", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dns1" : { + "description" : "First name server IP address.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dns2" : { + "description" : "Second name server IP address.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dns3" : { + "description" : "Third name server IP address.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "search" : { + "description" : "Search domain for host-name lookup.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/dns", + "text" : "dns" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read server time and time zone settings.", + "method" : "GET", + "name" : "time", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "properties" : { + "localtime" : { + "description" : "Seconds since 1970-01-01 00:00:00 (local time)", + "minimum" : 1297163644, + "renderer" : "timestamp_gmt", + "type" : "integer" + }, + "time" : { + "description" : "Seconds since 1970-01-01 00:00:00 UTC.", + "minimum" : 1297163644, + "renderer" : "timestamp", + "type" : "integer" + }, + "timezone" : { + "description" : "Time zone", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set time zone.", + "method" : "PUT", + "name" : "set_timezone", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timezone" : { + "description" : "Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/time", + "text" : "time" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get list of appliances.", + "method" : "GET", + "name" : "aplinfo", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Download appliance templates.", + "method" : "POST", + "name" : "apl_download", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage where the template will be stored", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "template" : { + "description" : "The template which will downloaded", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/aplinfo", + "text" : "aplinfo" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Query metadata of an URL: file size, file name and mime type.", + "method" : "GET", + "name" : "query_url_metadata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "url" : { + "description" : "The URL to query the metadata from.", + "pattern" : "https?://.*", + "type" : "string" + }, + "verify-certificates" : { + "default" : 1, + "description" : "If false, no SSL/TLS certificates will be verified.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "filename" : { + "optional" : 1, + "type" : "string" + }, + "mimetype" : { + "optional" : 1, + "type" : "string" + }, + "size" : { + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/query-url-metadata", + "text" : "query-url-metadata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Gather various systems information about a node", + "method" : "GET", + "name" : "report", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/report", + "text" : "report" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start all VMs and containers located on this node (by default only those with onboot=1).", + "method" : "POST", + "name" : "startall", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : "off", + "description" : "Issue start command even if virtual guest have 'onboot' not set or set to off.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "Only consider guests from this comma separated list of VMIDs.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/startall", + "text" : "startall" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop all VMs and Containers.", + "method" : "POST", + "name" : "stopall", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force-stop" : { + "default" : 1, + "description" : "Force a hard-stop after the timeout.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 180, + "description" : "Timeout for each guest shutdown task. Depending on `force-stop`, the shutdown gets then simply aborted or a hard-stop is forced.", + "maximum" : 7200, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 7200)" + }, + "vms" : { + "description" : "Only consider Guests with these IDs.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/stopall", + "text" : "stopall" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migrate all VMs and Containers.", + "method" : "POST", + "name" : "migrateall", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "maxworkers" : { + "description" : "Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg. One of both must be set!", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "Only consider Guests with these IDs.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "with-local-disks" : { + "description" : "Enable live storage migration for local disk", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The 'VM.Migrate' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/migrateall", + "text" : "migrateall" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the content of /etc/hosts.", + "method" : "GET", + "name" : "get_etc_hosts", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "data" : { + "description" : "The content of /etc/hosts.", + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Write /etc/hosts.", + "method" : "POST", + "name" : "write_etc_hosts", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "data" : { + "description" : "The target content of /etc/hosts.", + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/hosts", + "text" : "hosts" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Node index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}", + "text" : "{node}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Cluster node index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "cpu" : { + "description" : "CPU utilization.", + "optional" : 1, + "renderer" : "fraction_as_percentage", + "type" : "number" + }, + "level" : { + "description" : "Support level.", + "optional" : 1, + "type" : "string" + }, + "maxcpu" : { + "description" : "Number of available CPUs.", + "optional" : 1, + "type" : "integer" + }, + "maxmem" : { + "description" : "Number of available memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "mem" : { + "description" : "Used memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "ssl_fingerprint" : { + "description" : "The SSL fingerprint for the node certificate.", + "optional" : 1, + "type" : "string" + }, + "status" : { + "description" : "Node status.", + "enum" : [ + "unknown", + "online", + "offline" + ], + "type" : "string" + }, + "uptime" : { + "description" : "Node uptime in seconds.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{node}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes", + "text" : "nodes" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete storage configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read storage configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update storage configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "blocksize" : { + "description" : "block size", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bwlimit" : { + "description" : "Set bandwidth/io limits various operations.", + "format" : { + "clone" : { + "description" : "bandwidth limit in KiB/s for cloning disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "default" : { + "description" : "default bandwidth limit in KiB/s", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "migration" : { + "description" : "bandwidth limit in KiB/s for migrating guests (including moving local disks)", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "move" : { + "description" : "bandwidth limit in KiB/s for moving disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "restore" : { + "description" : "bandwidth limit in KiB/s for restoring guests from backups", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[clone=] [,default=] [,migration=] [,move=] [,restore=]" + }, + "comstar_hg" : { + "description" : "host group for comstar views", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comstar_tg" : { + "description" : "target group for comstar views", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "content" : { + "description" : "Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n", + "format" : "pve-storage-content-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "content-dirs" : { + "description" : "Overrides for default content type directories.", + "format" : "pve-dir-override-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "data-pool" : { + "description" : "Data Pool (for erasure coding only)", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the storage.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "domain" : { + "description" : "CIFS domain.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "encryption-key" : { + "description" : "Encryption key. Use 'autogen' to generate one automatically without passphrase.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "format" : { + "description" : "Default image format.", + "format" : "pve-storage-format", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fs-name" : { + "description" : "The Ceph filesystem name.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fuse" : { + "description" : "Mount CephFS through FUSE.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "is_mountpoint" : { + "default" : "no", + "description" : "Assume the given path is an externally managed mountpoint and consider the storage offline if it is not mounted. Using a boolean (yes/no) value serves as a shortcut to using the target path in this field.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "keyring" : { + "description" : "Client keyring contents (for external clusters).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "krbd" : { + "description" : "Always access rbd through krbd kernel module.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lio_tpg" : { + "description" : "target portal group for Linux LIO targets", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "master-pubkey" : { + "description" : "Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "max-protected-backups" : { + "default" : "Unlimited for users with Datastore.Allocate privilege, 5 for other users", + "description" : "Maximal number of protected backups per guest. Use '-1' for unlimited.", + "minimum" : -1, + "optional" : 1, + "type" : "integer", + "typetext" : " (-1 - N)" + }, + "maxfiles" : { + "description" : "Deprecated: use 'prune-backups' instead. Maximal number of backup files per VM. Use '0' for unlimited.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mkdir" : { + "default" : "yes", + "description" : "Create the directory if it doesn't exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "monhost" : { + "description" : "IP addresses of monitors (for external clusters).", + "format" : "pve-storage-portal-dns-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mountpoint" : { + "description" : "mount point", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "namespace" : { + "description" : "Namespace.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nocow" : { + "default" : 0, + "description" : "Set the NOCOW flag on files. Disables data checksumming and causes data errors to be unrecoverable from while allowing direct I/O. Only use this if data does not need to be any more safe than on a single ext4 formatted disk with no underlying raid system.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nowritecache" : { + "description" : "disable write caching on the target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "options" : { + "description" : "NFS mount options (see 'man nfs')", + "format" : "pve-storage-options", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "Password for accessing the share/datastore.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "default" : 8007, + "description" : "For non default port.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "preallocation" : { + "default" : "metadata", + "description" : "Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off.", + "enum" : [ + "off", + "metadata", + "falloc", + "full" + ], + "optional" : 1, + "type" : "string" + }, + "prune-backups" : { + "description" : "The retention options with shorter intervals are processed first with --keep-last being the very first one. Each option covers a specific period of time. We say that backups within this period are covered by this option. The next option does not take care of already covered backups and only considers older backups.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "saferemove" : { + "description" : "Zero-out data when removing LVs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "saferemove_throughput" : { + "description" : "Wipe throughput (cstream -t parameter value).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "Server IP or DNS name.", + "format" : "pve-storage-server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server2" : { + "description" : "Backup volfile server IP or DNS name.", + "format" : "pve-storage-server", + "optional" : 1, + "requires" : "server", + "type" : "string", + "typetext" : "" + }, + "shared" : { + "description" : "Mark storage as shared.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "smbversion" : { + "default" : "default", + "description" : "SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server.", + "enum" : [ + "default", + "2.0", + "2.1", + "3", + "3.0", + "3.11" + ], + "optional" : 1, + "type" : "string" + }, + "sparse" : { + "description" : "use sparse volumes", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "subdir" : { + "description" : "Subdir to mount.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tagged_only" : { + "description" : "Only use logical volumes tagged with 'pve-vm-ID'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "transport" : { + "description" : "Gluster transport: tcp or rdma", + "enum" : [ + "tcp", + "rdma", + "unix" + ], + "optional" : 1, + "type" : "string" + }, + "username" : { + "description" : "RBD Id.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "config" : { + "additionalProperties" : 1, + "description" : "Partial, possible server generated, configuration properties.", + "optional" : 1, + "properties" : { + "encryption-key" : { + "description" : "The, possible auto-generated, encryption-key.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "storage" : { + "description" : "The ID of the created storage.", + "type" : "string" + }, + "type" : { + "description" : "The type of the created storage.", + "enum" : [ + "btrfs", + "cephfs", + "cifs", + "dir", + "glusterfs", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/storage/{storage}", + "text" : "{storage}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Storage index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list storage of specific type", + "enum" : [ + "btrfs", + "cephfs", + "cifs", + "dir", + "glusterfs", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "storage" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{storage}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new storage.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "authsupported" : { + "description" : "Authsupported.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "base" : { + "description" : "Base volume. This volume is automatically activated.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "blocksize" : { + "description" : "block size", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bwlimit" : { + "description" : "Set bandwidth/io limits various operations.", + "format" : { + "clone" : { + "description" : "bandwidth limit in KiB/s for cloning disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "default" : { + "description" : "default bandwidth limit in KiB/s", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "migration" : { + "description" : "bandwidth limit in KiB/s for migrating guests (including moving local disks)", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "move" : { + "description" : "bandwidth limit in KiB/s for moving disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "restore" : { + "description" : "bandwidth limit in KiB/s for restoring guests from backups", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[clone=] [,default=] [,migration=] [,move=] [,restore=]" + }, + "comstar_hg" : { + "description" : "host group for comstar views", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comstar_tg" : { + "description" : "target group for comstar views", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "content" : { + "description" : "Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n", + "format" : "pve-storage-content-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "content-dirs" : { + "description" : "Overrides for default content type directories.", + "format" : "pve-dir-override-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "data-pool" : { + "description" : "Data Pool (for erasure coding only)", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "datastore" : { + "description" : "Proxmox Backup Server datastore name.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the storage.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "domain" : { + "description" : "CIFS domain.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "encryption-key" : { + "description" : "Encryption key. Use 'autogen' to generate one automatically without passphrase.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "export" : { + "description" : "NFS export path.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "format" : { + "description" : "Default image format.", + "format" : "pve-storage-format", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fs-name" : { + "description" : "The Ceph filesystem name.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fuse" : { + "description" : "Mount CephFS through FUSE.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "is_mountpoint" : { + "default" : "no", + "description" : "Assume the given path is an externally managed mountpoint and consider the storage offline if it is not mounted. Using a boolean (yes/no) value serves as a shortcut to using the target path in this field.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iscsiprovider" : { + "description" : "iscsi provider", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "keyring" : { + "description" : "Client keyring contents (for external clusters).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "krbd" : { + "description" : "Always access rbd through krbd kernel module.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lio_tpg" : { + "description" : "target portal group for Linux LIO targets", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "master-pubkey" : { + "description" : "Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "max-protected-backups" : { + "default" : "Unlimited for users with Datastore.Allocate privilege, 5 for other users", + "description" : "Maximal number of protected backups per guest. Use '-1' for unlimited.", + "minimum" : -1, + "optional" : 1, + "type" : "integer", + "typetext" : " (-1 - N)" + }, + "maxfiles" : { + "description" : "Deprecated: use 'prune-backups' instead. Maximal number of backup files per VM. Use '0' for unlimited.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mkdir" : { + "default" : "yes", + "description" : "Create the directory if it doesn't exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "monhost" : { + "description" : "IP addresses of monitors (for external clusters).", + "format" : "pve-storage-portal-dns-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mountpoint" : { + "description" : "mount point", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "namespace" : { + "description" : "Namespace.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nocow" : { + "default" : 0, + "description" : "Set the NOCOW flag on files. Disables data checksumming and causes data errors to be unrecoverable from while allowing direct I/O. Only use this if data does not need to be any more safe than on a single ext4 formatted disk with no underlying raid system.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nowritecache" : { + "description" : "disable write caching on the target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "options" : { + "description" : "NFS mount options (see 'man nfs')", + "format" : "pve-storage-options", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "Password for accessing the share/datastore.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "File system path.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "default" : 8007, + "description" : "For non default port.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "portal" : { + "description" : "iSCSI portal (IP or DNS name with optional port).", + "format" : "pve-storage-portal-dns", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "preallocation" : { + "default" : "metadata", + "description" : "Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off.", + "enum" : [ + "off", + "metadata", + "falloc", + "full" + ], + "optional" : 1, + "type" : "string" + }, + "prune-backups" : { + "description" : "The retention options with shorter intervals are processed first with --keep-last being the very first one. Each option covers a specific period of time. We say that backups within this period are covered by this option. The next option does not take care of already covered backups and only considers older backups.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "saferemove" : { + "description" : "Zero-out data when removing LVs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "saferemove_throughput" : { + "description" : "Wipe throughput (cstream -t parameter value).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "Server IP or DNS name.", + "format" : "pve-storage-server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server2" : { + "description" : "Backup volfile server IP or DNS name.", + "format" : "pve-storage-server", + "optional" : 1, + "requires" : "server", + "type" : "string", + "typetext" : "" + }, + "share" : { + "description" : "CIFS share.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "shared" : { + "description" : "Mark storage as shared.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "smbversion" : { + "default" : "default", + "description" : "SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server.", + "enum" : [ + "default", + "2.0", + "2.1", + "3", + "3.0", + "3.11" + ], + "optional" : 1, + "type" : "string" + }, + "sparse" : { + "description" : "use sparse volumes", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "subdir" : { + "description" : "Subdir to mount.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tagged_only" : { + "description" : "Only use logical volumes tagged with 'pve-vm-ID'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target" : { + "description" : "iSCSI target.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "thinpool" : { + "description" : "LVM thin pool LV name.", + "format" : "pve-storage-vgname", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "transport" : { + "description" : "Gluster transport: tcp or rdma", + "enum" : [ + "tcp", + "rdma", + "unix" + ], + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Storage type.", + "enum" : [ + "btrfs", + "cephfs", + "cifs", + "dir", + "glusterfs", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "type" : "string" + }, + "username" : { + "description" : "RBD Id.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vgname" : { + "description" : "Volume group name.", + "format" : "pve-storage-vgname", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Glusterfs Volume.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "config" : { + "additionalProperties" : 1, + "description" : "Partial, possible server generated, configuration properties.", + "optional" : 1, + "properties" : { + "encryption-key" : { + "description" : "The, possible auto-generated, encryption-key.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "storage" : { + "description" : "The ID of the created storage.", + "type" : "string" + }, + "type" : { + "description" : "The type of the created storage.", + "enum" : [ + "btrfs", + "cephfs", + "cifs", + "dir", + "glusterfs", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 0, + "path" : "/storage", + "text" : "storage" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get user TFA types (Personal and Realm).", + "method" : "GET", + "name" : "read_user_tfa_type", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "multiple" : { + "default" : 0, + "description" : "Request all entries as an array.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "realm" : { + "description" : "The type of TFA the users realm has set, if any.", + "enum" : [ + "oath", + "yubico" + ], + "optional" : 1, + "type" : "string" + }, + "types" : { + "description" : "Array of the user configured TFA types, if any. Only available if 'multiple' was not passed.", + "items" : { + "description" : "A TFA type.", + "enum" : [ + "totp", + "u2f", + "yubico", + "webauthn", + "recovedry" + ], + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "user" : { + "description" : "The type of TFA the user has set, if any. Only set if 'multiple' was not passed.", + "enum" : [ + "oath", + "u2f" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/users/{userid}/tfa", + "text" : "tfa" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove API token for a specific user.", + "method" : "DELETE", + "name" : "remove_token", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get specific API token information.", + "method" : "GET", + "name" : "read_token", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "returns" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Generate a new API token for a specific user. NOTE: returns API token value, which needs to be stored as it cannot be retrieved afterwards!", + "method" : "POST", + "name" : "generate_token", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "full-tokenid" : { + "description" : "The full token id.", + "format_description" : "!", + "type" : "string" + }, + "info" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "value" : { + "description" : "API token value used for authentication.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update API token for a specific user.", + "method" : "PUT", + "name" : "update_token_info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "Updated token information.", + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/users/{userid}/token/{tokenid}", + "text" : "{tokenid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get user API tokens.", + "method" : "GET", + "name" : "token_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + }, + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{tokenid}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/access/users/{userid}/token", + "text" : "token" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete user.", + "method" : "DELETE", + "name" : "delete_user", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get user configuration.", + "method" : "GET", + "name" : "read_user", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "email" : { + "format" : "email-opt", + "optional" : 1, + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Enable the account (default). You can set this to '0' to disable the account", + "optional" : 1, + "type" : "boolean" + }, + "expire" : { + "description" : "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "firstname" : { + "optional" : 1, + "type" : "string" + }, + "groups" : { + "items" : { + "format" : "pve-groupid", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "keys" : { + "description" : "Keys for two factor auth (yubico).", + "optional" : 1, + "type" : "string" + }, + "lastname" : { + "optional" : 1, + "type" : "string" + }, + "tokens" : { + "additionalProperties" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "object" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update user configuration.", + "method" : "PUT", + "name" : "update_user", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "append" : { + "optional" : 1, + "requires" : "groups", + "type" : "boolean", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "email" : { + "format" : "email-opt", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 1, + "description" : "Enable the account (default). You can set this to '0' to disable the account", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "expire" : { + "description" : "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "firstname" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groups" : { + "format" : "pve-groupid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "keys" : { + "description" : "Keys for two factor auth (yubico).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lastname" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "userid-group", + [ + "User.Modify" + ], + "groups_param", + "update" + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/users/{userid}", + "text" : "{userid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "User index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "enabled" : { + "description" : "Optional filter for enable property.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "full" : { + "default" : 0, + "description" : "Include group and token information.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The returned list is restricted to users where you have 'User.Modify' or 'Sys.Audit' permissions on '/access/groups' or on a group the user belongs too. But it always includes the current (authenticated) user.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "email" : { + "format" : "email-opt", + "optional" : 1, + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Enable the account (default). You can set this to '0' to disable the account", + "optional" : 1, + "type" : "boolean" + }, + "expire" : { + "description" : "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "firstname" : { + "optional" : 1, + "type" : "string" + }, + "groups" : { + "format" : "pve-groupid-list", + "optional" : 1, + "type" : "string" + }, + "keys" : { + "description" : "Keys for two factor auth (yubico).", + "optional" : 1, + "type" : "string" + }, + "lastname" : { + "optional" : 1, + "type" : "string" + }, + "realm-type" : { + "description" : "The type of the users realm", + "format" : "pve-realm", + "optional" : 1, + "type" : "string" + }, + "tokens" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + }, + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{userid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new user.", + "method" : "POST", + "name" : "create_user", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "email" : { + "format" : "email-opt", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 1, + "description" : "Enable the account (default). You can set this to '0' to disable the account", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "expire" : { + "description" : "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "firstname" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groups" : { + "format" : "pve-groupid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "keys" : { + "description" : "Keys for two factor auth (yubico).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lastname" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "Initial password.", + "maxLength" : 64, + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ], + "groups_param", + "create" + ] + ], + "description" : "You need 'Realm.AllocateUser' on '/access/realm/' on the realm of user , and 'User.Modify' permissions to '/access/groups/' for any group specified (or 'User.Modify' on '/access/groups' if you pass no groups." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/users", + "text" : "users" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete group.", + "method" : "DELETE", + "name" : "delete_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "groupid" : { + "format" : "pve-groupid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get group configuration.", + "method" : "GET", + "name" : "read_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "groupid" : { + "format" : "pve-groupid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/groups", + [ + "Sys.Audit", + "Group.Allocate" + ], + "any", + 1 + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "members" : { + "items" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update group data.", + "method" : "PUT", + "name" : "update_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groupid" : { + "format" : "pve-groupid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/groups/{groupid}", + "text" : "{groupid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Group index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "The returned list is restricted to groups where you have 'User.Modify', 'Sys.Audit' or 'Group.Allocate' permissions on /access/groups/.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "groupid" : { + "format" : "pve-groupid", + "type" : "string" + }, + "users" : { + "description" : "list of users which form this group", + "format" : "pve-userid-list", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{groupid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new group.", + "method" : "POST", + "name" : "create_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groupid" : { + "format" : "pve-groupid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/groups", + "text" : "groups" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete role.", + "method" : "DELETE", + "name" : "delete_role", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "roleid" : { + "format" : "pve-roleid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get role configuration.", + "method" : "GET", + "name" : "read_role", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "roleid" : { + "format" : "pve-roleid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "Datastore.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "Datastore.AllocateSpace" : { + "optional" : 1, + "type" : "boolean" + }, + "Datastore.AllocateTemplate" : { + "optional" : 1, + "type" : "boolean" + }, + "Datastore.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "Group.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "Permissions.Modify" : { + "optional" : 1, + "type" : "boolean" + }, + "Pool.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "Pool.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "Realm.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "Realm.AllocateUser" : { + "optional" : 1, + "type" : "boolean" + }, + "SDN.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "SDN.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Console" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Incoming" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Modify" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.PowerMgmt" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Syslog" : { + "optional" : 1, + "type" : "boolean" + }, + "User.Modify" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Backup" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Clone" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.CDROM" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.CPU" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Cloudinit" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Disk" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.HWType" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Memory" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Network" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Options" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Console" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Migrate" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Monitor" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.PowerMgmt" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Snapshot" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Snapshot.Rollback" : { + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update an existing role.", + "method" : "PUT", + "name" : "update_role", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "append" : { + "optional" : 1, + "requires" : "privs", + "type" : "boolean", + "typetext" : "" + }, + "privs" : { + "format" : "pve-priv-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "roleid" : { + "format" : "pve-roleid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/roles/{roleid}", + "text" : "{roleid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Role index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "privs" : { + "format" : "pve-priv-list", + "optional" : 1, + "type" : "string" + }, + "roleid" : { + "format" : "pve-roleid", + "type" : "string" + }, + "special" : { + "default" : 0, + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{roleid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new role.", + "method" : "POST", + "name" : "create_role", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "privs" : { + "format" : "pve-priv-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "roleid" : { + "format" : "pve-roleid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/roles", + "text" : "roles" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Access Control List (ACLs).", + "method" : "GET", + "name" : "read_acl", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "The returned list is restricted to objects where you have rights to modify permissions.", + "user" : "all" + }, + "returns" : { + "items" : { + "additionalProperties" : 0, + "properties" : { + "path" : { + "description" : "Access control path", + "type" : "string" + }, + "propagate" : { + "default" : 1, + "description" : "Allow to propagate (inherit) permissions.", + "optional" : 1, + "type" : "boolean" + }, + "roleid" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "user", + "group", + "token" + ], + "type" : "string" + }, + "ugid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update Access Control List (add or remove permissions).", + "method" : "PUT", + "name" : "update_acl", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "Remove permissions (instead of adding it).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "groups" : { + "description" : "List of groups.", + "format" : "pve-groupid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "Access control path", + "type" : "string", + "typetext" : "" + }, + "propagate" : { + "default" : 1, + "description" : "Allow to propagate (inherit) permissions.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "roles" : { + "description" : "List of roles.", + "format" : "pve-roleid-list", + "type" : "string", + "typetext" : "" + }, + "tokens" : { + "description" : "List of API tokens.", + "format" : "pve-tokenid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "users" : { + "description" : "List of users.", + "format" : "pve-userid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm-modify", + "{path}" + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/acl", + "text" : "acl" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Syncs users and/or groups from the configured LDAP to user.cfg. NOTE: Synced groups will have the name 'name-$realm', so make sure those groups do not exist to prevent overwriting.", + "method" : "POST", + "name" : "sync", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dry-run" : { + "default" : 0, + "description" : "If set, does not write anything.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "enable-new" : { + "default" : "1", + "description" : "Enable newly synced users immediately.", + "optional" : "1", + "type" : "boolean", + "typetext" : "" + }, + "full" : { + "description" : "DEPRECATED: use 'remove-vanished' instead. If set, uses the LDAP Directory as source of truth, deleting users or groups not returned from the sync and removing all locally modified properties of synced users. If not set, only syncs information which is present in the synced data, and does not delete or modify anything else.", + "optional" : "1", + "type" : "boolean", + "typetext" : "" + }, + "purge" : { + "description" : "DEPRECATED: use 'remove-vanished' instead. Remove ACLs for users or groups which were removed from the config during a sync.", + "optional" : "1", + "type" : "boolean", + "typetext" : "" + }, + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + }, + "remove-vanished" : { + "default" : "none", + "description" : "A semicolon-seperated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).", + "optional" : "1", + "pattern" : "(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none", + "type" : "string", + "typetext" : "([acl];[properties];[entry])|none" + }, + "scope" : { + "description" : "Select what to sync.", + "enum" : [ + "users", + "groups", + "both" + ], + "optional" : "1", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/access/realm/{realm}", + [ + "Realm.AllocateUser" + ] + ], + [ + "perm", + "/access/groups", + [ + "User.Modify" + ] + ] + ], + "description" : "'Realm.AllocateUser' on '/access/realm/' and 'User.Modify' permissions to '/access/groups/'." + }, + "protected" : 1, + "returns" : { + "description" : "Worker Task-UPID", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/access/domains/{realm}/sync", + "text" : "sync" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete an authentication server.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get auth server configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/realm", + [ + "Realm.Allocate", + "Sys.Audit" + ], + "any", + 1 + ] + }, + "returns" : {} + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update authentication server settings.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acr-values" : { + "description" : "Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "autocreate" : { + "default" : 0, + "description" : "Automatically create users if they do not exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "base_dn" : { + "description" : "LDAP base domain name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^:\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+)(,\\s*\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+))*)", + "type" : "string" + }, + "bind_dn" : { + "description" : "LDAP bind domain name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^:\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+)(,\\s*\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+))*)", + "type" : "string" + }, + "capath" : { + "default" : "/etc/ssl/certs", + "description" : "Path to the CA certificate store", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "case-sensitive" : { + "default" : 1, + "description" : "username is case-sensitive", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cert" : { + "description" : "Path to the client certificate", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "certkey" : { + "description" : "Path to the client certificate key", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "client-id" : { + "description" : "OpenID Client ID", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "client-key" : { + "description" : "OpenID Client Key", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "default" : { + "description" : "Use this as default realm", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "domain" : { + "description" : "AD domain name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\S+", + "type" : "string" + }, + "filter" : { + "description" : "LDAP filter for user sync.", + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_classes" : { + "default" : "groupOfNames, group, univentionGroup, ipausergroup", + "description" : "The objectclasses for groups.", + "format" : "ldap-simple-attr-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_dn" : { + "description" : "LDAP base domain name for group sync. If not set, the base_dn will be used.", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^:\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+)(,\\s*\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+))*)", + "type" : "string" + }, + "group_filter" : { + "description" : "LDAP filter for group sync.", + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_name_attr" : { + "description" : "LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.", + "format" : "ldap-simple-attr", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "issuer-url" : { + "description" : "OpenID Issuer Url", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mode" : { + "default" : "ldap", + "description" : "LDAP protocol mode.", + "enum" : [ + "ldap", + "ldaps", + "ldap+starttls" + ], + "optional" : 1, + "type" : "string" + }, + "password" : { + "description" : "LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Server port.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "prompt" : { + "description" : "Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.", + "optional" : 1, + "pattern" : "(?:none|login|consent|select_account|\\S+)", + "type" : "string" + }, + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + }, + "scopes" : { + "default" : "email profile", + "description" : "Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "secure" : { + "description" : "Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "server1" : { + "description" : "Server IP address (or DNS name)", + "format" : "address", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server2" : { + "description" : "Fallback Server IP address (or DNS name)", + "format" : "address", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sslversion" : { + "description" : "LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!", + "enum" : [ + "tlsv1", + "tlsv1_1", + "tlsv1_2", + "tlsv1_3" + ], + "optional" : 1, + "type" : "string" + }, + "sync-defaults-options" : { + "description" : "The default options for behavior of synchronizations.", + "format" : "realm-sync-options", + "optional" : 1, + "type" : "string", + "typetext" : "[enable-new=<1|0>] [,full=<1|0>] [,purge=<1|0>] [,remove-vanished=([acl];[properties];[entry])|none] [,scope=]" + }, + "sync_attributes" : { + "description" : "Comma separated list of key=value pairs for specifying which LDAP attributes map to which PVE user field. For example, to map the LDAP attribute 'mail' to PVEs 'email', write 'email=mail'. By default, each PVE user field is represented by an LDAP attribute of the same name.", + "optional" : 1, + "pattern" : "\\w+=[^,]+(,\\s*\\w+=[^,]+)*", + "type" : "string" + }, + "tfa" : { + "description" : "Use Two-factor authentication.", + "format" : "pve-tfa-config", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "type= [,digits=] [,id=] [,key=] [,step=] [,url=]" + }, + "user_attr" : { + "description" : "LDAP user attribute name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\S{2,}", + "type" : "string" + }, + "user_classes" : { + "default" : "inetorgperson, posixaccount, person, user", + "description" : "The objectclasses for users.", + "format" : "ldap-simple-attr-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "verify" : { + "default" : 0, + "description" : "Verify the server's SSL certificate", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/domains/{realm}", + "text" : "{realm}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Authentication domain index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "Anyone can access that, because we need that list for the login box (before the user is authenticated).", + "user" : "world" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "A comment. The GUI use this text when you select a domain (Realm) on the login window.", + "optional" : 1, + "type" : "string" + }, + "realm" : { + "type" : "string" + }, + "tfa" : { + "description" : "Two-factor authentication provider.", + "enum" : [ + "yubico", + "oath" + ], + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{realm}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add an authentication server.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acr-values" : { + "description" : "Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "autocreate" : { + "default" : 0, + "description" : "Automatically create users if they do not exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "base_dn" : { + "description" : "LDAP base domain name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^:\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+)(,\\s*\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+))*)", + "type" : "string" + }, + "bind_dn" : { + "description" : "LDAP bind domain name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^:\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+)(,\\s*\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+))*)", + "type" : "string" + }, + "capath" : { + "default" : "/etc/ssl/certs", + "description" : "Path to the CA certificate store", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "case-sensitive" : { + "default" : 1, + "description" : "username is case-sensitive", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cert" : { + "description" : "Path to the client certificate", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "certkey" : { + "description" : "Path to the client certificate key", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "client-id" : { + "description" : "OpenID Client ID", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "client-key" : { + "description" : "OpenID Client Key", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "default" : { + "description" : "Use this as default realm", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "domain" : { + "description" : "AD domain name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\S+", + "type" : "string" + }, + "filter" : { + "description" : "LDAP filter for user sync.", + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_classes" : { + "default" : "groupOfNames, group, univentionGroup, ipausergroup", + "description" : "The objectclasses for groups.", + "format" : "ldap-simple-attr-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_dn" : { + "description" : "LDAP base domain name for group sync. If not set, the base_dn will be used.", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^:\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+)(,\\s*\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+))*)", + "type" : "string" + }, + "group_filter" : { + "description" : "LDAP filter for group sync.", + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_name_attr" : { + "description" : "LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.", + "format" : "ldap-simple-attr", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "issuer-url" : { + "description" : "OpenID Issuer Url", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mode" : { + "default" : "ldap", + "description" : "LDAP protocol mode.", + "enum" : [ + "ldap", + "ldaps", + "ldap+starttls" + ], + "optional" : 1, + "type" : "string" + }, + "password" : { + "description" : "LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Server port.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "prompt" : { + "description" : "Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.", + "optional" : 1, + "pattern" : "(?:none|login|consent|select_account|\\S+)", + "type" : "string" + }, + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + }, + "scopes" : { + "default" : "email profile", + "description" : "Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "secure" : { + "description" : "Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "server1" : { + "description" : "Server IP address (or DNS name)", + "format" : "address", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server2" : { + "description" : "Fallback Server IP address (or DNS name)", + "format" : "address", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sslversion" : { + "description" : "LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!", + "enum" : [ + "tlsv1", + "tlsv1_1", + "tlsv1_2", + "tlsv1_3" + ], + "optional" : 1, + "type" : "string" + }, + "sync-defaults-options" : { + "description" : "The default options for behavior of synchronizations.", + "format" : "realm-sync-options", + "optional" : 1, + "type" : "string", + "typetext" : "[enable-new=<1|0>] [,full=<1|0>] [,purge=<1|0>] [,remove-vanished=([acl];[properties];[entry])|none] [,scope=]" + }, + "sync_attributes" : { + "description" : "Comma separated list of key=value pairs for specifying which LDAP attributes map to which PVE user field. For example, to map the LDAP attribute 'mail' to PVEs 'email', write 'email=mail'. By default, each PVE user field is represented by an LDAP attribute of the same name.", + "optional" : 1, + "pattern" : "\\w+=[^,]+(,\\s*\\w+=[^,]+)*", + "type" : "string" + }, + "tfa" : { + "description" : "Use Two-factor authentication.", + "format" : "pve-tfa-config", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "type= [,digits=] [,id=] [,key=] [,step=] [,url=]" + }, + "type" : { + "description" : "Realm type.", + "enum" : [ + "ad", + "ldap", + "openid", + "pam", + "pve" + ], + "type" : "string" + }, + "user_attr" : { + "description" : "LDAP user attribute name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\S{2,}", + "type" : "string" + }, + "user_classes" : { + "default" : "inetorgperson, posixaccount, person, user", + "description" : "The objectclasses for users.", + "format" : "ldap-simple-attr-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "username-claim" : { + "description" : "OpenID claim used to generate the unique username.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "verify" : { + "default" : 0, + "description" : "Verify the server's SSL certificate", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/domains", + "text" : "domains" + }, + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Get the OpenId Authorization Url for the specified realm.", + "method" : "POST", + "name" : "auth_url", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + }, + "redirect-url" : { + "description" : "Redirection Url. The client should set this to the used server url (location.origin).", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "world" + }, + "protected" : 1, + "returns" : { + "description" : "Redirection URL.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/access/openid/auth-url", + "text" : "auth-url" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : " Verify OpenID authorization code and create a ticket.", + "method" : "POST", + "name" : "login", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "code" : { + "description" : "OpenId authorization code.", + "maxLength" : 4096, + "type" : "string", + "typetext" : "" + }, + "redirect-url" : { + "description" : "Redirection Url. The client should set this to the used server url (location.origin).", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + }, + "state" : { + "description" : "OpenId state.", + "maxLength" : 1024, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "world" + }, + "protected" : 1, + "returns" : { + "properties" : { + "CSRFPreventionToken" : { + "type" : "string" + }, + "cap" : { + "type" : "object" + }, + "clustername" : { + "optional" : 1, + "type" : "string" + }, + "ticket" : { + "type" : "string" + }, + "username" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/access/openid/login", + "text" : "login" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/access/openid", + "text" : "openid" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 0, + "description" : "Delete a TFA entry by ID.", + "method" : "DELETE", + "name" : "delete_tfa", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "A TFA entry id.", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The current password.", + "maxLength" : 64, + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 0, + "description" : "Fetch a requested TFA entry if present.", + "method" : "GET", + "name" : "get_tfa_entry", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "A TFA entry id.", + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "TFA Entry.", + "properties" : { + "created" : { + "description" : "Creation time of this entry as unix epoch.", + "type" : "integer" + }, + "description" : { + "description" : "User chosen description for this entry.", + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Whether this TFA entry is currently enabled.", + "optional" : 1, + "type" : "boolean" + }, + "id" : { + "description" : "The id used to reference this entry.", + "type" : "string" + }, + "type" : { + "description" : "TFA Entry Type.", + "enum" : [ + "totp", + "u2f", + "webauthn", + "recovery", + "yubico" + ], + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 0, + "description" : "Add a TFA entry for a user.", + "method" : "PUT", + "name" : "update_tfa_entry", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A description to distinguish multiple entries from one another", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Whether the entry should be enabled for login.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "A TFA entry id.", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The current password.", + "maxLength" : 64, + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/tfa/{userid}/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 0, + "description" : "List TFA configurations of users.", + "method" : "GET", + "name" : "list_user_tfa", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "A list of the user's TFA entries.", + "items" : { + "description" : "TFA Entry.", + "properties" : { + "created" : { + "description" : "Creation time of this entry as unix epoch.", + "type" : "integer" + }, + "description" : { + "description" : "User chosen description for this entry.", + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Whether this TFA entry is currently enabled.", + "optional" : 1, + "type" : "boolean" + }, + "id" : { + "description" : "The id used to reference this entry.", + "type" : "string" + }, + "type" : { + "description" : "TFA Entry Type.", + "enum" : [ + "totp", + "u2f", + "webauthn", + "recovery", + "yubico" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 0, + "description" : "Add a TFA entry for a user.", + "method" : "POST", + "name" : "add_tfa_entry", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "challenge" : { + "description" : "When responding to a u2f challenge: the original challenge string", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "A description to distinguish multiple entries from one another", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The current password.", + "maxLength" : 64, + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "totp" : { + "description" : "A totp URI.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "TFA Entry Type.", + "enum" : [ + "totp", + "u2f", + "webauthn", + "recovery", + "yubico" + ], + "type" : "string" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + }, + "value" : { + "description" : "The current value for the provided totp URI, or a Webauthn/U2F challenge response", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "challenge" : { + "description" : "When adding u2f entries, this contains a challenge the user must respond to in order to finish the registration.", + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "The id of a newly added TFA entry.", + "type" : "string" + }, + "recovery" : { + "description" : "When adding recovery codes, this contains the list of codes to be displayed to the user", + "items" : { + "description" : "A recovery entry.", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 0, + "path" : "/access/tfa/{userid}", + "text" : "{userid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 0, + "description" : "List TFA configurations of users.", + "method" : "GET", + "name" : "list_tfa", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "Returns all or just the logged-in user, depending on privileges.", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "description" : "The list tuples of user and TFA entries.", + "items" : { + "properties" : { + "entries" : { + "items" : { + "description" : "TFA Entry.", + "properties" : { + "created" : { + "description" : "Creation time of this entry as unix epoch.", + "type" : "integer" + }, + "description" : { + "description" : "User chosen description for this entry.", + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Whether this TFA entry is currently enabled.", + "optional" : 1, + "type" : "boolean" + }, + "id" : { + "description" : "The id used to reference this entry.", + "type" : "string" + }, + "type" : { + "description" : "TFA Entry Type.", + "enum" : [ + "totp", + "u2f", + "webauthn", + "recovery", + "yubico" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "userid" : { + "description" : "User this entry belongs to.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 0, + "description" : "Finish a u2f challenge.", + "method" : "POST", + "name" : "verify_tfa", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "response" : { + "description" : "The response to the current authentication challenge.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "protected" : 1, + "returns" : { + "properties" : { + "ticket" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 0, + "path" : "/access/tfa", + "text" : "tfa" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Dummy. Useful for formatters which want to provide a login page.", + "method" : "GET", + "name" : "get_ticket", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "world" + }, + "returns" : { + "type" : "null" + } + }, + "POST" : { + "allowtoken" : 0, + "description" : "Create or verify authentication ticket.", + "method" : "POST", + "name" : "create_ticket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "new-format" : { + "default" : 0, + "description" : "With webauthn the format of half-authenticated tickts changed. New clients should pass 1 here and not worry about the old format. The old format is deprecated and will be retired with PVE-8.0", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "otp" : { + "description" : "One-time password for Two-factor authentication.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The secret password. This can also be a valid ticket.", + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "Verify ticket, and check if user have access 'privs' on 'path'", + "maxLength" : 64, + "optional" : 1, + "requires" : "privs", + "type" : "string", + "typetext" : "" + }, + "privs" : { + "description" : "Verify ticket, and check if user have access 'privs' on 'path'", + "format" : "pve-priv-list", + "maxLength" : 64, + "optional" : 1, + "requires" : "path", + "type" : "string", + "typetext" : "" + }, + "realm" : { + "description" : "You can optionally pass the realm using this parameter. Normally the realm is simply added to the username @.", + "format" : "pve-realm", + "maxLength" : 32, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tfa-challenge" : { + "description" : "The signed TFA challenge string the user wants to respond to.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "User name", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need to pass valid credientials.", + "user" : "world" + }, + "protected" : 1, + "returns" : { + "properties" : { + "CSRFPreventionToken" : { + "optional" : 1, + "type" : "string" + }, + "clustername" : { + "optional" : 1, + "type" : "string" + }, + "ticket" : { + "optional" : 1, + "type" : "string" + }, + "username" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/ticket", + "text" : "ticket" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 0, + "description" : "Change user password.", + "method" : "PUT", + "name" : "change_password", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "password" : { + "description" : "The new password.", + "maxLength" : 64, + "minLength" : 5, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + ], + "description" : "Each user is allowed to change his own password. A user can change the password of another user if he has 'Realm.AllocateUser' (on the realm of user ) and 'User.Modify' permission on /access/groups/ on a group where user is member of." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/password", + "text" : "password" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Retrieve effective permissions of given user/token.", + "method" : "GET", + "name" : "permissions", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "path" : { + "description" : "Only dump this specific path, not the whole tree.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "User ID or full API token ID", + "optional" : 1, + "pattern" : "(?^:^(?^:[^\\s:/]+)\\@(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)(?:!(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+))?$)", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Each user/token is allowed to dump their own permissions. A user can dump the permissions of another user if they have 'Sys.Audit' permission on /access.", + "user" : "all" + }, + "returns" : { + "description" : "Map of \"path\" => (Map of \"privilege\" => \"propagate boolean\").", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/permissions", + "text" : "permissions" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/access", + "text" : "access" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete pool.", + "method" : "DELETE", + "name" : "delete_pool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description" : "You can only delete empty pools (no members)." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get pool configuration.", + "method" : "GET", + "name" : "read_pool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + }, + "type" : { + "enum" : [ + "qemu", + "lxc", + "storage" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Audit" + ] + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "members" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "id" : { + "type" : "string" + }, + "node" : { + "type" : "string" + }, + "storage" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "enum" : [ + "qemu", + "lxc", + "openvz", + "storage" + ], + "type" : "string" + }, + "vmid" : { + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update pool data.", + "method" : "PUT", + "name" : "update_pool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "Remove vms/storage (instead of adding it).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "List of storage IDs.", + "format" : "pve-storage-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "List of virtual machines.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description" : "You also need the right to modify permissions on any object you add/delete." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/pools/{poolid}", + "text" : "{poolid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Pool index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "List all pools where you have Pool.Audit permissions on /pool/.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "poolid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{poolid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new pool.", + "method" : "POST", + "name" : "create_pool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/pools", + "text" : "pools" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "API version details, including some parts of the global datacenter config.", + "method" : "GET", + "name" : "version", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "properties" : { + "console" : { + "description" : "The default console viewer to use.", + "enum" : [ + "applet", + "vv", + "html5", + "xtermjs" + ], + "optional" : 1, + "type" : "string" + }, + "release" : { + "description" : "The current Proxmox VE point release in `x.y` format.", + "type" : "string" + }, + "repoid" : { + "description" : "The short git revision from which this version was build.", + "type" : "string" + }, + "version" : { + "description" : "The full pve-manager package version of this node.", + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/version", + "text" : "version" + } +] +; + +let method2cmd = { + GET: 'get', + POST: 'create', + PUT: 'set', + DELETE: 'delete' +}; + +function cliUsageRenderer(method, path) { + return ` CLI:pvesh ${method2cmd[method]} ${path}`; +} +/*global apiSchema*/ + +Ext.onReady(function() { + Ext.define('pmx-param-schema', { + extend: 'Ext.data.Model', + fields: [ + 'name', 'type', 'typetext', 'description', 'verbose_description', + 'enum', 'minimum', 'maximum', 'minLength', 'maxLength', + 'pattern', 'title', 'requires', 'format', 'default', + 'disallow', 'extends', 'links', + { + name: 'optional', + type: 'boolean', + }, + ], + }); + + let store = Ext.define('pmx-updated-treestore', { + extend: 'Ext.data.TreeStore', + model: Ext.define('pmx-api-doc', { + extend: 'Ext.data.Model', + fields: [ + 'path', 'info', 'text', + ], + }), + proxy: { + type: 'memory', + data: apiSchema, + }, + sorters: [{ + property: 'leaf', + direction: 'ASC', + }, { + property: 'text', + direction: 'ASC', + }], + filterer: 'bottomup', + doFilter: function(node) { + this.filterNodes(node, this.getFilters().getFilterFn(), true); + }, + + filterNodes: function(node, filterFn, parentVisible) { + let me = this; + + let match = filterFn(node) && (parentVisible || (node.isRoot() && !me.getRootVisible())); + + if (node.childNodes && node.childNodes.length) { + let bottomUpFiltering = me.filterer === 'bottomup'; + let childMatch; + for (const child of node.childNodes) { + childMatch = me.filterNodes(child, filterFn, match || bottomUpFiltering) || childMatch; + } + if (bottomUpFiltering) { + match = childMatch || match; + } + } + + node.set("visible", match, me._silentOptions); + return match; + }, + + }).create(); + + let render_description = function(value, metaData, record) { + let pdef = record.data; + + value = pdef.verbose_description || value; + + // TODO: try to render asciidoc correctly + + metaData.style = 'white-space:pre-wrap;'; + + return Ext.htmlEncode(value); + }; + + let render_type = function(value, metaData, record) { + let pdef = record.data; + + return pdef.enum ? 'enum' : pdef.type || 'string'; + }; + + const renderFormatString = function(obj) { + if (!Ext.isObject(obj)) { + return obj; + } + const mandatory = []; + const optional = []; + Object.entries(obj).forEach(function([name, param]) { + let list = param.optional ? optional : mandatory; + let str = param.default_key ? `[${name}=]` : `${name}=`; + if (param.alias) { + return; + } else if (param.enum) { + str += `(${param.enum?.join(' | ')})`; + } else { + str += `<${param.format_description || param.pattern || param.type}>`; + } + list.push(str); + }); + return mandatory.join(", ") + ' ' + optional.map(each => `[,${each}]`).join(' '); + }; + + let render_simple_format = function(pdef, type_fallback) { + if (pdef.typetext) { + return pdef.typetext; + } + if (pdef.enum) { + return pdef.enum.join(' | '); + } + if (pdef.format) { + return renderFormatString(pdef.format); + } + if (pdef.pattern) { + return pdef.pattern; + } + if (pdef.type === 'boolean') { + return ``; + } + if (type_fallback && pdef.type) { + return `<${pdef.type}>`; + } + if (pdef.minimum || pdef.maximum) { + return `${pdef.minimum || 'N'} - ${pdef.maximum || 'N'}`; + } + return ''; + }; + + let render_format = function(value, metaData, record) { + let pdef = record.data; + + metaData.style = 'white-space:normal;'; + + if (pdef.type === 'array' && pdef.items) { + let format = render_simple_format(pdef.items, true); + return `[${Ext.htmlEncode(format)}, ...]`; + } + + return Ext.htmlEncode(render_simple_format(pdef)); + }; + + let real_path = function(path) { + if (!path.match(/^[/]/)) { + path = `/${path}`; + } + return path.replace(/^.*\/_upgrade_(\/)?/, "/"); + }; + + let permission_text = function(permission) { + let permhtml = ""; + + if (permission.user) { + if (!permission.description) { + if (permission.user === 'world') { + permhtml += "Accessible without any authentication."; + } else if (permission.user === 'all') { + permhtml += "Accessible by all authenticated users."; + } else { + permhtml += `Only accessible by user "${permission.user}"`; + } + } + } else if (permission.check) { + permhtml += `
Check: ${Ext.htmlEncode(JSON.stringify(permission.check))}
`; + } else if (permission.userParam) { + permhtml += `
Check if user matches parameter '${permission.userParam}'`; + } else if (permission.or) { + permhtml += "
Or
"; + permhtml += permission.or.map(v => permission_text(v)).join(''); + permhtml += "
"; + } else if (permission.and) { + permhtml += "
And
"; + permhtml += permission.and.map(v => permission_text(v)).join(''); + permhtml += "
"; + } else { + permhtml += "Unknown syntax!"; + } + + return permhtml; + }; + + let render_docu = function(data) { + let md = data.info; + + let items = []; + + Ext.Array.each(['GET', 'POST', 'PUT', 'DELETE'], function(method) { + let info = md[method]; + if (info) { + let endpoint = real_path(data.path); + let usage = ``; + + if (typeof cliUsageRenderer === 'function') { + usage += cliUsageRenderer(method, endpoint); // eslint-disable-line no-undef + } + + let sections = [ + { + title: 'Description', + html: Ext.htmlEncode(info.description), + bodyPadding: 10, + }, + { + title: 'Usage', + html: usage, + bodyPadding: 10, + }, + ]; + + if (info.parameters && info.parameters.properties) { + let pstore = Ext.create('Ext.data.Store', { + model: 'pmx-param-schema', + proxy: { + type: 'memory', + }, + groupField: 'optional', + sorters: [ + { + property: 'name', + direction: 'ASC', + }, + ], + }); + + Ext.Object.each(info.parameters.properties, function(name, pdef) { + pdef.name = name; + pstore.add(pdef); + }); + + pstore.sort(); + + let groupingFeature = Ext.create('Ext.grid.feature.Grouping', { + enableGroupingMenu: false, + groupHeaderTpl: 'OptionalRequired', + }); + + sections.push({ + xtype: 'gridpanel', + title: 'Parameters', + features: [groupingFeature], + store: pstore, + viewConfig: { + trackOver: false, + stripeRows: true, + enableTextSelection: true, + }, + columns: [ + { + header: 'Name', + dataIndex: 'name', + flex: 1, + }, + { + header: 'Type', + dataIndex: 'type', + renderer: render_type, + flex: 1, + }, + { + header: 'Default', + dataIndex: 'default', + flex: 1, + }, + { + header: 'Format', + dataIndex: 'type', + renderer: render_format, + flex: 2, + }, + { + header: 'Description', + dataIndex: 'description', + renderer: render_description, + flex: 6, + }, + ], + }); + } + + if (info.returns) { + let retinf = info.returns; + let rtype = retinf.type; + if (!rtype && retinf.items) {rtype = 'array';} + if (!rtype) {rtype = 'object';} + + let rpstore = Ext.create('Ext.data.Store', { + model: 'pmx-param-schema', + proxy: { + type: 'memory', + }, + groupField: 'optional', + sorters: [ + { + property: 'name', + direction: 'ASC', + }, + ], + }); + + let properties; + if (rtype === 'array' && retinf.items.properties) { + properties = retinf.items.properties; + } + + if (rtype === 'object' && retinf.properties) { + properties = retinf.properties; + } + + Ext.Object.each(properties, function(name, pdef) { + pdef.name = name; + rpstore.add(pdef); + }); + + rpstore.sort(); + + let groupingFeature = Ext.create('Ext.grid.feature.Grouping', { + enableGroupingMenu: false, + groupHeaderTpl: 'OptionalObligatory', + }); + let returnhtml; + if (retinf.items) { + returnhtml = '
items: ' + Ext.htmlEncode(JSON.stringify(retinf.items, null, 4)) + '
'; + } + + if (retinf.properties) { + returnhtml = returnhtml || ''; + returnhtml += '
properties:' + Ext.htmlEncode(JSON.stringify(retinf.properties, null, 4)) + '
'; + } + + let rawSection = Ext.create('Ext.panel.Panel', { + bodyPadding: '0px 10px 10px 10px', + html: returnhtml, + hidden: true, + }); + + sections.push({ + xtype: 'gridpanel', + title: 'Returns: ' + rtype, + features: [groupingFeature], + store: rpstore, + viewConfig: { + trackOver: false, + stripeRows: true, + enableTextSelection: true, + }, + columns: [ + { + header: 'Name', + dataIndex: 'name', + flex: 1, + }, + { + header: 'Type', + dataIndex: 'type', + renderer: render_type, + flex: 1, + }, + { + header: 'Default', + dataIndex: 'default', + flex: 1, + }, + { + header: 'Format', + dataIndex: 'type', + renderer: render_format, + flex: 2, + }, + { + header: 'Description', + dataIndex: 'description', + renderer: render_description, + flex: 6, + }, + ], + bbar: [ + { + xtype: 'button', + text: 'Show RAW', + handler: function(btn) { + rawSection.setVisible(!rawSection.isVisible()); + btn.setText(rawSection.isVisible() ? 'Hide RAW' : 'Show RAW'); + }, + }, + ], + }); + + sections.push(rawSection); + } + + if (!data.path.match(/\/_upgrade_/)) { + let permhtml = ''; + + if (!info.permissions) { + permhtml = "Root only."; + } else { + if (info.permissions.description) { + permhtml += "
" + + Ext.htmlEncode(info.permissions.description) + "
"; + } + permhtml += permission_text(info.permissions); + } + + if (info.allowtoken !== undefined && !info.allowtoken) { + permhtml += "
This API endpoint is not available for API tokens."; + } + + sections.push({ + title: 'Required permissions', + bodyPadding: 10, + html: permhtml, + }); + } + + items.push({ + title: method, + autoScroll: true, + defaults: { + border: false, + }, + items: sections, + }); + } + }); + + let ct = Ext.getCmp('docview'); + ct.setTitle("Path: " + real_path(data.path)); + ct.removeAll(true); + ct.add(items); + ct.setActiveTab(0); + }; + + Ext.define('Ext.form.SearchField', { + extend: 'Ext.form.field.Text', + alias: 'widget.searchfield', + + emptyText: 'Search...', + + flex: 1, + + inputType: 'search', + listeners: { + 'change': function() { + let value = this.getValue(); + if (!Ext.isEmpty(value)) { + store.filter({ + property: 'path', + value: value, + anyMatch: true, + }); + } else { + store.clearFilter(); + } + }, + }, + }); + + let treePanel = Ext.create('Ext.tree.Panel', { + title: 'Resource Tree', + tbar: [ + { + xtype: 'searchfield', + }, + ], + tools: [ + { + type: 'expand', + tooltip: 'Expand all', + tooltipType: 'title', + callback: tree => tree.expandAll(), + }, + { + type: 'collapse', + tooltip: 'Collapse all', + tooltipType: 'title', + callback: tree => tree.collapseAll(), + }, + ], + store: store, + width: 200, + region: 'west', + split: true, + margins: '5 0 5 5', + rootVisible: false, + listeners: { + selectionchange: function(v, selections) { + if (!selections[0]) {return;} + let rec = selections[0]; + render_docu(rec.data); + location.hash = '#' + rec.data.path; + }, + }, + }); + + Ext.create('Ext.container.Viewport', { + layout: 'border', + renderTo: Ext.getBody(), + items: [ + treePanel, + { + xtype: 'tabpanel', + title: 'Documentation', + id: 'docview', + region: 'center', + margins: '5 5 5 0', + layout: 'fit', + items: [], + }, + ], + }); + + let deepLink = function() { + let path = window.location.hash.substring(1).replace(/\/\s*$/, ''); + let endpoint = store.findNode('path', path); + + if (endpoint) { + treePanel.getSelectionModel().select(endpoint); + treePanel.expandPath(endpoint.getPath()); + render_docu(endpoint.data); + } + }; + window.onhashchange = deepLink; + + deepLink(); +}); diff --git a/contracts/2cf632fa6ea4939ca9cb7998ade688150db25b0684600f53ac0ca95730f1d99f/snapshot.json b/contracts/2cf632fa6ea4939ca9cb7998ade688150db25b0684600f53ac0ca95730f1d99f/snapshot.json new file mode 100644 index 0000000..e118eba --- /dev/null +++ b/contracts/2cf632fa6ea4939ca9cb7998ade688150db25b0684600f53ac0ca95730f1d99f/snapshot.json @@ -0,0 +1 @@ +{"extra":{"warning_count":0},"format_version":1,"method_count":540,"path_count":364,"paths":[{"extra":{},"methods":[{"allow_token":true,"checksum":"381dbe2603a3fe4644aef5716358b57a8c8df69ae5476d4204ec50da62e28f19","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/access"},{"extra":{},"methods":[{"allow_token":true,"checksum":"69d1196ad983a4e9b6440c4dc7050a74d305be5327ff2b7231df69a5f7300f0a","description":"Get Access Control List (ACLs).","extra":{},"name":"read_acl","parameters":[],"permissions":{"description":"The returned list is restricted to objects where you have rights to modify permissions.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":0},"properties":{"path":{"description":"Access control path","enum":[],"extra":{},"properties":{},"type":"string"},"propagate":{"default":1,"description":"Allow to propagate (inherit) permissions.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"roleid":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":["user","group","token"],"extra":{},"properties":{},"type":"string"},"ugid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f303163fa6559541cc81fcd57689b33e3ed216ea236d34d63cd9d35e3fce947a","description":"Update Access Control List (add or remove permissions).","extra":{},"name":"update_acl","parameters":[{"definition":{"description":"Remove permissions (instead of adding it).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"List of groups.","enum":[],"extra":{"typetext":""},"format":"pve-groupid-list","optional":true,"properties":{},"type":"string"},"name":"groups"},{"definition":{"description":"Access control path","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"path"},{"definition":{"default":1,"description":"Allow to propagate (inherit) permissions.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"propagate"},{"definition":{"description":"List of roles.","enum":[],"extra":{"typetext":""},"format":"pve-roleid-list","properties":{},"type":"string"},"name":"roles"},{"definition":{"description":"List of API tokens.","enum":[],"extra":{"typetext":""},"format":"pve-tokenid-list","optional":true,"properties":{},"type":"string"},"name":"tokens"},{"definition":{"description":"List of users.","enum":[],"extra":{"typetext":""},"format":"pve-userid-list","optional":true,"properties":{},"type":"string"},"name":"users"}],"permissions":{"expression":{"check":["perm-modify","{path}"]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/acl"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f6bd08a792d4f4d22aac7aaddba3d623b96b8333f6e0e464a8782c3ebc6c764b","description":"Authentication domain index.","extra":{},"name":"index","parameters":[],"permissions":{"description":"Anyone can access that, because we need that list for the login box (before the user is authenticated).","expression":{},"extra":{},"user":"world"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{realm}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"A comment. The GUI use this text when you select a domain (Realm) on the login window.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"realm":{"enum":[],"extra":{},"properties":{},"type":"string"},"tfa":{"description":"Two-factor authentication provider.","enum":["yubico","oath"],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"c37036ddcec2f32b7dce103bb0920bdc021e7eb3a2c97605ce38250ea05170d3","description":"Add an authentication server.","extra":{},"name":"create","parameters":[{"definition":{"description":"Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"acr-values"},{"definition":{"default":0,"description":"Automatically create users if they do not exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autocreate"},{"definition":{"description":"LDAP base domain name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^:\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+)(,\\s*\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+))*)","properties":{},"type":"string"},"name":"base_dn"},{"definition":{"description":"LDAP bind domain name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^:\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+)(,\\s*\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+))*)","properties":{},"type":"string"},"name":"bind_dn"},{"definition":{"default":"/etc/ssl/certs","description":"Path to the CA certificate store","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"capath"},{"definition":{"default":1,"description":"username is case-sensitive","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"case-sensitive"},{"definition":{"description":"Path to the client certificate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cert"},{"definition":{"description":"Path to the client certificate key","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"certkey"},{"definition":{"description":"OpenID Client ID","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"client-id"},{"definition":{"description":"OpenID Client Key","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"client-key"},{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Use this as default realm","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"default"},{"definition":{"description":"AD domain name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\S+","properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"LDAP filter for user sync.","enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"filter"},{"definition":{"default":"groupOfNames, group, univentionGroup, ipausergroup","description":"The objectclasses for groups.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr-list","optional":true,"properties":{},"type":"string"},"name":"group_classes"},{"definition":{"description":"LDAP base domain name for group sync. If not set, the base_dn will be used.","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^:\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+)(,\\s*\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+))*)","properties":{},"type":"string"},"name":"group_dn"},{"definition":{"description":"LDAP filter for group sync.","enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"group_filter"},{"definition":{"description":"LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"group_name_attr"},{"definition":{"description":"OpenID Issuer Url","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"issuer-url"},{"definition":{"default":"ldap","description":"LDAP protocol mode.","enum":["ldap","ldaps","ldap+starttls"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Server port.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.","enum":[],"extra":{},"optional":true,"pattern":"(?:none|login|consent|select_account|\\S+)","properties":{},"type":"string"},"name":"prompt"},{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"},{"definition":{"default":"email profile","description":"Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"scopes"},{"definition":{"description":"Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"secure"},{"definition":{"description":"Server IP address (or DNS name)","enum":[],"extra":{"typetext":""},"format":"address","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"server1"},{"definition":{"description":"Fallback Server IP address (or DNS name)","enum":[],"extra":{"typetext":""},"format":"address","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"server2"},{"definition":{"description":"LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!","enum":["tlsv1","tlsv1_1","tlsv1_2","tlsv1_3"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"sslversion"},{"definition":{"description":"The default options for behavior of synchronizations.","enum":[],"extra":{"typetext":"[enable-new=<1|0>] [,full=<1|0>] [,purge=<1|0>] [,remove-vanished=([acl];[properties];[entry])|none] [,scope=]"},"format":"realm-sync-options","optional":true,"properties":{},"type":"string"},"name":"sync-defaults-options"},{"definition":{"description":"Comma separated list of key=value pairs for specifying which LDAP attributes map to which PVE user field. For example, to map the LDAP attribute 'mail' to PVEs 'email', write 'email=mail'. By default, each PVE user field is represented by an LDAP attribute of the same name.","enum":[],"extra":{},"optional":true,"pattern":"\\w+=[^,]+(,\\s*\\w+=[^,]+)*","properties":{},"type":"string"},"name":"sync_attributes"},{"definition":{"description":"Use Two-factor authentication.","enum":[],"extra":{"typetext":"type= [,digits=] [,id=] [,key=] [,step=] [,url=]"},"format":"pve-tfa-config","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"tfa"},{"definition":{"description":"Realm type.","enum":["ad","ldap","openid","pam","pve"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"LDAP user attribute name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\S{2,}","properties":{},"type":"string"},"name":"user_attr"},{"definition":{"default":"inetorgperson, posixaccount, person, user","description":"The objectclasses for users.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr-list","optional":true,"properties":{},"type":"string"},"name":"user_classes"},{"definition":{"description":"OpenID claim used to generate the unique username.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username-claim"},{"definition":{"default":0,"description":"Verify the server's SSL certificate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify"}],"permissions":{"expression":{"check":["perm","/access/realm",["Realm.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/domains"},{"extra":{},"methods":[{"allow_token":true,"checksum":"67ef2d8bf073fff13e3d81cd559ffa0c8d70b56f153a1a682bf52b5e6068f2ee","description":"Delete an authentication server.","extra":{},"name":"delete","parameters":[{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"}],"permissions":{"expression":{"check":["perm","/access/realm",["Realm.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"68ad3629142a043ace8f38217d65a6ecf29d34a83d21ff690c0def6efcdabd7c","description":"Get auth server configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"}],"permissions":{"expression":{"check":["perm","/access/realm",["Realm.Allocate","Sys.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{}},"verb":"GET"},{"allow_token":true,"checksum":"34572a9051c4ec6d5935234c0eee6df1d6368603949085772d65a2361a882523","description":"Update authentication server settings.","extra":{},"name":"update","parameters":[{"definition":{"description":"Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"acr-values"},{"definition":{"default":0,"description":"Automatically create users if they do not exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autocreate"},{"definition":{"description":"LDAP base domain name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^:\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+)(,\\s*\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+))*)","properties":{},"type":"string"},"name":"base_dn"},{"definition":{"description":"LDAP bind domain name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^:\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+)(,\\s*\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+))*)","properties":{},"type":"string"},"name":"bind_dn"},{"definition":{"default":"/etc/ssl/certs","description":"Path to the CA certificate store","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"capath"},{"definition":{"default":1,"description":"username is case-sensitive","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"case-sensitive"},{"definition":{"description":"Path to the client certificate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cert"},{"definition":{"description":"Path to the client certificate key","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"certkey"},{"definition":{"description":"OpenID Client ID","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"client-id"},{"definition":{"description":"OpenID Client Key","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"client-key"},{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Use this as default realm","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"default"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"AD domain name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\S+","properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"LDAP filter for user sync.","enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"filter"},{"definition":{"default":"groupOfNames, group, univentionGroup, ipausergroup","description":"The objectclasses for groups.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr-list","optional":true,"properties":{},"type":"string"},"name":"group_classes"},{"definition":{"description":"LDAP base domain name for group sync. If not set, the base_dn will be used.","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^:\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+)(,\\s*\\w+=(\"[\\w ,+/<>;=]+\"|[^ ,+\"/<>;=]+))*)","properties":{},"type":"string"},"name":"group_dn"},{"definition":{"description":"LDAP filter for group sync.","enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"group_filter"},{"definition":{"description":"LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"group_name_attr"},{"definition":{"description":"OpenID Issuer Url","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"issuer-url"},{"definition":{"default":"ldap","description":"LDAP protocol mode.","enum":["ldap","ldaps","ldap+starttls"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Server port.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.","enum":[],"extra":{},"optional":true,"pattern":"(?:none|login|consent|select_account|\\S+)","properties":{},"type":"string"},"name":"prompt"},{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"},{"definition":{"default":"email profile","description":"Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"scopes"},{"definition":{"description":"Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"secure"},{"definition":{"description":"Server IP address (or DNS name)","enum":[],"extra":{"typetext":""},"format":"address","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"server1"},{"definition":{"description":"Fallback Server IP address (or DNS name)","enum":[],"extra":{"typetext":""},"format":"address","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"server2"},{"definition":{"description":"LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!","enum":["tlsv1","tlsv1_1","tlsv1_2","tlsv1_3"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"sslversion"},{"definition":{"description":"The default options for behavior of synchronizations.","enum":[],"extra":{"typetext":"[enable-new=<1|0>] [,full=<1|0>] [,purge=<1|0>] [,remove-vanished=([acl];[properties];[entry])|none] [,scope=]"},"format":"realm-sync-options","optional":true,"properties":{},"type":"string"},"name":"sync-defaults-options"},{"definition":{"description":"Comma separated list of key=value pairs for specifying which LDAP attributes map to which PVE user field. For example, to map the LDAP attribute 'mail' to PVEs 'email', write 'email=mail'. By default, each PVE user field is represented by an LDAP attribute of the same name.","enum":[],"extra":{},"optional":true,"pattern":"\\w+=[^,]+(,\\s*\\w+=[^,]+)*","properties":{},"type":"string"},"name":"sync_attributes"},{"definition":{"description":"Use Two-factor authentication.","enum":[],"extra":{"typetext":"type= [,digits=] [,id=] [,key=] [,step=] [,url=]"},"format":"pve-tfa-config","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"tfa"},{"definition":{"description":"LDAP user attribute name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\S{2,}","properties":{},"type":"string"},"name":"user_attr"},{"definition":{"default":"inetorgperson, posixaccount, person, user","description":"The objectclasses for users.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr-list","optional":true,"properties":{},"type":"string"},"name":"user_classes"},{"definition":{"default":0,"description":"Verify the server's SSL certificate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify"}],"permissions":{"expression":{"check":["perm","/access/realm",["Realm.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/domains/{realm}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"22fdaec44885c324712bcbccec1df92bb47923a19cc62c7eb7db5e0fb502e600","description":"Syncs users and/or groups from the configured LDAP to user.cfg. NOTE: Synced groups will have the name 'name-$realm', so make sure those groups do not exist to prevent overwriting.","extra":{},"name":"sync","parameters":[{"definition":{"default":0,"description":"If set, does not write anything.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"dry-run"},{"definition":{"default":"1","description":"Enable newly synced users immediately.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable-new"},{"definition":{"description":"DEPRECATED: use 'remove-vanished' instead. If set, uses the LDAP Directory as source of truth, deleting users or groups not returned from the sync and removing all locally modified properties of synced users. If not set, only syncs information which is present in the synced data, and does not delete or modify anything else.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"},{"definition":{"description":"DEPRECATED: use 'remove-vanished' instead. Remove ACLs for users or groups which were removed from the config during a sync.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"purge"},{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"},{"definition":{"default":"none","description":"A semicolon-seperated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).","enum":[],"extra":{"typetext":"([acl];[properties];[entry])|none"},"optional":true,"pattern":"(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none","properties":{},"type":"string"},"name":"remove-vanished"},{"definition":{"description":"Select what to sync.","enum":["users","groups","both"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scope"}],"permissions":{"description":"'Realm.AllocateUser' on '/access/realm/' and 'User.Modify' permissions to '/access/groups/'.","expression":{"check":["and",["perm","/access/realm/{realm}",["Realm.AllocateUser"]],["perm","/access/groups",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"description":"Worker Task-UPID","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/access/domains/{realm}/sync"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4c91cdccabc91aef686778145ca3abfc7c583221f55d71a6a63742c0c9e8620e","description":"Group index.","extra":{},"name":"index","parameters":[],"permissions":{"description":"The returned list is restricted to groups where you have 'User.Modify', 'Sys.Audit' or 'Group.Allocate' permissions on /access/groups/.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{groupid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"groupid":{"enum":[],"extra":{},"format":"pve-groupid","properties":{},"type":"string"},"users":{"description":"list of users which form this group","enum":[],"extra":{},"format":"pve-userid-list","optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f98ce64f3980dff63659bf39b78cfd90bc57491d5a6b16adf211ad89cb5bacbf","description":"Create new group.","extra":{},"name":"create_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid","properties":{},"type":"string"},"name":"groupid"}],"permissions":{"expression":{"check":["perm","/access/groups",["Group.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/groups"},{"extra":{},"methods":[{"allow_token":true,"checksum":"da8c8fd5b71fd2ffb0d9a877a6a55bf3fece5793e6e84103fd32ce8393b143a9","description":"Delete group.","extra":{},"name":"delete_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid","properties":{},"type":"string"},"name":"groupid"}],"permissions":{"expression":{"check":["perm","/access/groups",["Group.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"97141e0ff4c0c701de5667b1695e08f82f1c7ca0457b431a4544c6b1b2ebf164","description":"Get group configuration.","extra":{},"name":"read_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid","properties":{},"type":"string"},"name":"groupid"}],"permissions":{"expression":{"check":["perm","/access/groups",["Sys.Audit","Group.Allocate"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"members":{"enum":[],"extra":{},"items":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"acae7739337fa0edb0e0a31549c4d29be7fdf80fd872c3b0e65f946d447c8570","description":"Update group data.","extra":{},"name":"update_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid","properties":{},"type":"string"},"name":"groupid"}],"permissions":{"expression":{"check":["perm","/access/groups",["Group.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/groups/{groupid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"381dbe2603a3fe4644aef5716358b57a8c8df69ae5476d4204ec50da62e28f19","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/access/openid"},{"extra":{},"methods":[{"allow_token":true,"checksum":"11698bf61b11bf04b51047fbad48466f21c0e0de4d90d25ed9650486cab24fdb","description":"Get the OpenId Authorization Url for the specified realm.","extra":{},"name":"auth_url","parameters":[{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"},{"definition":{"description":"Redirection Url. The client should set this to the used server url (location.origin).","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"redirect-url"}],"permissions":{"expression":{},"extra":{},"user":"world"},"protected":true,"returns":{"description":"Redirection URL.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/access/openid/auth-url"},{"extra":{},"methods":[{"allow_token":true,"checksum":"19ede18ffcfecdd547ec697670a70a44b18fe1b9f0160ba1e02d8446072ad21d","description":" Verify OpenID authorization code and create a ticket.","extra":{},"name":"login","parameters":[{"definition":{"description":"OpenId authorization code.","enum":[],"extra":{"typetext":""},"max_length":4096,"properties":{},"type":"string"},"name":"code"},{"definition":{"description":"Redirection Url. The client should set this to the used server url (location.origin).","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"redirect-url"},{"definition":{"description":"OpenId state.","enum":[],"extra":{"typetext":""},"max_length":1024,"properties":{},"type":"string"},"name":"state"}],"permissions":{"expression":{},"extra":{},"user":"world"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"CSRFPreventionToken":{"enum":[],"extra":{},"properties":{},"type":"string"},"cap":{"enum":[],"extra":{},"properties":{},"type":"object"},"clustername":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"username":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/access/openid/login"},{"extra":{},"methods":[{"allow_token":false,"checksum":"4ab1b1bfc745b312ceaf57e5fdf876a900209097c6d9e0f3a29344f0e575df90","description":"Change user password.","extra":{},"name":"change_password","parameters":[{"definition":{"description":"The new password.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":5,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"description":"Each user is allowed to change his own password. A user can change the password of another user if he has 'Realm.AllocateUser' (on the realm of user ) and 'User.Modify' permission on /access/groups/ on a group where user is member of.","expression":{"check":["or",["userid-param","self"],["and",["userid-param","Realm.AllocateUser"],["userid-group",["User.Modify"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/password"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4aac04b822f3f74be0f263ff09f286b4faa9ab89e430d6d635783be4935ad0a9","description":"Retrieve effective permissions of given user/token.","extra":{},"name":"permissions","parameters":[{"definition":{"description":"Only dump this specific path, not the whole tree.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"User ID or full API token ID","enum":[],"extra":{},"optional":true,"pattern":"(?^:^(?^:[^\\s:/]+)\\@(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)(?:!(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+))?$)","properties":{},"type":"string"},"name":"userid"}],"permissions":{"description":"Each user/token is allowed to dump their own permissions. A user can dump the permissions of another user if they have 'Sys.Audit' permission on /access.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"Map of \"path\" => (Map of \"privilege\" => \"propagate boolean\").","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/access/permissions"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7d4735a632ce33c51d1e2e47102b18f3b391b730e88f11993ab2319447462466","description":"Role index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{roleid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"privs":{"enum":[],"extra":{},"format":"pve-priv-list","optional":true,"properties":{},"type":"string"},"roleid":{"enum":[],"extra":{},"format":"pve-roleid","properties":{},"type":"string"},"special":{"default":0,"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f57a81b3de7e8d88ea26453fd9bf5d26eb5b707474daa5d903df0fd5883860d5","description":"Create new role.","extra":{},"name":"create_role","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-priv-list","optional":true,"properties":{},"type":"string"},"name":"privs"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-roleid","properties":{},"type":"string"},"name":"roleid"}],"permissions":{"expression":{"check":["perm","/access",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/roles"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f1877684ae2970429259e20a70086722eda0e3fbd75ec22dc770adfed8cdad01","description":"Delete role.","extra":{},"name":"delete_role","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-roleid","properties":{},"type":"string"},"name":"roleid"}],"permissions":{"expression":{"check":["perm","/access",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"b3a84cb5b20e5095de9b0afb9b643e4ac45431a60e3d88935996b6432e9c0977","description":"Get role configuration.","extra":{},"name":"read_role","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-roleid","properties":{},"type":"string"},"name":"roleid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"Datastore.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Datastore.AllocateSpace":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Datastore.AllocateTemplate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Datastore.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Group.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Permissions.Modify":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Pool.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Pool.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Realm.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Realm.AllocateUser":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"SDN.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"SDN.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Console":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Incoming":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Modify":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.PowerMgmt":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Syslog":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"User.Modify":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Backup":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Clone":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.CDROM":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.CPU":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Cloudinit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Disk":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.HWType":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Memory":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Network":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Options":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Console":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Migrate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Monitor":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.PowerMgmt":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Snapshot":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Snapshot.Rollback":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"de543d90c405a031a8d83dba37eaf7b9faa4301cd0cac388ad12bc18dfdeb306","description":"Update an existing role.","extra":{},"name":"update_role","parameters":[{"definition":{"enum":[],"extra":{"requires":"privs","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"append"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-priv-list","optional":true,"properties":{},"type":"string"},"name":"privs"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-roleid","properties":{},"type":"string"},"name":"roleid"}],"permissions":{"expression":{"check":["perm","/access",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/roles/{roleid}"},{"extra":{},"methods":[{"allow_token":false,"checksum":"6308917d5d2e19d85ce0cb7b15fc9ed309a42027ffab68c6931676947a1a0c51","description":"List TFA configurations of users.","extra":{},"name":"list_tfa","parameters":[],"permissions":{"description":"Returns all or just the logged-in user, depending on privileges.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"description":"The list tuples of user and TFA entries.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"entries":{"enum":[],"extra":{},"items":{"description":"TFA Entry.","enum":[],"extra":{},"properties":{"created":{"description":"Creation time of this entry as unix epoch.","enum":[],"extra":{},"properties":{},"type":"integer"},"description":{"description":"User chosen description for this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"enable":{"default":1,"description":"Whether this TFA entry is currently enabled.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"id":{"description":"The id used to reference this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"TFA Entry Type.","enum":["totp","u2f","webauthn","recovery","yubico"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"userid":{"description":"User this entry belongs to.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":false,"checksum":"31ea74e0ee99e322f30f18a289573617242eb338a8f4465ba2c512f018f6a12e","description":"Finish a u2f challenge.","extra":{},"name":"verify_tfa","parameters":[{"definition":{"description":"The response to the current authentication challenge.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"response"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"POST"}],"path":"/access/tfa"},{"extra":{},"methods":[{"allow_token":false,"checksum":"f069eadcc9ccdac1483aa057c744533fbacec9224c0ab93d3f70e6fb5a12501c","description":"List TFA configurations of users.","extra":{},"name":"list_user_tfa","parameters":[{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify","Sys.Audit"]]]},"extra":{}},"protected":true,"returns":{"description":"A list of the user's TFA entries.","enum":[],"extra":{},"items":{"description":"TFA Entry.","enum":[],"extra":{},"properties":{"created":{"description":"Creation time of this entry as unix epoch.","enum":[],"extra":{},"properties":{},"type":"integer"},"description":{"description":"User chosen description for this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"enable":{"default":1,"description":"Whether this TFA entry is currently enabled.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"id":{"description":"The id used to reference this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"TFA Entry Type.","enum":["totp","u2f","webauthn","recovery","yubico"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":false,"checksum":"efd3603f890aaf67cb1c5a0cd2fc7e562f55fa636c03266133fa63490aa87fce","description":"Add a TFA entry for a user.","extra":{},"name":"add_tfa_entry","parameters":[{"definition":{"description":"When responding to a u2f challenge: the original challenge string","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"challenge"},{"definition":{"description":"A description to distinguish multiple entries from one another","enum":[],"extra":{"typetext":""},"max_length":255,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The current password.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"A totp URI.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"totp"},{"definition":{"description":"TFA Entry Type.","enum":["totp","u2f","webauthn","recovery","yubico"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"},{"definition":{"description":"The current value for the provided totp URI, or a Webauthn/U2F challenge response","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"value"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"challenge":{"description":"When adding u2f entries, this contains a challenge the user must respond to in order to finish the registration.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"description":"The id of a newly added TFA entry.","enum":[],"extra":{},"properties":{},"type":"string"},"recovery":{"description":"When adding recovery codes, this contains the list of codes to be displayed to the user","enum":[],"extra":{},"items":{"description":"A recovery entry.","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"verb":"POST"}],"path":"/access/tfa/{userid}"},{"extra":{},"methods":[{"allow_token":false,"checksum":"f8893d41edd79934c7e276fd6066752d7d600892237ad4aa191ab66b4733df11","description":"Delete a TFA entry by ID.","extra":{},"name":"delete_tfa","parameters":[{"definition":{"description":"A TFA entry id.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The current password.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":false,"checksum":"32d994c8b130332559bacd6fd4ca62cda2aa60d32e7cf1e9bcc92b08bf913e4f","description":"Fetch a requested TFA entry if present.","extra":{},"name":"get_tfa_entry","parameters":[{"definition":{"description":"A TFA entry id.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"id"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify","Sys.Audit"]]]},"extra":{}},"protected":true,"returns":{"description":"TFA Entry.","enum":[],"extra":{},"properties":{"created":{"description":"Creation time of this entry as unix epoch.","enum":[],"extra":{},"properties":{},"type":"integer"},"description":{"description":"User chosen description for this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"enable":{"default":1,"description":"Whether this TFA entry is currently enabled.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"id":{"description":"The id used to reference this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"TFA Entry Type.","enum":["totp","u2f","webauthn","recovery","yubico"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":false,"checksum":"e8d67d921cccc9da89622f0c69fc32d518e0177ba2d933a11033ff86dd41428b","description":"Add a TFA entry for a user.","extra":{},"name":"update_tfa_entry","parameters":[{"definition":{"description":"A description to distinguish multiple entries from one another","enum":[],"extra":{"typetext":""},"max_length":255,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Whether the entry should be enabled for login.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"A TFA entry id.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The current password.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/tfa/{userid}/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b7321acfd13335fc9d66fb47358fa1b8f0ec6775a3c1733a8cdc617c3f9778b8","description":"Dummy. Useful for formatters which want to provide a login page.","extra":{},"name":"get_ticket","parameters":[],"permissions":{"expression":{},"extra":{},"user":"world"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"GET"},{"allow_token":false,"checksum":"2bbcb1f7d293bbdcc4806cab09a7b20bbb34bfc5852fcd14404e7a0092c9ea4d","description":"Create or verify authentication ticket.","extra":{},"name":"create_ticket","parameters":[{"definition":{"default":0,"description":"With webauthn the format of half-authenticated tickts changed. New clients should pass 1 here and not worry about the old format. The old format is deprecated and will be retired with PVE-8.0","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"new-format"},{"definition":{"description":"One-time password for Two-factor authentication.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"otp"},{"definition":{"description":"The secret password. This can also be a valid ticket.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Verify ticket, and check if user have access 'privs' on 'path'","enum":[],"extra":{"requires":"privs","typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"Verify ticket, and check if user have access 'privs' on 'path'","enum":[],"extra":{"requires":"path","typetext":""},"format":"pve-priv-list","max_length":64,"optional":true,"properties":{},"type":"string"},"name":"privs"},{"definition":{"description":"You can optionally pass the realm using this parameter. Normally the realm is simply added to the username @.","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"optional":true,"properties":{},"type":"string"},"name":"realm"},{"definition":{"description":"The signed TFA challenge string the user wants to respond to.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tfa-challenge"},{"definition":{"description":"User name","enum":[],"extra":{"typetext":""},"max_length":64,"properties":{},"type":"string"},"name":"username"}],"permissions":{"description":"You need to pass valid credientials.","expression":{},"extra":{},"user":"world"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"CSRFPreventionToken":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"clustername":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ticket":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"username":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"POST"}],"path":"/access/ticket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ba894d0080ca0b08cdd86c603d86e790da6f623fc9b8d0fcc25c6dd5bc2b80e7","description":"User index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Optional filter for enable property.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"default":0,"description":"Include group and token information.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"}],"permissions":{"description":"The returned list is restricted to users where you have 'User.Modify' or 'Sys.Audit' permissions on '/access/groups' or on a group the user belongs too. But it always includes the current (authenticated) user.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{userid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"email":{"enum":[],"extra":{},"format":"email-opt","optional":true,"properties":{},"type":"string"},"enable":{"default":1,"description":"Enable the account (default). You can set this to '0' to disable the account","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"expire":{"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"firstname":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"groups":{"enum":[],"extra":{},"format":"pve-groupid-list","optional":true,"properties":{},"type":"string"},"keys":{"description":"Keys for two factor auth (yubico).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"lastname":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"realm-type":{"description":"The type of the users realm","enum":[],"extra":{},"format":"pve-realm","optional":true,"properties":{},"type":"string"},"tokens":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"tokenid":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"userid":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{},"format":"pve-userid","max_length":64,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"55efa6eef167c35f01eefeb4143216763a72ceed2c81592b3f920db314587ded","description":"Create new user.","extra":{},"name":"create_user","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"email-opt","optional":true,"properties":{},"type":"string"},"name":"email"},{"definition":{"default":1,"description":"Enable the account (default). You can set this to '0' to disable the account","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"expire"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"firstname"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid-list","optional":true,"properties":{},"type":"string"},"name":"groups"},{"definition":{"description":"Keys for two factor auth (yubico).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"keys"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lastname"},{"definition":{"description":"Initial password.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"description":"You need 'Realm.AllocateUser' on '/access/realm/' on the realm of user , and 'User.Modify' permissions to '/access/groups/' for any group specified (or 'User.Modify' on '/access/groups' if you pass no groups.","expression":{"check":["and",["userid-param","Realm.AllocateUser"],["userid-group",["User.Modify"],"groups_param","create"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/users"},{"extra":{},"methods":[{"allow_token":true,"checksum":"22780e2427b9f89adfddae9c96331bf99e9988faa7d41c686fb83495858757ae","description":"Delete user.","extra":{},"name":"delete_user","parameters":[{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["and",["userid-param","Realm.AllocateUser"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"780680da123b7eeca4a8012243aa6738646567927a0069c3b515daf975a4efd0","description":"Get user configuration.","extra":{},"name":"read_user","parameters":[{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["userid-group",["User.Modify","Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"email":{"enum":[],"extra":{},"format":"email-opt","optional":true,"properties":{},"type":"string"},"enable":{"default":1,"description":"Enable the account (default). You can set this to '0' to disable the account","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"expire":{"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"firstname":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"groups":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"pve-groupid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"keys":{"description":"Keys for two factor auth (yubico).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"lastname":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"tokens":{"enum":[],"extra":{"additionalProperties":{"properties":{"comment":{"optional":1,"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","minimum":0,"optional":1,"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","optional":1,"type":"boolean"}},"type":"object"}},"optional":true,"properties":{},"type":"object"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"400939402ff9eb6014b430de2d31687e57c728b3530d47922f23121fa2f148a5","description":"Update user configuration.","extra":{},"name":"update_user","parameters":[{"definition":{"enum":[],"extra":{"requires":"groups","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"append"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"email-opt","optional":true,"properties":{},"type":"string"},"name":"email"},{"definition":{"default":1,"description":"Enable the account (default). You can set this to '0' to disable the account","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"expire"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"firstname"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid-list","optional":true,"properties":{},"type":"string"},"name":"groups"},{"definition":{"description":"Keys for two factor auth (yubico).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"keys"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lastname"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["userid-group",["User.Modify"],"groups_param","update"]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/users/{userid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"26f06a801f3aeabfcda58f7abde4e44ae2ea0b7d444bb45d43ab0a2b0ea914f6","description":"Get user TFA types (Personal and Realm).","extra":{},"name":"read_user_tfa_type","parameters":[{"definition":{"default":0,"description":"Request all entries as an array.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"multiple"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify","Sys.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"realm":{"description":"The type of TFA the users realm has set, if any.","enum":["oath","yubico"],"extra":{},"optional":true,"properties":{},"type":"string"},"types":{"description":"Array of the user configured TFA types, if any. Only available if 'multiple' was not passed.","enum":[],"extra":{},"items":{"description":"A TFA type.","enum":["totp","u2f","yubico","webauthn","recovedry"],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"user":{"description":"The type of TFA the user has set, if any. Only set if 'multiple' was not passed.","enum":["oath","u2f"],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/access/users/{userid}/tfa"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2360720a844aea0ccfa1e79e038d8f7e51fdbbf56b0326c4c494f6c74cda5c23","description":"Get user API tokens.","extra":{},"name":"token_index","parameters":[{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{tokenid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"tokenid":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/access/users/{userid}/token"},{"extra":{},"methods":[{"allow_token":true,"checksum":"90a204f61f32d1c0a9d7013a9d97a94ad045ddf8e8a632185529ef137603b2cf","description":"Remove API token for a specific user.","extra":{},"name":"remove_token","parameters":[{"definition":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"tokenid"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f828f02deaee05fa61e8f6f3a516e80c673e3378a5ee3207a542c04c0ec6ffeb","description":"Get specific API token information.","extra":{},"name":"read_token","parameters":[{"definition":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"tokenid"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"b49a880be0c3083d372de13e274dae7d56a3b454d854ae90924ed5ecde1cba28","description":"Generate a new API token for a specific user. NOTE: returns API token value, which needs to be stored as it cannot be retrieved afterwards!","extra":{},"name":"generate_token","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"expire"},{"definition":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"privsep"},{"definition":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"tokenid"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"full-tokenid":{"description":"The full token id.","enum":[],"extra":{"format_description":"!"},"properties":{},"type":"string"},"info":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"value":{"description":"API token value used for authentication.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"POST"},{"allow_token":true,"checksum":"479161dc3bc0e315503384e52b71a816bb68d2b8f04ad8880b76dd2b3f6c3a0d","description":"Update API token for a specific user.","extra":{},"name":"update_token_info","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"expire"},{"definition":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"privsep"},{"definition":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"tokenid"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"description":"Updated token information.","enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"PUT"}],"path":"/access/users/{userid}/token/{tokenid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8208fe00dcce4afff6857aaaea1b384b09f47069978af63ec4017df08db2adc2","description":"Cluster index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster"},{"extra":{},"methods":[{"allow_token":true,"checksum":"454de9c8ff02ffa321a5cb4dec888a3a945bddc5bb7b099c0da6cca8fb62090b","description":"ACMEAccount index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/acme"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1effbffd5ff5a4763a2fe7769dff21fc58d70d542b250d7117b4d7aa2264e0ca","description":"ACMEAccount index.","extra":{},"name":"account_index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"8d0f6d8961219fac42537b588694882669de3f2762a283e16e7ad4b918184a8e","description":"Register a new ACME account with CA.","extra":{},"name":"register_account","parameters":[{"definition":{"description":"Contact email addresses.","enum":[],"extra":{"typetext":""},"format":"email-list","properties":{},"type":"string"},"name":"contact"},{"definition":{"default":"https://acme-v02.api.letsencrypt.org/directory","description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"optional":true,"pattern":"^https?://.*","properties":{},"type":"string"},"name":"directory"},{"definition":{"default":"default","description":"ACME account config file name.","enum":[],"extra":{"format_description":"name","typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"URL of CA TermsOfService - setting this indicates agreement.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tos_url"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/acme/account"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b454212b12e22548f4709a1c2a277a21c02818412eadbb2d14bd24d8352bddf8","description":"Deactivate existing ACME account at CA.","extra":{},"name":"deactivate_account","parameters":[{"definition":{"default":"default","description":"ACME account config file name.","enum":[],"extra":{"format_description":"name","typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"name"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"8a68ee3cda0d4d131277b3fe68cbea1ed1fb044dc7ecec47cb77afc513eef373","description":"Return existing ACME account information.","extra":{},"name":"get_account","parameters":[{"definition":{"default":"default","description":"ACME account config file name.","enum":[],"extra":{"format_description":"name","typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"name"}],"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"account":{"enum":[],"extra":{"renderer":"yaml"},"optional":true,"properties":{},"type":"object"},"directory":{"description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"optional":true,"pattern":"^https?://.*","properties":{},"type":"string"},"location":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"tos":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"d34253209420f70af9ce9636d062d86816aa0aaad6156da14616f0c62a52bf93","description":"Update existing ACME account information with CA. Note: not specifying any new account information triggers a refresh.","extra":{},"name":"update_account","parameters":[{"definition":{"description":"Contact email addresses.","enum":[],"extra":{"typetext":""},"format":"email-list","optional":true,"properties":{},"type":"string"},"name":"contact"},{"definition":{"default":"default","description":"ACME account config file name.","enum":[],"extra":{"format_description":"name","typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"name"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/cluster/acme/account/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bb3b64c0f654249ad36a0e6d6795943403662e273ec2511021fde72e27414433","description":"Get schema of ACME challenge types.","extra":{},"name":"challengeschema","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":0},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Human readable name, falls back to id","enum":[],"extra":{},"properties":{},"type":"string"},"schema":{"enum":[],"extra":{},"properties":{},"type":"object"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/acme/challenge-schema"},{"extra":{},"methods":[{"allow_token":true,"checksum":"83c926d16ce96312b6485852605650ec68d069e1004de1bf706cf88ce5230a8b","description":"Get named known ACME directory endpoints.","extra":{},"name":"get_directories","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":0},"properties":{"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"url":{"description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"pattern":"^https?://.*","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/acme/directories"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3e96f2ad7d3b068e319a6e185995cb4727138447c78db5fb64029588946ae88d","description":"ACME plugin index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list ACME plugins of a specific type","enum":["dns","standalone"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{plugin}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"plugin":{"description":"Unique identifier for ACME plugin instance.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"b8f3d38b84b5f20346707c54b807efc9f29fc1a92aac73c806201f3d68957086","description":"Add ACME plugin configuration.","extra":{},"name":"add_plugin","parameters":[{"definition":{"description":"API plugin name","enum":["1984hosting","acmedns","acmeproxy","active24","ad","ali","anx","arvan","aurora","autodns","aws","azion","azure","bunny","cf","clouddns","cloudns","cn","conoha","constellix","cpanel","curanet","cyon","da","ddnss","desec","df","dgon","dnshome","dnsimple","dnsservices","do","doapi","domeneshop","dp","dpi","dreamhost","duckdns","durabledns","dyn","dynu","dynv6","easydns","edgedns","euserv","exoscale","fornex","freedns","gandi_livedns","gcloud","gd","geoscaling","he","hetzner","hexonet","hostingde","huaweicloud","infoblox","infomaniak","internetbs","inwx","ionos","ispconfig","jd","joker","kappernet","kas","kinghost","knot","la","leaseweb","lexicon","linode","linode_v4","loopia","lua","maradns","me","miab","misaka","myapi","mydevil","mydnsjp","mythic_beasts","namecheap","namecom","namesilo","nederhost","neodigit","netcup","netlify","nic","njalla","nm","nsd","nsone","nsupdate","nw","oci","one","online","openprovider","openstack","opnsense","ovh","pdns","pleskxml","pointhq","porkbun","rackcorp","rackspace","rage4","rcode0","regru","scaleway","schlundtech","selectel","selfhost","servercow","simply","tele3","transip","udr","ultra","unoeuro","variomedia","veesp","vercel","vscale","vultr","websupport","world4you","yandex","yc","zilore","zone","zonomi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"api"},{"definition":{"description":"DNS plugin data. (base64 encoded)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"data"},{"definition":{"description":"Flag to disable the config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"ACME Plugin ID name","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"ACME challenge type.","enum":["dns","standalone"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"default":30,"description":"Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.","enum":[],"extra":{"typetext":" (0 - 172800)"},"maximum":172800,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"validation-delay"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/acme/plugins"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e31513c49230a6793d02a258e1461555d3d724ed5007c688cdf61d6047f43335","description":"Delete ACME plugin configuration.","extra":{},"name":"delete_plugin","parameters":[{"definition":{"description":"Unique identifier for ACME plugin instance.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"75aa54b197ffabed6256c4937525a341970e630aa4ea348fa6604b00f2b14e5c","description":"Get ACME plugin configuration.","extra":{},"name":"get_plugin_config","parameters":[{"definition":{"description":"Unique identifier for ACME plugin instance.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"4f95aa17aa8b448a7a9b1f5842461114b4591e93d10ccaef8e74116839e86b2e","description":"Update ACME plugin configuration.","extra":{},"name":"update_plugin","parameters":[{"definition":{"description":"API plugin name","enum":["1984hosting","acmedns","acmeproxy","active24","ad","ali","anx","arvan","aurora","autodns","aws","azion","azure","bunny","cf","clouddns","cloudns","cn","conoha","constellix","cpanel","curanet","cyon","da","ddnss","desec","df","dgon","dnshome","dnsimple","dnsservices","do","doapi","domeneshop","dp","dpi","dreamhost","duckdns","durabledns","dyn","dynu","dynv6","easydns","edgedns","euserv","exoscale","fornex","freedns","gandi_livedns","gcloud","gd","geoscaling","he","hetzner","hexonet","hostingde","huaweicloud","infoblox","infomaniak","internetbs","inwx","ionos","ispconfig","jd","joker","kappernet","kas","kinghost","knot","la","leaseweb","lexicon","linode","linode_v4","loopia","lua","maradns","me","miab","misaka","myapi","mydevil","mydnsjp","mythic_beasts","namecheap","namecom","namesilo","nederhost","neodigit","netcup","netlify","nic","njalla","nm","nsd","nsone","nsupdate","nw","oci","one","online","openprovider","openstack","opnsense","ovh","pdns","pleskxml","pointhq","porkbun","rackcorp","rackspace","rage4","rcode0","regru","scaleway","schlundtech","selectel","selfhost","servercow","simply","tele3","transip","udr","ultra","unoeuro","variomedia","veesp","vercel","vscale","vultr","websupport","world4you","yandex","yc","zilore","zone","zonomi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"api"},{"definition":{"description":"DNS plugin data. (base64 encoded)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"data"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Flag to disable the config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"ACME Plugin ID name","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"default":30,"description":"Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.","enum":[],"extra":{"typetext":" (0 - 172800)"},"maximum":172800,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"validation-delay"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/acme/plugins/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e778ef22db38342828980d7c53532b03f67ee66cc94de0febacf3fba7e7e2deb","description":"Retrieve ACME TermsOfService URL from CA.","extra":{},"name":"get_tos","parameters":[{"definition":{"default":"https://acme-v02.api.letsencrypt.org/directory","description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"optional":true,"pattern":"^https?://.*","properties":{},"type":"string"},"name":"directory"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"ACME TermsOfService URL.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"verb":"GET"}],"path":"/cluster/acme/tos"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b313982759943e059ca83951b1c7d999dc02e144bb6bb0aa7b540f0af19dcbcc","description":"List vzdump backup schedule.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"description":"The job ID.","enum":[],"extra":{},"max_length":50,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"209fa16eff43fe820ffd32b9c24c6771f54ca95ac5f2eec2b775abe913ad44d4","description":"Create new vzdump backup job.","extra":{},"name":"create_job","parameters":[{"definition":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"all"},{"definition":{"default":0,"description":"Limit I/O bandwidth (KBytes per second).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"Description for the Job.","enum":[],"extra":{"typetext":""},"max_length":512,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"compress"},{"definition":{"default":"mon,tue,wed,thu,fri,sat,sun","description":"Day of week selection.","enum":[],"extra":{"requires":"starttime","typetext":""},"format":"pve-day-of-week-list","optional":true,"properties":{},"type":"string"},"name":"dow"},{"definition":{"description":"Store resulting files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dumpdir"},{"definition":{"default":"1","description":"Enable or disable the job.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"exclude"},{"definition":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{"typetext":""},"format":"string-alist","optional":true,"properties":{},"type":"string"},"name":"exclude-path"},{"definition":{"description":"Job ID (will be autogenerated).","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"id"},{"definition":{"default":7,"description":"Set CFQ ionice priority.","enum":[],"extra":{"typetext":" (0 - 8)"},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"ionice"},{"definition":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"lockwait"},{"definition":{"default":"always","description":"Specify when to send an email","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mailnotification"},{"definition":{"description":"Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{"typetext":""},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"name":"mailto"},{"definition":{"description":"Deprecated: use 'prune-backups' instead. Maximal number of backup files per guest system.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxfiles"},{"definition":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"Only run if executed on this node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.","enum":[],"extra":{"requires":"storage","typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"notes-template"},{"definition":{"description":"Other performance-related settings.","enum":[],"extra":{"typetext":"[max-workers=]"},"format":"backup-performance","optional":true,"properties":{},"type":"string"},"name":"performance"},{"definition":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"pigz"},{"definition":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"If true, mark backup(s) as protected.","enum":[],"extra":{"requires":"storage","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protected"},{"definition":{"default":"keep-all=1","description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"default":0,"description":"Be quiet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"quiet"},{"definition":{"default":1,"description":"Prune older backups according to 'prune-backups'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove"},{"definition":{"default":0,"description":"If true, the job will be run as soon as possible if it was missed while the scheduler was not running.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"repeat-missed"},{"definition":{"description":"Backup schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"Use specified hook script.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"script"},{"definition":{"description":"Job Start time.","enum":[],"extra":{"typetext":"HH:MM"},"optional":true,"pattern":"\\d{1,2}:\\d{1,2}","properties":{},"type":"string"},"name":"starttime"},{"definition":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stdexcludes"},{"definition":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stop"},{"definition":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"stopwait"},{"definition":{"description":"Store resulting file to this storage.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Store temporary files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tmpdir"},{"definition":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vmid"},{"definition":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, N>0 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"zstd"}],"permissions":{"description":"The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user.","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/backup"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e8fa5d6fa114f069dcf59323f56dc2636286f1d895cf328de285fd9c651a1f48","description":"Index for backup info related endpoints","extra":{},"name":"index","parameters":[],"protected":false,"returns":{"description":"Directory index.","enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"description":"API sub-directory endpoint","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/backup-info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"10072ad7bf08fad7b5214622361f9bcfe52101f6e15709fc5661262557128b24","description":"Shows all guests which are not covered by any backup job.","extra":{},"name":"get_guests_not_in_backup","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"description":"Contains the guest objects.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"name":{"description":"Name of the guest","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Type of the guest.","enum":["qemu","lxc"],"extra":{},"properties":{},"type":"string"},"vmid":{"description":"VMID of the guest.","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/backup-info/not-backed-up"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b708c19c2b686aec67700af7135175d2039bd1b1fc411d259686b8f60d10262c","description":"Delete vzdump backup job definition.","extra":{},"name":"delete_job","parameters":[{"definition":{"description":"The job ID.","enum":[],"extra":{"typetext":""},"max_length":50,"properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"27b8de88f0a2f4f349cb4583bbe3633900bff8cd09d72677828f591560dde4ae","description":"Read vzdump backup job definition.","extra":{},"name":"read_job","parameters":[{"definition":{"description":"The job ID.","enum":[],"extra":{"typetext":""},"max_length":50,"properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"5692ab1cb73b800d41c31a71bc46ea270603d0279dfb2482628fcb426840d22c","description":"Update vzdump backup job definition.","extra":{},"name":"update_job","parameters":[{"definition":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"all"},{"definition":{"default":0,"description":"Limit I/O bandwidth (KBytes per second).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"Description for the Job.","enum":[],"extra":{"typetext":""},"max_length":512,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"compress"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Day of week selection.","enum":[],"extra":{"requires":"starttime","typetext":""},"format":"pve-day-of-week-list","optional":true,"properties":{},"type":"string"},"name":"dow"},{"definition":{"description":"Store resulting files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dumpdir"},{"definition":{"default":"1","description":"Enable or disable the job.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"exclude"},{"definition":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{"typetext":""},"format":"string-alist","optional":true,"properties":{},"type":"string"},"name":"exclude-path"},{"definition":{"description":"The job ID.","enum":[],"extra":{"typetext":""},"max_length":50,"properties":{},"type":"string"},"name":"id"},{"definition":{"default":7,"description":"Set CFQ ionice priority.","enum":[],"extra":{"typetext":" (0 - 8)"},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"ionice"},{"definition":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"lockwait"},{"definition":{"default":"always","description":"Specify when to send an email","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mailnotification"},{"definition":{"description":"Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{"typetext":""},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"name":"mailto"},{"definition":{"description":"Deprecated: use 'prune-backups' instead. Maximal number of backup files per guest system.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxfiles"},{"definition":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"Only run if executed on this node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.","enum":[],"extra":{"requires":"storage","typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"notes-template"},{"definition":{"description":"Other performance-related settings.","enum":[],"extra":{"typetext":"[max-workers=]"},"format":"backup-performance","optional":true,"properties":{},"type":"string"},"name":"performance"},{"definition":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"pigz"},{"definition":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"If true, mark backup(s) as protected.","enum":[],"extra":{"requires":"storage","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protected"},{"definition":{"default":"keep-all=1","description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"default":0,"description":"Be quiet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"quiet"},{"definition":{"default":1,"description":"Prune older backups according to 'prune-backups'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove"},{"definition":{"default":0,"description":"If true, the job will be run as soon as possible if it was missed while the scheduler was not running.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"repeat-missed"},{"definition":{"description":"Backup schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"Use specified hook script.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"script"},{"definition":{"description":"Job Start time.","enum":[],"extra":{"typetext":"HH:MM"},"optional":true,"pattern":"\\d{1,2}:\\d{1,2}","properties":{},"type":"string"},"name":"starttime"},{"definition":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stdexcludes"},{"definition":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stop"},{"definition":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"stopwait"},{"definition":{"description":"Store resulting file to this storage.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Store temporary files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tmpdir"},{"definition":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vmid"},{"definition":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, N>0 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"zstd"}],"permissions":{"description":"The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user.","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/backup/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"62c0ad7abee78ab3a2bc37808d4d965ad58c97cbc5d7ff19f953ad9f7bbb331a","description":"Returns included guests and the backup status of their disks. Optimized to be used in ExtJS tree views.","extra":{},"name":"get_volume_backup_included","parameters":[{"definition":{"description":"The job ID.","enum":[],"extra":{"typetext":""},"max_length":50,"properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"description":"Root node of the tree object. Children represent guests, grandchildren represent volumes of that guest.","enum":[],"extra":{},"properties":{"children":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"children":{"description":"The volumes of the guest with the information if they will be included in backups.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"id":{"description":"Configuration key of the volume.","enum":[],"extra":{},"properties":{},"type":"string"},"included":{"description":"Whether the volume is included in the backup or not.","enum":[],"extra":{},"properties":{},"type":"boolean"},"name":{"description":"Name of the volume.","enum":[],"extra":{},"properties":{},"type":"string"},"reason":{"description":"The reason why the volume is included (or excluded).","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"id":{"description":"VMID of the guest.","enum":[],"extra":{},"properties":{},"type":"integer"},"name":{"description":"Name of the guest","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Type of the guest, VM, CT or unknown for removed but not purged guests.","enum":["qemu","lxc","unknown"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"}],"path":"/cluster/backup/{id}/included_volumes"},{"extra":{},"methods":[{"allow_token":true,"checksum":"eba2ffcf3c2b12528c59e5ea186dccaf2c83608b8f244536294254186e44c927","description":"Cluster ceph index.","extra":{},"name":"cephindex","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/ceph"},{"extra":{},"methods":[{"allow_token":true,"checksum":"02afb14bbc8590601cd50857ea48b148df439fcd0eeb68ad743f81117830e050","description":"get the status of all ceph flags","extra":{},"name":"get_all_flags","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"description":{"description":"Flag description.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Flag name.","enum":["nobackfill","nodeep-scrub","nodown","noin","noout","norebalance","norecover","noscrub","notieragent","noup","pause"],"extra":{},"properties":{},"type":"string"},"value":{"description":"Flag value.","enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"970a0fb05e1b758fb4fdf2eb40ec7342550b919ccbc76dbfcfb001afefa4ae31","description":"Set/Unset multiple ceph flags at once.","extra":{},"name":"set_flags","parameters":[{"definition":{"description":"Backfilling of PGs is suspended.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nobackfill"},{"definition":{"description":"Deep Scrubbing is disabled.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nodeep-scrub"},{"definition":{"description":"OSD failure reports are being ignored, such that the monitors will not mark OSDs down.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nodown"},{"definition":{"description":"OSDs that were previously marked out will not be marked back in when they start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"noin"},{"definition":{"description":"OSDs will not automatically be marked out after the configured interval.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"noout"},{"definition":{"description":"Rebalancing of PGs is suspended.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"norebalance"},{"definition":{"description":"Recovery of PGs is suspended.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"norecover"},{"definition":{"description":"Scrubbing is disabled.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"noscrub"},{"definition":{"description":"Cache tiering activity is suspended.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"notieragent"},{"definition":{"description":"OSDs are not allowed to start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"noup"},{"definition":{"description":"Pauses read and writes.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pause"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/cluster/ceph/flags"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ec390749f9b3b558092a75a9d5b9a3a05a0f4d7caaba0587fbbc491a53147656","description":"Get the status of a specific ceph flag.","extra":{},"name":"get_flag","parameters":[{"definition":{"description":"The name of the flag name to get.","enum":["nobackfill","nodeep-scrub","nodown","noin","noout","norebalance","norecover","noscrub","notieragent","noup","pause"],"extra":{},"properties":{},"type":"string"},"name":"flag"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"verb":"GET"},{"allow_token":true,"checksum":"2e9c3fffaa1d7970614c7564afef27bfb7e06a951d8f2cd26e7995f90f827bf1","description":"Set or clear (unset) a specific ceph flag","extra":{},"name":"update_flag","parameters":[{"definition":{"description":"The ceph flag to update","enum":["nobackfill","nodeep-scrub","nodown","noin","noout","norebalance","norecover","noscrub","notieragent","noup","pause"],"extra":{},"properties":{},"type":"string"},"name":"flag"},{"definition":{"description":"The new value of the flag","enum":[],"extra":{"typetext":""},"properties":{},"type":"boolean"},"name":"value"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/ceph/flags/{flag}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4a403969f7330d91a3a498833fd5420b4091516e69a60e1f4047f53574320e54","description":"Get ceph metadata.","extra":{},"name":"metadata","parameters":[{"definition":{"default":"all","enum":["all","versions"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scope"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Items for each type of service containing objects for each instance.","enum":[],"extra":{},"properties":{"mds":{"description":"Metadata servers configured in the cluster and their properties.","enum":[],"extra":{},"properties":{"{id}":{"description":"Useful properties are listed, but not the full list.","enum":[],"extra":{},"properties":{"addr":{"description":"Bind addresses and ports.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_release":{"description":"Ceph release codename currently used.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version":{"description":"Version info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version_short":{"description":"Short version (numerical) info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"hostname":{"description":"Hostname on which the service is running.","enum":[],"extra":{},"properties":{},"type":"string"},"mem_swap_kb":{"description":"Memory of the service currently in swap.","enum":[],"extra":{},"properties":{},"type":"integer"},"mem_total_kb":{"description":"Memory consumption of the service.","enum":[],"extra":{},"properties":{},"type":"integer"},"name":{"description":"Name of the service instance.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"}},"type":"object"},"mgr":{"description":"Managers configured in the cluster and their properties.","enum":[],"extra":{},"properties":{"{id}":{"description":"Useful properties are listed, but not the full list.","enum":[],"extra":{},"properties":{"addr":{"description":"Bind address","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_release":{"description":"Ceph release codename currently used.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version":{"description":"Version info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version_short":{"description":"Short version (numerical) info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"hostname":{"description":"Hostname on which the service is running.","enum":[],"extra":{},"properties":{},"type":"string"},"mem_swap_kb":{"description":"Memory of the service currently in swap.","enum":[],"extra":{},"properties":{},"type":"integer"},"mem_total_kb":{"description":"Memory consumption of the service.","enum":[],"extra":{},"properties":{},"type":"integer"},"name":{"description":"Name of the service instance.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"}},"type":"object"},"mon":{"description":"Monitors configured in the cluster and their properties.","enum":[],"extra":{},"properties":{"{id}":{"description":"Useful properties are listed, but not the full list.","enum":[],"extra":{},"properties":{"addrs":{"description":"Bind addresses and ports.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_release":{"description":"Ceph release codename currently used.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version":{"description":"Version info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version_short":{"description":"Short version (numerical) info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"hostname":{"description":"Hostname on which the service is running.","enum":[],"extra":{},"properties":{},"type":"string"},"mem_swap_kb":{"description":"Memory of the service currently in swap.","enum":[],"extra":{},"properties":{},"type":"integer"},"mem_total_kb":{"description":"Memory consumption of the service.","enum":[],"extra":{},"properties":{},"type":"integer"},"name":{"description":"Name of the service instance.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"}},"type":"object"},"node":{"description":"Ceph version installed on the nodes.","enum":[],"extra":{},"properties":{"{node}":{"enum":[],"extra":{},"properties":{"buildcommit":{"description":"GIT commit used for the build.","enum":[],"extra":{},"properties":{},"type":"string"},"version":{"description":"Version info.","enum":[],"extra":{},"properties":{"parts":{"description":"major, minor & patch","enum":[],"extra":{},"properties":{},"type":"array"},"str":{"description":"Version as single string.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"}},"type":"object"}},"type":"object"},"osd":{"description":"OSDs configured in the cluster and their properties.","enum":[],"extra":{},"properties":{"{id}":{"description":"Useful properties are listed, but not the full list.","enum":[],"extra":{},"properties":{"back_addr":{"description":"Bind addresses and ports for backend inter OSD traffic.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_release":{"description":"Ceph release codename currently used.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version":{"description":"Version info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version_short":{"description":"Short version (numerical) info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"device_id":{"description":"Devices used by the OSD.","enum":[],"extra":{},"properties":{},"type":"string"},"front_addr":{"description":"Bind addresses and ports for frontend traffic to OSDs.","enum":[],"extra":{},"properties":{},"type":"string"},"hostname":{"description":"Hostname on which the service is running.","enum":[],"extra":{},"properties":{},"type":"string"},"id":{"description":"OSD ID.","enum":[],"extra":{},"properties":{},"type":"integer"},"mem_swap_kb":{"description":"Memory of the service currently in swap.","enum":[],"extra":{},"properties":{},"type":"integer"},"mem_total_kb":{"description":"Memory consumption of the service.","enum":[],"extra":{},"properties":{},"type":"integer"},"osd_data":{"description":"Path to the OSD data directory.","enum":[],"extra":{},"properties":{},"type":"string"},"osd_objectstore":{"description":"OSD objectstore type.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"}},"type":"array"}},"type":"object"},"verb":"GET"}],"path":"/cluster/ceph/metadata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"409b59805f3b7f2541a2610e760ac490c3c6c53e2f4107c9149cc5870f3999ab","description":"Get ceph status.","extra":{},"name":"status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/ceph/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4e462b2d722b46bdaa5c6d40f69bc9f0fea21bf2b17f55764148409d7e6634a1","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"dc847d83f7fc30755b2764c4614fade64611f8f97ac8d872642a9b3fb1cadc5e","description":"Generate new cluster configuration. If no links given, default to local IP address as link0.","extra":{},"name":"create","parameters":[{"definition":{"description":"The name of the cluster.","enum":[],"extra":{"typetext":""},"format":"pve-node","max_length":15,"properties":{},"type":"string"},"name":"clustername"},{"definition":{"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)","enum":[],"extra":{"typetext":"[address=] [,priority=]"},"format":{"address":{"default_key":1,"description":"Hostname (or IP) of this corosync link address.","format":"address","format_description":"IP","type":"string"},"priority":{"default":0,"description":"The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.","maximum":255,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"link[n]"},{"definition":{"description":"Node id for this node.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"nodeid"},{"definition":{"description":"Number of votes for this node.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"votes"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5861b788cde0b7cc8e00ed4490c40cc476724fc3e74e8d888af4e2667f4fc440","description":"Return the version of the cluster join API available on this node.","extra":{},"name":"join_api_version","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"description":"Cluster Join API version, currently 1","enum":[],"extra":{},"minimum":0,"properties":{},"type":"integer"},"verb":"GET"}],"path":"/cluster/config/apiversion"},{"extra":{},"methods":[{"allow_token":true,"checksum":"27b190ca706bbf299b7db981785dc2470fa61c40ce5577145f166e14dfa5ab80","description":"Get information needed to join this cluster over the connected node.","extra":{},"name":"join_info","parameters":[{"definition":{"default":"current connected node","description":"The node for which the joinee gets the nodeinfo. ","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"config_digest":{"enum":[],"extra":{},"properties":{},"type":"string"},"nodelist":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"name":{"description":"The cluster node name.","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"nodeid":{"description":"Node id for this node.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"pve_addr":{"enum":[],"extra":{},"format":"ip","properties":{},"type":"string"},"pve_fp":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"quorum_votes":{"enum":[],"extra":{},"minimum":0,"properties":{},"type":"integer"},"ring0_addr":{"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)","enum":[],"extra":{},"format":{"address":{"default_key":1,"description":"Hostname (or IP) of this corosync link address.","format":"address","format_description":"IP","type":"string"},"priority":{"default":0,"description":"The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.","maximum":255,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"preferred_node":{"description":"The cluster node name.","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"totem":{"enum":[],"extra":{},"properties":{},"type":"object"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"b68eacfbf66e39c59302d333b33cc64f4ff8211a81f4b5e13e745569757d2229","description":"Joins this node into an existing cluster. If no links are given, default to IP resolved by node's hostname on single link (fallback fails for clusters with multiple links).","extra":{},"name":"join","parameters":[{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"Do not throw error if node already exists.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Hostname (or IP) of an existing cluster member.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"hostname"},{"definition":{"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)","enum":[],"extra":{"typetext":"[address=] [,priority=]"},"format":{"address":{"default_key":1,"description":"Hostname (or IP) of this corosync link address.","format":"address","format_description":"IP","type":"string"},"priority":{"default":0,"description":"The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.","maximum":255,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"link[n]"},{"definition":{"description":"Node id for this node.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"nodeid"},{"definition":{"description":"Superuser (root) password of peer node.","enum":[],"extra":{"typetext":""},"max_length":128,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Number of votes for this node","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"votes"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/config/join"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1f1fa8f6c73d69a06ca87952831af1858a31d439c8ce22d6db1dc91f7ca064ba","description":"Corosync node list.","extra":{},"name":"nodes","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{node}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"node":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/config/nodes"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4ad5a311d984ff153e9e2592b537f44cdcce104ab314eadbe47ce01a97c6f77c","description":"Removes a node from the cluster configuration.","extra":{},"name":"delnode","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"2304b23018ece442ff87923324c1fd7f3616f5b677fc4dc2af779b5c3da61fd7","description":"Adds a node to the cluster configuration. This call is for internal use.","extra":{},"name":"addnode","parameters":[{"definition":{"description":"The JOIN_API_VERSION of the new node.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"apiversion"},{"definition":{"description":"Do not throw error if node already exists.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)","enum":[],"extra":{"typetext":"[address=] [,priority=]"},"format":{"address":{"default_key":1,"description":"Hostname (or IP) of this corosync link address.","format":"address","format_description":"IP","type":"string"},"priority":{"default":0,"description":"The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.","maximum":255,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"link[n]"},{"definition":{"description":"IP Address of node to add. Used as fallback if no links are given.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"new_node_ip"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Node id for this node.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"nodeid"},{"definition":{"description":"Number of votes for this node","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"votes"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{"corosync_authkey":{"enum":[],"extra":{},"properties":{},"type":"string"},"corosync_conf":{"enum":[],"extra":{},"properties":{},"type":"string"},"warnings":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"verb":"POST"}],"path":"/cluster/config/nodes/{node}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"51bd45c1bad501ab6b44ef5c67e7ca632259b91909c89431696c26607bfa79ae","description":"Get QDevice status","extra":{},"name":"status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/config/qdevice"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c99926d6eacc2ee248abe8c35c3b919d67610792d6702ff22aee72db49cc4a84","description":"Get corosync totem protocol settings.","extra":{},"name":"totem","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/config/totem"},{"extra":{},"methods":[{"allow_token":true,"checksum":"74551df8a7f69c7a92251a3cae53f3fa26e51e7232e76071c74973bbbcee0c60","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f06ffe119587de3302e717bba7a4b65a1c2d80187a105c9ea6bbf37e77cd97fd","description":"List aliases","extra":{},"name":"get_aliases","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f144d7afa87a39ea6a57ac4e64d062df366af072960ccdf34d6336ac2377b7f3","description":"Create IP or Network Alias.","extra":{},"name":"create_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/aliases"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ad4257a1d4b41dd23e4430b9f983c567fea8145f05649ae95e007dae6463c90b","description":"Remove IP or Network alias.","extra":{},"name":"remove_alias","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"31f91732baef0ccfba57dfc0c349ce762ef253d020ab23770f2a16b530eb55ed","description":"Read alias.","extra":{},"name":"read_alias","parameters":[{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"5a17c347604603437b19f09ba99fe14c5e4bafb67ed183f11f1627de33ef07df","description":"Update IP or Network alias.","extra":{},"name":"update_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Rename an existing alias.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/aliases/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3445c46206838d35be8e0c694952f880add553e8132b23f4614da8e28cb8a3a4","description":"List security groups.","extra":{},"name":"list_security_groups","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{group}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"group":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"2883536c84a6a0652e559b7fd1cf8eb6e13f33c9aa8b01adba443345121a8628","description":"Create new security group.","extra":{},"name":"create_security_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Rename/update an existing security group. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing group.","enum":[],"extra":{},"max_length":18,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/groups"},{"extra":{},"methods":[{"allow_token":true,"checksum":"acdcc8bdd19b229574d5ede528b0727f932a90c3fbb9ef47222856db9f4531d9","description":"Delete security group.","extra":{},"name":"delete_security_group","parameters":[{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"5e311b86179420cbc403ca7c6e0bb22d853c4be88b8ef0b63aab2614af61e428","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"65a9c8966d4401b33d83944bc236895c491e1441b677159732248e1251135ab1","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/groups/{group}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7317683249582e6e573527a83e3ee1f4f29da0e5e8d527b1243f55a42bb66e7f","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"1f3be3248486446917c63efaf928e95d33b8e383145a7ac4f9a7f4abf4b7fa19","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"8dc5176d09fe5ba99946a987f34732e818fe753500d3bdae8fb08174dcb219a6","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/groups/{group}/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dd7e3fad6a4b03050665f4570709b30493d1bed7cfed03fc6663fdbab459d635","description":"List IPSets","extra":{},"name":"ipset_index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"name":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"23066626f06f9d98f626a6f91170e532e1d77c32a9164acef556b7124cd71ed6","description":"Create new IPSet","extra":{},"name":"create_ipset","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/ipset"},{"extra":{},"methods":[{"allow_token":true,"checksum":"26a94d7acf918753aa6d8f5ec4155fb0e85f270e9366a91473ab924cb19cc9f0","description":"Delete IPSet","extra":{},"name":"delete_ipset","parameters":[{"definition":{"description":"Delete all members of the IPSet, if there are any.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"c2d29e48c4bfd7c5b4052b880d990a132c3631ce457fd0a8ec1f9ad69df7994f","description":"List IPSet content","extra":{},"name":"get_ipset","parameters":[{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cidr}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"nomatch":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"64742b376a8e3ee9b6b16b594db4e04c4b486e54165aa69f492fb0b952ea3225","description":"Add IP or Network to IPSet.","extra":{},"name":"create_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/ipset/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"33ecae376ac07622130a4734f2b8dae40e26c659e07f734da8896f2cd104589c","description":"Remove IP or Network from IPSet.","extra":{},"name":"remove_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"63a5cefffbd4607d42d80144ed58b521edc579d7778d60043f08271ec0332405","description":"Read IP or Network settings from IPSet.","extra":{},"name":"read_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"94e10f5e55188acae83a4e96b0661e47d0d509cd12091dbf8beba054613f762a","description":"Update IP or Network settings","extra":{},"name":"update_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/ipset/{name}/{cidr}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8e98c5e0609b2624b64c801c530753f356fe8bd2682f5a27a745f43d6f986123","description":"List available macros","extra":{},"name":"get_macros","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"descr":{"description":"More verbose description (if available).","enum":[],"extra":{},"properties":{},"type":"string"},"macro":{"description":"Macro name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/firewall/macros"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0ab6fd03e17819c0c790d03086a619c7cbb5a5b16d82b4fdcb8f314269e88ef4","description":"Get Firewall options.","extra":{},"name":"get_options","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"ebtables":{"default":1,"description":"Enable ebtables rules cluster wide.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"enable":{"description":"Enable or disable the firewall cluster wide.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"log_ratelimit":{"description":"Log ratelimiting settings","enum":[],"extra":{},"format":{"burst":{"default":5,"description":"Initial burst of packages which will always get logged before the rate is applied","minimum":0,"optional":1,"type":"integer"},"enable":{"default":"1","default_key":1,"description":"Enable or disable log rate limiting","type":"boolean"},"rate":{"default":"1/second","description":"Frequency with which the burst bucket gets refilled","format_description":"rate","optional":1,"pattern":"[1-9][0-9]*\\/(second|minute|hour|day)","type":"string"}},"optional":true,"properties":{},"type":"string"},"policy_in":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"policy_out":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"aee671ef989ed185dfc5469a2df19a8dbbb3fc4988cbe5934e1e6218980988c5","description":"Set Firewall options.","extra":{},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":1,"description":"Enable ebtables rules cluster wide.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ebtables"},{"definition":{"description":"Enable or disable the firewall cluster wide.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Log ratelimiting settings","enum":[],"extra":{"typetext":"[enable=]<1|0> [,burst=] [,rate=]"},"format":{"burst":{"default":5,"description":"Initial burst of packages which will always get logged before the rate is applied","minimum":0,"optional":1,"type":"integer"},"enable":{"default":"1","default_key":1,"description":"Enable or disable log rate limiting","type":"boolean"},"rate":{"default":"1/second","description":"Frequency with which the burst bucket gets refilled","format_description":"rate","optional":1,"pattern":"[1-9][0-9]*\\/(second|minute|hour|day)","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"log_ratelimit"},{"definition":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_in"},{"definition":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_out"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"cf22699ed1dcfd76824b83c1cae7ab8e370d43a281f04efb3ddbb4445d20fa0e","description":"Lists possible IPSet/Alias reference which are allowed in source/dest properties.","extra":{},"name":"refs","parameters":[{"definition":{"description":"Only list references of specified type.","enum":["alias","ipset"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"ref":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":["alias","ipset"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/firewall/refs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9165dc3d913c799db2db301b2e535e230c212b7dbfcef2f3918b7e9c7d6408bd","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"dc2f7ff17a6a50f6040bdd6477054327c19ce2e28bb35c97226602ce4135fa6f","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"42b1d8a16029ab6833aebf089137bfdb5f2f5f1bbe4ff4676c40c4f0b5841c70","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"cbc43552b6224f680019cd55a400aab123117e58e2be663243e2ffd77259b8aa","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"3dd655a639513e06bd27fbe2ad17f33095d81705ad5d054cfceb46e72f5d784b","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d001f6a38904cb5a8c874fb6d751e0a54ea9d1d75042d71b3c21dffb4e5c59ca","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/ha"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d0d28a184b53d0e953807ded4c6b2790bdae617fc6b96ff4fa1649238a2c8c13","description":"Get HA groups.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{group}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"group":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"21ad8fd25ef2daef3468a2f62950905e934be2c2b149fa846158df06be2891e8","description":"Create a new HA group.","extra":{},"name":"create","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"List of cluster node names with optional priority.","enum":[],"extra":{"typetext":"[:]{,[:]}*","verbose_description":"List of cluster node members, where a priority can be given to each node. A resource bound to a group will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the services will get distributed to those nodes. The priorities have a relative meaning only."},"format":"pve-ha-group-node-list","optional":false,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"default":0,"description":"The CRM tries to run services on the node with the highest priority. If a node with higher priority comes online, the CRM migrates the service to that node. Enabling nofailback prevents that behavior.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nofailback"},{"definition":{"default":0,"description":"Resources bound to restricted groups may only run on nodes defined by the group.","enum":[],"extra":{"typetext":"","verbose_description":"Resources bound to restricted groups may only run on nodes defined by the group. The resource will be placed in the stopped state if no group node member is online. Resources on unrestricted groups may run on any cluster node if all group members are offline, but they will migrate back as soon as a group member comes online. One can implement a 'preferred node' behavior using an unrestricted group with only one member."},"optional":true,"properties":{},"type":"boolean"},"name":"restricted"},{"definition":{"description":"Group type.","enum":["group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/groups"},{"extra":{},"methods":[{"allow_token":true,"checksum":"fcab72c57ac4373ef959202b673be62b63d50770dd9a16025d12a8e0f6e4a594","description":"Delete ha group configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f1dc580cb73eb7352d1f1af8768548109d5fbeee4519fb704492e9eb204c3673","description":"Read ha group configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{}},"verb":"GET"},{"allow_token":true,"checksum":"eecbd2ad7b079c07176d36049ef7e2fe4534a166c55f3b02719dff612274b284","description":"Update ha group configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"List of cluster node names with optional priority.","enum":[],"extra":{"typetext":"[:]{,[:]}*","verbose_description":"List of cluster node members, where a priority can be given to each node. A resource bound to a group will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the services will get distributed to those nodes. The priorities have a relative meaning only."},"format":"pve-ha-group-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"default":0,"description":"The CRM tries to run services on the node with the highest priority. If a node with higher priority comes online, the CRM migrates the service to that node. Enabling nofailback prevents that behavior.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nofailback"},{"definition":{"default":0,"description":"Resources bound to restricted groups may only run on nodes defined by the group.","enum":[],"extra":{"typetext":"","verbose_description":"Resources bound to restricted groups may only run on nodes defined by the group. The resource will be placed in the stopped state if no group node member is online. Resources on unrestricted groups may run on any cluster node if all group members are offline, but they will migrate back as soon as a group member comes online. One can implement a 'preferred node' behavior using an unrestricted group with only one member."},"optional":true,"properties":{},"type":"boolean"},"name":"restricted"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/ha/groups/{group}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"47984f628310d0cb88a50b127b972338f4cd63248dd3c160e5200d3e7bd0cdd1","description":"List HA resources.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list resources of specific type","enum":["ct","vm"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{sid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"sid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"70fd3e7cb628f787ba3909ce16210856bb634a2b64df6e277be007cbcee9d178","description":"Create a new HA resource.","extra":{},"name":"create","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"group"},{"definition":{"default":1,"description":"Maximal number of service relocate tries when a service failes to start.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"max_relocate"},{"definition":{"default":1,"description":"Maximal number of tries to restart the service on a node after its start failed.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"max_restart"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"},{"definition":{"default":"started","description":"Requested resource state.","enum":["started","stopped","enabled","disabled","ignored"],"extra":{"verbose_description":"Requested resource state. The CRM reads this state and acts accordingly.\nPlease note that `enabled` is just an alias for `started`.\n\n`started`;;\n\nThe CRM tries to start the resource. Service state is\nset to `started` after successful start. On node failures, or when start\nfails, it tries to recover the resource. If everything fails, service\nstate it set to `error`.\n\n`stopped`;;\n\nThe CRM tries to keep the resource in `stopped` state, but it\nstill tries to relocate the resources on node failures.\n\n`disabled`;;\n\nThe CRM tries to put the resource in `stopped` state, but does not try\nto relocate the resources on node failures. The main purpose of this\nstate is error recovery, because it is the only way to move a resource out\nof the `error` state.\n\n`ignored`;;\n\nThe resource gets removed from the manager status and so the CRM and the LRM do\nnot touch the resource anymore. All {pve} API calls affecting this resource\nwill be executed, directly bypassing the HA stack. CRM commands will be thrown\naway while there source is in this state. The resource will not get relocated\non node failures.\n\n"},"optional":true,"properties":{},"type":"string"},"name":"state"},{"definition":{"description":"Resource type.","enum":["ct","vm"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/resources"},{"extra":{},"methods":[{"allow_token":true,"checksum":"abd1828ee1c6a70f7ffa5f609831cbbc19915841154fa87ae1986c48e299a35e","description":"Delete resource configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"20b2c61081918714beedef8bf2b0263c914335b03e88f592e05a48637b5ffca1","description":"Read resource configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"comment":{"description":"Description.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Can be used to prevent concurrent modifications.","enum":[],"extra":{},"properties":{},"type":"string"},"group":{"description":"The HA group identifier.","enum":[],"extra":{},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"max_relocate":{"description":"Maximal number of service relocate tries when a service failes to start.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"max_restart":{"description":"Maximal number of tries to restart the service on a node after its start failed.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"sid":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"state":{"description":"Requested resource state.","enum":["started","stopped","enabled","disabled","ignored"],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"The type of the resources.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"9fade4d798de642c2fa6b40e68d11f6a2a782d36f6197f7d9e542464231a87a9","description":"Update resource configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"group"},{"definition":{"default":1,"description":"Maximal number of service relocate tries when a service failes to start.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"max_relocate"},{"definition":{"default":1,"description":"Maximal number of tries to restart the service on a node after its start failed.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"max_restart"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"},{"definition":{"default":"started","description":"Requested resource state.","enum":["started","stopped","enabled","disabled","ignored"],"extra":{"verbose_description":"Requested resource state. The CRM reads this state and acts accordingly.\nPlease note that `enabled` is just an alias for `started`.\n\n`started`;;\n\nThe CRM tries to start the resource. Service state is\nset to `started` after successful start. On node failures, or when start\nfails, it tries to recover the resource. If everything fails, service\nstate it set to `error`.\n\n`stopped`;;\n\nThe CRM tries to keep the resource in `stopped` state, but it\nstill tries to relocate the resources on node failures.\n\n`disabled`;;\n\nThe CRM tries to put the resource in `stopped` state, but does not try\nto relocate the resources on node failures. The main purpose of this\nstate is error recovery, because it is the only way to move a resource out\nof the `error` state.\n\n`ignored`;;\n\nThe resource gets removed from the manager status and so the CRM and the LRM do\nnot touch the resource anymore. All {pve} API calls affecting this resource\nwill be executed, directly bypassing the HA stack. CRM commands will be thrown\naway while there source is in this state. The resource will not get relocated\non node failures.\n\n"},"optional":true,"properties":{},"type":"string"},"name":"state"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/ha/resources/{sid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0899ff908a613bc0e585e0d0ff7c3689a0290c57a6ea0a132c1736f2870ef038","description":"Request resource migration (online) to another node.","extra":{},"name":"migrate","parameters":[{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/resources/{sid}/migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0fe9da71d2503a4b046199d9088d1f15a843b739258a94575aea1eaa204385f0","description":"Request resource relocatzion to another node. This stops the service on the old node, and restarts it on the target node.","extra":{},"name":"relocate","parameters":[{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/resources/{sid}/relocate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"74551df8a7f69c7a92251a3cae53f3fa26e51e7232e76071c74973bbbcee0c60","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/ha/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7aa9929c7b96c76701abdb6b90d6158bd2fe9c5b59916ca70f40e51235716eca","description":"Get HA manger status.","extra":{},"name":"status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/ha/status/current"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3a9edd6753b478f7eee2e02fa4859a8d405979a3bcff5640774bf8cd14b5d31f","description":"Get full HA manger status, including LRM status.","extra":{},"name":"manager_status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/ha/status/manager_status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e7fd541dc6bd5ac3934f5af8ff6c623fb4c63ac8f34778331904648f4ef034d9","description":"Index for jobs related endpoints.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"Directory index.","enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"description":"API sub-directory endpoint","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/jobs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b962117d14e12c92d1e1391addc0b51843bd1d16028ebdf260180f0585f7d628","description":"Returns a list of future schedule runtimes.","extra":{},"name":"schedule-analyze","parameters":[{"definition":{"default":10,"description":"Number of event-iteration to simulate and return.","enum":[],"extra":{"typetext":" (1 - 100)"},"maximum":100,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"iterations"},{"definition":{"description":"Job schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"UNIX timestamp to start the calculation from. Defaults to the current time.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"starttime"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"An array of the next events since .","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"timestamp":{"description":"UNIX timestamp for the run.","enum":[],"extra":{},"properties":{},"type":"integer"},"utc":{"description":"UTC timestamp for the run.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/jobs/schedule-analyze"},{"extra":{},"methods":[{"allow_token":true,"checksum":"83ec57bf65a25fea7789dc000d330836a5facedb780afa50156b1634bbf5d40a","description":"Read cluster log","extra":{},"name":"log","parameters":[{"definition":{"description":"Maximum number of entries.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"32e4e0d625a43113ca32f9e4eba0fba77b683c1450a608bddb7a54be11776ea3","description":"Metrics index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/metrics"},{"extra":{},"methods":[{"allow_token":true,"checksum":"27149ea7f2dd2e6d37dc5ad79fe1835f771a7232d81bc38e686157565a692fc6","description":"List configured metric servers.","extra":{},"name":"server_index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"disable":{"description":"Flag to disable the plugin.","enum":[],"extra":{},"properties":{},"type":"boolean"},"id":{"description":"The ID of the entry.","enum":[],"extra":{},"properties":{},"type":"string"},"port":{"description":"Server network port","enum":[],"extra":{},"properties":{},"type":"integer"},"server":{"description":"Server dns name or IP address","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"Plugin type.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/metrics/server"},{"extra":{},"methods":[{"allow_token":true,"checksum":"56bc7f1733b6ce3c54389c9ceed9a20983de2c44898310930261592680aa259a","description":"Remove Metric server.","extra":{},"name":"delete","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"a53d502e8ae6ee9c25effeb04789f394e23cf119b2a13a620c971ed75e925a3f","description":"Read metric server configuration.","extra":{},"name":"read","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"6312f9174ff71367ba00ae59b7472497a643ab96b470b021c08f6c6b9649dde8","description":"Create a new external metric server config","extra":{},"name":"create","parameters":[{"definition":{"description":"An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"api-path-prefix"},{"definition":{"description":"The InfluxDB bucket/db. Only necessary when using the http v2 api.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"bucket"},{"definition":{"description":"Flag to disable the plugin.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"The ID of the entry.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"default":"udp","enum":["udp","http","https"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"influxdbproto"},{"definition":{"default":25000000,"description":"InfluxDB max-body-size in bytes. Requests are batched up to this size.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max-body-size"},{"definition":{"default":1500,"description":"MTU for metrics transmission over UDP","enum":[],"extra":{"typetext":" (512 - 65536)"},"maximum":65536,"minimum":512,"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"organization"},{"definition":{"description":"root graphite path (ex: proxmox.mycluster.mykey)","enum":[],"extra":{"typetext":""},"format":"graphite-path","optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"server network port","enum":[],"extra":{"typetext":" (1 - 65536)"},"maximum":65536,"minimum":1,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Protocol to send graphite data. TCP or UDP (default)","enum":["udp","tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"server dns name or IP address","enum":[],"extra":{"typetext":""},"format":"address","properties":{},"type":"string"},"name":"server"},{"definition":{"default":1,"description":"graphite TCP socket timeout (default=1)","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"},{"definition":{"description":"Plugin type.","enum":["graphite","influxdb"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"},{"definition":{"default":1,"description":"Set to 0 to disable certificate verification for https endpoints.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify-certificate"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"cd3935929283f3ab396447084856f1c02684cf6a0b7d6dfe6edd3a889e6e5d87","description":"Update metric server configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"api-path-prefix"},{"definition":{"description":"The InfluxDB bucket/db. Only necessary when using the http v2 api.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"bucket"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Flag to disable the plugin.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"The ID of the entry.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"default":"udp","enum":["udp","http","https"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"influxdbproto"},{"definition":{"default":25000000,"description":"InfluxDB max-body-size in bytes. Requests are batched up to this size.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max-body-size"},{"definition":{"default":1500,"description":"MTU for metrics transmission over UDP","enum":[],"extra":{"typetext":" (512 - 65536)"},"maximum":65536,"minimum":512,"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"organization"},{"definition":{"description":"root graphite path (ex: proxmox.mycluster.mykey)","enum":[],"extra":{"typetext":""},"format":"graphite-path","optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"server network port","enum":[],"extra":{"typetext":" (1 - 65536)"},"maximum":65536,"minimum":1,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Protocol to send graphite data. TCP or UDP (default)","enum":["udp","tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"server dns name or IP address","enum":[],"extra":{"typetext":""},"format":"address","properties":{},"type":"string"},"name":"server"},{"definition":{"default":1,"description":"graphite TCP socket timeout (default=1)","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"},{"definition":{"default":1,"description":"Set to 0 to disable certificate verification for https endpoints.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify-certificate"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/metrics/server/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ddb808dcf7a548851bf05a3112279f5ba5a8d02e907f2136fa07968214ef0e0f","description":"Get next free VMID. Pass a VMID to assert that its free (at time of check).","extra":{},"name":"nextid","parameters":[{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"The next free VMID.","enum":[],"extra":{},"properties":{},"type":"integer"},"verb":"GET"}],"path":"/cluster/nextid"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f25824d5aa61d78e9fdb1f99a5845b39d507b9c2093b786e95acd8d8e072ede3","description":"Get datacenter options. Without 'Sys.Audit' on '/' not all options are returned.","extra":{},"name":"get_options","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"29539d9103a38389f04196a1e47edbcc837a66877bc7a46fa239d168a908b6cb","description":"Set datacenter options.","extra":{},"name":"set_options","parameters":[{"definition":{"description":"Set bandwidth/io limits various operations.","enum":[],"extra":{"typetext":"[clone=] [,default=] [,migration=] [,move=] [,restore=]"},"format":{"clone":{"description":"bandwidth limit in KiB/s for cloning disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"default":{"description":"default bandwidth limit in KiB/s","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"migration":{"description":"bandwidth limit in KiB/s for migrating guests (including moving local disks)","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"move":{"description":"bandwidth limit in KiB/s for moving disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"restore":{"description":"bandwidth limit in KiB/s for restoring guests from backups","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"}},"optional":true,"properties":{},"type":"string"},"name":"bwlimit"},{"definition":{"description":"Select the default Console viewer. You can either use the builtin java applet (VNC; deprecated and maps to html5), an external virt-viewer comtatible application (SPICE), an HTML5 based vnc viewer (noVNC), or an HTML5 based console client (xtermjs). If the selected viewer is not available (e.g. SPICE not activated for the VM), the fallback is noVNC.","enum":["applet","vv","html5","xtermjs"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"console"},{"definition":{"description":"Cluster resource scheduling settings.","enum":[],"extra":{"typetext":"[ha=] [,ha-rebalance-on-start=<1|0>]"},"format":{"ha":{"default":"basic","description":"Use this resource scheduler mode for HA.","enum":["basic","static"],"optional":1,"type":"string","verbose_description":"Configures how the HA manager should select nodes to start or recover services. With 'basic', only the number of services is used, with 'static', static CPU and memory configuration of services is considered."},"ha-rebalance-on-start":{"default":0,"description":"Set to use CRS for selecting a suited node when a HA services request-state changes from stop to start.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"crs"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Datacenter description. Shown in the web-interface datacenter notes panel. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":65536,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Specify email address to send notification from (default is root@$hostname)","enum":[],"extra":{"typetext":""},"format":"email-opt","optional":true,"properties":{},"type":"string"},"name":"email_from"},{"definition":{"default":"watchdog","description":"Set the fencing mode of the HA cluster. Hardware mode needs a valid configuration of fence devices in /etc/pve/ha/fence.cfg. With both all two modes are used.\n\nWARNING: 'hardware' and 'both' are EXPERIMENTAL & WIP","enum":["watchdog","hardware","both"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"fencing"},{"definition":{"description":"Cluster wide HA settings.","enum":[],"extra":{"typetext":"shutdown_policy="},"format":{"shutdown_policy":{"default":"conditional","description":"The policy for HA services on node shutdown. 'freeze' disables auto-recovery, 'failover' ensures recovery, 'conditional' recovers on poweroff and freezes on reboot. 'migrate' will migrate running services to other nodes, if possible. With 'freeze' or 'failover', HA Services will always get stopped first on shutdown.","enum":["freeze","failover","conditional","migrate"],"type":"string","verbose_description":"Describes the policy for handling HA services on poweroff or reboot of a node. Freeze will always freeze services which are still located on the node on shutdown, those services won't be recovered by the HA manager. Failover will not mark the services as frozen and thus the services will get recovered to other nodes, if the shutdown node does not come up again quickly (< 1min). 'conditional' chooses automatically depending on the type of shutdown, i.e., on a reboot the service will be frozen but on a poweroff the service will stay as is, and thus get recovered after about 2 minutes. Migrate will try to move all running services to another node when a reboot or shutdown was triggered. The poweroff process will only continue once no running services are located on the node anymore. If the node comes up again, the service will be moved back to the previously powered-off node, at least if no other migration, reloaction or recovery took place."}},"optional":true,"properties":{},"type":"string"},"name":"ha"},{"definition":{"description":"Specify external http proxy which is used for downloads (example: 'http://username:password@host:port/')","enum":[],"extra":{},"optional":true,"pattern":"http://.*","properties":{},"type":"string"},"name":"http_proxy"},{"definition":{"description":"Default keybord layout for vnc server.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"keyboard"},{"definition":{"description":"Default GUI language.","enum":["ca","da","de","en","es","eu","fa","fr","he","it","ja","nb","nn","pl","pt_BR","ru","sl","sv","tr","zh_CN","zh_TW"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"language"},{"definition":{"description":"Prefix for autogenerated MAC addresses.","enum":[],"extra":{"typetext":""},"format":"mac-prefix","optional":true,"properties":{},"type":"string"},"name":"mac_prefix"},{"definition":{"description":"Defines how many workers (per node) are maximal started on actions like 'stopall VMs' or task from the ha-manager.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max_workers"},{"definition":{"description":"For cluster wide migration settings.","enum":[],"extra":{"typetext":"[type=] [,network=]"},"format":{"network":{"description":"CIDR of the (sub) network that is used for migration.","format":"CIDR","format_description":"CIDR","optional":1,"type":"string"},"type":{"default":"secure","default_key":1,"description":"Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.","enum":["secure","insecure"],"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"migration"},{"definition":{"description":"Migration is secure using SSH tunnel by default. For secure private networks you can disable it to speed up migration. Deprecated, use the 'migration' property instead!","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"migration_unsecure"},{"definition":{"description":"Control the range for the free VMID auto-selection pool.","enum":[],"extra":{"typetext":"[lower=] [,upper=]"},"format":{"lower":{"default":100,"description":"Lower, inclusive boundary for free next-id API range.","max":999999999,"min":100,"optional":1,"type":"integer"},"upper":{"default":1000000,"description":"Upper, exclusive boundary for free next-id API range.","max":1000000000,"min":100,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"next-id"},{"definition":{"description":"Cluster-wide notification settings.","enum":[],"extra":{"typetext":"package-updates="},"format":{"package-updates":{"default":"auto","description":"Control when the daily update job should send out notification mails.","enum":["auto","always","never"],"type":"string","verbose_description":"Control how often the daily update job should send out notification mails:\n* 'auto' daily for systems with a valid subscription, as those are assumed to be production-ready and thus should know about pending updates.\n* 'always' every update, if there are new pending updates.\n* 'never' never send a notification for new pending updates.\n"}},"optional":true,"properties":{},"type":"string"},"name":"notify"},{"definition":{"description":"A list of tags that require a `Sys.Modify` on '/' to set and delete. Tags set here that are also in 'user-tag-access' also require `Sys.Modify`.","enum":[],"extra":{"typetext":"[;...]"},"optional":true,"pattern":"(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*);)*(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*)","properties":{},"type":"string"},"name":"registered-tags"},{"definition":{"description":"Tag style options.","enum":[],"extra":{"typetext":"[case-sensitive=<1|0>] [,color-map=:[:][;=...]] [,ordering=] [,shape=]"},"format":{"case-sensitive":{"default":0,"description":"Controls if filtering for unique tags on update should check case-sensitive.","optional":1,"type":"boolean"},"color-map":{"description":"Manual color mapping for tags (semicolon separated).","optional":1,"pattern":"(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*):[0-9a-fA-F]{6}(?::[0-9a-fA-F]{6})?)(?:;(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*):[0-9a-fA-F]{6}(?::[0-9a-fA-F]{6})?))*","type":"string","typetext":":[:][;=...]"},"ordering":{"default":"alphabetical","description":"Controls the sorting of the tags in the web-interface and the API update.","enum":["config","alphabetical"],"optional":1,"type":"string"},"shape":{"default":"circle","description":"Tag shape for the web ui tree. 'full' draws the full tag. 'circle' draws only a circle with the background color. 'dense' only draws a small rectancle (useful when many tags are assigned to each guest).'none' disables showing the tags.","enum":["full","circle","dense","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"tag-style"},{"definition":{"description":"u2f","enum":[],"extra":{"typetext":"[appid=] [,origin=]"},"format":{"appid":{"description":"U2F AppId URL override. Defaults to the origin.","format_description":"APPID","optional":1,"type":"string"},"origin":{"description":"U2F Origin override. Mostly useful for single nodes with a single URL.","format_description":"URL","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"u2f"},{"definition":{"description":"Privilege options for user-settable tags","enum":[],"extra":{"typetext":"[user-allow=] [,user-allow-list=[;...]]"},"format":{"user-allow":{"default":"free","description":"Controls tag usage for users without `Sys.Modify` on `/` by either allowing `none`, a `list`, already `existing` or anything (`free`).","enum":["none","list","existing","free"],"optional":1,"type":"string","verbose_description":"Controls which tags can be set or deleted on resources a user controls (such as guests). Users with the `Sys.Modify` privilege on `/` are always unrestricted. * 'none' no tags are usable. * 'list' tags from 'user-allow-list' are usable. * 'existing' like list, but already existing tags of resources are also usable.* 'free' no tag restrictions."},"user-allow-list":{"description":"List of tags users are allowed to set and delete (semicolon separated) for 'user-allow' values 'list' and 'existing'.","optional":1,"pattern":"(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*)(?:;(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*))*","type":"string","typetext":"[;...]"}},"optional":true,"properties":{},"type":"string"},"name":"user-tag-access"},{"definition":{"description":"webauthn configuration","enum":[],"extra":{"typetext":"[allow-subdomains=<1|0>] [,id=] [,origin=] [,rp=]"},"format":{"allow-subdomains":{"default":1,"description":"Whether to allow the origin to be a subdomain, rather than the exact URL.","optional":1,"type":"boolean"},"id":{"description":"Relying party ID. Must be the domain name without protocol, port or location. Changing this *will* break existing credentials.","format_description":"DOMAINNAME","optional":1,"type":"string"},"origin":{"description":"Site origin. Must be a `https://` URL (or `http://localhost`). Should contain the address users type in their browsers to access the web interface. Changing this *may* break existing credentials.","format_description":"URL","optional":1,"type":"string"},"rp":{"description":"Relying party name. Any text identifier. Changing this *may* break existing credentials.","format_description":"RELYING_PARTY","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"webauthn"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"836667aaea1693e9740b25ea05dfe4494a11b7bc0c6b94abf52e4c27455e17b0","description":"List replication jobs.","extra":{},"name":"index","parameters":[],"permissions":{"description":"Requires the VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"6e719bf689a19e11db1c645c80b7c865cfbd44d07efa6a1dc0fef3692b58b0a2","description":"Create a new replication job","extra":{},"name":"create","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Flag to disable/deactivate the entry.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"number"},"name":"rate"},{"definition":{"description":"Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.","enum":["local","full"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"remove_job"},{"definition":{"default":"*/15","description":"Storage replication schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"For internal use, to detect if the guest was stolen.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":false,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Section type.","enum":["local"],"extra":{},"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/replication"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a755e3fc20618d34ac577bb6749b86e277a78938aafcc74d3d1ef45aee2995da","description":"Mark replication job for removal.","extra":{},"name":"delete","parameters":[{"definition":{"default":0,"description":"Will remove the jobconfig entry, but will not cleanup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"default":0,"description":"Keep replicated data at target (do not remove).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keep"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"e7ec17056fddc5bf05f3598911533fad45ff9b2eadbc69102c3ae6404a996582","description":"Read replication job configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"}],"permissions":{"description":"Requires the VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"b2a02a200edfe9eef9130cab266cc7fc0fe6d6089aac0c7fab9430f7b8ec2b35","description":"Update replication job configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Flag to disable/deactivate the entry.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"number"},"name":"rate"},{"definition":{"description":"Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.","enum":["local","full"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"remove_job"},{"definition":{"default":"*/15","description":"Storage replication schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"For internal use, to detect if the guest was stolen.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"source"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/replication/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6b42641ea222f96365862ded1d0386b8208c36d982164e33ed8491e2f6d84afd","description":"Resources index (cluster wide).","extra":{},"name":"resources","parameters":[{"definition":{"enum":["vm","storage","node","sdn"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"cgroup-mode":{"description":"The cgroup mode the node operates under (when type == node).","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"content":{"description":"Allowed storage content types (when type == storage).","enum":[],"extra":{},"format":"pve-storage-content-list","optional":true,"properties":{},"type":"string"},"cpu":{"description":"CPU utilization (when type in node,qemu,lxc).","enum":[],"extra":{"renderer":"fraction_as_percentage"},"minimum":0,"optional":true,"properties":{},"type":"number"},"disk":{"description":"Used disk space in bytes (when type in storage), used root image spave for VMs (type in qemu,lxc).","enum":[],"extra":{"renderer":"bytes"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"hastate":{"description":"HA service status (for HA managed VMs).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"level":{"description":"Support level (when type == node).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxcpu":{"description":"Number of available CPUs (when type in node,qemu,lxc).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"number"},"maxdisk":{"description":"Storage size in bytes (when type in storage), root image size for VMs (type in qemu,lxc).","enum":[],"extra":{"renderer":"bytes"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Number of available memory in bytes (when type in node,qemu,lxc).","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"mem":{"description":"Used memory in bytes (when type in node,qemu,lxc).","enum":[],"extra":{"renderer":"bytes"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":{"description":"Name of the resource.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"node":{"description":"The cluster node name (when type in node,storage,qemu,lxc).","enum":[],"extra":{},"format":"pve-node","optional":true,"properties":{},"type":"string"},"plugintype":{"description":"More specific type, if available.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pool":{"description":"The pool name (when type in pool,qemu,lxc).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"status":{"description":"Resource type dependent status.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"storage":{"description":"The storage identifier (when type == storage).","enum":[],"extra":{},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"type":{"description":"Resource type.","enum":["node","storage","pool","qemu","lxc","openvz","sdn"],"extra":{},"properties":{},"type":"string"},"uptime":{"description":"Node uptime in seconds (when type in node,qemu,lxc).","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The numerical vmid (when type in qemu,lxc).","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/resources"},{"extra":{},"methods":[{"allow_token":true,"checksum":"50dd0532cd996f30fd2ca1c578f00b7f09b5ac6a8735b377a9e74caaf9578106","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["SDN.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"e3e53e99bf397ad633261a85727564ec67c8818f3f78fba390f6a9b51f809ea2","description":"Apply sdn controller changes && reload.","extra":{},"name":"reload","parameters":[],"permissions":{"expression":{"check":["perm","/sdn",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/cluster/sdn"},{"extra":{},"methods":[{"allow_token":true,"checksum":"fffd9d5d2ede50c655273daa582c9055f5c64935bc8a916216092e618b97ed02","description":"SDN controllers index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"Only list sdn controllers of specific type","enum":["bgp","evpn","faucet"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/controllers/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{controller}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"controller":{"enum":[],"extra":{},"properties":{},"type":"string"},"pending":{"enum":[],"extra":{},"optional":true,"properties":{}},"state":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"83f0b8c64241d62d620ae4b9ae1bda25f429b5471437d24f0194a6230031d20c","description":"Create a new sdn controller object.","extra":{},"name":"create","parameters":[{"definition":{"description":"autonomous system number","enum":[],"extra":{"typetext":" (0 - 4294967296)"},"maximum":4294967296,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"asn"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bgp-multipath-as-path-relax"},{"definition":{"description":"The SDN controller object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-controller-id","properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"Enable ebgp. (remote-as external)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ebgp"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"ebgp-multihop"},{"definition":{"description":"source loopback interface.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"loopback"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"peers address list.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"peers"},{"definition":{"description":"Plugin type.","enum":["bgp","evpn","faucet"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/sdn/controllers",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/controllers"},{"extra":{},"methods":[{"allow_token":true,"checksum":"cd5848ee8488704f054d262616cdac7dafce590f953307860febf76eb5b924d3","description":"Delete sdn controller object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN controller object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-controller-id","properties":{},"type":"string"},"name":"controller"}],"permissions":{"expression":{"check":["perm","/sdn/controllers",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"10ce0dd020d72fc27315b708c59822eda08951a6408ee5cdf9ef59e6c77b1285","description":"Read sdn controller configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The SDN controller object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-controller-id","properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"}],"permissions":{"expression":{"check":["perm","/sdn/controllers/{controller}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"799b542ed61e374281e606b88700964bb128aefb5c497a857291be65faa8dd71","description":"Update sdn controller object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"autonomous system number","enum":[],"extra":{"typetext":" (0 - 4294967296)"},"maximum":4294967296,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"asn"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bgp-multipath-as-path-relax"},{"definition":{"description":"The SDN controller object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-controller-id","properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Enable ebgp. (remote-as external)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ebgp"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"ebgp-multihop"},{"definition":{"description":"source loopback interface.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"loopback"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"peers address list.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"peers"}],"permissions":{"expression":{"check":["perm","/sdn/controllers",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/controllers/{controller}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"eb447be7b8deba4c48a26dec0552342de4afd2b7ed9b023f63bf59e8a899344a","description":"SDN dns index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list sdn dns of specific type","enum":["powerdns"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/dns/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{dns}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"dns":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"029ea423810eeebc69994f36e681a535cad885f3d584cb7ac480a9832a101d6b","description":"Create a new sdn dns object.","extra":{},"name":"create","parameters":[{"definition":{"description":"The SDN dns object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-dns-id","properties":{},"type":"string"},"name":"dns"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":false,"properties":{},"type":"string"},"name":"key"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"reversemaskv6"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"reversev6mask"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"ttl"},{"definition":{"description":"Plugin type.","enum":["powerdns"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":false,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["perm","/sdn/dns",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/dns"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5eabbb998398cee212dd2507f83c5e968a90e3413d0844b3f51a3a1e206e869e","description":"Delete sdn dns object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN dns object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-dns-id","properties":{},"type":"string"},"name":"dns"}],"permissions":{"expression":{"check":["perm","/sdn/dns",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f06c8afd05ffad3362aa90b64a2ab7239e95ed803211979c4579c145bffe8b3f","description":"Read sdn dns configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The SDN dns object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-dns-id","properties":{},"type":"string"},"name":"dns"}],"permissions":{"expression":{"check":["perm","/sdn/dns/{dns}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"75d2e9fc2b7a13fb2f70178ab6fc2a52ea2578724efe3480d361f7ab2b4fa4fc","description":"Update sdn dns object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The SDN dns object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-dns-id","properties":{},"type":"string"},"name":"dns"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"key"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"reversemaskv6"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"ttl"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["perm","/sdn/dns",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/dns/{dns}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2082f53189334ff79a0eb8a997c9e416b23b351b06e0804f95ee35b13963c6fc","description":"SDN ipams index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list sdn ipams of specific type","enum":["netbox","phpipam","pve"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/ipams/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{ipam}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"ipam":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"cacd82e3d8c942972501b03a8f9a51e0d8deb4c05b09bf5a6408565ac3235640","description":"Create a new sdn ipam object.","extra":{},"name":"create","parameters":[{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-ipam-id","properties":{},"type":"string"},"name":"ipam"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"section"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"},{"definition":{"description":"Plugin type.","enum":["netbox","phpipam","pve"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["perm","/sdn/ipams",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/ipams"},{"extra":{},"methods":[{"allow_token":true,"checksum":"02da5207be93d63cb52d2e2ffe9ddcd11d1fe46bf238811457b52efa44753926","description":"Delete sdn ipam object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-ipam-id","properties":{},"type":"string"},"name":"ipam"}],"permissions":{"expression":{"check":["perm","/sdn/ipams",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"6b0cd8f67bfc09eea4cf6d833cbf185c78ad36625225e852696671085c14793a","description":"Read sdn ipam configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-ipam-id","properties":{},"type":"string"},"name":"ipam"}],"permissions":{"expression":{"check":["perm","/sdn/ipams/{ipam}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"dc47088f2be0777370c2a4ebb16fdf883145961ab50add6cedaa41739acda7be","description":"Update sdn ipam object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-ipam-id","properties":{},"type":"string"},"name":"ipam"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"section"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["perm","/sdn/ipams",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/ipams/{ipam}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"440c93761319b6496065694cc7b444afeb1a253fdeb4d129e5c83687310fb1a2","description":"SDN vnets index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/vnets/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{vnet}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"aafa9d20a2d0980a15803fb064c0fbbbb55de2b51687b6b749aa76ab62f3328d","description":"Create a new sdn vnet object.","extra":{},"name":"create","parameters":[{"definition":{"description":"alias name of the vnet","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})","properties":{},"type":"string"},"name":"alias"},{"definition":{"description":"vlan or vxlan id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"tag"},{"definition":{"description":"Type","enum":["vnet"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"Allow vm VLANs to pass through this vnet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"vlanaware"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"},{"definition":{"description":"zone id","enum":[],"extra":{"typetext":""},"optional":false,"properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/vnets",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/vnets"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d742d25dc41efc5c0b6f36aa04dd6b6ae07edaf8f8b3153fe81463ade004e748","description":"Delete sdn vnet object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"expression":{"check":["perm","/sdn/vnets",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"cb4269ac5f852e47e5c9b0c4066a6fb8beb6092b7fbb86eb21dedb24431d5834","description":"Read sdn vnet configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"expression":{"check":["perm","/sdn/vnets/{vnet}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"b97cec1ff3ac59908347900ef8a0980b4410027a712395e1188f684dca5f7a10","description":"Update sdn vnet object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"alias name of the vnet","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})","properties":{},"type":"string"},"name":"alias"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"vlan or vxlan id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"tag"},{"definition":{"description":"Allow vm VLANs to pass through this vnet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"vlanaware"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"},{"definition":{"description":"zone id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/vnets",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/vnets/{vnet}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bf7f3930d8114570d72e14e69a562a1b6a3bbc0bfb96f02a6283c8569f53e79a","description":"SDN subnets index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/subnets/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subnet}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"70912f6334b6fb8c741681f4b84db7a6647df44a376d31ac5d3ed287876f3e49","description":"Create a new sdn subnet object.","extra":{},"name":"create","parameters":[{"definition":{"description":"dns domain zone prefix ex: 'adm' -> .adm.mydomain.com","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"dnszoneprefix"},{"definition":{"description":"Subnet Gateway: Will be assign on vnet for layer3 zones","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"gateway"},{"definition":{"description":"enable masquerade for this subnet if pve-firewall","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"snat"},{"definition":{"description":"The SDN subnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-subnet-id","properties":{},"type":"string"},"name":"subnet"},{"definition":{"enum":["subnet"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"associated vnet","enum":[],"extra":{"typetext":""},"optional":false,"properties":{},"type":"string"},"name":"vnet"}],"permissions":{"expression":{"check":["perm","/sdn/vnets/{vnet}/subnets",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/vnets/{vnet}/subnets"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2629cf52e6350fa8e61ebd0752e9eaa41f27f91368695e92ddb48ea4a62ccf21","description":"Delete sdn subnet object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN subnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-subnet-id","properties":{},"type":"string"},"name":"subnet"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"expression":{"check":["perm","/sdn/vnets/{vnet}/subnets",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"e6a1aefebb68d276b7c8e61031c8e0f1691056c37876ace9fcaf7364e5510322","description":"Read sdn subnet configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"The SDN subnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-subnet-id","properties":{},"type":"string"},"name":"subnet"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"expression":{"check":["perm","/sdn/vnets/{vnet}/subnets/{subnet}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"256a9321d58e67172d33d5395bf341062209409176cf7cec066967f828996c2d","description":"Update sdn subnet object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"dns domain zone prefix ex: 'adm' -> .adm.mydomain.com","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"dnszoneprefix"},{"definition":{"description":"Subnet Gateway: Will be assign on vnet for layer3 zones","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"gateway"},{"definition":{"description":"enable masquerade for this subnet if pve-firewall","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"snat"},{"definition":{"description":"The SDN subnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-subnet-id","properties":{},"type":"string"},"name":"subnet"},{"definition":{"description":"associated vnet","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"vnet"}],"permissions":{"expression":{"check":["perm","/sdn/vnets/{vnet}/subnets",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/vnets/{vnet}/subnets/{subnet}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"703256a54caba27a0fe1e54aadfd275f490b49dfe9071dddc1872d3c74684250","description":"SDN zones index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"Only list SDN zones of specific type","enum":["evpn","faucet","qinq","simple","vlan","vxlan"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{zone}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"dns":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dnszone":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipam":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mtu":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"nodes":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pending":{"enum":[],"extra":{},"optional":true,"properties":{}},"reversedns":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"state":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"},"zone":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"04977cc4b537126e9e9226cd09e825a6be9bda576af0af43922166ff89280ca1","description":"Create a new sdn zone object.","extra":{},"name":"create","parameters":[{"definition":{"description":"Advertise evpn subnets if you have silent hosts","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"advertise-subnets"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"bridge"},{"definition":{"description":"Disable auto mac learning.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bridge-disable-mac-learning"},{"definition":{"description":"Frr router name","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"Disable ipv4 arp && ipv6 neighbour discovery suppression","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable-arp-nd-suppression"},{"definition":{"description":"dns api server","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dns"},{"definition":{"description":"dns domain zone ex: mydomain.com","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"dnszone"},{"definition":{"description":"Faucet dataplane id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"dp-id"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"exitnodes"},{"definition":{"description":"Allow exitnodes to connect to evpn guests","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"exitnodes-local-routing"},{"definition":{"description":"Force traffic to this exitnode first.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"exitnodes-primary"},{"definition":{"description":"use a specific ipam","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ipam"},{"definition":{"description":"Anycast logical router mac address","enum":[],"extra":{"typetext":""},"format":"mac-addr","optional":true,"properties":{},"type":"string"},"name":"mac"},{"definition":{"description":"MTU","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"peers address list.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"peers"},{"definition":{"description":"reverse dns api server","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"reversedns"},{"definition":{"description":"Route-Target import","enum":[],"extra":{"typetext":""},"format":"pve-sdn-bgp-rt-list","optional":true,"properties":{},"type":"string"},"name":"rt-import"},{"definition":{"description":"Service-VLAN Tag","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"tag"},{"definition":{"description":"Plugin type.","enum":["evpn","faucet","qinq","simple","vlan","vxlan"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"},{"definition":{"default":"802.1q","enum":["802.1q","802.1ad"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"vlan-protocol"},{"definition":{"description":"l3vni.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"vrf-vxlan"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/zones"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2f5064f43ef051fe497248fbda38d7e28b717d65019a575baca823d297de25d0","description":"Delete sdn zone object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"38131dcce447712ecf268c650a95c5166219287eacc37bc414317b3c94239a9f","description":"Read sdn zone configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"3488f9ffb2019c2fbc3fb700bf6bf343e6ae734d4340977ef8059d7cd5bdfb51","description":"Update sdn zone object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"Advertise evpn subnets if you have silent hosts","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"advertise-subnets"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"bridge"},{"definition":{"description":"Disable auto mac learning.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bridge-disable-mac-learning"},{"definition":{"description":"Frr router name","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Disable ipv4 arp && ipv6 neighbour discovery suppression","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable-arp-nd-suppression"},{"definition":{"description":"dns api server","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dns"},{"definition":{"description":"dns domain zone ex: mydomain.com","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"dnszone"},{"definition":{"description":"Faucet dataplane id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"dp-id"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"exitnodes"},{"definition":{"description":"Allow exitnodes to connect to evpn guests","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"exitnodes-local-routing"},{"definition":{"description":"Force traffic to this exitnode first.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"exitnodes-primary"},{"definition":{"description":"use a specific ipam","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ipam"},{"definition":{"description":"Anycast logical router mac address","enum":[],"extra":{"typetext":""},"format":"mac-addr","optional":true,"properties":{},"type":"string"},"name":"mac"},{"definition":{"description":"MTU","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"peers address list.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"peers"},{"definition":{"description":"reverse dns api server","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"reversedns"},{"definition":{"description":"Route-Target import","enum":[],"extra":{"typetext":""},"format":"pve-sdn-bgp-rt-list","optional":true,"properties":{},"type":"string"},"name":"rt-import"},{"definition":{"description":"Service-VLAN Tag","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"tag"},{"definition":{"default":"802.1q","enum":["802.1q","802.1ad"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"vlan-protocol"},{"definition":{"description":"l3vni.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"vrf-vxlan"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/zones/{zone}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5a589a6f8ca9ac2030fd4d33ef13a80e575465992929b29725526face0399cc5","description":"Get cluster status information.","extra":{},"name":"get_status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"ip":{"description":"[node] IP of the resolved nodename.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"level":{"description":"[node] Proxmox VE Subscription level, indicates if eligible for enterprise support as well as access to the stable Proxmox VE Enterprise Repository.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"local":{"description":"[node] Indicates if this is the responding node.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"nodeid":{"description":"[node] ID of the node from the corosync configuration.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"nodes":{"description":"[cluster] Nodes count, including offline nodes.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"online":{"description":"[node] Indicates if the node is online or offline.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"quorate":{"description":"[cluster] Indicates if there is a majority of nodes online to make decisions","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"type":{"description":"Indicates the type, either cluster or node. The type defines the object properties e.g. quorate available for type cluster.","enum":["cluster","node"],"extra":{},"properties":{},"type":"string"},"version":{"description":"[cluster] Current version of the corosync configuration file.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d04c3b849a0aa5e5920867f414fba45c484719be08796bcbeaf8832f5833fe88","description":"List recent tasks (cluster wide).","extra":{},"name":"tasks","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"upid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/tasks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"31b002c17296ec68232ef7ac7414c584f56baeeefffa7dc7edd05d8ce5e5f183","description":"Cluster node index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{node}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cpu":{"description":"CPU utilization.","enum":[],"extra":{"renderer":"fraction_as_percentage"},"optional":true,"properties":{},"type":"number"},"level":{"description":"Support level.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxcpu":{"description":"Number of available CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Number of available memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"mem":{"description":"Used memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"node":{"description":"The cluster node name.","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"ssl_fingerprint":{"description":"The SSL fingerprint for the node certificate.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"status":{"description":"Node status.","enum":["unknown","online","offline"],"extra":{},"properties":{},"type":"string"},"uptime":{"description":"Node uptime in seconds.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes"},{"extra":{},"methods":[{"allow_token":true,"checksum":"407b3d66a300b7bc4f15ce81eadffc3e3ff161e7940cd646fc925a219be029f3","description":"Node index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"35b8e469447bd0b2011a8dfbb2d764cd4c5d26a960c23bfb523d2b8c078bbaf0","description":"Get list of appliances.","extra":{"proxyto":"node"},"name":"aplinfo","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"d4aad4483b7b17e8ec114d3e2f2e0454dc69dfdda3d679e441ec953cc1bb4dd7","description":"Download appliance templates.","extra":{"proxyto":"node"},"name":"apl_download","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage where the template will be stored","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"The template which will downloaded","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"template"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.AllocateTemplate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/aplinfo"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9fba10841493cc0c3608fd5b429677bf1e44b64bc3298479603a5da713b6c7e6","description":"Directory index for apt (Advanced Package Tool).","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/apt"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a2d6c099458fd722c750e1161be41fe0d364c22884858a3a0828f0f52cb8da10","description":"Get package changelogs.","extra":{"proxyto":"node"},"name":"changelog","parameters":[{"definition":{"description":"Package name.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Package version.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"version"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/apt/changelog"},{"extra":{},"methods":[{"allow_token":true,"checksum":"31afb6060270acc12e023a6b7f2e929996e408352872438f6456b06ca9790cd0","description":"Get APT repository information.","extra":{"proxyto":"node"},"name":"repositories","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"description":"Result from parsing the APT repository files in /etc/apt/.","enum":[],"extra":{},"properties":{"digest":{"description":"Common digest of all files.","enum":[],"extra":{},"properties":{},"type":"string"},"errors":{"description":"List of problematic repository files.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"error":{"description":"The error message","enum":[],"extra":{},"properties":{},"type":"string"},"path":{"description":"Path to the problematic file.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"files":{"description":"List of parsed repository files.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"digest":{"description":"Digest of the file as bytes.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"integer"},"properties":{},"type":"array"},"file-type":{"description":"Format of the file.","enum":["list","sources"],"extra":{},"properties":{},"type":"string"},"path":{"description":"Path to the problematic file.","enum":[],"extra":{},"properties":{},"type":"string"},"repositories":{"description":"The parsed repositories.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"Comment":{"description":"Associated comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"Components":{"description":"List of repository components","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"Enabled":{"description":"Whether the repository is enabled or not","enum":[],"extra":{},"properties":{},"type":"boolean"},"FileType":{"description":"Format of the defining file.","enum":["list","sources"],"extra":{},"properties":{},"type":"string"},"Options":{"description":"Additional options","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"Key":{"enum":[],"extra":{},"properties":{},"type":"string"},"Values":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"Suites":{"description":"List of package distribuitions","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"Types":{"description":"List of package types.","enum":[],"extra":{},"items":{"enum":["deb","deb-src"],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"URIs":{"description":"List of repository URIs.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"},"infos":{"description":"Additional information/warnings for APT repositories.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"index":{"description":"Index of the associated repository within the file.","enum":[],"extra":{},"properties":{},"type":"string"},"kind":{"description":"Kind of the information (e.g. warning).","enum":[],"extra":{},"properties":{},"type":"string"},"message":{"description":"Information message.","enum":[],"extra":{},"properties":{},"type":"string"},"path":{"description":"Path to the associated file.","enum":[],"extra":{},"properties":{},"type":"string"},"property":{"description":"Property from which the info originates.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"standard-repos":{"description":"List of standard repositories and their configuration status","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"handle":{"description":"Handle to identify the repository.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Full name of the repository.","enum":[],"extra":{},"properties":{},"type":"string"},"status":{"description":"Indicating enabled/disabled status, if the repository is configured.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"2e6c839d6bc3336bbd44277a870b0c9286a191be1f0ab21bc059a03be572b892","description":"Change the properties of a repository. Currently only allows enabling/disabling.","extra":{"proxyto":"node"},"name":"change_repository","parameters":[{"definition":{"description":"Digest to detect modifications.","enum":[],"extra":{"typetext":""},"max_length":80,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Whether the repository should be enabled or not.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"description":"Index within the file (starting from 0).","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"index"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Path to the containing file.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"path"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"fe3a49714d62a93527594a310f2dafe8786e91acabd0932a1d50d07073dca22d","description":"Add a standard repository to the configuration","extra":{"proxyto":"node"},"name":"add_repository","parameters":[{"definition":{"description":"Digest to detect modifications.","enum":[],"extra":{"typetext":""},"max_length":80,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Handle that identifies a repository.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"handle"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/apt/repositories"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b67270ad2512c5a995135eb26fb3729c5d8711de50412275d659531302779e2a","description":"List available updates.","extra":{"proxyto":"node"},"name":"list_updates","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"4727da3cf5e9aa4553a84f63261c3561da0bce68e5a573711f49edfde5cfc249","description":"This is used to resynchronize the package index files from their sources (apt-get update).","extra":{"proxyto":"node"},"name":"update_database","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Send notification mail about new packages (to email address specified for user 'root@pam').","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"notify"},{"definition":{"default":0,"description":"Only produces output suitable for logging, omitting progress indicators.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"quiet"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/apt/update"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f99cfcd0bb0ec2bf579674fc6cfd8c56025b24f68e28984c5318e468a369fa24","description":"Get package information for important Proxmox packages.","extra":{"proxyto":"node"},"name":"versions","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/apt/versions"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8323065d812e5e1377041e57ec0822474ada502b7d6d00636fe213e047e9de68","description":"Node capabilities index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/capabilities"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e27a6b54ddd6b980e5e1d7ddede6947b8cf3f81dc2cf5a3b59b263186afae2d7","description":"QEMU capabilities index.","extra":{},"name":"qemu_caps_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/capabilities/qemu"},{"extra":{},"methods":[{"allow_token":true,"checksum":"927d1325a9a50865ae950f9d9ec8be45d125376424b8b48420d3105b711ba85e","description":"List all custom and default CPU models.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Only returns custom models when the current user has Sys.Audit on /nodes.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"custom":{"description":"True if this is a custom CPU model.","enum":[],"extra":{},"properties":{},"type":"boolean"},"name":{"description":"Name of the CPU model. Identifies it for subsequent API calls. Prefixed with 'custom-' for custom models.","enum":[],"extra":{},"properties":{},"type":"string"},"vendor":{"description":"CPU vendor visible to the guest when this model is selected. Vendor of 'reported-model' in case of custom models.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/capabilities/qemu/cpu"},{"extra":{},"methods":[{"allow_token":true,"checksum":"aa82f4e315b0d3d45f24590c081570d951d49f694f60716734889b5d02e8c01f","description":"Get available QEMU/KVM machine types.","extra":{"proxyto":"node"},"name":"types","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"id":{"description":"Full name of machine type and version.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The machine type.","enum":["q35","i440fx"],"extra":{},"properties":{},"type":"string"},"version":{"description":"The machine version.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/capabilities/qemu/machines"},{"extra":{},"methods":[{"allow_token":true,"checksum":"50808c982a4bc72c9bba3f95d85803db4a5a6d9897255ac750c522b0369f4f21","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph"},{"extra":{},"methods":[{"allow_token":true,"checksum":"23dca6507cde2ae0cabadf81020c2e06e2c8878c3e19c7356ba7dbc49c506a9a","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/cfg"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0a6db46755187dc915b8cc1af63033dc1d37ca5142fa6f5d6316de794dcefc35","description":"Get the Ceph configuration database.","extra":{"proxyto":"node"},"name":"db","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"can_update_at_runtime":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"level":{"enum":[],"extra":{},"properties":{},"type":"string"},"mask":{"enum":[],"extra":{},"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"section":{"enum":[],"extra":{},"properties":{},"type":"string"},"value":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/cfg/db"},{"extra":{},"methods":[{"allow_token":true,"checksum":"566ab98133cdf7bf8664225da85a43166f5b253cad7a29e5b5d58b8f36b11786","description":"Get the Ceph configuration file.","extra":{"proxyto":"node"},"name":"raw","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/ceph/cfg/raw"},{"extra":{},"methods":[{"allow_token":true,"checksum":"98c0d6719a80dc5b3088ba5c5793892bf04a7a07a42dfbb37861b5797b0a69f8","description":"Heuristical check if it is safe to perform an action.","extra":{"proxyto":"node"},"name":"cmd_safety","parameters":[{"definition":{"description":"Action to check","enum":["stop","destroy"],"extra":{},"properties":{},"type":"string"},"name":"action"},{"definition":{"description":"ID of the service","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service type","enum":["osd","mon","mds"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"safe":{"description":"If it is safe to run the command.","enum":[],"extra":{},"properties":{},"type":"boolean"},"status":{"description":"Status message given by Ceph.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/cmd-safety"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9cf0ae20171a33d5f41a394ec20f987655e00407daf589f39797244527704fa8","description":"Get the Ceph configuration file. Deprecated, please use `/nodes/{node}/ceph/cfg/raw.","extra":{"proxyto":"node"},"name":"config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/ceph/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"51bfa385a86031dbc430b77260560e7b4a44610995d65783f75107f8b55348a7","description":"Get the Ceph configuration database. Deprecated, please use `/nodes/{node}/ceph/cfg/db.","extra":{"proxyto":"node"},"name":"configdb","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"can_update_at_runtime":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"level":{"enum":[],"extra":{},"properties":{},"type":"string"},"mask":{"enum":[],"extra":{},"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"section":{"enum":[],"extra":{},"properties":{},"type":"string"},"value":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/configdb"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e0322c6f07c65f5c1619204f0c7e670156521f47e8951f35563c74787459eefd","description":"Get OSD crush map","extra":{"proxyto":"node"},"name":"crush","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/ceph/crush"},{"extra":{},"methods":[{"allow_token":true,"checksum":"26fe33f0ff9494d29cd6768124890f101bf0ce6aa94b0171689a06f41af1e95f","description":"Directory index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"data_pool":{"description":"The name of the data pool.","enum":[],"extra":{},"properties":{},"type":"string"},"metadata_pool":{"description":"The name of the metadata pool.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"The ceph filesystem name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/fs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dc423ab96f13144b7889e6746c2e79a238c9d36e08762a85235fec362eab0df3","description":"Create a Ceph filesystem","extra":{"proxyto":"node"},"name":"createfs","parameters":[{"definition":{"default":0,"description":"Configure the created CephFS as storage for this cluster.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add-storage"},{"definition":{"default":"cephfs","description":"The ceph filesystem name.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":128,"description":"Number of placement groups for the backing data pool. The metadata pool will use a quarter of this.","enum":[],"extra":{"typetext":" (8 - 32768)"},"maximum":32768,"minimum":8,"optional":true,"properties":{},"type":"integer"},"name":"pg_num"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/fs/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"eb5af2fb65663011d0126319b08e7596f5c1f628ce5d5281ab3946e246c38ed8","description":"Create initial ceph default configuration and setup symlinks.","extra":{"proxyto":"node"},"name":"init","parameters":[{"definition":{"description":"Declare a separate cluster network, OSDs will routeheartbeat, object replication and recovery traffic over it","enum":[],"extra":{"requires":"network","typetext":""},"format":"CIDR","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"cluster-network"},{"definition":{"default":0,"description":"Disable cephx authentication.\n\nWARNING: cephx is a security feature protecting against man-in-the-middle attacks. Only consider disabling cephx if your network is private!","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable_cephx"},{"definition":{"default":2,"description":"Minimum number of available replicas per object to allow I/O","enum":[],"extra":{"typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"min_size"},{"definition":{"description":"Use specific network for all ceph related traffic","enum":[],"extra":{"typetext":""},"format":"CIDR","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"network"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":6,"description":"Placement group bits, used to specify the default number of placement groups.\n\nNOTE: 'osd pool default pg num' does not work for default pools.","enum":[],"extra":{"typetext":" (6 - 14)"},"maximum":14,"minimum":6,"optional":true,"properties":{},"type":"integer"},"name":"pg_bits"},{"definition":{"default":3,"description":"Targeted number of replicas per object","enum":[],"extra":{"typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"size"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/init"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8a31ac771c928fe9eb6235d17a52ecaf2ae45e2169ec83ac019a01378dd9c35a","description":"Read ceph log","extra":{"proxyto":"node"},"name":"log","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"572f311d8fc0eb7f66a89e38bda2cd329ee39d8ba4a8025ce6713bf3f7d6c1be","description":"MDS directory index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"addr":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"host":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"The name (ID) for the MDS","enum":[],"extra":{},"properties":{}},"rank":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"standby_replay":{"description":"If true, the standby MDS is polling the active MDS for faster recovery (hot standby).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"state":{"description":"State of the MDS","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/mds"},{"extra":{},"methods":[{"allow_token":true,"checksum":"95bfdf6b725d610975f2cb9b78b5c858072ceb2d7fa1e721df8554522b7ff936","description":"Destroy Ceph Metadata Server","extra":{"proxyto":"node"},"name":"destroymds","parameters":[{"definition":{"description":"The name (ID) of the mds","enum":[],"extra":{},"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"9c3ec6795adb762b6e5f1367b947a261fc983bf1377a29f675353f65636f8e77","description":"Create Ceph Metadata Server (MDS)","extra":{"proxyto":"node"},"name":"createmds","parameters":[{"definition":{"default":"0","description":"Determines whether a ceph-mds daemon should poll and replay the log of an active MDS. Faster switch on MDS failure, but needs more idle resources.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"hotstandby"},{"definition":{"default":"nodename","description":"The ID for the mds, when omitted the same as the nodename","enum":[],"extra":{},"max_length":200,"optional":true,"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/mds/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"66c37a28e4da09b1f5d9ed47d7aa6d37f754c5fad2f1d951d8dfd682cc4ae54a","description":"MGR directory index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"addr":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"host":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"The name (ID) for the MGR","enum":[],"extra":{},"properties":{}},"state":{"description":"State of the MGR","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/mgr"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1b6eac6b4b1058f7d0564b86f899fc1c39d08317e8482afa20115de4fd4c5f3c","description":"Destroy Ceph Manager.","extra":{"proxyto":"node"},"name":"destroymgr","parameters":[{"definition":{"description":"The ID of the manager","enum":[],"extra":{},"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"9a9667c69cb29e5a499d6a2369ff4f46790bf4fd55e6b6364daaf2846d1e86f4","description":"Create Ceph Manager","extra":{"proxyto":"node"},"name":"createmgr","parameters":[{"definition":{"description":"The ID for the manager, when omitted the same as the nodename","enum":[],"extra":{},"max_length":200,"optional":true,"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/mgr/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"06bf64866d2a3b4d94987e41f6bd86edd908e439943193b47a70294b6c519ae8","description":"Get Ceph monitor list.","extra":{"proxyto":"node"},"name":"listmon","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"addr":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ceph_version":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ceph_version_short":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"direxists":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"host":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"quorum":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"rank":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"service":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"state":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/mon"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0f5ae748cffda16f98dc9978fd9e9abc28c3131e1e102f2ebe3fbf965db5b663","description":"Destroy Ceph Monitor and Manager.","extra":{"proxyto":"node"},"name":"destroymon","parameters":[{"definition":{"description":"Monitor ID","enum":[],"extra":{},"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"monid"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"da2a2ad7e4477ad2aa7b3b1f28cf3ce7e9ae03cb7c553f98f26071d6ad2c4056","description":"Create Ceph Monitor and Manager","extra":{"proxyto":"node"},"name":"createmon","parameters":[{"definition":{"description":"Overwrites autodetected monitor IP address(es). Must be in the public network(s) of Ceph.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"mon-address"},{"definition":{"description":"The ID for the monitor, when omitted the same as the nodename","enum":[],"extra":{},"max_length":200,"optional":true,"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"monid"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/mon/{monid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4c731af45d22963c4c9ff4d2c9e8f3eb4464b1e7e3c4b462fa0ac18c0a67ce24","description":"Get Ceph osd list/tree.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"flags":{"enum":[],"extra":{},"properties":{},"type":"string"},"root":{"description":"Tree with OSDs in the CRUSH map structure.","enum":[],"extra":{},"properties":{},"type":"object"}},"type":"object"},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"d93cc549a296d8b476863b73edffd682c9aa56ea870d5140917243e67567eea8","description":"Create OSD","extra":{"proxyto":"node"},"name":"createosd","parameters":[{"definition":{"description":"Set the device class of the OSD in crush.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"crush-device-class"},{"definition":{"description":"Block device name for block.db.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"db_dev"},{"definition":{"default":"bluestore_block_db_size or 10% of OSD size","description":"Size in GiB for block.db.","enum":[],"extra":{"requires":"db_dev","typetext":" (1 - N)","verbose_description":"If a block.db is requested but the size is not given, will be automatically selected by: bluestore_block_db_size from the ceph database (osd or global section) or config (osd or global section)in that order. If this is not available, it will be sized 10% of the size of the OSD device. Fails if the available size is not enough."},"minimum":1,"optional":true,"properties":{},"type":"number"},"name":"db_dev_size"},{"definition":{"description":"Block device name.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"dev"},{"definition":{"default":0,"description":"Enables encryption of the OSD.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"encrypted"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Block device name for block.wal.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"wal_dev"},{"definition":{"default":"bluestore_block_wal_size or 1% of OSD size","description":"Size in GiB for block.wal.","enum":[],"extra":{"requires":"wal_dev","typetext":" (0.5 - N)","verbose_description":"If a block.wal is requested but the size is not given, will be automatically selected by: bluestore_block_wal_size from the ceph database (osd or global section) or config (osd or global section)in that order. If this is not available, it will be sized 1% of the size of the OSD device. Fails if the available size is not enough."},"minimum":0.5,"optional":true,"properties":{},"type":"number"},"name":"wal_dev_size"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/osd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ad8e2808277aa89b9d2fe58df7fe5a889cd128fd7b21e68ac6e2fd628f18125b","description":"Destroy OSD","extra":{"proxyto":"node"},"name":"destroyosd","parameters":[{"definition":{"default":0,"description":"If set, we remove partition table entries.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"b0f0250fd1edc6d6565b0c04f6252bdec7e416f3d6f5b2209aff3559cf79b1a7","description":"OSD index.","extra":{},"name":"osdindex","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/osd/{osdid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bf7b180ff0f405fde06dc5d87505bd8ab58b5d1502106abd87441f78d23f5e26","description":"ceph osd in","extra":{"proxyto":"node"},"name":"in","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/osd/{osdid}/in"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5836bad68fa9724eac7f11cc92c5cd8dc2364d7f44ddc9a2e0e45627a167922f","description":"Get OSD volume details","extra":{"proxyto":"node"},"name":"osdvolume","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"},{"definition":{"default":"block","description":"OSD device type","enum":["block","db","wal"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"creation_time":{"description":"Creation time as reported by `lvs`.","enum":[],"extra":{},"properties":{},"type":"string"},"lv_name":{"description":"Name of the logical volume (LV).","enum":[],"extra":{},"properties":{},"type":"string"},"lv_path":{"description":"Path to the logical volume (LV).","enum":[],"extra":{},"properties":{},"type":"string"},"lv_size":{"description":"Size of the logical volume (LV).","enum":[],"extra":{},"properties":{},"type":"integer"},"lv_uuid":{"description":"UUID of the logical volume (LV).","enum":[],"extra":{},"properties":{},"type":"string"},"vg_name":{"description":"Name of the volume group (VG).","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/osd/{osdid}/lv-info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"363748f4c0625f5db816e30cd1e564a8ac21f5bc56f18f1e13b291726a256f9c","description":"Get OSD details","extra":{"proxyto":"node"},"name":"osddetails","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"devices":{"description":"Array containing data about devices","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"dev_node":{"description":"Device node","enum":[],"extra":{},"properties":{},"type":"string"},"device":{"description":"Kind of OSD device","enum":["block","db","wal"],"extra":{},"properties":{},"type":"string"},"devices":{"description":"Physical disks used","enum":[],"extra":{},"properties":{},"type":"string"},"size":{"description":"Size in bytes","enum":[],"extra":{},"properties":{},"type":"integer"},"support_discard":{"description":"Discard support of the physical device","enum":[],"extra":{},"properties":{},"type":"boolean"},"type":{"description":"Type of device. For example, hdd or ssd","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"osd":{"description":"General information about the OSD","enum":[],"extra":{},"properties":{"back_addr":{"description":"Address and port used to talk to other OSDs.","enum":[],"extra":{},"properties":{},"type":"string"},"front_addr":{"description":"Address and port used to talk to clients and monitors.","enum":[],"extra":{},"properties":{},"type":"string"},"hb_back_addr":{"description":"Heartbeat address and port for other OSDs.","enum":[],"extra":{},"properties":{},"type":"string"},"hb_front_addr":{"description":"Heartbeat address and port for clients and monitors.","enum":[],"extra":{},"properties":{},"type":"string"},"hostname":{"description":"Name of the host containing the OSD.","enum":[],"extra":{},"properties":{},"type":"string"},"id":{"description":"ID of the OSD.","enum":[],"extra":{},"properties":{},"type":"integer"},"mem_usage":{"description":"Memory usage of the OSD service.","enum":[],"extra":{},"properties":{},"type":"integer"},"osd_data":{"description":"Path to the OSD's data directory.","enum":[],"extra":{},"properties":{},"type":"string"},"osd_objectstore":{"description":"The type of object store used.","enum":[],"extra":{},"properties":{},"type":"string"},"pid":{"description":"OSD process ID.","enum":[],"extra":{},"properties":{},"type":"integer"},"version":{"description":"Ceph version of the OSD service.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/osd/{osdid}/metadata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"23d8222b59c8aab7050f8c7415d7e3d12494cab703c1ee49bb4be15f1b666800","description":"ceph osd out","extra":{"proxyto":"node"},"name":"out","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/osd/{osdid}/out"},{"extra":{},"methods":[{"allow_token":true,"checksum":"60019df48da0442ab7a3f116bc02cc627d89cc4c978434e73175e44fa0e2107b","description":"Instruct the OSD to scrub.","extra":{"proxyto":"node"},"name":"scrub","parameters":[{"definition":{"default":0,"description":"If set, instructs a deep scrub instead of a normal one.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"deep"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/osd/{osdid}/scrub"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bfeafc5a2851d4149ce8b6da7275a7c90e2e486b0299edd8e633dd9e306a62b6","description":"List all pools and their settings (which are settable by the POST/PUT endpoints).","extra":{"proxyto":"node"},"name":"lspools","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{pool_name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"application_metadata":{"enum":[],"extra":{"title":"Associated Applications"},"optional":true,"properties":{},"type":"object"},"autoscale_status":{"enum":[],"extra":{"title":"Autoscale Status"},"optional":true,"properties":{},"type":"object"},"bytes_used":{"enum":[],"extra":{"title":"Used"},"properties":{},"type":"integer"},"crush_rule":{"enum":[],"extra":{"title":"Crush Rule"},"properties":{},"type":"integer"},"crush_rule_name":{"enum":[],"extra":{"title":"Crush Rule Name"},"properties":{},"type":"string"},"min_size":{"enum":[],"extra":{"title":"Min Size"},"properties":{},"type":"integer"},"percent_used":{"enum":[],"extra":{"title":"%-Used"},"properties":{},"type":"number"},"pg_autoscale_mode":{"enum":[],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"pg_num":{"enum":[],"extra":{"title":"PG Num"},"properties":{},"type":"integer"},"pg_num_final":{"enum":[],"extra":{"title":"Optimal PG Num"},"optional":true,"properties":{},"type":"integer"},"pg_num_min":{"enum":[],"extra":{"title":"min. PG Num"},"optional":true,"properties":{},"type":"integer"},"pool":{"enum":[],"extra":{"title":"ID"},"properties":{},"type":"integer"},"pool_name":{"enum":[],"extra":{"title":"Name"},"properties":{},"type":"string"},"size":{"enum":[],"extra":{"title":"Size"},"properties":{},"type":"integer"},"target_size":{"enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"properties":{},"type":"integer"},"target_size_ratio":{"enum":[],"extra":{"title":"PG Autoscale Target Ratio"},"optional":true,"properties":{},"type":"number"},"type":{"enum":["replicated","erasure","unknown"],"extra":{"title":"Type"},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"ab685abe023a15422deec78f2a7c60ea86f2d81526355e246d43be41a929053e","description":"Create Ceph pool","extra":{"proxyto":"node"},"name":"createpool","parameters":[{"definition":{"default":"0; for erasure coded pools: 1","description":"Configure VM and CT storage using the new pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storages"},{"definition":{"default":"rbd","description":"The application of the pool.","enum":["rbd","cephfs","rgw"],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"string"},"name":"application"},{"definition":{"description":"The rule to use for mapping object placement in the cluster.","enum":[],"extra":{"title":"Crush Rule Name","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"crush_rule"},{"definition":{"description":"Create an erasure coded pool for RBD with an accompaning replicated pool for metadata storage. With EC, the common ceph options 'size', 'min_size' and 'crush_rule' parameters will be applied to the metadata pool.","enum":[],"extra":{"typetext":"k= ,m= [,device-class=] [,failure-domain=] [,profile=]"},"format":{"device-class":{"description":"CRUSH device class. Will create an erasure coded pool plus a replicated pool for metadata.","format_description":"class","optional":1,"type":"string"},"failure-domain":{"default":"host","description":"CRUSH failure domain. Default is 'host'. Will create an erasure coded pool plus a replicated pool for metadata.","format_description":"domain","optional":1,"type":"string"},"k":{"description":"Number of data chunks. Will create an erasure coded pool plus a replicated pool for metadata.","minimum":2,"type":"integer"},"m":{"description":"Number of coding chunks. Will create an erasure coded pool plus a replicated pool for metadata.","minimum":1,"type":"integer"},"profile":{"description":"Override the erasure code (EC) profile to use. Will create an erasure coded pool plus a replicated pool for metadata.","format_description":"profile","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"erasure-coding"},{"definition":{"default":2,"description":"Minimum number of replicas per object","enum":[],"extra":{"title":"Min Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"min_size"},{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"title":"Name","typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"warn","description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"name":"pg_autoscale_mode"},{"definition":{"default":128,"description":"Number of placement groups.","enum":[],"extra":{"title":"PG Num","typetext":" (1 - 32768)"},"maximum":32768,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"pg_num"},{"definition":{"description":"Minimal number of placement groups.","enum":[],"extra":{"title":"min. PG Num","typetext":" (-N - 32768)"},"maximum":32768,"optional":true,"properties":{},"type":"integer"},"name":"pg_num_min"},{"definition":{"default":3,"description":"Number of replicas per object","enum":[],"extra":{"title":"Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"size"},{"definition":{"description":"The estimated target size of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"pattern":"^(\\d+(\\.\\d+)?)([KMGT])?$","properties":{},"type":"string"},"name":"target_size"},{"definition":{"description":"The estimated target ratio of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Ratio","typetext":""},"optional":true,"properties":{},"type":"number"},"name":"target_size_ratio"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/pool"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8708fe36bb2d3f3abbf03cb27e6db8fd1c5baaf58225e6095a69a2ea6b3217c6","description":"Destroy pool","extra":{"proxyto":"node"},"name":"destroypool","parameters":[{"definition":{"default":0,"description":"If true, destroys pool even if in use","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":1,"description":"Remove the erasure code profile. Defaults to true, if applicable.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove_ecprofile"},{"definition":{"default":0,"description":"Remove all pveceph-managed storages configured for this pool","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove_storages"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"aa0616ec83924fa46a149a0e35dedaf66156879c4aed761d93bd66aaa00aa242","description":"Pool index.","extra":{},"name":"poolindex","parameters":[{"definition":{"description":"The name of the pool.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"cbb73dbca627e66e481cb19a244c569135954dd33ce6307d1bb6bc08ad6ed62d","description":"Change POOL settings","extra":{"proxyto":"node"},"name":"setpool","parameters":[{"definition":{"description":"The application of the pool.","enum":["rbd","cephfs","rgw"],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"string"},"name":"application"},{"definition":{"description":"The rule to use for mapping object placement in the cluster.","enum":[],"extra":{"title":"Crush Rule Name","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"crush_rule"},{"definition":{"description":"Minimum number of replicas per object","enum":[],"extra":{"title":"Min Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"min_size"},{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"title":"Name","typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"name":"pg_autoscale_mode"},{"definition":{"description":"Number of placement groups.","enum":[],"extra":{"title":"PG Num","typetext":" (1 - 32768)"},"maximum":32768,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"pg_num"},{"definition":{"description":"Minimal number of placement groups.","enum":[],"extra":{"title":"min. PG Num","typetext":" (-N - 32768)"},"maximum":32768,"optional":true,"properties":{},"type":"integer"},"name":"pg_num_min"},{"definition":{"description":"Number of replicas per object","enum":[],"extra":{"title":"Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"size"},{"definition":{"description":"The estimated target size of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"pattern":"^(\\d+(\\.\\d+)?)([KMGT])?$","properties":{},"type":"string"},"name":"target_size"},{"definition":{"description":"The estimated target ratio of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Ratio","typetext":""},"optional":true,"properties":{},"type":"number"},"name":"target_size_ratio"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/ceph/pool/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"303fe1d87b08aa51a6ea6261a42f3f7bbf9f3365c87c9d132e2341fd80499fc6","description":"Show the current pool status.","extra":{"proxyto":"node"},"name":"getpool","parameters":[{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"If enabled, will display additional data(eg. statistics).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verbose"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"application":{"default":"rbd","description":"The application of the pool.","enum":["rbd","cephfs","rgw"],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"string"},"application_list":{"enum":[],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"array"},"autoscale_status":{"enum":[],"extra":{"title":"Autoscale Status"},"optional":true,"properties":{},"type":"object"},"crush_rule":{"description":"The rule to use for mapping object placement in the cluster.","enum":[],"extra":{"title":"Crush Rule Name"},"optional":true,"properties":{},"type":"string"},"fast_read":{"enum":[],"extra":{"title":"Fast Read"},"properties":{},"type":"boolean"},"hashpspool":{"enum":[],"extra":{"title":"hashpspool"},"properties":{},"type":"boolean"},"id":{"enum":[],"extra":{"title":"ID"},"properties":{},"type":"integer"},"min_size":{"default":2,"description":"Minimum number of replicas per object","enum":[],"extra":{"title":"Min Size"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"title":"Name"},"properties":{},"type":"string"},"nodeep-scrub":{"enum":[],"extra":{"title":"nodeep-scrub"},"properties":{},"type":"boolean"},"nodelete":{"enum":[],"extra":{"title":"nodelete"},"properties":{},"type":"boolean"},"nopgchange":{"enum":[],"extra":{"title":"nopgchange"},"properties":{},"type":"boolean"},"noscrub":{"enum":[],"extra":{"title":"noscrub"},"properties":{},"type":"boolean"},"nosizechange":{"enum":[],"extra":{"title":"nosizechange"},"properties":{},"type":"boolean"},"pg_autoscale_mode":{"default":"warn","description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"pg_num":{"default":128,"description":"Number of placement groups.","enum":[],"extra":{"title":"PG Num"},"maximum":32768,"minimum":1,"optional":true,"properties":{},"type":"integer"},"pg_num_min":{"description":"Minimal number of placement groups.","enum":[],"extra":{"title":"min. PG Num"},"maximum":32768,"optional":true,"properties":{},"type":"integer"},"pgp_num":{"enum":[],"extra":{"title":"PGP num"},"properties":{},"type":"integer"},"size":{"default":3,"description":"Number of replicas per object","enum":[],"extra":{"title":"Size"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"statistics":{"enum":[],"extra":{"title":"Statistics"},"optional":true,"properties":{},"type":"object"},"target_size":{"description":"The estimated target size of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"pattern":"^(\\d+(\\.\\d+)?)([KMGT])?$","properties":{},"type":"string"},"target_size_ratio":{"description":"The estimated target ratio of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Ratio"},"optional":true,"properties":{},"type":"number"},"use_gmt_hitset":{"enum":[],"extra":{"title":"use_gmt_hitset"},"properties":{},"type":"boolean"},"write_fadvise_dontneed":{"enum":[],"extra":{"title":"write_fadvise_dontneed"},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/pool/{name}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c6f9a3d0e0ebcba009255157386e636a3669227f75068b4ce76919c7a11f45ee","description":"List all pools. Deprecated, please use `/nodes/{node}/ceph/pool`.","extra":{"proxyto":"node"},"name":"lspools","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{pool_name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"application_metadata":{"enum":[],"extra":{"title":"Associated Applications"},"optional":true,"properties":{},"type":"object"},"autoscale_status":{"enum":[],"extra":{"title":"Autoscale Status"},"optional":true,"properties":{},"type":"object"},"bytes_used":{"enum":[],"extra":{"title":"Used"},"properties":{},"type":"integer"},"crush_rule":{"enum":[],"extra":{"title":"Crush Rule"},"properties":{},"type":"integer"},"crush_rule_name":{"enum":[],"extra":{"title":"Crush Rule Name"},"properties":{},"type":"string"},"min_size":{"enum":[],"extra":{"title":"Min Size"},"properties":{},"type":"integer"},"percent_used":{"enum":[],"extra":{"title":"%-Used"},"properties":{},"type":"number"},"pg_autoscale_mode":{"enum":[],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"pg_num":{"enum":[],"extra":{"title":"PG Num"},"properties":{},"type":"integer"},"pg_num_final":{"enum":[],"extra":{"title":"Optimal PG Num"},"optional":true,"properties":{},"type":"integer"},"pg_num_min":{"enum":[],"extra":{"title":"min. PG Num"},"optional":true,"properties":{},"type":"integer"},"pool":{"enum":[],"extra":{"title":"ID"},"properties":{},"type":"integer"},"pool_name":{"enum":[],"extra":{"title":"Name"},"properties":{},"type":"string"},"size":{"enum":[],"extra":{"title":"Size"},"properties":{},"type":"integer"},"target_size":{"enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"properties":{},"type":"integer"},"target_size_ratio":{"enum":[],"extra":{"title":"PG Autoscale Target Ratio"},"optional":true,"properties":{},"type":"number"},"type":{"enum":["replicated","erasure","unknown"],"extra":{"title":"Type"},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"fc3673ad1c9f83f7f280779a7b9fa12003435b8c5b2eae74c38bf3be0ea455c4","description":"Create Ceph pool. Deprecated, please use `/nodes/{node}/ceph/pool`.","extra":{"proxyto":"node"},"name":"createpool","parameters":[{"definition":{"default":"0; for erasure coded pools: 1","description":"Configure VM and CT storage using the new pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storages"},{"definition":{"default":"rbd","description":"The application of the pool.","enum":["rbd","cephfs","rgw"],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"string"},"name":"application"},{"definition":{"description":"The rule to use for mapping object placement in the cluster.","enum":[],"extra":{"title":"Crush Rule Name","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"crush_rule"},{"definition":{"description":"Create an erasure coded pool for RBD with an accompaning replicated pool for metadata storage. With EC, the common ceph options 'size', 'min_size' and 'crush_rule' parameters will be applied to the metadata pool.","enum":[],"extra":{"typetext":"k= ,m= [,device-class=] [,failure-domain=] [,profile=]"},"format":{"device-class":{"description":"CRUSH device class. Will create an erasure coded pool plus a replicated pool for metadata.","format_description":"class","optional":1,"type":"string"},"failure-domain":{"default":"host","description":"CRUSH failure domain. Default is 'host'. Will create an erasure coded pool plus a replicated pool for metadata.","format_description":"domain","optional":1,"type":"string"},"k":{"description":"Number of data chunks. Will create an erasure coded pool plus a replicated pool for metadata.","minimum":2,"type":"integer"},"m":{"description":"Number of coding chunks. Will create an erasure coded pool plus a replicated pool for metadata.","minimum":1,"type":"integer"},"profile":{"description":"Override the erasure code (EC) profile to use. Will create an erasure coded pool plus a replicated pool for metadata.","format_description":"profile","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"erasure-coding"},{"definition":{"default":2,"description":"Minimum number of replicas per object","enum":[],"extra":{"title":"Min Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"min_size"},{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"title":"Name","typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"warn","description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"name":"pg_autoscale_mode"},{"definition":{"default":128,"description":"Number of placement groups.","enum":[],"extra":{"title":"PG Num","typetext":" (1 - 32768)"},"maximum":32768,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"pg_num"},{"definition":{"description":"Minimal number of placement groups.","enum":[],"extra":{"title":"min. PG Num","typetext":" (-N - 32768)"},"maximum":32768,"optional":true,"properties":{},"type":"integer"},"name":"pg_num_min"},{"definition":{"default":3,"description":"Number of replicas per object","enum":[],"extra":{"title":"Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"size"},{"definition":{"description":"The estimated target size of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"pattern":"^(\\d+(\\.\\d+)?)([KMGT])?$","properties":{},"type":"string"},"name":"target_size"},{"definition":{"description":"The estimated target ratio of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Ratio","typetext":""},"optional":true,"properties":{},"type":"number"},"name":"target_size_ratio"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/pools"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7b32a4fed9a8a3b44a7eb95aa6e814539e5303e92c249f584f540e8e747b4fb0","description":"Destroy pool. Deprecated, please use `/nodes/{node}/ceph/pool/{name}`.","extra":{"proxyto":"node"},"name":"destroypool","parameters":[{"definition":{"default":0,"description":"If true, destroys pool even if in use","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":1,"description":"Remove the erasure code profile. Defaults to true, if applicable.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove_ecprofile"},{"definition":{"default":0,"description":"Remove all pveceph-managed storages configured for this pool","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove_storages"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"2ccd0aa423f829d8beb092d2d2df204e908f2a9a891b1d1198de9c00ad67452c","description":"List pool settings. Deprecated, please use `/nodes/{node}/ceph/pool/{pool}/status`.","extra":{"proxyto":"node"},"name":"getpool","parameters":[{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"If enabled, will display additional data(eg. statistics).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verbose"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"application":{"default":"rbd","description":"The application of the pool.","enum":["rbd","cephfs","rgw"],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"string"},"application_list":{"enum":[],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"array"},"autoscale_status":{"enum":[],"extra":{"title":"Autoscale Status"},"optional":true,"properties":{},"type":"object"},"crush_rule":{"description":"The rule to use for mapping object placement in the cluster.","enum":[],"extra":{"title":"Crush Rule Name"},"optional":true,"properties":{},"type":"string"},"fast_read":{"enum":[],"extra":{"title":"Fast Read"},"properties":{},"type":"boolean"},"hashpspool":{"enum":[],"extra":{"title":"hashpspool"},"properties":{},"type":"boolean"},"id":{"enum":[],"extra":{"title":"ID"},"properties":{},"type":"integer"},"min_size":{"default":2,"description":"Minimum number of replicas per object","enum":[],"extra":{"title":"Min Size"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"title":"Name"},"properties":{},"type":"string"},"nodeep-scrub":{"enum":[],"extra":{"title":"nodeep-scrub"},"properties":{},"type":"boolean"},"nodelete":{"enum":[],"extra":{"title":"nodelete"},"properties":{},"type":"boolean"},"nopgchange":{"enum":[],"extra":{"title":"nopgchange"},"properties":{},"type":"boolean"},"noscrub":{"enum":[],"extra":{"title":"noscrub"},"properties":{},"type":"boolean"},"nosizechange":{"enum":[],"extra":{"title":"nosizechange"},"properties":{},"type":"boolean"},"pg_autoscale_mode":{"default":"warn","description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"pg_num":{"default":128,"description":"Number of placement groups.","enum":[],"extra":{"title":"PG Num"},"maximum":32768,"minimum":1,"optional":true,"properties":{},"type":"integer"},"pg_num_min":{"description":"Minimal number of placement groups.","enum":[],"extra":{"title":"min. PG Num"},"maximum":32768,"optional":true,"properties":{},"type":"integer"},"pgp_num":{"enum":[],"extra":{"title":"PGP num"},"properties":{},"type":"integer"},"size":{"default":3,"description":"Number of replicas per object","enum":[],"extra":{"title":"Size"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"statistics":{"enum":[],"extra":{"title":"Statistics"},"optional":true,"properties":{},"type":"object"},"target_size":{"description":"The estimated target size of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"pattern":"^(\\d+(\\.\\d+)?)([KMGT])?$","properties":{},"type":"string"},"target_size_ratio":{"description":"The estimated target ratio of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Ratio"},"optional":true,"properties":{},"type":"number"},"use_gmt_hitset":{"enum":[],"extra":{"title":"use_gmt_hitset"},"properties":{},"type":"boolean"},"write_fadvise_dontneed":{"enum":[],"extra":{"title":"write_fadvise_dontneed"},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"83661faac2dfbce1afb7c9001f1df7e5ec15f9aad820acd8e3caf9760db7bf28","description":"Change POOL settings. Deprecated, please use `/nodes/{node}/ceph/pool/{name}`.","extra":{"proxyto":"node"},"name":"setpool","parameters":[{"definition":{"description":"The application of the pool.","enum":["rbd","cephfs","rgw"],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"string"},"name":"application"},{"definition":{"description":"The rule to use for mapping object placement in the cluster.","enum":[],"extra":{"title":"Crush Rule Name","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"crush_rule"},{"definition":{"description":"Minimum number of replicas per object","enum":[],"extra":{"title":"Min Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"min_size"},{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"title":"Name","typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"name":"pg_autoscale_mode"},{"definition":{"description":"Number of placement groups.","enum":[],"extra":{"title":"PG Num","typetext":" (1 - 32768)"},"maximum":32768,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"pg_num"},{"definition":{"description":"Minimal number of placement groups.","enum":[],"extra":{"title":"min. PG Num","typetext":" (-N - 32768)"},"maximum":32768,"optional":true,"properties":{},"type":"integer"},"name":"pg_num_min"},{"definition":{"description":"Number of replicas per object","enum":[],"extra":{"title":"Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"size"},{"definition":{"description":"The estimated target size of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"pattern":"^(\\d+(\\.\\d+)?)([KMGT])?$","properties":{},"type":"string"},"name":"target_size"},{"definition":{"description":"The estimated target ratio of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Ratio","typetext":""},"optional":true,"properties":{},"type":"number"},"name":"target_size_ratio"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/ceph/pools/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d8f63039ca364b164a8e68d30f3a03f1ebe8c071133098c0a1781588258c7c56","description":"Restart ceph services.","extra":{"proxyto":"node"},"name":"restart","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"ceph.target","description":"Ceph service name.","enum":[],"extra":{},"optional":true,"pattern":"(mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?","properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/restart"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d1d564dc8fb769d538a36abe333e96421609c5e6a7fb99fd92be6a90fedf4f44","description":"List ceph rules.","extra":{"proxyto":"node"},"name":"rules","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"name":{"description":"Name of the CRUSH rule.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ecb354e68cb5aeaa1e4b8b63c176ff7410fa0fed35f792c2891964ab6662d962","description":"Start ceph services.","extra":{"proxyto":"node"},"name":"start","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"ceph.target","description":"Ceph service name.","enum":[],"extra":{},"optional":true,"pattern":"(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?","properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"46eb9852d690eec67eee3282fa3db6841f26e1a7ad8a7eb34f367777223906e4","description":"Get ceph status.","extra":{"proxyto":"node"},"name":"status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2844e52262806ae8703017f4b336a790d3c54cd9c0ad3ae772ed9fe138def456","description":"Stop ceph services.","extra":{"proxyto":"node"},"name":"stop","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"ceph.target","description":"Ceph service name.","enum":[],"extra":{},"optional":true,"pattern":"(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?","properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/stop"},{"extra":{},"methods":[{"allow_token":true,"checksum":"407b3d66a300b7bc4f15ce81eadffc3e3ff161e7940cd646fc925a219be029f3","description":"Node index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/certificates"},{"extra":{},"methods":[{"allow_token":true,"checksum":"93b19d6ea7cca4a3a682a7c06117351418c9725fb782f6ed86050c0ac92f4bd4","description":"ACME index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/certificates/acme"},{"extra":{},"methods":[{"allow_token":true,"checksum":"79bd82498d21a1c5d90f053e1aaec400ad82efd3983c8cf0559fe0c47b5b293c","description":"Revoke existing certificate from CA.","extra":{"proxyto":"node"},"name":"revoke_certificate","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"eb094550eb00e663dca797ef8c9dc07865542e546832f3d913080f5638f81c3a","description":"Order a new certificate from ACME-compatible CA.","extra":{"proxyto":"node"},"name":"new_certificate","parameters":[{"definition":{"default":0,"description":"Overwrite existing custom certificate.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"},{"allow_token":true,"checksum":"f8eea8445722cd9588417a2079abe85620556ba298b502dd0717e3876aa1abc5","description":"Renew existing certificate from CA.","extra":{"proxyto":"node"},"name":"renew_certificate","parameters":[{"definition":{"default":0,"description":"Force renewal even if expiry is more than 30 days away.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/certificates/acme/certificate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"929493029f5253253302d24f7a1e2c0046bf726108c3d37ed8c86801ddc3384a","description":"DELETE custom certificate chain and key.","extra":{"proxyto":"node"},"name":"remove_custom_cert","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Restart pveproxy.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restart"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"604d77053bdcded86a50810bad7ad1b20c14ff8887d4068b001db73771908654","description":"Upload or update custom certificate chain and key.","extra":{"proxyto":"node"},"name":"upload_custom_cert","parameters":[{"definition":{"description":"PEM encoded certificate (chain).","enum":[],"extra":{"typetext":""},"format":"pem-certificate-chain","properties":{},"type":"string"},"name":"certificates"},{"definition":{"default":0,"description":"Overwrite existing custom or ACME certificate files.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"PEM encoded private key.","enum":[],"extra":{"typetext":""},"format":"pem-string","optional":true,"properties":{},"type":"string"},"name":"key"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Restart pveproxy.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restart"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"fingerprint":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"issuer":{"description":"Certificate issuer name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"notafter":{"description":"Certificate's notAfter timestamp (UNIX epoch).","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"notbefore":{"description":"Certificate's notBefore timestamp (UNIX epoch).","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"pem":{"description":"Certificate in PEM format","enum":[],"extra":{},"format":"pem-certificate","optional":true,"properties":{},"type":"string"},"public-key-bits":{"description":"Certificate's public key size","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"public-key-type":{"description":"Certificate's public key algorithm","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"san":{"description":"List of Certificate's SubjectAlternativeName entries.","enum":[],"extra":{"renderer":"yaml"},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"subject":{"description":"Certificate subject name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/certificates/custom"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2a9b8f5b1a046e68e76e42747bf6de9bb776652ea56f1797a0b8f6bd32e2d21b","description":"Get information about node's certificates.","extra":{"proxyto":"node"},"name":"info","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"fingerprint":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"issuer":{"description":"Certificate issuer name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"notafter":{"description":"Certificate's notAfter timestamp (UNIX epoch).","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"notbefore":{"description":"Certificate's notBefore timestamp (UNIX epoch).","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"pem":{"description":"Certificate in PEM format","enum":[],"extra":{},"format":"pem-certificate","optional":true,"properties":{},"type":"string"},"public-key-bits":{"description":"Certificate's public key size","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"public-key-type":{"description":"Certificate's public key algorithm","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"san":{"description":"List of Certificate's SubjectAlternativeName entries.","enum":[],"extra":{"renderer":"yaml"},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"subject":{"description":"Certificate subject name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/certificates/info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"09cab7eefc06ec6d2a9705e400f8b899f3fd34f05dac16cf50ef7aaba688f415","description":"Get node configuration options.","extra":{"proxyto":"node"},"name":"get_config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"all","description":"Return only a specific property from the node configuration.","enum":["acme","acmedomain0","acmedomain1","acmedomain2","acmedomain3","acmedomain4","acmedomain5","description","startall-onboot-delay","wakeonlan"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"property"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"acme":{"description":"Node specific ACME settings.","enum":[],"extra":{},"format":{"account":{"default":"default","description":"ACME account config file name.","format":"pve-configid","format_description":"name","optional":1,"type":"string"},"domains":{"description":"List of domains for this node's ACME certificate","format":"pve-acme-domain-list","format_description":"domain[;domain;...]","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"acmedomain[n]":{"description":"ACME domain and validation plugin","enum":[],"extra":{},"format":{"alias":{"description":"Alias for the Domain to verify ACME Challenge over DNS","format":"pve-acme-alias","format_description":"domain","optional":1,"type":"string"},"domain":{"default_key":1,"description":"domain for this node's ACME certificate","format":"pve-acme-domain","format_description":"domain","type":"string"},"plugin":{"default":"standalone","description":"The ACME plugin ID","format":"pve-configid","format_description":"name of the plugin configuration","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"description":{"description":"Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.","enum":[],"extra":{},"max_length":65536,"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":true,"properties":{},"type":"string"},"startall-onboot-delay":{"default":0,"description":"Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.","enum":[],"extra":{},"maximum":300,"minimum":0,"optional":true,"properties":{},"type":"integer"},"wakeonlan":{"description":"MAC address for wake on LAN","enum":[],"extra":{},"format":"mac-addr","optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"5245986f89c5b7c2325435833d8fd3152519a7f9f7dc3838579a9be0bd87e3fc","description":"Set node configuration options.","extra":{"proxyto":"node"},"name":"set_options","parameters":[{"definition":{"description":"Node specific ACME settings.","enum":[],"extra":{"typetext":"[account=] [,domains=]"},"format":{"account":{"default":"default","description":"ACME account config file name.","format":"pve-configid","format_description":"name","optional":1,"type":"string"},"domains":{"description":"List of domains for this node's ACME certificate","format":"pve-acme-domain-list","format_description":"domain[;domain;...]","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"acme"},{"definition":{"description":"ACME domain and validation plugin","enum":[],"extra":{"typetext":"[domain=] [,alias=] [,plugin=]"},"format":{"alias":{"description":"Alias for the Domain to verify ACME Challenge over DNS","format":"pve-acme-alias","format_description":"domain","optional":1,"type":"string"},"domain":{"default_key":1,"description":"domain for this node's ACME certificate","format":"pve-acme-domain","format_description":"domain","type":"string"},"plugin":{"default":"standalone","description":"The ACME plugin ID","format":"pve-configid","format_description":"name of the plugin configuration","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"acmedomain[n]"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":65536,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.","enum":[],"extra":{"typetext":" (0 - 300)"},"maximum":300,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"startall-onboot-delay"},{"definition":{"description":"MAC address for wake on LAN","enum":[],"extra":{"typetext":""},"format":"mac-addr","optional":true,"properties":{},"type":"string"},"name":"wakeonlan"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c852718145641f2177102cbfc0fd436f6aeef81be29c2faedeed85f289314d9f","description":"Node index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/disks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f3537522c4031753f813beb7da086e204086ac5c89763bf227d68af05223c3f3","description":"PVE Managed Directory storages.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"device":{"description":"The mounted device.","enum":[],"extra":{},"properties":{},"type":"string"},"options":{"description":"The mount options.","enum":[],"extra":{},"properties":{},"type":"string"},"path":{"description":"The mount path.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The filesystem type.","enum":[],"extra":{},"properties":{},"type":"string"},"unitfile":{"description":"The path of the mount unit.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"122355716467fdd8f226f5aef647e6eea691d9368c73be9b8f3870a055a53b8c","description":"Create a Filesystem on an unused disk. Will be mounted under '/mnt/pve/NAME'.","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"default":0,"description":"Configure storage using the directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storage"},{"definition":{"description":"The block device you want to create the filesystem on.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"device"},{"definition":{"default":"ext4","description":"The desired filesystem.","enum":["ext4","xfs"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"filesystem"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify","Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/directory"},{"extra":{},"methods":[{"allow_token":true,"checksum":"fcf7de095dc650a84afaaecc6e791d4be58e22163b3d5aff0cc479c359d7c62b","description":"Unmounts the storage and removes the mount unit.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"default":0,"description":"Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-config"},{"definition":{"default":0,"description":"Also wipe disk so it can be repurposed afterwards.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-disks"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify","Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"}],"path":"/nodes/{node}/disks/directory/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e07569915888aa6baceeffec53ed6c431ea006c760c7620558ca0980ba012061","description":"Initialize Disk with GPT","extra":{"proxyto":"node"},"name":"initgpt","parameters":[{"definition":{"description":"Block device name","enum":[],"extra":{},"pattern":"^/dev/[a-zA-Z0-9\\/]+$","properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"UUID for the GPT table","enum":[],"extra":{},"max_length":36,"optional":true,"pattern":"[a-fA-F0-9\\-]+","properties":{},"type":"string"},"name":"uuid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/initgpt"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7def832764a9a127267d2a7af395721e4fc43e983ca826f183c2dcfa151b59d5","description":"List local disks.","extra":{"proxyto":"node"},"name":"list","parameters":[{"definition":{"default":0,"description":"Also include partitions.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"include-partitions"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Skip smart checks.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skipsmart"},{"definition":{"description":"Only list specific types of disks.","enum":["unused","journal_disks"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["or",["perm","/",["Sys.Audit","Datastore.Audit"],"any",1],["perm","/nodes/{node}",["Sys.Audit","Datastore.Audit"],"any",1]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"devpath":{"description":"The device path","enum":[],"extra":{},"properties":{},"type":"string"},"gpt":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"health":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"model":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mounted":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"osdid":{"enum":[],"extra":{},"properties":{},"type":"integer"},"parent":{"description":"For partitions only. The device path of the disk the partition resides on.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"size":{"enum":[],"extra":{},"properties":{},"type":"integer"},"used":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vendor":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"wwn":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/disks/list"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d06c7ceb2c64f1f9d871a7879687c33cac78acaba470ba1a4d105be971a56e95","description":"List LVM Volume Groups","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"children":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"children":{"description":"The underlying physical volumes","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"free":{"description":"The free bytes in the physical volume","enum":[],"extra":{},"properties":{},"type":"integer"},"leaf":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"name":{"description":"The name of the physical volume","enum":[],"extra":{},"properties":{},"type":"string"},"size":{"description":"The size of the physical volume in bytes","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"free":{"description":"The free bytes in the volume group","enum":[],"extra":{},"properties":{},"type":"integer"},"leaf":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"name":{"description":"The name of the volume group","enum":[],"extra":{},"properties":{},"type":"string"},"size":{"description":"The size of the volume group in bytes","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"leaf":{"enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"412d8d6327a72b39c6a9292e0a2bcb78f97ae945d52c8b5eb1efd00c867c990f","description":"Create an LVM Volume Group","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"default":0,"description":"Configure storage using the Volume Group","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storage"},{"definition":{"description":"The block device you want to create the volume group on","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"device"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify","Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/lvm"},{"extra":{},"methods":[{"allow_token":true,"checksum":"330611280b35b4547ef35ccd12d9ab4925d66474471639a70141617cb1049a9e","description":"Remove an LVM Volume Group.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"default":0,"description":"Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-config"},{"definition":{"default":0,"description":"Also wipe disks so they can be repurposed afterwards.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-disks"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify","Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"}],"path":"/nodes/{node}/disks/lvm/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a24f8edad66f2f85f71c5b7271ba7b69837f9b5910d05c5fafc1336500843b89","description":"List LVM thinpools","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"lv":{"description":"The name of the thinpool.","enum":[],"extra":{},"properties":{},"type":"string"},"lv_size":{"description":"The size of the thinpool in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"metadata_size":{"description":"The size of the metadata lv in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"metadata_used":{"description":"The used bytes of the metadata lv.","enum":[],"extra":{},"properties":{},"type":"integer"},"used":{"description":"The used bytes of the thinpool.","enum":[],"extra":{},"properties":{},"type":"integer"},"vg":{"description":"The associated volume group.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f3550aafa62fea1ce8de5079fbd8588d813f6c4df9975d524b8d126006c5ae1b","description":"Create an LVM thinpool","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"default":0,"description":"Configure storage using the thinpool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storage"},{"definition":{"description":"The block device you want to create the thinpool on.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"device"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify","Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/lvmthin"},{"extra":{},"methods":[{"allow_token":true,"checksum":"369ccd3835d00eab8220ab942f37c69f8dfdeeecbde6fb4fd8e6c78ff5199b73","description":"Remove an LVM thin pool.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"default":0,"description":"Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-config"},{"definition":{"default":0,"description":"Also wipe disks so they can be repurposed afterwards.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-disks"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"volume-group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify","Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"}],"path":"/nodes/{node}/disks/lvmthin/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6a92c85a34adf096e370bf05961141c522e5cc0aaf6f8fc7bd73251844ee6b0b","description":"Get SMART Health of a disk.","extra":{"proxyto":"node"},"name":"smart","parameters":[{"definition":{"description":"Block device name","enum":[],"extra":{},"pattern":"^/dev/[a-zA-Z0-9\\/]+$","properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"If true returns only the health status","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"healthonly"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"attributes":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"array"},"health":{"enum":[],"extra":{},"properties":{},"type":"string"},"text":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/disks/smart"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5863de4fd64b709cb09f59e5ed64aa977df1243471343673fedafcc9441196d4","description":"Wipe a disk or partition.","extra":{"proxyto":"node"},"name":"wipe_disk","parameters":[{"definition":{"description":"Block device name","enum":[],"extra":{},"pattern":"^/dev/[a-zA-Z0-9\\/]+$","properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/disks/wipedisk"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9258079c31e8352aea31f38f0b16ebd2190aa0d3bcac19ddabad2d1920847934","description":"List Zpools.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"alloc":{"description":"","enum":[],"extra":{},"properties":{},"type":"integer"},"dedup":{"description":"","enum":[],"extra":{},"properties":{},"type":"number"},"frag":{"description":"","enum":[],"extra":{},"properties":{},"type":"integer"},"free":{"description":"","enum":[],"extra":{},"properties":{},"type":"integer"},"health":{"description":"","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"","enum":[],"extra":{},"properties":{},"type":"string"},"size":{"description":"","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"690d6a30d8777b1ef5354c86902a62140bfe5bc3778c5974c05d74b8832b2470","description":"Create a ZFS pool.","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"default":0,"description":"Configure storage using the zpool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storage"},{"definition":{"default":12,"description":"Pool sector size exponent.","enum":[],"extra":{"typetext":" (9 - 16)"},"maximum":16,"minimum":9,"optional":true,"properties":{},"type":"integer"},"name":"ashift"},{"definition":{"default":"on","description":"The compression algorithm to use.","enum":["on","off","gzip","lz4","lzjb","zle","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"compression"},{"definition":{"description":"The block devices you want to create the zpool on.","enum":[],"extra":{"typetext":""},"format":"string-list","properties":{},"type":"string"},"name":"devices"},{"definition":{"enum":[],"extra":{"typetext":"data= ,spares="},"format":{"data":{"description":"The number of data devices per redundancy group. (dRAID)","minimum":1,"type":"integer"},"spares":{"description":"Number of dRAID spares.","minimum":0,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"draid-config"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The RAID level to use.","enum":["single","mirror","raid10","raidz","raidz2","raidz3","draid","draid2","draid3"],"extra":{},"properties":{},"type":"string"},"name":"raidlevel"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify","Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/zfs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f4e9ca4e0013de82882376f4cecf66e9456a17e3c35f94bdd082062519536174","description":"Destroy a ZFS pool.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"default":0,"description":"Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-config"},{"definition":{"default":0,"description":"Also wipe disks so they can be repurposed afterwards.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-disks"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify","Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"b2a84edcfa15d4f29cc2620ccb8d1820c12a52b3990c2bfb88bb104c4e31dc4c","description":"Get details about a zpool.","extra":{"proxyto":"node"},"name":"detail","parameters":[{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"action":{"description":"Information about the recommended action to fix the state.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"children":{"description":"The pool configuration information, including the vdevs for each section (e.g. spares, cache), may be nested.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"cksum":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"msg":{"description":"An optional message about the vdev.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"The name of the vdev or section.","enum":[],"extra":{},"properties":{},"type":"string"},"read":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"state":{"description":"The state of the vdev.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"write":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"number"}},"type":"object"},"properties":{},"type":"array"},"errors":{"description":"Information about the errors on the zpool.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"The name of the zpool.","enum":[],"extra":{},"properties":{},"type":"string"},"scan":{"description":"Information about the last/current scrub.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"state":{"description":"The state of the zpool.","enum":[],"extra":{},"properties":{},"type":"string"},"status":{"description":"Information about the state of the zpool.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/disks/zfs/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a2a9840bc5b5f6fedb64fc871e0f30293e36589bef2b2cca3b75b167641bd3ad","description":"Read DNS settings.","extra":{"proxyto":"node"},"name":"dns","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"dns1":{"description":"First name server IP address.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dns2":{"description":"Second name server IP address.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dns3":{"description":"Third name server IP address.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"search":{"description":"Search domain for host-name lookup.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"aa3976a9e9313d0108087afc577aaef882c6caa542300b9aa580823664733034","description":"Write DNS settings.","extra":{"proxyto":"node"},"name":"update_dns","parameters":[{"definition":{"description":"First name server IP address.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"dns1"},{"definition":{"description":"Second name server IP address.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"dns2"},{"definition":{"description":"Third name server IP address.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"dns3"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Search domain for host-name lookup.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"search"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/dns"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c92f08a4675bdc54a5bdedf28a192ed6ddc6aa310eb2c2f76bbce95493dc4ad6","description":"Execute multiple commands in order.","extra":{"proxyto":"node"},"name":"execute","parameters":[{"definition":{"description":"JSON encoded array of commands.","enum":[],"extra":{"typetext":"","verbose_description":"JSON encoded array of commands, where each command is an object with the following properties:\n args: \n\n\t A set of parameter names and their values.\n\n method: (GET|POST|PUT|DELETE)\n\n\t A method related to the API endpoint (GET, POST etc.).\n\n path: \n\n\t A relative path to an API endpoint on this node.\n\n"},"format":"pve-command-batch","properties":{},"type":"string"},"name":"commands"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"POST"}],"path":"/nodes/{node}/execute"},{"extra":{},"methods":[{"allow_token":true,"checksum":"23dca6507cde2ae0cabadf81020c2e06e2c8878c3e19c7356ba7dbc49c506a9a","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0bf35a80d104d2faaf32511debedeee1423c276df3c2eeba6d83b3e7ee589cd3","description":"Read firewall log","extra":{"proxyto":"node"},"name":"log","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Display log since this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"since"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"Display log until this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"until"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/firewall/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b48f9f1e687497cc04a22162d003d5c2dfbde5399fa7baff88f28a213c8c58df","description":"Get host firewall options.","extra":{"proxyto":"node"},"name":"get_options","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"enable":{"description":"Enable host firewall rules.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"log_level_in":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_level_out":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_nf_conntrack":{"default":0,"description":"Enable logging of conntrack information.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ndp":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"nf_conntrack_allow_invalid":{"default":0,"description":"Allow invalid packets on connection tracking.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"nf_conntrack_helpers":{"default":"","description":"Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp","enum":[],"extra":{},"format":"pve-fw-conntrack-helper","optional":true,"properties":{},"type":"string"},"nf_conntrack_max":{"default":262144,"description":"Maximum number of tracked connections.","enum":[],"extra":{},"minimum":32768,"optional":true,"properties":{},"type":"integer"},"nf_conntrack_tcp_timeout_established":{"default":432000,"description":"Conntrack established timeout.","enum":[],"extra":{},"minimum":7875,"optional":true,"properties":{},"type":"integer"},"nf_conntrack_tcp_timeout_syn_recv":{"default":60,"description":"Conntrack syn recv timeout.","enum":[],"extra":{},"maximum":60,"minimum":30,"optional":true,"properties":{},"type":"integer"},"nosmurfs":{"description":"Enable SMURFS filter.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"protection_synflood":{"default":0,"description":"Enable synflood protection","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"protection_synflood_burst":{"default":1000,"description":"Synflood protection rate burst by ip src.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"protection_synflood_rate":{"default":200,"description":"Synflood protection rate syn/sec by ip src.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"smurf_log_level":{"description":"Log level for SMURFS filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"tcp_flags_log_level":{"description":"Log level for illegal tcp flags filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"tcpflags":{"default":0,"description":"Filter illegal combinations of TCP flags.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"7a592a8a8018ef88e672f0ed736ca2f84be4f4b8c1bd1b4cc5570c66a66c0c41","description":"Set Firewall options.","extra":{"proxyto":"node"},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Enable host firewall rules.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_in"},{"definition":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_out"},{"definition":{"default":0,"description":"Enable logging of conntrack information.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"log_nf_conntrack"},{"definition":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ndp"},{"definition":{"default":0,"description":"Allow invalid packets on connection tracking.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nf_conntrack_allow_invalid"},{"definition":{"default":"","description":"Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp","enum":[],"extra":{"typetext":""},"format":"pve-fw-conntrack-helper","optional":true,"properties":{},"type":"string"},"name":"nf_conntrack_helpers"},{"definition":{"default":262144,"description":"Maximum number of tracked connections.","enum":[],"extra":{"typetext":" (32768 - N)"},"minimum":32768,"optional":true,"properties":{},"type":"integer"},"name":"nf_conntrack_max"},{"definition":{"default":432000,"description":"Conntrack established timeout.","enum":[],"extra":{"typetext":" (7875 - N)"},"minimum":7875,"optional":true,"properties":{},"type":"integer"},"name":"nf_conntrack_tcp_timeout_established"},{"definition":{"default":60,"description":"Conntrack syn recv timeout.","enum":[],"extra":{"typetext":" (30 - 60)"},"maximum":60,"minimum":30,"optional":true,"properties":{},"type":"integer"},"name":"nf_conntrack_tcp_timeout_syn_recv"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Enable SMURFS filter.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nosmurfs"},{"definition":{"default":0,"description":"Enable synflood protection","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection_synflood"},{"definition":{"default":1000,"description":"Synflood protection rate burst by ip src.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"protection_synflood_burst"},{"definition":{"default":200,"description":"Synflood protection rate syn/sec by ip src.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"protection_synflood_rate"},{"definition":{"description":"Log level for SMURFS filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"smurf_log_level"},{"definition":{"description":"Log level for illegal tcp flags filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"tcp_flags_log_level"},{"definition":{"default":0,"description":"Filter illegal combinations of TCP flags.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tcpflags"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b60ddfff9873ec325386c9e661b00a7b59dc13a05b46d58a5a77ed0925c039ab","description":"List rules.","extra":{"proxyto":"node"},"name":"get_rules","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"4c520a3079794a818dfb857f4e8284d9c49ceda03bd7674e04cec5e770422c19","description":"Create new rule.","extra":{"proxyto":"node"},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"169c2557fcf5b10d3a2d121dca1e9c370648a2c511dc7983d56e10ac9e09ba80","description":"Delete rule.","extra":{"proxyto":"node"},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"334c82a7807d96fdd30b6fc1678394170a14b3aa9668f1c3231b928df2338d78","description":"Get single rule data.","extra":{"proxyto":"node"},"name":"get_rule","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"603226b5c39f8627c2d178a985d16a90fdb212442249fd0ce9b308a35b05c3d2","description":"Modify rule data.","extra":{"proxyto":"node"},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a942affba5edd9876d3a47c7aaed97b5c3eeca8b6a2748dbb6cfd04b87ec4985","description":"Index of hardware types","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{type}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c7d8315b1b343a437938b8d0f936a7f8e33ae72efb5fa3016a5b1679b314aae2","description":"List local PCI devices.","extra":{"proxyto":"node"},"name":"pciscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"05;06;0b","description":"A list of blacklisted PCI classes, which will not be returned. Following are filtered by default: Memory Controller (05), Bridge (06) and Processor (0b).","enum":[],"extra":{"typetext":""},"format":"string-list","optional":true,"properties":{},"type":"string"},"name":"pci-class-blacklist"},{"definition":{"default":1,"description":"If disabled, does only print the PCI IDs. Otherwise, additional information like vendor and device will be returned.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verbose"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Sys.Modify"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"class":{"description":"The PCI Class of the device.","enum":[],"extra":{},"properties":{},"type":"string"},"device":{"description":"The Device ID.","enum":[],"extra":{},"properties":{},"type":"string"},"device_name":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"description":"The PCI ID.","enum":[],"extra":{},"properties":{},"type":"string"},"iommugroup":{"description":"The IOMMU group in which the device is in. If no IOMMU group is detected, it is set to -1.","enum":[],"extra":{},"properties":{},"type":"integer"},"mdev":{"description":"If set, marks that the device is capable of creating mediated devices.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"subsystem_device":{"description":"The Subsystem Device ID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"subsystem_device_name":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"subsystem_vendor":{"description":"The Subsystem Vendor ID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"subsystem_vendor_name":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vendor":{"description":"The Vendor ID.","enum":[],"extra":{},"properties":{},"type":"string"},"vendor_name":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware/pci"},{"extra":{},"methods":[{"allow_token":true,"checksum":"00db499ff891c1ed4084f98a93db79971b16ac33db9f5294d0012ba6ded291c4","description":"Index of available pci methods","extra":{},"name":"pciindex","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{},"pattern":"(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\\.[0-9a-fA-F]","properties":{},"type":"string"},"name":"pciid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{method}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"method":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware/pci/{pciid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7ab922c0e52593b4f101993199efaf014a153358a727d2438e5e4fcde6749495","description":"List mediated device types for given PCI device.","extra":{"proxyto":"node"},"name":"mdevscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The PCI ID to list the mdev types for.","enum":[],"extra":{},"pattern":"(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\\.[0-9a-fA-F]","properties":{},"type":"string"},"name":"pciid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Sys.Modify"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"available":{"description":"The number of still available instances of this type.","enum":[],"extra":{},"properties":{},"type":"integer"},"description":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The name of the mdev type.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware/pci/{pciid}/mdev"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c34730e00f0d40259fe27fa8d10c86ca51d09c55d88e56c0a58a874dcf7bff9c","description":"List local USB devices.","extra":{"proxyto":"node"},"name":"usbscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"busnum":{"enum":[],"extra":{},"properties":{},"type":"integer"},"class":{"enum":[],"extra":{},"properties":{},"type":"integer"},"devnum":{"enum":[],"extra":{},"properties":{},"type":"integer"},"level":{"enum":[],"extra":{},"properties":{},"type":"integer"},"manufacturer":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"prodid":{"enum":[],"extra":{},"properties":{},"type":"string"},"product":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"speed":{"enum":[],"extra":{},"properties":{},"type":"string"},"usbpath":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vendid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware/usb"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e943b9c325ad6feb5fa744fd25c3496a70cffce248b736581e7f9f0ce0ad7535","description":"Get the content of /etc/hosts.","extra":{"proxyto":"node"},"name":"get_etc_hosts","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"data":{"description":"The content of /etc/hosts.","enum":[],"extra":{},"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"6e5c04602315f9bcc7d02e0c8aa2c968f3e6d7dfe2b370294162e79e765dcc82","description":"Write /etc/hosts.","extra":{"proxyto":"node"},"name":"write_etc_hosts","parameters":[{"definition":{"description":"The target content of /etc/hosts.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"data"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/hosts"},{"extra":{},"methods":[{"allow_token":true,"checksum":"04faf2d1e6766b07df402cdf939d22c00773c9ec6b520222875837f1043a7dfb","description":"Read Journal","extra":{"proxyto":"node"},"name":"journal","parameters":[{"definition":{"description":"End before the given Cursor. Conflicts with 'until'","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"endcursor"},{"definition":{"description":"Limit to the last X lines. Conflicts with a range.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"lastentries"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Display all log since this UNIX epoch. Conflicts with 'startcursor'.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"since"},{"definition":{"description":"Start after the given Cursor. Conflicts with 'since'","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"startcursor"},{"definition":{"description":"Display all log until this UNIX epoch. Conflicts with 'endcursor'.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"until"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/journal"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3a6d5650ce0097ef3a4aaada9b5c8e2331e1d13f172998ffe5a960a8d0c5d647","description":"LXC container index (per node).","extra":{"proxyto":"node"},"name":"vmlist","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Only list CTs where you have VM.Audit permissons on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{vmid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cpus":{"description":"Maximum usable CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"lock":{"description":"The current config lock, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxdisk":{"description":"Root disk size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Maximum memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxswap":{"description":"Maximum SWAP memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"name":{"description":"Container name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"status":{"description":"LXC Container status.","enum":["stopped","running"],"extra":{},"properties":{},"type":"string"},"tags":{"description":"The current configured tags, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"uptime":{"description":"Uptime.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"57bd53db76ba33052f4241565b7c543de3caedb60775bf3434523fbb1e961ddb","description":"Create or restore a container.","extra":{"proxyto":"node"},"name":"create_vm","parameters":[{"definition":{"default":"amd64","description":"OS architecture type.","enum":["amd64","i386","arm64","armhf","riscv32","riscv64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"default":"restore limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"default":"tty","description":"Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).","enum":["shell","console","tty"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmode"},{"definition":{"default":1,"description":"Attach a console device (/dev/console) to the container.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"console"},{"definition":{"description":"The number of cores assigned to the container. A container can use all available cores by default.","enum":[],"extra":{"typetext":" (1 - 8192)"},"maximum":8192,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"default":0,"description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.","enum":[],"extra":{"typetext":" (0 - 8192)"},"maximum":8192,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"typetext":" (0 - 500000)","verbose_description":"CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests."},"maximum":500000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"default":0,"description":"Try to be more verbose. For now this only enables debug log-level on start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"debug"},{"definition":{"description":"Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":8192,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Allow containers access to advanced features.","enum":[],"extra":{"typetext":"[force_rw_sys=<1|0>] [,fuse=<1|0>] [,keyctl=<1|0>] [,mknod=<1|0>] [,mount=] [,nesting=<1|0>]"},"format":{"force_rw_sys":{"default":0,"description":"Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.","optional":1,"type":"boolean"},"fuse":{"default":0,"description":"Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.","optional":1,"type":"boolean"},"keyctl":{"default":0,"description":"For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.","optional":1,"type":"boolean"},"mknod":{"default":0,"description":"Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.","optional":1,"type":"boolean"},"mount":{"description":"Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.","format_description":"fstype;fstype;...","optional":1,"pattern":"(?^:[a-zA-Z0-9_; ]+)","type":"string"},"nesting":{"default":0,"description":"Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"features"},{"definition":{"description":"Allow to overwrite existing container.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Script that will be exectued during various steps in the containers lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Set a host name for the container.","enum":[],"extra":{"typetext":""},"format":"dns-name","max_length":255,"optional":true,"properties":{},"type":"string"},"name":"hostname"},{"definition":{"description":"Ignore errors when extracting the template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ignore-unpack-errors"},{"definition":{"description":"Lock/unlock the container.","enum":["backup","create","destroyed","disk","fstrim","migrate","mounted","rollback","snapshot","snapshot-delete"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"default":512,"description":"Amount of RAM for the container in MB.","enum":[],"extra":{"typetext":" (16 - N)"},"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"memory"},{"definition":{"description":"Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[volume=] ,mp= [,acl=<1|0>] [,backup=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]"},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"backup":{"description":"Whether to include the mount point in backups.","optional":1,"type":"boolean","verbose_description":"Whether to include the mount point in backups (only used for volume mount points)."},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(noatime|lazytime|nodev|nosuid|noexec))(;(?^:(noatime|lazytime|nodev|nosuid|noexec)))*)","type":"string"},"mp":{"description":"Path to the mount point as seen from inside the container (must not contain symlinks).","format":"pve-lxc-mp-string","format_description":"Path","type":"string","verbose_description":"Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons."},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"mp[n]"},{"definition":{"description":"Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{"typetext":""},"format":"lxc-ip-with-ll-iface-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specifies network interfaces for the container.","enum":[],"extra":{"typetext":"name= [,bridge=] [,firewall=<1|0>] [,gw=] [,gw6=] [,hwaddr=] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=<(IPv6/CIDR|auto|dhcp|manual)>] [,link_down=<1|0>] [,mtu=] [,rate=] [,tag=] [,trunks=] [,type=]"},"format":{"bridge":{"description":"Bridge to attach the network device to.","format_description":"bridge","optional":1,"pattern":"[-_.\\w\\d]+","type":"string"},"firewall":{"description":"Controls whether this interface's firewall rules should be used.","optional":1,"type":"boolean"},"gw":{"description":"Default gateway for IPv4 traffic.","format":"ipv4","format_description":"GatewayIPv4","optional":1,"type":"string"},"gw6":{"description":"Default gateway for IPv6 traffic.","format":"ipv6","format_description":"GatewayIPv6","optional":1,"type":"string"},"hwaddr":{"description":"The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"ip":{"description":"IPv4 address in CIDR format.","format":"pve-ipv4-config","format_description":"(IPv4/CIDR|dhcp|manual)","optional":1,"type":"string"},"ip6":{"description":"IPv6 address in CIDR format.","format":"pve-ipv6-config","format_description":"(IPv6/CIDR|auto|dhcp|manual)","optional":1,"type":"string"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"mtu":{"description":"Maximum transfer unit of the interface. (lxc.network.mtu)","maximum":65535,"minimum":64,"optional":1,"type":"integer"},"name":{"description":"Name of the network device as seen from inside the container. (lxc.network.name)","format_description":"string","pattern":"[-_.\\w\\d]+","type":"string"},"rate":{"description":"Apply rate limiting to the interface","format_description":"mbps","optional":1,"type":"number"},"tag":{"description":"VLAN tag for this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN ids to pass through the interface","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:;\\d+)*)","type":"string"},"type":{"description":"Network interface type.","enum":["veth"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Specifies whether a container will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"The OS template or backup file.","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"ostemplate"},{"definition":{"description":"OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.","enum":["debian","devuan","ubuntu","centos","fedora","opensuse","archlinux","alpine","gentoo","nixos","unmanaged"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"description":"Sets root password inside container.","enum":[],"extra":{"typetext":""},"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Add the VM to the specified pool.","enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"default":0,"description":"Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"description":"Mark this as restore task.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restore"},{"definition":{"description":"Use volume as container root.","enum":[],"extra":{"typetext":"[volume=] [,acl=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]"},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(noatime|lazytime|nodev|nosuid|noexec))(;(?^:(noatime|lazytime|nodev|nosuid|noexec)))*)","type":"string"},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"rootfs"},{"definition":{"description":"Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{"typetext":""},"format":"dns-name-list","optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ssh-public-keys"},{"definition":{"default":0,"description":"Start the CT after its creation finished successfully.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"start"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"default":"local","description":"Default Storage.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"default":512,"description":"Amount of SWAP for the container in MB.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"swap"},{"definition":{"description":"Tags of the Container. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab","enum":[],"extra":{"typetext":""},"format":"pve-ct-timezone","optional":true,"properties":{},"type":"string"},"name":"timezone"},{"definition":{"default":2,"description":"Specify the number of tty available to the container","enum":[],"extra":{"typetext":" (0 - 6)"},"maximum":6,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"tty"},{"definition":{"description":"Assign a unique random ethernet address.","enum":[],"extra":{"requires":"restore","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"unique"},{"definition":{"default":0,"description":"Makes the container run as unprivileged user. (Should not be modified manually.)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"unprivileged"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[volume=]"},"format":{"volume":{"default_key":1,"description":"The volume that is not used currently.","format":"pve-volume-id","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permissions on /vms/{vmid} or on the VM pool /pool/{pool}. For restore, it is enough if the user has 'VM.Backup' permission and the VM already exists. You also need 'Datastore.AllocateSpace' permissions on the storage.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc"},{"extra":{},"methods":[{"allow_token":true,"checksum":"358b02759151ae6704197e0283558b6e0754b232b70a3c894aa3e49ec04abbe2","description":"Destroy the container (also delete all uses files).","extra":{"proxyto":"node"},"name":"destroy_vm","parameters":[{"definition":{"description":"If set, destroy additionally all disks with the VMID from all enabled storages which are not referenced in the config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"destroy-unreferenced-disks"},{"definition":{"default":0,"description":"Force destroy, even if running.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Remove container from all related configurations. For example, backup jobs, replication jobs or HA. Related ACLs and Firewall entries will *always* be removed.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"purge"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"fa055338b801bce39c739df867cff19ab708c821f45e2cd7c6ee100546aea617","description":"Directory index","extra":{"proxyto":"node"},"name":"vmdiridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"922fdc838693b8a0f7f6990ff6ab0e3cb1f4f3227b3e90953f6314bdb014742a","description":"Create a container clone/copy","extra":{"proxyto":"node"},"name":"clone_vm","parameters":[{"definition":{"default":"clone limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"description":"Description for the new CT.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Create a full copy of all disks. This is always done when you clone a normal CT. For CT templates, we try to create a linked clone by default.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"},{"definition":{"description":"Set a hostname for the new CT.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"hostname"},{"definition":{"description":"VMID for the clone.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"newid"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Add the new CT to the specified pool.","enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"Target storage for full clone.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Target node. Only allowed if the original VM is on shared storage.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions on /vms/{newid} (or on the VM pool /pool/{pool}). You also need 'Datastore.AllocateSpace' on any used storage.","expression":{"check":["and",["perm","/vms/{vmid}",["VM.Clone"]],["or",["perm","/vms/{newid}",["VM.Allocate"]],["perm","/pool/{pool}",["VM.Allocate"],"require_param","pool"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/clone"},{"extra":{},"methods":[{"allow_token":true,"checksum":"41f59618d2a6ed94c6ad7e39df1519091fa87cfca4906d1c5230a619c2268347","description":"Get container configuration.","extra":{"proxyto":"node"},"name":"vm_config","parameters":[{"definition":{"default":0,"description":"Get current values (instead of pending values).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"current"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Fetch config values from given snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapshot"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"arch":{"default":"amd64","description":"OS architecture type.","enum":["amd64","i386","arm64","armhf","riscv32","riscv64"],"extra":{},"optional":true,"properties":{},"type":"string"},"cmode":{"default":"tty","description":"Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).","enum":["shell","console","tty"],"extra":{},"optional":true,"properties":{},"type":"string"},"console":{"default":1,"description":"Attach a console device (/dev/console) to the container.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"cores":{"description":"The number of cores assigned to the container. A container can use all available cores by default.","enum":[],"extra":{},"maximum":8192,"minimum":1,"optional":true,"properties":{},"type":"integer"},"cpulimit":{"default":0,"description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.","enum":[],"extra":{},"maximum":8192,"minimum":0,"optional":true,"properties":{},"type":"number"},"cpuunits":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"verbose_description":"CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests."},"maximum":500000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"debug":{"default":0,"description":"Try to be more verbose. For now this only enables debug log-level on start.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"description":{"description":"Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{},"max_length":8192,"optional":true,"properties":{},"type":"string"},"digest":{"description":"SHA1 digest of configuration file. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"properties":{},"type":"string"},"features":{"description":"Allow containers access to advanced features.","enum":[],"extra":{},"format":{"force_rw_sys":{"default":0,"description":"Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.","optional":1,"type":"boolean"},"fuse":{"default":0,"description":"Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.","optional":1,"type":"boolean"},"keyctl":{"default":0,"description":"For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.","optional":1,"type":"boolean"},"mknod":{"default":0,"description":"Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.","optional":1,"type":"boolean"},"mount":{"description":"Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.","format_description":"fstype;fstype;...","optional":1,"pattern":"(?^:[a-zA-Z0-9_; ]+)","type":"string"},"nesting":{"default":0,"description":"Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"hookscript":{"description":"Script that will be exectued during various steps in the containers lifetime.","enum":[],"extra":{},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"hostname":{"description":"Set a host name for the container.","enum":[],"extra":{},"format":"dns-name","max_length":255,"optional":true,"properties":{},"type":"string"},"lock":{"description":"Lock/unlock the container.","enum":["backup","create","destroyed","disk","fstrim","migrate","mounted","rollback","snapshot","snapshot-delete"],"extra":{},"optional":true,"properties":{},"type":"string"},"lxc":{"description":"Array of lxc low-level configurations ([[key1, value1], [key2, value2] ...]).","enum":[],"extra":{},"items":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"optional":true,"properties":{},"type":"array"},"memory":{"default":512,"description":"Amount of RAM for the container in MB.","enum":[],"extra":{},"minimum":16,"optional":true,"properties":{},"type":"integer"},"mp[n]":{"description":"Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"backup":{"description":"Whether to include the mount point in backups.","optional":1,"type":"boolean","verbose_description":"Whether to include the mount point in backups (only used for volume mount points)."},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(noatime|lazytime|nodev|nosuid|noexec))(;(?^:(noatime|lazytime|nodev|nosuid|noexec)))*)","type":"string"},"mp":{"description":"Path to the mount point as seen from inside the container (must not contain symlinks).","format":"pve-lxc-mp-string","format_description":"Path","type":"string","verbose_description":"Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons."},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"nameserver":{"description":"Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{},"format":"lxc-ip-with-ll-iface-list","optional":true,"properties":{},"type":"string"},"net[n]":{"description":"Specifies network interfaces for the container.","enum":[],"extra":{},"format":{"bridge":{"description":"Bridge to attach the network device to.","format_description":"bridge","optional":1,"pattern":"[-_.\\w\\d]+","type":"string"},"firewall":{"description":"Controls whether this interface's firewall rules should be used.","optional":1,"type":"boolean"},"gw":{"description":"Default gateway for IPv4 traffic.","format":"ipv4","format_description":"GatewayIPv4","optional":1,"type":"string"},"gw6":{"description":"Default gateway for IPv6 traffic.","format":"ipv6","format_description":"GatewayIPv6","optional":1,"type":"string"},"hwaddr":{"description":"The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"ip":{"description":"IPv4 address in CIDR format.","format":"pve-ipv4-config","format_description":"(IPv4/CIDR|dhcp|manual)","optional":1,"type":"string"},"ip6":{"description":"IPv6 address in CIDR format.","format":"pve-ipv6-config","format_description":"(IPv6/CIDR|auto|dhcp|manual)","optional":1,"type":"string"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"mtu":{"description":"Maximum transfer unit of the interface. (lxc.network.mtu)","maximum":65535,"minimum":64,"optional":1,"type":"integer"},"name":{"description":"Name of the network device as seen from inside the container. (lxc.network.name)","format_description":"string","pattern":"[-_.\\w\\d]+","type":"string"},"rate":{"description":"Apply rate limiting to the interface","format_description":"mbps","optional":1,"type":"number"},"tag":{"description":"VLAN tag for this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN ids to pass through the interface","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:;\\d+)*)","type":"string"},"type":{"description":"Network interface type.","enum":["veth"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"onboot":{"default":0,"description":"Specifies whether a container will be started during system bootup.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ostype":{"description":"OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.","enum":["debian","devuan","ubuntu","centos","fedora","opensuse","archlinux","alpine","gentoo","nixos","unmanaged"],"extra":{},"optional":true,"properties":{},"type":"string"},"protection":{"default":0,"description":"Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"rootfs":{"description":"Use volume as container root.","enum":[],"extra":{},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(noatime|lazytime|nodev|nosuid|noexec))(;(?^:(noatime|lazytime|nodev|nosuid|noexec)))*)","type":"string"},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"searchdomain":{"description":"Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{},"format":"dns-name-list","optional":true,"properties":{},"type":"string"},"startup":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"swap":{"default":512,"description":"Amount of SWAP for the container in MB.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"tags":{"description":"Tags of the Container. This is only meta information.","enum":[],"extra":{},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"template":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"timezone":{"description":"Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab","enum":[],"extra":{},"format":"pve-ct-timezone","optional":true,"properties":{},"type":"string"},"tty":{"default":2,"description":"Specify the number of tty available to the container","enum":[],"extra":{},"maximum":6,"minimum":0,"optional":true,"properties":{},"type":"integer"},"unprivileged":{"default":0,"description":"Makes the container run as unprivileged user. (Should not be modified manually.)","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"unused[n]":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{},"format":{"volume":{"default_key":1,"description":"The volume that is not used currently.","format":"pve-volume-id","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"cb73b46cc1399910a0e0e6ab9b3b67e09d605af71251e24e9d1b4b41e7fdf68c","description":"Set container options.","extra":{"proxyto":"node"},"name":"update_vm","parameters":[{"definition":{"default":"amd64","description":"OS architecture type.","enum":["amd64","i386","arm64","armhf","riscv32","riscv64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"default":"tty","description":"Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).","enum":["shell","console","tty"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmode"},{"definition":{"default":1,"description":"Attach a console device (/dev/console) to the container.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"console"},{"definition":{"description":"The number of cores assigned to the container. A container can use all available cores by default.","enum":[],"extra":{"typetext":" (1 - 8192)"},"maximum":8192,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"default":0,"description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.","enum":[],"extra":{"typetext":" (0 - 8192)"},"maximum":8192,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"typetext":" (0 - 500000)","verbose_description":"CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests."},"maximum":500000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"default":0,"description":"Try to be more verbose. For now this only enables debug log-level on start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"debug"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":8192,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Allow containers access to advanced features.","enum":[],"extra":{"typetext":"[force_rw_sys=<1|0>] [,fuse=<1|0>] [,keyctl=<1|0>] [,mknod=<1|0>] [,mount=] [,nesting=<1|0>]"},"format":{"force_rw_sys":{"default":0,"description":"Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.","optional":1,"type":"boolean"},"fuse":{"default":0,"description":"Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.","optional":1,"type":"boolean"},"keyctl":{"default":0,"description":"For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.","optional":1,"type":"boolean"},"mknod":{"default":0,"description":"Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.","optional":1,"type":"boolean"},"mount":{"description":"Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.","format_description":"fstype;fstype;...","optional":1,"pattern":"(?^:[a-zA-Z0-9_; ]+)","type":"string"},"nesting":{"default":0,"description":"Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"features"},{"definition":{"description":"Script that will be exectued during various steps in the containers lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Set a host name for the container.","enum":[],"extra":{"typetext":""},"format":"dns-name","max_length":255,"optional":true,"properties":{},"type":"string"},"name":"hostname"},{"definition":{"description":"Lock/unlock the container.","enum":["backup","create","destroyed","disk","fstrim","migrate","mounted","rollback","snapshot","snapshot-delete"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"default":512,"description":"Amount of RAM for the container in MB.","enum":[],"extra":{"typetext":" (16 - N)"},"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"memory"},{"definition":{"description":"Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[volume=] ,mp= [,acl=<1|0>] [,backup=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]"},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"backup":{"description":"Whether to include the mount point in backups.","optional":1,"type":"boolean","verbose_description":"Whether to include the mount point in backups (only used for volume mount points)."},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(noatime|lazytime|nodev|nosuid|noexec))(;(?^:(noatime|lazytime|nodev|nosuid|noexec)))*)","type":"string"},"mp":{"description":"Path to the mount point as seen from inside the container (must not contain symlinks).","format":"pve-lxc-mp-string","format_description":"Path","type":"string","verbose_description":"Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons."},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"mp[n]"},{"definition":{"description":"Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{"typetext":""},"format":"lxc-ip-with-ll-iface-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specifies network interfaces for the container.","enum":[],"extra":{"typetext":"name= [,bridge=] [,firewall=<1|0>] [,gw=] [,gw6=] [,hwaddr=] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=<(IPv6/CIDR|auto|dhcp|manual)>] [,link_down=<1|0>] [,mtu=] [,rate=] [,tag=] [,trunks=] [,type=]"},"format":{"bridge":{"description":"Bridge to attach the network device to.","format_description":"bridge","optional":1,"pattern":"[-_.\\w\\d]+","type":"string"},"firewall":{"description":"Controls whether this interface's firewall rules should be used.","optional":1,"type":"boolean"},"gw":{"description":"Default gateway for IPv4 traffic.","format":"ipv4","format_description":"GatewayIPv4","optional":1,"type":"string"},"gw6":{"description":"Default gateway for IPv6 traffic.","format":"ipv6","format_description":"GatewayIPv6","optional":1,"type":"string"},"hwaddr":{"description":"The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"ip":{"description":"IPv4 address in CIDR format.","format":"pve-ipv4-config","format_description":"(IPv4/CIDR|dhcp|manual)","optional":1,"type":"string"},"ip6":{"description":"IPv6 address in CIDR format.","format":"pve-ipv6-config","format_description":"(IPv6/CIDR|auto|dhcp|manual)","optional":1,"type":"string"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"mtu":{"description":"Maximum transfer unit of the interface. (lxc.network.mtu)","maximum":65535,"minimum":64,"optional":1,"type":"integer"},"name":{"description":"Name of the network device as seen from inside the container. (lxc.network.name)","format_description":"string","pattern":"[-_.\\w\\d]+","type":"string"},"rate":{"description":"Apply rate limiting to the interface","format_description":"mbps","optional":1,"type":"number"},"tag":{"description":"VLAN tag for this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN ids to pass through the interface","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:;\\d+)*)","type":"string"},"type":{"description":"Network interface type.","enum":["veth"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Specifies whether a container will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.","enum":["debian","devuan","ubuntu","centos","fedora","opensuse","archlinux","alpine","gentoo","nixos","unmanaged"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"default":0,"description":"Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"description":"Revert a pending change.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"revert"},{"definition":{"description":"Use volume as container root.","enum":[],"extra":{"typetext":"[volume=] [,acl=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]"},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(noatime|lazytime|nodev|nosuid|noexec))(;(?^:(noatime|lazytime|nodev|nosuid|noexec)))*)","type":"string"},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"rootfs"},{"definition":{"description":"Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{"typetext":""},"format":"dns-name-list","optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"default":512,"description":"Amount of SWAP for the container in MB.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"swap"},{"definition":{"description":"Tags of the Container. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab","enum":[],"extra":{"typetext":""},"format":"pve-ct-timezone","optional":true,"properties":{},"type":"string"},"name":"timezone"},{"definition":{"default":2,"description":"Specify the number of tty available to the container","enum":[],"extra":{"typetext":" (0 - 6)"},"maximum":6,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"tty"},{"definition":{"default":0,"description":"Makes the container run as unprivileged user. (Should not be modified manually.)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"unprivileged"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[volume=]"},"format":{"volume":{"default_key":1,"description":"The volume that is not used currently.","format":"pve-volume-id","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"non-volume mount points in rootfs and mp[n] are restricted to root@pam","expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk","VM.Config.CPU","VM.Config.Memory","VM.Config.Network","VM.Config.Options"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3afc3a1f31bfc059c6274826a2899d12006ce23d5c77d09bd86b548bcc751ae3","description":"Check if feature for virtual machine is available.","extra":{"proxyto":"node"},"name":"vm_feature","parameters":[{"definition":{"description":"Feature to check.","enum":["snapshot","clone","copy"],"extra":{},"properties":{},"type":"string"},"name":"feature"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"hasFeature":{"enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/feature"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5bb143c67c66cf5b8450a21b7962a9429555249c9a169a229e7745f9d8304495","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f3ade8db07d7e168cf2c244f2327d3845c4d148a021436cde1e65f01fcc58db7","description":"List aliases","extra":{},"name":"get_aliases","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"0d804bcfd2565a8543511d9fd83e3425760031b592c1d1e50326d6725d38c139","description":"Create IP or Network Alias.","extra":{},"name":"create_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/aliases"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5920ae6968407878a5b9eb64bd68e522549bb7009cd3895d915d8adbe17e161d","description":"Remove IP or Network alias.","extra":{},"name":"remove_alias","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"1858b8e7f12863024af22797024f75a6fdf6cda0c224f6a4ce9815d3a4cb483b","description":"Read alias.","extra":{},"name":"read_alias","parameters":[{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"7e9b6195d2cd189f3b1fa52dc54fb8369c0324de89694c2614fdb3e30409670f","description":"Update IP or Network alias.","extra":{},"name":"update_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Rename an existing alias.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"72f4e0abfc4fc1fc45cf29ac6cf40bb3810b4463327824ba821b6bd63d1ebc30","description":"List IPSets","extra":{},"name":"ipset_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"name":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"ca3a7645ec2c6c377c1ae0dfb99c5feec2ef5e9bf3aa743b44670f851374983b","description":"Create new IPSet","extra":{},"name":"create_ipset","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/ipset"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dc4ac4abdba8f718fb26da69b42d836063c338aa7d709b68db6e0d8cb1bebda7","description":"Delete IPSet","extra":{},"name":"delete_ipset","parameters":[{"definition":{"description":"Delete all members of the IPSet, if there are any.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"c14d95b34b1dcc471da836cadc0ac6dbc2b2fc74105df7ff98f5cfc6b133644d","description":"List IPSet content","extra":{},"name":"get_ipset","parameters":[{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cidr}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"nomatch":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"e9612cc0bf355acd89e38d888ee4f89a951948c0840cb620e55d6b7bfc2cfad7","description":"Add IP or Network to IPSet.","extra":{},"name":"create_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"17a70102f27b6d30ea52149ee3614d9b300342b77b66edfeccf9f0c6662ab255","description":"Remove IP or Network from IPSet.","extra":{},"name":"remove_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"a4e0753e2fa85678d8a8d5b232c4403e3ec801c1beb4fd8f537802b987df83a4","description":"Read IP or Network settings from IPSet.","extra":{},"name":"read_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"e033d28015b80e8073780c388cbec51e67f613039684b31d4e9a10aa02c1db33","description":"Update IP or Network settings","extra":{},"name":"update_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5fc42cab2dbf26a9e3bbde213139e3f5b4c46b1dabb3d101cc5fa06bfcc760b9","description":"Read firewall log","extra":{"proxyto":"node"},"name":"log","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Display log since this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"since"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"Display log until this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"until"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a8aae893a1eea32c7368a145bac302634ad742b680ce50f656b02b75a41fc5d3","description":"Get VM firewall options.","extra":{"proxyto":"node"},"name":"get_options","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"dhcp":{"default":0,"description":"Enable DHCP.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"enable":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ipfilter":{"description":"Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"log_level_in":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_level_out":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macfilter":{"default":1,"description":"Enable/disable MAC address filter.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ndp":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"policy_in":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"policy_out":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"radv":{"description":"Allow sending Router Advertisement.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"07114b02e0de67e410a7a6664ac411239cd2bd830835a78f93b826c8c6defb6e","description":"Set Firewall options.","extra":{"proxyto":"node"},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"default":0,"description":"Enable DHCP.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"dhcp"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ipfilter"},{"definition":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_in"},{"definition":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_out"},{"definition":{"default":1,"description":"Enable/disable MAC address filter.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"macfilter"},{"definition":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ndp"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_in"},{"definition":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_out"},{"definition":{"description":"Allow sending Router Advertisement.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"radv"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"37d9588c916a6008f684c9911b05557c57a0334b032dc6feadc90bdffbddf35a","description":"Lists possible IPSet/Alias reference which are allowed in source/dest properties.","extra":{},"name":"refs","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list references of specified type.","enum":["alias","ipset"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":["alias","ipset"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/refs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9aca6c2421abc582ee1474baf7a4e1986ba3cc546ff95ffe612bbe4a7806ac0e","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"75ede4f1c7a73875c879ec0593cdd560c143667747ade3b33132b57fd5de4ba8","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dad1a485162cfc3b459d6d3cb052c9be411bfd535ad8eec7eb1567ad899d3a47","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"74b69d51de0371ce4003eb94ff6ce4d0208d139b00d70d22cef90bc1c8693c46","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"869a4c60a0360a085c0354f1ac4c4b8987e6db1cfd7231cebf2e78a22c249e4e","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"19e627f2788ec8f6a82a03b4b40f659334fd28a6f5eed8b573e105b34c3ed0f2","description":"Migrate the container to another node. Creates a new migration task.","extra":{"proxyto":"node"},"name":"migrate_vm","parameters":[{"definition":{"default":"migrate limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use online/live migration.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"online"},{"definition":{"description":"Use restart migration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restart"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storage-pair-list","optional":true,"properties":{},"type":"string"},"name":"target-storage"},{"definition":{"default":180,"description":"Timeout in seconds for shutdown for restart migration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1bcb2dd0ecd4bbc480fc33edbda39309d841a41708fdf0e34f53feb1c6b87dc7","description":"Move a rootfs-/mp-volume to a different storage or to a different container.","extra":{"proxyto":"node"},"name":"move_volume","parameters":[{"definition":{"default":"clone limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"default":0,"description":"Delete the original volume after successful copy. By default the original is kept as an unused volume entry.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 \" .\n\t\t \"digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target Storage.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Prevent changes if current configuration file of the target \" .\n\t\t \"container has a different SHA1 digest. This can be used to prevent \" .\n\t\t \"concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"target-digest"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"target-vmid"},{"definition":{"description":"The config key the volume will be moved to. Default is the source volume key.","enum":["rootfs","mp0","mp1","mp2","mp3","mp4","mp5","mp6","mp7","mp8","mp9","mp10","mp11","mp12","mp13","mp14","mp15","mp16","mp17","mp18","mp19","mp20","mp21","mp22","mp23","mp24","mp25","mp26","mp27","mp28","mp29","mp30","mp31","mp32","mp33","mp34","mp35","mp36","mp37","mp38","mp39","mp40","mp41","mp42","mp43","mp44","mp45","mp46","mp47","mp48","mp49","mp50","mp51","mp52","mp53","mp54","mp55","mp56","mp57","mp58","mp59","mp60","mp61","mp62","mp63","mp64","mp65","mp66","mp67","mp68","mp69","mp70","mp71","mp72","mp73","mp74","mp75","mp76","mp77","mp78","mp79","mp80","mp81","mp82","mp83","mp84","mp85","mp86","mp87","mp88","mp89","mp90","mp91","mp92","mp93","mp94","mp95","mp96","mp97","mp98","mp99","mp100","mp101","mp102","mp103","mp104","mp105","mp106","mp107","mp108","mp109","mp110","mp111","mp112","mp113","mp114","mp115","mp116","mp117","mp118","mp119","mp120","mp121","mp122","mp123","mp124","mp125","mp126","mp127","mp128","mp129","mp130","mp131","mp132","mp133","mp134","mp135","mp136","mp137","mp138","mp139","mp140","mp141","mp142","mp143","mp144","mp145","mp146","mp147","mp148","mp149","mp150","mp151","mp152","mp153","mp154","mp155","mp156","mp157","mp158","mp159","mp160","mp161","mp162","mp163","mp164","mp165","mp166","mp167","mp168","mp169","mp170","mp171","mp172","mp173","mp174","mp175","mp176","mp177","mp178","mp179","mp180","mp181","mp182","mp183","mp184","mp185","mp186","mp187","mp188","mp189","mp190","mp191","mp192","mp193","mp194","mp195","mp196","mp197","mp198","mp199","mp200","mp201","mp202","mp203","mp204","mp205","mp206","mp207","mp208","mp209","mp210","mp211","mp212","mp213","mp214","mp215","mp216","mp217","mp218","mp219","mp220","mp221","mp222","mp223","mp224","mp225","mp226","mp227","mp228","mp229","mp230","mp231","mp232","mp233","mp234","mp235","mp236","mp237","mp238","mp239","mp240","mp241","mp242","mp243","mp244","mp245","mp246","mp247","mp248","mp249","mp250","mp251","mp252","mp253","mp254","mp255","unused0","unused1","unused2","unused3","unused4","unused5","unused6","unused7","unused8","unused9","unused10","unused11","unused12","unused13","unused14","unused15","unused16","unused17","unused18","unused19","unused20","unused21","unused22","unused23","unused24","unused25","unused26","unused27","unused28","unused29","unused30","unused31","unused32","unused33","unused34","unused35","unused36","unused37","unused38","unused39","unused40","unused41","unused42","unused43","unused44","unused45","unused46","unused47","unused48","unused49","unused50","unused51","unused52","unused53","unused54","unused55","unused56","unused57","unused58","unused59","unused60","unused61","unused62","unused63","unused64","unused65","unused66","unused67","unused68","unused69","unused70","unused71","unused72","unused73","unused74","unused75","unused76","unused77","unused78","unused79","unused80","unused81","unused82","unused83","unused84","unused85","unused86","unused87","unused88","unused89","unused90","unused91","unused92","unused93","unused94","unused95","unused96","unused97","unused98","unused99","unused100","unused101","unused102","unused103","unused104","unused105","unused106","unused107","unused108","unused109","unused110","unused111","unused112","unused113","unused114","unused115","unused116","unused117","unused118","unused119","unused120","unused121","unused122","unused123","unused124","unused125","unused126","unused127","unused128","unused129","unused130","unused131","unused132","unused133","unused134","unused135","unused136","unused137","unused138","unused139","unused140","unused141","unused142","unused143","unused144","unused145","unused146","unused147","unused148","unused149","unused150","unused151","unused152","unused153","unused154","unused155","unused156","unused157","unused158","unused159","unused160","unused161","unused162","unused163","unused164","unused165","unused166","unused167","unused168","unused169","unused170","unused171","unused172","unused173","unused174","unused175","unused176","unused177","unused178","unused179","unused180","unused181","unused182","unused183","unused184","unused185","unused186","unused187","unused188","unused189","unused190","unused191","unused192","unused193","unused194","unused195","unused196","unused197","unused198","unused199","unused200","unused201","unused202","unused203","unused204","unused205","unused206","unused207","unused208","unused209","unused210","unused211","unused212","unused213","unused214","unused215","unused216","unused217","unused218","unused219","unused220","unused221","unused222","unused223","unused224","unused225","unused226","unused227","unused228","unused229","unused230","unused231","unused232","unused233","unused234","unused235","unused236","unused237","unused238","unused239","unused240","unused241","unused242","unused243","unused244","unused245","unused246","unused247","unused248","unused249","unused250","unused251","unused252","unused253","unused254","unused255"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"target-volume"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Volume which will be moved.","enum":["rootfs","mp0","mp1","mp2","mp3","mp4","mp5","mp6","mp7","mp8","mp9","mp10","mp11","mp12","mp13","mp14","mp15","mp16","mp17","mp18","mp19","mp20","mp21","mp22","mp23","mp24","mp25","mp26","mp27","mp28","mp29","mp30","mp31","mp32","mp33","mp34","mp35","mp36","mp37","mp38","mp39","mp40","mp41","mp42","mp43","mp44","mp45","mp46","mp47","mp48","mp49","mp50","mp51","mp52","mp53","mp54","mp55","mp56","mp57","mp58","mp59","mp60","mp61","mp62","mp63","mp64","mp65","mp66","mp67","mp68","mp69","mp70","mp71","mp72","mp73","mp74","mp75","mp76","mp77","mp78","mp79","mp80","mp81","mp82","mp83","mp84","mp85","mp86","mp87","mp88","mp89","mp90","mp91","mp92","mp93","mp94","mp95","mp96","mp97","mp98","mp99","mp100","mp101","mp102","mp103","mp104","mp105","mp106","mp107","mp108","mp109","mp110","mp111","mp112","mp113","mp114","mp115","mp116","mp117","mp118","mp119","mp120","mp121","mp122","mp123","mp124","mp125","mp126","mp127","mp128","mp129","mp130","mp131","mp132","mp133","mp134","mp135","mp136","mp137","mp138","mp139","mp140","mp141","mp142","mp143","mp144","mp145","mp146","mp147","mp148","mp149","mp150","mp151","mp152","mp153","mp154","mp155","mp156","mp157","mp158","mp159","mp160","mp161","mp162","mp163","mp164","mp165","mp166","mp167","mp168","mp169","mp170","mp171","mp172","mp173","mp174","mp175","mp176","mp177","mp178","mp179","mp180","mp181","mp182","mp183","mp184","mp185","mp186","mp187","mp188","mp189","mp190","mp191","mp192","mp193","mp194","mp195","mp196","mp197","mp198","mp199","mp200","mp201","mp202","mp203","mp204","mp205","mp206","mp207","mp208","mp209","mp210","mp211","mp212","mp213","mp214","mp215","mp216","mp217","mp218","mp219","mp220","mp221","mp222","mp223","mp224","mp225","mp226","mp227","mp228","mp229","mp230","mp231","mp232","mp233","mp234","mp235","mp236","mp237","mp238","mp239","mp240","mp241","mp242","mp243","mp244","mp245","mp246","mp247","mp248","mp249","mp250","mp251","mp252","mp253","mp254","mp255","unused0","unused1","unused2","unused3","unused4","unused5","unused6","unused7","unused8","unused9","unused10","unused11","unused12","unused13","unused14","unused15","unused16","unused17","unused18","unused19","unused20","unused21","unused22","unused23","unused24","unused25","unused26","unused27","unused28","unused29","unused30","unused31","unused32","unused33","unused34","unused35","unused36","unused37","unused38","unused39","unused40","unused41","unused42","unused43","unused44","unused45","unused46","unused47","unused48","unused49","unused50","unused51","unused52","unused53","unused54","unused55","unused56","unused57","unused58","unused59","unused60","unused61","unused62","unused63","unused64","unused65","unused66","unused67","unused68","unused69","unused70","unused71","unused72","unused73","unused74","unused75","unused76","unused77","unused78","unused79","unused80","unused81","unused82","unused83","unused84","unused85","unused86","unused87","unused88","unused89","unused90","unused91","unused92","unused93","unused94","unused95","unused96","unused97","unused98","unused99","unused100","unused101","unused102","unused103","unused104","unused105","unused106","unused107","unused108","unused109","unused110","unused111","unused112","unused113","unused114","unused115","unused116","unused117","unused118","unused119","unused120","unused121","unused122","unused123","unused124","unused125","unused126","unused127","unused128","unused129","unused130","unused131","unused132","unused133","unused134","unused135","unused136","unused137","unused138","unused139","unused140","unused141","unused142","unused143","unused144","unused145","unused146","unused147","unused148","unused149","unused150","unused151","unused152","unused153","unused154","unused155","unused156","unused157","unused158","unused159","unused160","unused161","unused162","unused163","unused164","unused165","unused166","unused167","unused168","unused169","unused170","unused171","unused172","unused173","unused174","unused175","unused176","unused177","unused178","unused179","unused180","unused181","unused182","unused183","unused184","unused185","unused186","unused187","unused188","unused189","unused190","unused191","unused192","unused193","unused194","unused195","unused196","unused197","unused198","unused199","unused200","unused201","unused202","unused203","unused204","unused205","unused206","unused207","unused208","unused209","unused210","unused211","unused212","unused213","unused214","unused215","unused216","unused217","unused218","unused219","unused220","unused221","unused222","unused223","unused224","unused225","unused226","unused227","unused228","unused229","unused230","unused231","unused232","unused233","unused234","unused235","unused236","unused237","unused238","unused239","unused240","unused241","unused242","unused243","unused244","unused245","unused246","unused247","unused248","unused249","unused250","unused251","unused252","unused253","unused254","unused255"],"extra":{},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need 'VM.Config.Disk' permissions on /vms/{vmid}, and 'Datastore.AllocateSpace' permissions on the storage. To move a volume to another container, you need the permissions on the target container as well.","expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/move_volume"},{"extra":{},"methods":[{"allow_token":true,"checksum":"20be12fda0c98d0f160d7635e02d9d23d17a15832ec48af28bf4bd55a0897e84","description":"Migration tunnel endpoint - only for internal use by CT migration.","extra":{},"name":"mtunnel","parameters":[{"definition":{"description":"List of network bridges to check availability. Will be checked again for actually used bridges during migration.","enum":[],"extra":{"typetext":""},"format":"pve-bridge-id-list","optional":true,"properties":{},"type":"string"},"name":"bridges"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"List of storages to check permission and availability. Will be checked again for all actually used storages during migration.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id-list","optional":true,"properties":{},"type":"string"},"name":"storages"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permissions on '/vms/{vmid}' and Sys.Incoming on '/'. Further permission checks happen during the actual migration.","expression":{"check":["and",["perm","/vms/{vmid}",["VM.Allocate"]],["perm","/",["Sys.Incoming"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"socket":{"enum":[],"extra":{},"properties":{},"type":"string"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/mtunnel"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e167ede2c65dbdab00d8fdd2d470e4eda018b889a4a2678d76a53898278943d9","description":"Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration.","extra":{},"name":"mtunnelwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"unix socket to forward to","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"socket"},{"definition":{"description":"ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"ticket"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need to pass a ticket valid for the selected socket. Tickets can be created via the mtunnel API call, which will check permissions accordingly.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"socket":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/mtunnelwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b8def4c87913765b840fe5700bca812ce9e40ea1b24553dbbb7789de3bc576c3","description":"Get container configuration, including pending changes.","extra":{"proxyto":"node"},"name":"vm_pending","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"delete":{"description":"Indicates a pending delete request if present and not 0.","enum":[],"extra":{},"maximum":2,"minimum":0,"optional":true,"properties":{},"type":"integer"},"key":{"description":"Configuration option name.","enum":[],"extra":{},"properties":{},"type":"string"},"pending":{"description":"Pending value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"value":{"description":"Current value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/pending"},{"extra":{},"methods":[{"allow_token":true,"checksum":"27357b59f7bb8ddc77ecd59f7f201df8b54a0df268c038e9a1508503303632ba","description":"Migrate the container to another cluster. Creates a new migration task. EXPERIMENTAL feature!","extra":{"proxyto":"node"},"name":"remote_migrate_vm","parameters":[{"definition":{"default":"migrate limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"default":0,"description":"Delete the original CT and related data after successful migration. By default the original CT is kept on the source cluster in a stopped state.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use online/live migration.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"online"},{"definition":{"description":"Use restart migration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restart"},{"definition":{"description":"Mapping from source to target bridges. Providing only a single bridge ID maps all source bridges to that bridge. Providing the special value '1' will map each source bridge to itself.","enum":[],"extra":{"typetext":""},"format":"bridge-pair-list","properties":{},"type":"string"},"name":"target-bridge"},{"definition":{"description":"Remote target endpoint","enum":[],"extra":{"typetext":"apitoken= ,host= [,fingerprint=] [,port=]"},"format":"proxmox-remote","properties":{},"type":"string"},"name":"target-endpoint"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storage-pair-list","optional":false,"properties":{},"type":"string"},"name":"target-storage"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"target-vmid"},{"definition":{"default":180,"description":"Timeout in seconds for shutdown for restart migration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/remote_migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"105aec7d23f0f3955a25470fc7adab20920971a64e877498886c5b45af215e71","description":"Resize a container mount point.","extra":{"proxyto":"node"},"name":"resize_vm","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The disk you want to resize.","enum":["rootfs","mp0","mp1","mp2","mp3","mp4","mp5","mp6","mp7","mp8","mp9","mp10","mp11","mp12","mp13","mp14","mp15","mp16","mp17","mp18","mp19","mp20","mp21","mp22","mp23","mp24","mp25","mp26","mp27","mp28","mp29","mp30","mp31","mp32","mp33","mp34","mp35","mp36","mp37","mp38","mp39","mp40","mp41","mp42","mp43","mp44","mp45","mp46","mp47","mp48","mp49","mp50","mp51","mp52","mp53","mp54","mp55","mp56","mp57","mp58","mp59","mp60","mp61","mp62","mp63","mp64","mp65","mp66","mp67","mp68","mp69","mp70","mp71","mp72","mp73","mp74","mp75","mp76","mp77","mp78","mp79","mp80","mp81","mp82","mp83","mp84","mp85","mp86","mp87","mp88","mp89","mp90","mp91","mp92","mp93","mp94","mp95","mp96","mp97","mp98","mp99","mp100","mp101","mp102","mp103","mp104","mp105","mp106","mp107","mp108","mp109","mp110","mp111","mp112","mp113","mp114","mp115","mp116","mp117","mp118","mp119","mp120","mp121","mp122","mp123","mp124","mp125","mp126","mp127","mp128","mp129","mp130","mp131","mp132","mp133","mp134","mp135","mp136","mp137","mp138","mp139","mp140","mp141","mp142","mp143","mp144","mp145","mp146","mp147","mp148","mp149","mp150","mp151","mp152","mp153","mp154","mp155","mp156","mp157","mp158","mp159","mp160","mp161","mp162","mp163","mp164","mp165","mp166","mp167","mp168","mp169","mp170","mp171","mp172","mp173","mp174","mp175","mp176","mp177","mp178","mp179","mp180","mp181","mp182","mp183","mp184","mp185","mp186","mp187","mp188","mp189","mp190","mp191","mp192","mp193","mp194","mp195","mp196","mp197","mp198","mp199","mp200","mp201","mp202","mp203","mp204","mp205","mp206","mp207","mp208","mp209","mp210","mp211","mp212","mp213","mp214","mp215","mp216","mp217","mp218","mp219","mp220","mp221","mp222","mp223","mp224","mp225","mp226","mp227","mp228","mp229","mp230","mp231","mp232","mp233","mp234","mp235","mp236","mp237","mp238","mp239","mp240","mp241","mp242","mp243","mp244","mp245","mp246","mp247","mp248","mp249","mp250","mp251","mp252","mp253","mp254","mp255"],"extra":{},"properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The new size. With the '+' sign the value is added to the actual size of the volume and without it, the value is taken as an absolute one. Shrinking disk size is not supported.","enum":[],"extra":{},"pattern":"\\+?\\d+(\\.\\d+)?[KMGT]?","properties":{},"type":"string"},"name":"size"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/resize"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4d311cc5db4c24ed1db63ef58b0d8f8e72b579d6828347fd89059bf258f8210e","description":"Read VM RRD statistics (returns PNG)","extra":{},"name":"rrd","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The list of datasources you want to display.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"ds"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/rrd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"53eace25a11ab03d9980fc2e58377060dd11abc1fa75a694adf1f2b2a88dcdf0","description":"Read VM RRD statistics","extra":{},"name":"rrddata","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/rrddata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3938e62f442f3c60a7df8f01428af01e4617ec9ba8fa5556d7519de159d7e483","description":"List all snapshots.","extra":{"proxyto":"node"},"name":"list","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"description":{"description":"Snapshot description.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Snapshot identifier. Value 'current' identifies the current VM.","enum":[],"extra":{},"properties":{},"type":"string"},"parent":{"description":"Parent snapshot identifier.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"snaptime":{"description":"Snapshot creation time","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"a0d4ab4772fea3e50e0d81bb7fb546db0d98690f7beadf0a9919dba46f6da8a0","description":"Snapshot a container.","extra":{"proxyto":"node"},"name":"snapshot","parameters":[{"definition":{"description":"A textual description or comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/snapshot"},{"extra":{},"methods":[{"allow_token":true,"checksum":"96f3395bd45be05f38e53134431646f83ee524e6c21b171a8b2db48c9680746d","description":"Delete a LXC snapshot.","extra":{"proxyto":"node"},"name":"delsnapshot","parameters":[{"definition":{"description":"For removal from config file, even if removing disk snapshots fails.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"3543f6f025f3e8edb235d3a81de6bc9ae888696632b72c8a0358c30d67d096cb","description":"","extra":{},"name":"snapshot_cmd_idx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cmd}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2e4c3ffc0a572cde350f82c1ed21f7483bdc0b55b3350b6c629ad4a87fce8660","description":"Get snapshot configuration","extra":{"proxyto":"node"},"name":"get_snapshot_config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback","VM.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"229bac50088cfccbb485c9371b58bfc8d8a4beddcc04c2ef4a88af7a288e62dc","description":"Update snapshot metadata.","extra":{"proxyto":"node"},"name":"update_snapshot_config","parameters":[{"definition":{"description":"A textual description or comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9b2a6209135aef4408eb89b8eb9dfcdf20584bf94bc486186e346ac74062e1c3","description":"Rollback LXC state to specified snapshot.","extra":{"proxyto":"node"},"name":"rollback","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"default":0,"description":"Whether the container should get started after rolling back successfully","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"start"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7f47a7c211dc02e8f33814e4037ecadcbd23cc44b4053260952a901ddcd8207d","description":"Returns a SPICE configuration to connect to the CT.","extra":{"proxyto":"node"},"name":"spiceproxy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).","enum":[],"extra":{"typetext":""},"format":"address","optional":true,"properties":{},"type":"string"},"name":"proxy"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"description":"Returned values can be directly passed to the 'remote-viewer' application.","enum":[],"extra":{"additionalProperties":1},"properties":{"host":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"enum":[],"extra":{},"properties":{},"type":"string"},"proxy":{"enum":[],"extra":{},"properties":{},"type":"string"},"tls-port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/spiceproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"94a0d535add5f584338da3a56b0765094683ec9f207cd53a95a4014fc19acdf6","description":"Directory index","extra":{"proxyto":"node"},"name":"vmcmdidx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3ceca17d631c8ea13a356778f4cf9faffcf1638cca0f334e8e39212bff6770dc","description":"Get virtual machine status.","extra":{"proxyto":"node"},"name":"vm_status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"cpus":{"description":"Maximum usable CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"ha":{"description":"HA manager service status.","enum":[],"extra":{},"properties":{},"type":"object"},"lock":{"description":"The current config lock, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxdisk":{"description":"Root disk size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Maximum memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxswap":{"description":"Maximum SWAP memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"name":{"description":"Container name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"status":{"description":"LXC Container status.","enum":["stopped","running"],"extra":{},"properties":{},"type":"string"},"tags":{"description":"The current configured tags, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"uptime":{"description":"Uptime.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/status/current"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3d30165bb34e86114bf39cb3a773f1d311f4a959da2997ce8498ef72e1304c66","description":"Reboot the container by shutting it down, and starting it again. Applies pending changes.","extra":{"proxyto":"node"},"name":"vm_reboot","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Wait maximal timeout seconds for the shutdown.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/reboot"},{"extra":{},"methods":[{"allow_token":true,"checksum":"57fbd090b0d3e57bfbdb9880c010907b98b7f014167ffd8c45356ae92ee49779","description":"Resume the container.","extra":{"proxyto":"node"},"name":"vm_resume","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/resume"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8c8a8ded3ac655846cd0d5a9f6336b3c6c19de8b72bd15fb881c3a811f0b44b4","description":"Shutdown the container. This will trigger a clean shutdown of the container, see lxc-stop(1) for details.","extra":{"proxyto":"node"},"name":"vm_shutdown","parameters":[{"definition":{"default":0,"description":"Make sure the Container stops.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"forceStop"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":60,"description":"Wait maximal timeout seconds.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/shutdown"},{"extra":{},"methods":[{"allow_token":true,"checksum":"74e1347597f095190b87ed4fc37f244762885d35b6f0ae1132c1b290d50587be","description":"Start the container.","extra":{"proxyto":"node"},"name":"vm_start","parameters":[{"definition":{"default":0,"description":"If set, enables very verbose debug log-level on start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"debug"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3588eb70dcef945b2a345ff3604b01203860fc53a231a91f155b3f0d454509a5","description":"Stop the container. This will abruptly stop all processes running in the container.","extra":{"proxyto":"node"},"name":"vm_stop","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/stop"},{"extra":{},"methods":[{"allow_token":true,"checksum":"668faf2a02d9fc2177c5645a120cc8496ed932b0eeef711c180e980e7508a6f5","description":"Suspend the container. This is experimental.","extra":{"proxyto":"node"},"name":"vm_suspend","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/suspend"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9e6329edbc164d2926eda1f33b0d65022b8435d588b1d0132965b4d53dc9a022","description":"Create a Template.","extra":{"proxyto":"node"},"name":"template","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permissions on /vms/{vmid}","expression":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/template"},{"extra":{},"methods":[{"allow_token":true,"checksum":"83d05bc119e943385f59c7b476b453d78f4cb3511a4179f137ca3eb37ccd9f22","description":"Creates a TCP proxy connection.","extra":{},"name":"termproxy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/termproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"22e8e54db027cc564d07db10ec8bf1e60554c5fb0f7080768157783ace4e297b","description":"Creates a TCP VNC proxy connections.","extra":{},"name":"vncproxy","parameters":[{"definition":{"description":"sets the height of the console in pixels.","enum":[],"extra":{"typetext":" (16 - 2160)"},"maximum":2160,"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"height"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"use websocket instead of standard VNC.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"websocket"},{"definition":{"description":"sets the width of the console in pixels.","enum":[],"extra":{"typetext":" (16 - 4096)"},"maximum":4096,"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"width"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"cert":{"enum":[],"extra":{},"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/vncproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ee391a9db15bf946d3fcf3622e765d731bb78079d2394c583723f26e79101ac5","description":"Opens a weksocket for VNC traffic.","extra":{},"name":"vncwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Port number returned by previous vncproxy call.","enum":[],"extra":{"typetext":" (5900 - 5999)"},"maximum":5999,"minimum":5900,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Ticket from previous call to vncproxy.","enum":[],"extra":{"typetext":""},"max_length":512,"properties":{},"type":"string"},"name":"vncticket"}],"permissions":{"description":"You also need to pass a valid ticket (vncticket).","expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/vncwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"896c5fe436ce73344ef37d78465b4785c481d5856c495b6142f3f4ba5e250983","description":"Migrate all VMs and Containers.","extra":{"proxyto":"node"},"name":"migrateall","parameters":[{"definition":{"description":"Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg. One of both must be set!","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxworkers"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Only consider Guests with these IDs.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"},{"definition":{"description":"Enable live storage migration for local disk","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"with-local-disks"}],"permissions":{"description":"The 'VM.Migrate' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/migrateall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c2c207a7e8a4df2370ac547d2a570d636677faa99ba285adbe6298dde17efefc","description":"Read tap/vm network device interface counters","extra":{"proxyto":"node"},"name":"netstat","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/netstat"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3de07e746f474e02ab38c834d3571d70c15aa5d66e4a80d73f9f67876bcd5bfc","description":"Revert network configuration changes.","extra":{"proxyto":"node"},"name":"revert_network_changes","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"46c1567fc0f13080215d5ae833706f8b69c3a836146ddcde0bbf4e73544b199f","description":"List available networks","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list specific interface types.","enum":["bridge","bond","eth","alias","vlan","OVSBridge","OVSBond","OVSPort","OVSIntPort","any_bridge"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{iface}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"369cd63b33c3fe2031b9eaed330a1a25d9993d8890c291e86dcc811334d48f7c","description":"Create network device configuration","extra":{"proxyto":"node"},"name":"create_network","parameters":[{"definition":{"description":"IP address.","enum":[],"extra":{"requires":"netmask","typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"address"},{"definition":{"description":"IP address.","enum":[],"extra":{"requires":"netmask6","typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"address6"},{"definition":{"description":"Automatically start interface on boot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Specify the primary interface for active-backup bond.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"bond-primary"},{"definition":{"description":"Bonding mode.","enum":["balance-rr","active-backup","balance-xor","broadcast","802.3ad","balance-tlb","balance-alb","balance-slb","lacp-balance-slb","lacp-balance-tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bond_mode"},{"definition":{"description":"Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.","enum":["layer2","layer2+3","layer3+4"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bond_xmit_hash_policy"},{"definition":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"bridge_ports"},{"definition":{"description":"Enable bridge vlan support.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bridge_vlan_aware"},{"definition":{"description":"IPv4 CIDR.","enum":[],"extra":{"typetext":""},"format":"CIDRv4","optional":true,"properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IPv6 CIDR.","enum":[],"extra":{"typetext":""},"format":"CIDRv6","optional":true,"properties":{},"type":"string"},"name":"cidr6"},{"definition":{"description":"Comments","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comments"},{"definition":{"description":"Comments","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comments6"},{"definition":{"description":"Default gateway address.","enum":[],"extra":{"typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"gateway"},{"definition":{"description":"Default ipv6 gateway address.","enum":[],"extra":{"typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"gateway6"},{"definition":{"description":"Network interface name.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"MTU.","enum":[],"extra":{"typetext":" (1280 - 65520)"},"maximum":65520,"minimum":1280,"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"Network mask.","enum":[],"extra":{"requires":"address","typetext":""},"format":"ipv4mask","optional":true,"properties":{},"type":"string"},"name":"netmask"},{"definition":{"description":"Network mask.","enum":[],"extra":{"requires":"address6","typetext":" (0 - 128)"},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"netmask6"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"ovs_bonds"},{"definition":{"description":"The OVS bridge associated with a OVS port. This is required when you create an OVS port.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"ovs_bridge"},{"definition":{"description":"OVS interface options.","enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"ovs_options"},{"definition":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"ovs_ports"},{"definition":{"description":"Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)","enum":[],"extra":{"typetext":" (1 - 4094)"},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"ovs_tag"},{"definition":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"slaves"},{"definition":{"description":"Network interface type","enum":["bridge","bond","eth","alias","vlan","OVSBridge","OVSBond","OVSPort","OVSIntPort","unknown"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"vlan-id for a custom named vlan interface (ifupdown2 only).","enum":[],"extra":{"typetext":" (1 - 4094)"},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vlan-id"},{"definition":{"description":"Specify the raw interface for the vlan interface.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"vlan-raw-device"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"5c5bb8977f0eeef180ddd9a799bd358f22ac79b3f4b58c6f1f197e7659aaabb9","description":"Reload network configuration","extra":{"proxyto":"node"},"name":"reload_network_config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/network"},{"extra":{},"methods":[{"allow_token":true,"checksum":"32c344b0dfe6220c53d77420aa2694e1bc65998071ee6a33024bccd2265550f3","description":"Delete network device configuration","extra":{"proxyto":"node"},"name":"delete_network","parameters":[{"definition":{"description":"Network interface name.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"91ab56660b1db09d5d12a3a1739ea872acc81e6d3a0f84993fa51ea56b78dea3","description":"Read network device configuration","extra":{"proxyto":"node"},"name":"network_config","parameters":[{"definition":{"description":"Network interface name.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"method":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"43d6e45e69f551627fa62b7c956dc9b0cdec5cb29e90d5bc265bf7fbdf4ce8fd","description":"Update network device configuration","extra":{"proxyto":"node"},"name":"update_network","parameters":[{"definition":{"description":"IP address.","enum":[],"extra":{"requires":"netmask","typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"address"},{"definition":{"description":"IP address.","enum":[],"extra":{"requires":"netmask6","typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"address6"},{"definition":{"description":"Automatically start interface on boot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Specify the primary interface for active-backup bond.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"bond-primary"},{"definition":{"description":"Bonding mode.","enum":["balance-rr","active-backup","balance-xor","broadcast","802.3ad","balance-tlb","balance-alb","balance-slb","lacp-balance-slb","lacp-balance-tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bond_mode"},{"definition":{"description":"Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.","enum":["layer2","layer2+3","layer3+4"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bond_xmit_hash_policy"},{"definition":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"bridge_ports"},{"definition":{"description":"Enable bridge vlan support.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bridge_vlan_aware"},{"definition":{"description":"IPv4 CIDR.","enum":[],"extra":{"typetext":""},"format":"CIDRv4","optional":true,"properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IPv6 CIDR.","enum":[],"extra":{"typetext":""},"format":"CIDRv6","optional":true,"properties":{},"type":"string"},"name":"cidr6"},{"definition":{"description":"Comments","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comments"},{"definition":{"description":"Comments","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comments6"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Default gateway address.","enum":[],"extra":{"typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"gateway"},{"definition":{"description":"Default ipv6 gateway address.","enum":[],"extra":{"typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"gateway6"},{"definition":{"description":"Network interface name.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"MTU.","enum":[],"extra":{"typetext":" (1280 - 65520)"},"maximum":65520,"minimum":1280,"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"Network mask.","enum":[],"extra":{"requires":"address","typetext":""},"format":"ipv4mask","optional":true,"properties":{},"type":"string"},"name":"netmask"},{"definition":{"description":"Network mask.","enum":[],"extra":{"requires":"address6","typetext":" (0 - 128)"},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"netmask6"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"ovs_bonds"},{"definition":{"description":"The OVS bridge associated with a OVS port. This is required when you create an OVS port.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"ovs_bridge"},{"definition":{"description":"OVS interface options.","enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"ovs_options"},{"definition":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"ovs_ports"},{"definition":{"description":"Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)","enum":[],"extra":{"typetext":" (1 - 4094)"},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"ovs_tag"},{"definition":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"slaves"},{"definition":{"description":"Network interface type","enum":["bridge","bond","eth","alias","vlan","OVSBridge","OVSBond","OVSPort","OVSIntPort","unknown"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"vlan-id for a custom named vlan interface (ifupdown2 only).","enum":[],"extra":{"typetext":" (1 - 4094)"},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vlan-id"},{"definition":{"description":"Specify the raw interface for the vlan interface.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"vlan-raw-device"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/network/{iface}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f3d32223473b761666f1b17e6f5560781b281b9659581e1622e83e1e15c53791","description":"Virtual machine index (per node).","extra":{"proxyto":"node"},"name":"vmlist","parameters":[{"definition":{"description":"Determine the full status of active VMs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Only list VMs where you have VM.Audit permissons on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{vmid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cpus":{"description":"Maximum usable CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"lock":{"description":"The current config lock, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxdisk":{"description":"Root disk size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Maximum memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"name":{"description":"VM name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pid":{"description":"PID of running qemu process.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"qmpstatus":{"description":"QEMU QMP agent status.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"running-machine":{"description":"The currently running machine type (if running).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"running-qemu":{"description":"The currently running QEMU version (if running).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"status":{"description":"QEMU process status.","enum":["stopped","running"],"extra":{},"properties":{},"type":"string"},"tags":{"description":"The current configured tags, if any","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"uptime":{"description":"Uptime.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"a0b5a69d1c703224b086b9addc693b8dc3955e0a85ebe8bb1f01c6dfac295fbf","description":"Create or restore a virtual machine.","extra":{"proxyto":"node"},"name":"create_vm","parameters":[{"definition":{"default":1,"description":"Enable/disable ACPI.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"acpi"},{"definition":{"description":"List of host cores used to execute guest processes, for example: 0,5,8-11","enum":[],"extra":{"typetext":""},"format":"pve-cpuset","optional":true,"properties":{},"type":"string"},"name":"affinity"},{"definition":{"description":"Enable/disable communication with the QEMU Guest Agent and its properties.","enum":[],"extra":{"typetext":"[enabled=]<1|0> [,freeze-fs-on-backup=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]"},"format":{"enabled":{"default":0,"default_key":1,"description":"Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.","type":"boolean"},"freeze-fs-on-backup":{"default":1,"description":"Freeze/thaw guest filesystems on backup for consistency.","optional":1,"type":"boolean"},"fstrim_cloned_disks":{"default":0,"description":"Run fstrim after moving a disk or migrating the VM.","optional":1,"type":"boolean"},"type":{"default":"virtio","description":"Select the agent type","enum":["virtio","isa"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"agent"},{"definition":{"description":"Virtual processor architecture. Defaults to the host.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"description":"The backup archive. Either the file system path to a .tar or .vma file (use '-' to pipe data from stdin) or a proxmox storage backup volume identifier.","enum":[],"extra":{"typetext":""},"max_length":255,"optional":true,"properties":{},"type":"string"},"name":"archive"},{"definition":{"description":"Arbitrary arguments passed to kvm.","enum":[],"extra":{"typetext":"","verbose_description":"Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -no-hpet\n\nNOTE: this option is for experts only.\n"},"optional":true,"properties":{},"type":"string"},"name":"args"},{"definition":{"description":"Configure a audio device, useful in combination with QXL/Spice.","enum":[],"extra":{"typetext":"device= [,driver=]"},"format":{"device":{"description":"Configure an audio device.","enum":["ich9-intel-hda","intel-hda","AC97"],"type":"string"},"driver":{"default":"spice","description":"Driver backend for the audio device.","enum":["spice","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"audio0"},{"definition":{"default":0,"description":"Automatic restart after crash (currently ignored).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Amount of target RAM for the VM in MiB. Using zero disables the ballon driver.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"balloon"},{"definition":{"default":"seabios","description":"Select BIOS implementation.","enum":["seabios","ovmf"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bios"},{"definition":{"description":"Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.","enum":[],"extra":{"typetext":"[[legacy=]<[acdn]{1,4}>] [,order=]"},"format":"pve-qm-boot","optional":true,"properties":{},"type":"string"},"name":"boot"},{"definition":{"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","enum":[],"extra":{},"format":"pve-qm-bootdisk","optional":true,"pattern":"(ide|sata|scsi|virtio)\\d+","properties":{},"type":"string"},"name":"bootdisk"},{"definition":{"default":"restore limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"This is an alias for option -ide2","enum":[],"extra":{"typetext":""},"format":"pve-qm-ide","optional":true,"properties":{},"type":"string"},"name":"cdrom"},{"definition":{"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","enum":[],"extra":{"typetext":"[meta=] [,network=] [,user=] [,vendor=]"},"format":"pve-qm-cicustom","optional":true,"properties":{},"type":"string"},"name":"cicustom"},{"definition":{"description":"cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cipassword"},{"definition":{"description":"Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.","enum":["configdrive2","nocloud","opennebula"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"citype"},{"definition":{"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ciuser"},{"definition":{"default":1,"description":"The number of cores per socket.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"description":"Emulated CPU type.","enum":[],"extra":{"typetext":"[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]"},"format":"pve-vm-cpu-conf","optional":true,"properties":{},"type":"string"},"name":"cpu"},{"definition":{"default":0,"description":"Limit of CPU usage.","enum":[],"extra":{"typetext":" (0 - 128)","verbose_description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit."},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"typetext":" (1 - 262144)","verbose_description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs."},"maximum":262144,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"description":"Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":8192,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,pre-enrolled-keys=<1|0>] [,size=]"},"format":{"efitype":{"default":"2m","description":"Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarc64 (ARM).","enum":["2m","4m"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"pre-enrolled-keys":{"default":0,"description":"Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.","optional":1,"type":"boolean"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"efidisk0"},{"definition":{"description":"Allow to overwrite existing VM.","enum":[],"extra":{"requires":"archive","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Freeze CPU at startup (use 'c' monitor command to start execution).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"freeze"},{"definition":{"description":"Script that will be executed during various steps in the vms lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Map host PCI devices into guest.","enum":[],"extra":{"typetext":"[host=] [,device-id=] [,legacy-igd=<1|0>] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]","verbose_description":"Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"format":"pve-qm-hostpci","optional":true,"properties":{},"type":"string"},"name":"hostpci[n]"},{"definition":{"default":"network,disk,usb","description":"Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.","enum":[],"extra":{"typetext":""},"format":"pve-hotplug-features","optional":true,"properties":{},"type":"string"},"name":"hotplug"},{"definition":{"description":"Enable/disable hugepages memory.","enum":["any","2","1024"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"hugepages"},{"definition":{"description":"Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"model":{"description":"The drive's reported model name, url-encoded, up to 40 bytes long.","format":"urlencoded","format_description":"model","maxLength":120,"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"ide[n]"},{"definition":{"description":"cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n","enum":[],"extra":{"typetext":"[gw=] [,gw6=] [,ip=] [,ip6=]"},"format":"pve-qm-ipconfig","optional":true,"properties":{},"type":"string"},"name":"ipconfig[n]"},{"definition":{"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host.","enum":[],"extra":{"typetext":"size= [,name=]"},"format":{"name":{"description":"The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.","format_description":"string","optional":1,"pattern":"[a-zA-Z0-9\\-]+","type":"string"},"size":{"description":"The size of the file in MB.","minimum":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"ivshmem"},{"definition":{"default":0,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keephugepages"},{"definition":{"description":"Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"keyboard"},{"definition":{"default":1,"description":"Enable/disable KVM hardware virtualization.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"kvm"},{"definition":{"description":"Start the VM immediately from the backup and restore in background. PBS only.","enum":[],"extra":{"requires":"archive","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"live-restore"},{"definition":{"description":"Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"localtime"},{"definition":{"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"description":"Specifies the QEMU machine type.","enum":[],"extra":{},"max_length":40,"optional":true,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","properties":{},"type":"string"},"name":"machine"},{"definition":{"default":512,"description":"Amount of RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.","enum":[],"extra":{"typetext":" (16 - N)"},"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"memory"},{"definition":{"default":0.1,"description":"Set maximum tolerated downtime (in seconds) for migrations.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"migrate_downtime"},{"definition":{"default":0,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"migrate_speed"},{"definition":{"description":"Set a name for the VM. Only used on the configuration web interface.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"format":"address-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specify network devices.","enum":[],"extra":{"typetext":"[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]"},"format":{"bridge":{"description":"Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n","format":"pve-bridge-id","format_description":"bridge","optional":1,"type":"string"},"e1000":{"alias":"macaddr","keyAlias":"model"},"e1000-82540em":{"alias":"macaddr","keyAlias":"model"},"e1000-82544gc":{"alias":"macaddr","keyAlias":"model"},"e1000-82545em":{"alias":"macaddr","keyAlias":"model"},"e1000e":{"alias":"macaddr","keyAlias":"model"},"firewall":{"description":"Whether this interface should be protected by the firewall.","optional":1,"type":"boolean"},"i82551":{"alias":"macaddr","keyAlias":"model"},"i82557b":{"alias":"macaddr","keyAlias":"model"},"i82559er":{"alias":"macaddr","keyAlias":"model"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"macaddr":{"description":"MAC address. That address must be unique withing your network. This is automatically generated if not specified.","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"model":{"default_key":1,"description":"Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.","enum":["e1000","e1000-82540em","e1000-82544gc","e1000-82545em","e1000e","i82551","i82557b","i82559er","ne2k_isa","ne2k_pci","pcnet","rtl8139","virtio","vmxnet3"],"type":"string"},"mtu":{"description":"Force MTU, for VirtIO only. Set to '1' to use the bridge MTU","maximum":65520,"minimum":1,"optional":1,"type":"integer"},"ne2k_isa":{"alias":"macaddr","keyAlias":"model"},"ne2k_pci":{"alias":"macaddr","keyAlias":"model"},"pcnet":{"alias":"macaddr","keyAlias":"model"},"queues":{"description":"Number of packet queues to be used on the device.","maximum":64,"minimum":0,"optional":1,"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":0,"optional":1,"type":"number"},"rtl8139":{"alias":"macaddr","keyAlias":"model"},"tag":{"description":"VLAN tag to apply to packets on this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN trunks to pass through this interface.","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"virtio":{"alias":"macaddr","keyAlias":"model"},"vmxnet3":{"alias":"macaddr","keyAlias":"model"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Enable/disable NUMA.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"numa"},{"definition":{"description":"NUMA topology.","enum":[],"extra":{"typetext":"cpus= [,hostnodes=] [,memory=] [,policy=]"},"format":{"cpus":{"description":"CPUs accessing this NUMA node.","format_description":"id[-id];...","pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"hostnodes":{"description":"Host NUMA nodes to use.","format_description":"id[-id];...","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"memory":{"description":"Amount of memory this NUMA node provides.","optional":1,"type":"number"},"policy":{"description":"NUMA allocation policy.","enum":["preferred","bind","interleave"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"numa[n]"},{"definition":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","win11","l24","l26","solaris"],"extra":{"verbose_description":"Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 6.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n"},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"description":"Map host parallel devices (n is 0 to 2).","enum":[],"extra":{"verbose_description":"Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"/dev/parport\\d+|/dev/usb/lp\\d+","properties":{},"type":"string"},"name":"parallel[n]"},{"definition":{"description":"Add the VM to the specified pool.","enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"default":0,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"default":1,"description":"Allow reboot. If set to '0' the VM exit on reboot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"reboot"},{"definition":{"description":"Configure a VirtIO-based Random Number Generator.","enum":[],"extra":{"typetext":"[source=] [,max_bytes=] [,period=]"},"format":{"max_bytes":{"default":1024,"description":"Maximum bytes of entropy allowed to get injected into the guest every 'period' milliseconds. Prefer a lower value when using '/dev/random' as source. Use `0` to disable limiting (potentially dangerous!).","optional":1,"type":"integer"},"period":{"default":1000,"description":"Every 'period' milliseconds the entropy-injection quota is reset, allowing the guest to retrieve another 'max_bytes' of entropy.","optional":1,"type":"integer"},"source":{"default_key":1,"description":"The file on the host to gather entropy from. In most cases '/dev/urandom' should be preferred over '/dev/random' to avoid entropy-starvation issues on the host. Using urandom does *not* decrease security in any meaningful way, as it's still seeded from real entropy, and the bytes provided will most likely be mixed with real entropy on the guest as well. '/dev/hwrng' can be used to pass through a hardware RNG from the host.","enum":["/dev/urandom","/dev/random","/dev/hwrng"],"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"rng0"},{"definition":{"description":"Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"sata[n]"},{"definition":{"description":"Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"queues":{"description":"Number of queues.","minimum":2,"optional":1,"type":"integer"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"scsiblock":{"default":0,"description":"whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"scsi[n]"},{"definition":{"default":"lsi","description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scsihw"},{"definition":{"description":"cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Create a serial device inside the VM (n is 0 to 3)","enum":[],"extra":{"verbose_description":"Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"(/dev/.+|socket)","properties":{},"type":"string"},"name":"serial[n]"},{"definition":{"default":1000,"description":"Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.","enum":[],"extra":{"typetext":" (0 - 50000)"},"maximum":50000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"shares"},{"definition":{"description":"Specify SMBIOS type 1 fields.","enum":[],"extra":{"typetext":"[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]"},"format":"pve-qm-smbios1","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"smbios1"},{"definition":{"default":1,"description":"The number of CPUs. Please use option -sockets instead.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"smp"},{"definition":{"default":1,"description":"The number of CPU sockets.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"sockets"},{"definition":{"description":"Configure additional enhancements for SPICE.","enum":[],"extra":{"typetext":"[foldersharing=<1|0>] [,videostreaming=]"},"format":{"foldersharing":{"default":"0","description":"Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.","optional":1,"type":"boolean"},"videostreaming":{"default":"off","description":"Enable video streaming. Uses compression for detected video streams.","enum":["off","all","filter"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"spice_enhancements"},{"definition":{"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{"typetext":""},"format":"urlencoded","optional":true,"properties":{},"type":"string"},"name":"sshkeys"},{"definition":{"default":0,"description":"Start VM after it was created successfully.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"start"},{"definition":{"default":"now","description":"Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.","enum":[],"extra":{"typetext":"(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)"},"optional":true,"pattern":"(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)","properties":{},"type":"string"},"name":"startdate"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"description":"Default storage.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"default":1,"description":"Enable/disable the USB tablet device.","enum":[],"extra":{"typetext":"","verbose_description":"Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)."},"optional":true,"properties":{},"type":"boolean"},"name":"tablet"},{"definition":{"description":"Tags of the VM. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable time drift fix.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tdf"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,import-from=] [,size=] [,version=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"version":{"default":"v2.0","description":"The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.","enum":["v1.2","v2.0"],"optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"tpmstate0"},{"definition":{"description":"Assign a unique random ethernet address.","enum":[],"extra":{"requires":"archive","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"unique"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[file=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id","format_description":"volume","type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).","enum":[],"extra":{"typetext":"[host=] [,usb3=<1|0>]"},"format":{"host":{"default_key":1,"description":"The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadeciaml numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n","format":"pve-qm-usb-device","format_description":"HOSTUSBDEVICE|spice","type":"string"},"usb3":{"default":0,"description":"Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"usb[n]"},{"definition":{"default":0,"description":"Number of hotplugged vcpus.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vcpus"},{"definition":{"description":"Configure the VGA hardware.","enum":[],"extra":{"typetext":"[[type=]] [,memory=]","verbose_description":"Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal."},"format":{"memory":{"description":"Sets the VGA memory (in MiB). Has no effect with serial display.","maximum":512,"minimum":4,"optional":1,"type":"integer"},"type":{"default":"std","default_key":1,"description":"Select the VGA type.","enum":["cirrus","qxl","qxl2","qxl3","qxl4","none","serial0","serial1","serial2","serial3","std","virtio","virtio-gl","vmware"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"vga"},{"definition":{"description":"Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"virtio[n]"},{"definition":{"default":"1 (autogenerated)","description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","enum":[],"extra":{"format_description":"UUID","verbose_description":"The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file."},"optional":true,"pattern":"(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])","properties":{},"type":"string"},"name":"vmgenid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Default storage for VM state volumes/files.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"vmstatestorage"},{"definition":{"description":"Create a virtual hardware watchdog device.","enum":[],"extra":{"typetext":"[[model=]] [,action=]","verbose_description":"Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)"},"format":"pve-qm-watchdog","optional":true,"properties":{},"type":"string"},"name":"watchdog"}],"permissions":{"description":"You need 'VM.Allocate' permissions on /vms/{vmid} or on the VM pool /pool/{pool}. For restore (option 'archive'), it is enough if the user has 'VM.Backup' permission and the VM already exists. If you create disks you need 'Datastore.AllocateSpace' on any used storage.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu"},{"extra":{},"methods":[{"allow_token":true,"checksum":"685d7b95debe906ba90b50a782acdbfa47829c08b592f8804ee3768c5aa07986","description":"Destroy the VM and all used/owned volumes. Removes any VM specific permissions and firewall rules","extra":{"proxyto":"node"},"name":"destroy_vm","parameters":[{"definition":{"default":0,"description":"If set, destroy additionally all disks not referenced in the config but with a matching VMID from all enabled storages.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"destroy-unreferenced-disks"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Remove VMID from configurations, like backup & replication jobs and HA.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"purge"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"fa055338b801bce39c739df867cff19ab708c821f45e2cd7c6ee100546aea617","description":"Directory index","extra":{"proxyto":"node"},"name":"vmdiridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"fc71618b6ae210865c89631d4261612d8ef62c3762d6c5e31f47e2c61a5a333c","description":"QEMU Guest Agent command index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"Returns the list of QEMU Guest Agent commands","enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"b7acc378dbdbef5e92979fa23699f31640ee380b530bddf97455e7f1ba6f733a","description":"Execute QEMU Guest Agent commands.","extra":{"proxyto":"node"},"name":"agent","parameters":[{"definition":{"description":"The QGA command.","enum":["fsfreeze-freeze","fsfreeze-status","fsfreeze-thaw","fstrim","get-fsinfo","get-host-name","get-memory-block-info","get-memory-blocks","get-osinfo","get-time","get-timezone","get-users","get-vcpus","info","network-get-interfaces","ping","shutdown","suspend-disk","suspend-hybrid","suspend-ram"],"extra":{},"properties":{},"type":"string"},"name":"command"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1919fa6f3b3e4fe70c732bbdb3927d38365482e4033921906a4287113450505a","description":"Executes the given command in the vm via the guest-agent and returns an object with the pid.","extra":{"proxyto":"node"},"name":"exec","parameters":[{"definition":{"description":"The command as a list of program + arguments","enum":[],"extra":{"typetext":""},"format":"string-alist","optional":true,"properties":{},"type":"string"},"name":"command"},{"definition":{"description":"Data to pass as 'input-data' to the guest. Usually treated as STDIN to 'command'.","enum":[],"extra":{"typetext":""},"max_length":65536,"optional":true,"properties":{},"type":"string"},"name":"input-data"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"pid":{"description":"The PID of the process started by the guest-agent.","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/exec"},{"extra":{},"methods":[{"allow_token":true,"checksum":"744a2477f62419e715cd74402770a4628d821a96c211aaedf5d6074af82cbd5a","description":"Gets the status of the given pid started by the guest-agent","extra":{"proxyto":"node"},"name":"exec-status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The PID to query","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"pid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"err-data":{"description":"stderr of the process","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"err-truncated":{"description":"true if stderr was not fully captured","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"exitcode":{"description":"process exit code if it was normally terminated.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"exited":{"description":"Tells if the given command has exited yet.","enum":[],"extra":{},"properties":{},"type":"boolean"},"out-data":{"description":"stdout of the process","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"out-truncated":{"description":"true if stdout was not fully captured","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"signal":{"description":"signal number or exception code if the process was abnormally terminated.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/exec-status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6c1b6b1f964befa755c9f0c71f9ab72f3969c0ee7aed0683a4c073e0182fd98b","description":"Reads the given file via guest agent. Is limited to 16777216 bytes.","extra":{"proxyto":"node"},"name":"file-read","parameters":[{"definition":{"description":"The path to the file","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"file"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a `content` property.","enum":[],"extra":{},"properties":{"content":{"description":"The content of the file, maximum 16777216","enum":[],"extra":{},"properties":{},"type":"string"},"truncated":{"description":"If set to 1, the output is truncated and not complete","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/file-read"},{"extra":{},"methods":[{"allow_token":true,"checksum":"60cab32161e1b85a9436bb9dfde2200073d3523b9cce2883576f82004990ec31","description":"Writes the given file via guest agent.","extra":{"proxyto":"node"},"name":"file-write","parameters":[{"definition":{"description":"The content to write into the file.","enum":[],"extra":{"typetext":""},"max_length":61440,"properties":{},"type":"string"},"name":"content"},{"definition":{"default":1,"description":"If set, the content will be encoded as base64 (required by QEMU).Otherwise the content needs to be encoded beforehand - defaults to true.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"encode"},{"definition":{"description":"The path to the file.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"file"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/file-write"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c28d21618be57ca1077632d96c9a1307a5dc56a98fb70095e197517d98382e79","description":"Execute fsfreeze-freeze.","extra":{"proxyto":"node"},"name":"fsfreeze-freeze","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze"},{"extra":{},"methods":[{"allow_token":true,"checksum":"94ea8c43248c9084afb23eb6981d541c188a770c9d45ba0c81a809f484d34e09","description":"Execute fsfreeze-status.","extra":{"proxyto":"node"},"name":"fsfreeze-status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ba7e0905312a35f9ed9b54a5d2f466764d482f20b1eb1e0c87b428cb1cc80b22","description":"Execute fsfreeze-thaw.","extra":{"proxyto":"node"},"name":"fsfreeze-thaw","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2c06bb7419c8dfeabc2a9f7ad57dccdbdb639c1e97f7076a266a72537699e4d4","description":"Execute fstrim.","extra":{"proxyto":"node"},"name":"fstrim","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/fstrim"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9925709188ca2e8228138a5f4b3f39786831a531b90ff5eb9c95939191b65ffe","description":"Execute get-fsinfo.","extra":{"proxyto":"node"},"name":"get-fsinfo","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-fsinfo"},{"extra":{},"methods":[{"allow_token":true,"checksum":"97fa3d29a33d517270e4e9f6cb42b84820b906b3d25290426da97dcd16f7ef0d","description":"Execute get-host-name.","extra":{"proxyto":"node"},"name":"get-host-name","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-host-name"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a03cce5e2343d9872b4e3d3afc1085ec3ef1975778a9fc2f1466b9a092e57e32","description":"Execute get-memory-block-info.","extra":{"proxyto":"node"},"name":"get-memory-block-info","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2ce6034fcef7cd88d4c5bc8e237aaea97ffdf7b608420d9f1567a5998c47ced2","description":"Execute get-memory-blocks.","extra":{"proxyto":"node"},"name":"get-memory-blocks","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"36d3b322e0596f046761eb102d6a4d4289e61f1a2516226e5ae55e12fa81870d","description":"Execute get-osinfo.","extra":{"proxyto":"node"},"name":"get-osinfo","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-osinfo"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5ee1af722313cc5a855977fd9886a3a605f809f44e9e7282bd0b22df6c18ecfe","description":"Execute get-time.","extra":{"proxyto":"node"},"name":"get-time","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-time"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1f45439fa6d0a5d768d276506153371ded53391eca506aef0d74cff5aee32074","description":"Execute get-timezone.","extra":{"proxyto":"node"},"name":"get-timezone","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-timezone"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e3a2e67e94d5c1108d9e604e3a87229c549243bf01e053bd2d95a1db06ea1255","description":"Execute get-users.","extra":{"proxyto":"node"},"name":"get-users","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-users"},{"extra":{},"methods":[{"allow_token":true,"checksum":"58343921431c44f8b47ddae6e015c065a705017450b82bcb02984b117e2a4cac","description":"Execute get-vcpus.","extra":{"proxyto":"node"},"name":"get-vcpus","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-vcpus"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a70d07c83af36feb6ff6c06084e36e0fc38b82cdb16d3e4d5033ebc14aa5b5ae","description":"Execute info.","extra":{"proxyto":"node"},"name":"info","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c1660e4d1ba26278dc1fc246560c4ced3189f8ca4f4db2ba5e24e90bc146f4eb","description":"Execute network-get-interfaces.","extra":{"proxyto":"node"},"name":"network-get-interfaces","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces"},{"extra":{},"methods":[{"allow_token":true,"checksum":"70759c6c57b459e7e55edd424c8529ba20c783b4aecb7aab600a57e2420da2fb","description":"Execute ping.","extra":{"proxyto":"node"},"name":"ping","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/ping"},{"extra":{},"methods":[{"allow_token":true,"checksum":"51598b3eef5745757d341759b910566de340887f06deb4d383f6d775cf8784a5","description":"Sets the password for the given user to the given password","extra":{"proxyto":"node"},"name":"set-user-password","parameters":[{"definition":{"default":0,"description":"set to 1 if the password has already been passed through crypt()","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"crypted"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The new password.","enum":[],"extra":{"typetext":""},"max_length":1024,"min_length":5,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"The user to set the password for.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"username"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/set-user-password"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b2fc0938c5e1b7ea6e10817e434fe094103366e4ebdef15354a4cbcedf112eca","description":"Execute shutdown.","extra":{"proxyto":"node"},"name":"shutdown","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/shutdown"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9e39e6d8b5266195f2f81e0414b442d1c39647c81881965e72c5805f2b6d487e","description":"Execute suspend-disk.","extra":{"proxyto":"node"},"name":"suspend-disk","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/suspend-disk"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1aeb5a294ce0ee9314e074d9c321bcaf37e7a35bcf3e239f03d70308c232ff12","description":"Execute suspend-hybrid.","extra":{"proxyto":"node"},"name":"suspend-hybrid","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e0f85b45b63334c20ddf91a6d89434b740c3a9305fa120ad6ed6c9573eb1212c","description":"Execute suspend-ram.","extra":{"proxyto":"node"},"name":"suspend-ram","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/suspend-ram"},{"extra":{},"methods":[{"allow_token":true,"checksum":"20e482b27ee16fa832fefc563fbba31b24e4c73c706a2e407cce44c0f2d55820","description":"Create a copy of virtual machine/template.","extra":{"proxyto":"node"},"name":"clone_vm","parameters":[{"definition":{"default":"clone limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"Description for the new VM.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Target format for file storage. Only valid for full clone.","enum":["raw","qcow2","vmdk"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"Create a full copy of all disks. This is always done when you clone a normal VM. For VM templates, we try to create a linked clone by default.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"},{"definition":{"description":"Set a name for the new VM.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"VMID for the clone.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"newid"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Add the new VM to the specified pool.","enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"Target storage for full clone.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Target node. Only allowed if the original VM is on shared storage.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions on /vms/{newid} (or on the VM pool /pool/{pool}). You also need 'Datastore.AllocateSpace' on any used storage.","expression":{"check":["and",["perm","/vms/{vmid}",["VM.Clone"]],["or",["perm","/vms/{newid}",["VM.Allocate"]],["perm","/pool/{pool}",["VM.Allocate"],"require_param","pool"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/clone"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bf7723f47c8de31d45d8740f316c5a3a8e8bbd88e03abcc8652ca7e790882422","description":"Get the cloudinit configuration with both current and pending values.","extra":{"proxyto":"node"},"name":"cloudinit_pending","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"key":{"description":"Configuration option name.","enum":[],"extra":{},"properties":{},"type":"string"},"new":{"description":"The new pending value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"old":{"description":"Value as it was used to generate the current cloudinit image.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"55f7728795631254f3464f606ad62ddfaaeda4bf2ba2b7668753a10828c9b2e2","description":"Regenerate and change cloudinit config drive.","extra":{"proxyto":"node"},"name":"cloudinit_update","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}","VM.Config.Cloudinit"]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/cloudinit"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2f6fd50c17e15dbe4418076618bd91a94157333bd8d9ee1763d366913d0436d5","description":"Get automatically generated cloudinit config.","extra":{"proxyto":"node"},"name":"cloudinit_generated_config_dump","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Config type.","enum":["user","network","meta"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/cloudinit/dump"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a643845dbf1fa8deae10107f7cb53407a35ef0177913df56635eecebc169f015","description":"Get the virtual machine configuration with pending configuration changes applied. Set the 'current' parameter to get the current configuration instead.","extra":{"proxyto":"node"},"name":"vm_config","parameters":[{"definition":{"default":0,"description":"Get current values (instead of pending values).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"current"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Fetch config values from given snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapshot"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"description":"The VM configuration.","enum":[],"extra":{},"properties":{"acpi":{"default":1,"description":"Enable/disable ACPI.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"affinity":{"description":"List of host cores used to execute guest processes, for example: 0,5,8-11","enum":[],"extra":{},"format":"pve-cpuset","optional":true,"properties":{},"type":"string"},"agent":{"description":"Enable/disable communication with the QEMU Guest Agent and its properties.","enum":[],"extra":{},"format":{"enabled":{"default":0,"default_key":1,"description":"Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.","type":"boolean"},"freeze-fs-on-backup":{"default":1,"description":"Freeze/thaw guest filesystems on backup for consistency.","optional":1,"type":"boolean"},"fstrim_cloned_disks":{"default":0,"description":"Run fstrim after moving a disk or migrating the VM.","optional":1,"type":"boolean"},"type":{"default":"virtio","description":"Select the agent type","enum":["virtio","isa"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"arch":{"description":"Virtual processor architecture. Defaults to the host.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"args":{"description":"Arbitrary arguments passed to kvm.","enum":[],"extra":{"verbose_description":"Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -no-hpet\n\nNOTE: this option is for experts only.\n"},"optional":true,"properties":{},"type":"string"},"audio0":{"description":"Configure a audio device, useful in combination with QXL/Spice.","enum":[],"extra":{},"format":{"device":{"description":"Configure an audio device.","enum":["ich9-intel-hda","intel-hda","AC97"],"type":"string"},"driver":{"default":"spice","description":"Driver backend for the audio device.","enum":["spice","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"autostart":{"default":0,"description":"Automatic restart after crash (currently ignored).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"balloon":{"description":"Amount of target RAM for the VM in MiB. Using zero disables the ballon driver.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"bios":{"default":"seabios","description":"Select BIOS implementation.","enum":["seabios","ovmf"],"extra":{},"optional":true,"properties":{},"type":"string"},"boot":{"description":"Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.","enum":[],"extra":{},"format":"pve-qm-boot","optional":true,"properties":{},"type":"string"},"bootdisk":{"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","enum":[],"extra":{},"format":"pve-qm-bootdisk","optional":true,"pattern":"(ide|sata|scsi|virtio)\\d+","properties":{},"type":"string"},"cdrom":{"description":"This is an alias for option -ide2","enum":[],"extra":{"typetext":""},"format":"pve-qm-ide","optional":true,"properties":{},"type":"string"},"cicustom":{"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","enum":[],"extra":{},"format":"pve-qm-cicustom","optional":true,"properties":{},"type":"string"},"cipassword":{"description":"cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"citype":{"description":"Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.","enum":["configdrive2","nocloud","opennebula"],"extra":{},"optional":true,"properties":{},"type":"string"},"ciuser":{"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"cores":{"default":1,"description":"The number of cores per socket.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"cpu":{"description":"Emulated CPU type.","enum":[],"extra":{},"format":"pve-vm-cpu-conf","optional":true,"properties":{},"type":"string"},"cpulimit":{"default":0,"description":"Limit of CPU usage.","enum":[],"extra":{"verbose_description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit."},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"number"},"cpuunits":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"verbose_description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs."},"maximum":262144,"minimum":1,"optional":true,"properties":{},"type":"integer"},"description":{"description":"Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{},"max_length":8192,"optional":true,"properties":{},"type":"string"},"digest":{"description":"SHA1 digest of configuration file. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"properties":{},"type":"string"},"efidisk0":{"description":"Configure a disk for storing EFI vars.","enum":[],"extra":{},"format":{"efitype":{"default":"2m","description":"Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarc64 (ARM).","enum":["2m","4m"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"pre-enrolled-keys":{"default":0,"description":"Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.","optional":1,"type":"boolean"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"freeze":{"description":"Freeze CPU at startup (use 'c' monitor command to start execution).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"hookscript":{"description":"Script that will be executed during various steps in the vms lifetime.","enum":[],"extra":{},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"hostpci[n]":{"description":"Map host PCI devices into guest.","enum":[],"extra":{"verbose_description":"Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"format":"pve-qm-hostpci","optional":true,"properties":{},"type":"string"},"hotplug":{"default":"network,disk,usb","description":"Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.","enum":[],"extra":{},"format":"pve-hotplug-features","optional":true,"properties":{},"type":"string"},"hugepages":{"description":"Enable/disable hugepages memory.","enum":["any","2","1024"],"extra":{},"optional":true,"properties":{},"type":"string"},"ide[n]":{"description":"Use volume as IDE hard disk or CD-ROM (n is 0 to 3).","enum":[],"extra":{},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"model":{"description":"The drive's reported model name, url-encoded, up to 40 bytes long.","format":"urlencoded","format_description":"model","maxLength":120,"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"ipconfig[n]":{"description":"cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n","enum":[],"extra":{},"format":"pve-qm-ipconfig","optional":true,"properties":{},"type":"string"},"ivshmem":{"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host.","enum":[],"extra":{},"format":{"name":{"description":"The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.","format_description":"string","optional":1,"pattern":"[a-zA-Z0-9\\-]+","type":"string"},"size":{"description":"The size of the file in MB.","minimum":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"keephugepages":{"default":0,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"keyboard":{"description":"Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"kvm":{"default":1,"description":"Enable/disable KVM hardware virtualization.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"localtime":{"description":"Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"lock":{"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"],"extra":{},"optional":true,"properties":{},"type":"string"},"machine":{"description":"Specifies the QEMU machine type.","enum":[],"extra":{},"max_length":40,"optional":true,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","properties":{},"type":"string"},"memory":{"default":512,"description":"Amount of RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.","enum":[],"extra":{},"minimum":16,"optional":true,"properties":{},"type":"integer"},"migrate_downtime":{"default":0.1,"description":"Set maximum tolerated downtime (in seconds) for migrations.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"number"},"migrate_speed":{"default":0,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":{"description":"Set a name for the VM. Only used on the configuration web interface.","enum":[],"extra":{},"format":"dns-name","optional":true,"properties":{},"type":"string"},"nameserver":{"description":"cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{},"format":"address-list","optional":true,"properties":{},"type":"string"},"net[n]":{"description":"Specify network devices.","enum":[],"extra":{},"format":{"bridge":{"description":"Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n","format":"pve-bridge-id","format_description":"bridge","optional":1,"type":"string"},"e1000":{"alias":"macaddr","keyAlias":"model"},"e1000-82540em":{"alias":"macaddr","keyAlias":"model"},"e1000-82544gc":{"alias":"macaddr","keyAlias":"model"},"e1000-82545em":{"alias":"macaddr","keyAlias":"model"},"e1000e":{"alias":"macaddr","keyAlias":"model"},"firewall":{"description":"Whether this interface should be protected by the firewall.","optional":1,"type":"boolean"},"i82551":{"alias":"macaddr","keyAlias":"model"},"i82557b":{"alias":"macaddr","keyAlias":"model"},"i82559er":{"alias":"macaddr","keyAlias":"model"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"macaddr":{"description":"MAC address. That address must be unique withing your network. This is automatically generated if not specified.","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"model":{"default_key":1,"description":"Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.","enum":["e1000","e1000-82540em","e1000-82544gc","e1000-82545em","e1000e","i82551","i82557b","i82559er","ne2k_isa","ne2k_pci","pcnet","rtl8139","virtio","vmxnet3"],"type":"string"},"mtu":{"description":"Force MTU, for VirtIO only. Set to '1' to use the bridge MTU","maximum":65520,"minimum":1,"optional":1,"type":"integer"},"ne2k_isa":{"alias":"macaddr","keyAlias":"model"},"ne2k_pci":{"alias":"macaddr","keyAlias":"model"},"pcnet":{"alias":"macaddr","keyAlias":"model"},"queues":{"description":"Number of packet queues to be used on the device.","maximum":64,"minimum":0,"optional":1,"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":0,"optional":1,"type":"number"},"rtl8139":{"alias":"macaddr","keyAlias":"model"},"tag":{"description":"VLAN tag to apply to packets on this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN trunks to pass through this interface.","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"virtio":{"alias":"macaddr","keyAlias":"model"},"vmxnet3":{"alias":"macaddr","keyAlias":"model"}},"optional":true,"properties":{},"type":"string"},"numa":{"default":0,"description":"Enable/disable NUMA.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"numa[n]":{"description":"NUMA topology.","enum":[],"extra":{},"format":{"cpus":{"description":"CPUs accessing this NUMA node.","format_description":"id[-id];...","pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"hostnodes":{"description":"Host NUMA nodes to use.","format_description":"id[-id];...","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"memory":{"description":"Amount of memory this NUMA node provides.","optional":1,"type":"number"},"policy":{"description":"NUMA allocation policy.","enum":["preferred","bind","interleave"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"onboot":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ostype":{"description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","win11","l24","l26","solaris"],"extra":{"verbose_description":"Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 6.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n"},"optional":true,"properties":{},"type":"string"},"parallel[n]":{"description":"Map host parallel devices (n is 0 to 2).","enum":[],"extra":{"verbose_description":"Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"/dev/parport\\d+|/dev/usb/lp\\d+","properties":{},"type":"string"},"protection":{"default":0,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"reboot":{"default":1,"description":"Allow reboot. If set to '0' the VM exit on reboot.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"rng0":{"description":"Configure a VirtIO-based Random Number Generator.","enum":[],"extra":{},"format":{"max_bytes":{"default":1024,"description":"Maximum bytes of entropy allowed to get injected into the guest every 'period' milliseconds. Prefer a lower value when using '/dev/random' as source. Use `0` to disable limiting (potentially dangerous!).","optional":1,"type":"integer"},"period":{"default":1000,"description":"Every 'period' milliseconds the entropy-injection quota is reset, allowing the guest to retrieve another 'max_bytes' of entropy.","optional":1,"type":"integer"},"source":{"default_key":1,"description":"The file on the host to gather entropy from. In most cases '/dev/urandom' should be preferred over '/dev/random' to avoid entropy-starvation issues on the host. Using urandom does *not* decrease security in any meaningful way, as it's still seeded from real entropy, and the bytes provided will most likely be mixed with real entropy on the guest as well. '/dev/hwrng' can be used to pass through a hardware RNG from the host.","enum":["/dev/urandom","/dev/random","/dev/hwrng"],"type":"string"}},"optional":true,"properties":{},"type":"string"},"sata[n]":{"description":"Use volume as SATA hard disk or CD-ROM (n is 0 to 5).","enum":[],"extra":{},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"scsi[n]":{"description":"Use volume as SCSI hard disk or CD-ROM (n is 0 to 30).","enum":[],"extra":{},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"queues":{"description":"Number of queues.","minimum":2,"optional":1,"type":"integer"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"scsiblock":{"default":0,"description":"whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"scsihw":{"default":"lsi","description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"extra":{},"optional":true,"properties":{},"type":"string"},"searchdomain":{"description":"cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial[n]":{"description":"Create a serial device inside the VM (n is 0 to 3)","enum":[],"extra":{"verbose_description":"Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"(/dev/.+|socket)","properties":{},"type":"string"},"shares":{"default":1000,"description":"Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.","enum":[],"extra":{},"maximum":50000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"smbios1":{"description":"Specify SMBIOS type 1 fields.","enum":[],"extra":{},"format":"pve-qm-smbios1","max_length":512,"optional":true,"properties":{},"type":"string"},"smp":{"default":1,"description":"The number of CPUs. Please use option -sockets instead.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"sockets":{"default":1,"description":"The number of CPU sockets.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"spice_enhancements":{"description":"Configure additional enhancements for SPICE.","enum":[],"extra":{},"format":{"foldersharing":{"default":"0","description":"Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.","optional":1,"type":"boolean"},"videostreaming":{"default":"off","description":"Enable video streaming. Uses compression for detected video streams.","enum":["off","all","filter"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"sshkeys":{"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{},"format":"urlencoded","optional":true,"properties":{},"type":"string"},"startdate":{"default":"now","description":"Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.","enum":[],"extra":{"typetext":"(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)"},"optional":true,"pattern":"(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)","properties":{},"type":"string"},"startup":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"tablet":{"default":1,"description":"Enable/disable the USB tablet device.","enum":[],"extra":{"verbose_description":"Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)."},"optional":true,"properties":{},"type":"boolean"},"tags":{"description":"Tags of the VM. This is only meta information.","enum":[],"extra":{},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"tdf":{"default":0,"description":"Enable/disable time drift fix.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"template":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"tpmstate0":{"description":"Configure a Disk for storing TPM state. The format is fixed to 'raw'.","enum":[],"extra":{},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"version":{"default":"v2.0","description":"The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.","enum":["v1.2","v2.0"],"optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"unused[n]":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id","format_description":"volume","type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"usb[n]":{"description":"Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).","enum":[],"extra":{},"format":{"host":{"default_key":1,"description":"The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadeciaml numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n","format":"pve-qm-usb-device","format_description":"HOSTUSBDEVICE|spice","type":"string"},"usb3":{"default":0,"description":"Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"vcpus":{"default":0,"description":"Number of hotplugged vcpus.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"vga":{"description":"Configure the VGA hardware.","enum":[],"extra":{"verbose_description":"Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal."},"format":{"memory":{"description":"Sets the VGA memory (in MiB). Has no effect with serial display.","maximum":512,"minimum":4,"optional":1,"type":"integer"},"type":{"default":"std","default_key":1,"description":"Select the VGA type.","enum":["cirrus","qxl","qxl2","qxl3","qxl4","none","serial0","serial1","serial2","serial3","std","virtio","virtio-gl","vmware"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"virtio[n]":{"description":"Use volume as VIRTIO hard disk (n is 0 to 15).","enum":[],"extra":{},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"vmgenid":{"default":"1 (autogenerated)","description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","enum":[],"extra":{"format_description":"UUID","verbose_description":"The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file."},"optional":true,"pattern":"(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])","properties":{},"type":"string"},"vmstatestorage":{"description":"Default storage for VM state volumes/files.","enum":[],"extra":{},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"watchdog":{"description":"Create a virtual hardware watchdog device.","enum":[],"extra":{"verbose_description":"Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)"},"format":"pve-qm-watchdog","optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"fffa8581cefca57fccf20ecf2c1a4f082aea0d614f30a797daaf2b05ab9ec246","description":"Set virtual machine options (asynchrounous API).","extra":{"proxyto":"node"},"name":"update_vm_async","parameters":[{"definition":{"default":1,"description":"Enable/disable ACPI.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"acpi"},{"definition":{"description":"List of host cores used to execute guest processes, for example: 0,5,8-11","enum":[],"extra":{"typetext":""},"format":"pve-cpuset","optional":true,"properties":{},"type":"string"},"name":"affinity"},{"definition":{"description":"Enable/disable communication with the QEMU Guest Agent and its properties.","enum":[],"extra":{"typetext":"[enabled=]<1|0> [,freeze-fs-on-backup=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]"},"format":{"enabled":{"default":0,"default_key":1,"description":"Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.","type":"boolean"},"freeze-fs-on-backup":{"default":1,"description":"Freeze/thaw guest filesystems on backup for consistency.","optional":1,"type":"boolean"},"fstrim_cloned_disks":{"default":0,"description":"Run fstrim after moving a disk or migrating the VM.","optional":1,"type":"boolean"},"type":{"default":"virtio","description":"Select the agent type","enum":["virtio","isa"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"agent"},{"definition":{"description":"Virtual processor architecture. Defaults to the host.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"description":"Arbitrary arguments passed to kvm.","enum":[],"extra":{"typetext":"","verbose_description":"Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -no-hpet\n\nNOTE: this option is for experts only.\n"},"optional":true,"properties":{},"type":"string"},"name":"args"},{"definition":{"description":"Configure a audio device, useful in combination with QXL/Spice.","enum":[],"extra":{"typetext":"device= [,driver=]"},"format":{"device":{"description":"Configure an audio device.","enum":["ich9-intel-hda","intel-hda","AC97"],"type":"string"},"driver":{"default":"spice","description":"Driver backend for the audio device.","enum":["spice","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"audio0"},{"definition":{"default":0,"description":"Automatic restart after crash (currently ignored).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Time to wait for the task to finish. We return 'null' if the task finish within that time.","enum":[],"extra":{"typetext":" (1 - 30)"},"maximum":30,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"background_delay"},{"definition":{"description":"Amount of target RAM for the VM in MiB. Using zero disables the ballon driver.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"balloon"},{"definition":{"default":"seabios","description":"Select BIOS implementation.","enum":["seabios","ovmf"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bios"},{"definition":{"description":"Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.","enum":[],"extra":{"typetext":"[[legacy=]<[acdn]{1,4}>] [,order=]"},"format":"pve-qm-boot","optional":true,"properties":{},"type":"string"},"name":"boot"},{"definition":{"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","enum":[],"extra":{},"format":"pve-qm-bootdisk","optional":true,"pattern":"(ide|sata|scsi|virtio)\\d+","properties":{},"type":"string"},"name":"bootdisk"},{"definition":{"description":"This is an alias for option -ide2","enum":[],"extra":{"typetext":""},"format":"pve-qm-ide","optional":true,"properties":{},"type":"string"},"name":"cdrom"},{"definition":{"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","enum":[],"extra":{"typetext":"[meta=] [,network=] [,user=] [,vendor=]"},"format":"pve-qm-cicustom","optional":true,"properties":{},"type":"string"},"name":"cicustom"},{"definition":{"description":"cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cipassword"},{"definition":{"description":"Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.","enum":["configdrive2","nocloud","opennebula"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"citype"},{"definition":{"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ciuser"},{"definition":{"default":1,"description":"The number of cores per socket.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"description":"Emulated CPU type.","enum":[],"extra":{"typetext":"[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]"},"format":"pve-vm-cpu-conf","optional":true,"properties":{},"type":"string"},"name":"cpu"},{"definition":{"default":0,"description":"Limit of CPU usage.","enum":[],"extra":{"typetext":" (0 - 128)","verbose_description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit."},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"typetext":" (1 - 262144)","verbose_description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs."},"maximum":262144,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":8192,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,pre-enrolled-keys=<1|0>] [,size=]"},"format":{"efitype":{"default":"2m","description":"Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarc64 (ARM).","enum":["2m","4m"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"pre-enrolled-keys":{"default":0,"description":"Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.","optional":1,"type":"boolean"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"efidisk0"},{"definition":{"description":"Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.","enum":[],"extra":{"requires":"delete","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Freeze CPU at startup (use 'c' monitor command to start execution).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"freeze"},{"definition":{"description":"Script that will be executed during various steps in the vms lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Map host PCI devices into guest.","enum":[],"extra":{"typetext":"[host=] [,device-id=] [,legacy-igd=<1|0>] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]","verbose_description":"Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"format":"pve-qm-hostpci","optional":true,"properties":{},"type":"string"},"name":"hostpci[n]"},{"definition":{"default":"network,disk,usb","description":"Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.","enum":[],"extra":{"typetext":""},"format":"pve-hotplug-features","optional":true,"properties":{},"type":"string"},"name":"hotplug"},{"definition":{"description":"Enable/disable hugepages memory.","enum":["any","2","1024"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"hugepages"},{"definition":{"description":"Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"model":{"description":"The drive's reported model name, url-encoded, up to 40 bytes long.","format":"urlencoded","format_description":"model","maxLength":120,"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"ide[n]"},{"definition":{"description":"cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n","enum":[],"extra":{"typetext":"[gw=] [,gw6=] [,ip=] [,ip6=]"},"format":"pve-qm-ipconfig","optional":true,"properties":{},"type":"string"},"name":"ipconfig[n]"},{"definition":{"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host.","enum":[],"extra":{"typetext":"size= [,name=]"},"format":{"name":{"description":"The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.","format_description":"string","optional":1,"pattern":"[a-zA-Z0-9\\-]+","type":"string"},"size":{"description":"The size of the file in MB.","minimum":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"ivshmem"},{"definition":{"default":0,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keephugepages"},{"definition":{"description":"Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"keyboard"},{"definition":{"default":1,"description":"Enable/disable KVM hardware virtualization.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"kvm"},{"definition":{"description":"Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"localtime"},{"definition":{"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"description":"Specifies the QEMU machine type.","enum":[],"extra":{},"max_length":40,"optional":true,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","properties":{},"type":"string"},"name":"machine"},{"definition":{"default":512,"description":"Amount of RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.","enum":[],"extra":{"typetext":" (16 - N)"},"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"memory"},{"definition":{"default":0.1,"description":"Set maximum tolerated downtime (in seconds) for migrations.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"migrate_downtime"},{"definition":{"default":0,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"migrate_speed"},{"definition":{"description":"Set a name for the VM. Only used on the configuration web interface.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"format":"address-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specify network devices.","enum":[],"extra":{"typetext":"[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]"},"format":{"bridge":{"description":"Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n","format":"pve-bridge-id","format_description":"bridge","optional":1,"type":"string"},"e1000":{"alias":"macaddr","keyAlias":"model"},"e1000-82540em":{"alias":"macaddr","keyAlias":"model"},"e1000-82544gc":{"alias":"macaddr","keyAlias":"model"},"e1000-82545em":{"alias":"macaddr","keyAlias":"model"},"e1000e":{"alias":"macaddr","keyAlias":"model"},"firewall":{"description":"Whether this interface should be protected by the firewall.","optional":1,"type":"boolean"},"i82551":{"alias":"macaddr","keyAlias":"model"},"i82557b":{"alias":"macaddr","keyAlias":"model"},"i82559er":{"alias":"macaddr","keyAlias":"model"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"macaddr":{"description":"MAC address. That address must be unique withing your network. This is automatically generated if not specified.","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"model":{"default_key":1,"description":"Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.","enum":["e1000","e1000-82540em","e1000-82544gc","e1000-82545em","e1000e","i82551","i82557b","i82559er","ne2k_isa","ne2k_pci","pcnet","rtl8139","virtio","vmxnet3"],"type":"string"},"mtu":{"description":"Force MTU, for VirtIO only. Set to '1' to use the bridge MTU","maximum":65520,"minimum":1,"optional":1,"type":"integer"},"ne2k_isa":{"alias":"macaddr","keyAlias":"model"},"ne2k_pci":{"alias":"macaddr","keyAlias":"model"},"pcnet":{"alias":"macaddr","keyAlias":"model"},"queues":{"description":"Number of packet queues to be used on the device.","maximum":64,"minimum":0,"optional":1,"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":0,"optional":1,"type":"number"},"rtl8139":{"alias":"macaddr","keyAlias":"model"},"tag":{"description":"VLAN tag to apply to packets on this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN trunks to pass through this interface.","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"virtio":{"alias":"macaddr","keyAlias":"model"},"vmxnet3":{"alias":"macaddr","keyAlias":"model"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Enable/disable NUMA.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"numa"},{"definition":{"description":"NUMA topology.","enum":[],"extra":{"typetext":"cpus= [,hostnodes=] [,memory=] [,policy=]"},"format":{"cpus":{"description":"CPUs accessing this NUMA node.","format_description":"id[-id];...","pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"hostnodes":{"description":"Host NUMA nodes to use.","format_description":"id[-id];...","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"memory":{"description":"Amount of memory this NUMA node provides.","optional":1,"type":"number"},"policy":{"description":"NUMA allocation policy.","enum":["preferred","bind","interleave"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"numa[n]"},{"definition":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","win11","l24","l26","solaris"],"extra":{"verbose_description":"Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 6.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n"},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"description":"Map host parallel devices (n is 0 to 2).","enum":[],"extra":{"verbose_description":"Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"/dev/parport\\d+|/dev/usb/lp\\d+","properties":{},"type":"string"},"name":"parallel[n]"},{"definition":{"default":0,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"default":1,"description":"Allow reboot. If set to '0' the VM exit on reboot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"reboot"},{"definition":{"description":"Revert a pending change.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"revert"},{"definition":{"description":"Configure a VirtIO-based Random Number Generator.","enum":[],"extra":{"typetext":"[source=] [,max_bytes=] [,period=]"},"format":{"max_bytes":{"default":1024,"description":"Maximum bytes of entropy allowed to get injected into the guest every 'period' milliseconds. Prefer a lower value when using '/dev/random' as source. Use `0` to disable limiting (potentially dangerous!).","optional":1,"type":"integer"},"period":{"default":1000,"description":"Every 'period' milliseconds the entropy-injection quota is reset, allowing the guest to retrieve another 'max_bytes' of entropy.","optional":1,"type":"integer"},"source":{"default_key":1,"description":"The file on the host to gather entropy from. In most cases '/dev/urandom' should be preferred over '/dev/random' to avoid entropy-starvation issues on the host. Using urandom does *not* decrease security in any meaningful way, as it's still seeded from real entropy, and the bytes provided will most likely be mixed with real entropy on the guest as well. '/dev/hwrng' can be used to pass through a hardware RNG from the host.","enum":["/dev/urandom","/dev/random","/dev/hwrng"],"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"rng0"},{"definition":{"description":"Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"sata[n]"},{"definition":{"description":"Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"queues":{"description":"Number of queues.","minimum":2,"optional":1,"type":"integer"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"scsiblock":{"default":0,"description":"whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"scsi[n]"},{"definition":{"default":"lsi","description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scsihw"},{"definition":{"description":"cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Create a serial device inside the VM (n is 0 to 3)","enum":[],"extra":{"verbose_description":"Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"(/dev/.+|socket)","properties":{},"type":"string"},"name":"serial[n]"},{"definition":{"default":1000,"description":"Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.","enum":[],"extra":{"typetext":" (0 - 50000)"},"maximum":50000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"shares"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Specify SMBIOS type 1 fields.","enum":[],"extra":{"typetext":"[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]"},"format":"pve-qm-smbios1","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"smbios1"},{"definition":{"default":1,"description":"The number of CPUs. Please use option -sockets instead.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"smp"},{"definition":{"default":1,"description":"The number of CPU sockets.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"sockets"},{"definition":{"description":"Configure additional enhancements for SPICE.","enum":[],"extra":{"typetext":"[foldersharing=<1|0>] [,videostreaming=]"},"format":{"foldersharing":{"default":"0","description":"Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.","optional":1,"type":"boolean"},"videostreaming":{"default":"off","description":"Enable video streaming. Uses compression for detected video streams.","enum":["off","all","filter"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"spice_enhancements"},{"definition":{"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{"typetext":""},"format":"urlencoded","optional":true,"properties":{},"type":"string"},"name":"sshkeys"},{"definition":{"default":"now","description":"Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.","enum":[],"extra":{"typetext":"(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)"},"optional":true,"pattern":"(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)","properties":{},"type":"string"},"name":"startdate"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"default":1,"description":"Enable/disable the USB tablet device.","enum":[],"extra":{"typetext":"","verbose_description":"Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)."},"optional":true,"properties":{},"type":"boolean"},"name":"tablet"},{"definition":{"description":"Tags of the VM. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable time drift fix.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tdf"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,import-from=] [,size=] [,version=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"version":{"default":"v2.0","description":"The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.","enum":["v1.2","v2.0"],"optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"tpmstate0"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[file=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id","format_description":"volume","type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).","enum":[],"extra":{"typetext":"[host=] [,usb3=<1|0>]"},"format":{"host":{"default_key":1,"description":"The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadeciaml numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n","format":"pve-qm-usb-device","format_description":"HOSTUSBDEVICE|spice","type":"string"},"usb3":{"default":0,"description":"Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"usb[n]"},{"definition":{"default":0,"description":"Number of hotplugged vcpus.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vcpus"},{"definition":{"description":"Configure the VGA hardware.","enum":[],"extra":{"typetext":"[[type=]] [,memory=]","verbose_description":"Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal."},"format":{"memory":{"description":"Sets the VGA memory (in MiB). Has no effect with serial display.","maximum":512,"minimum":4,"optional":1,"type":"integer"},"type":{"default":"std","default_key":1,"description":"Select the VGA type.","enum":["cirrus","qxl","qxl2","qxl3","qxl4","none","serial0","serial1","serial2","serial3","std","virtio","virtio-gl","vmware"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"vga"},{"definition":{"description":"Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"virtio[n]"},{"definition":{"default":"1 (autogenerated)","description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","enum":[],"extra":{"format_description":"UUID","verbose_description":"The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file."},"optional":true,"pattern":"(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])","properties":{},"type":"string"},"name":"vmgenid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Default storage for VM state volumes/files.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"vmstatestorage"},{"definition":{"description":"Create a virtual hardware watchdog device.","enum":[],"extra":{"typetext":"[[model=]] [,action=]","verbose_description":"Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)"},"format":"pve-qm-watchdog","optional":true,"properties":{},"type":"string"},"name":"watchdog"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk","VM.Config.CDROM","VM.Config.CPU","VM.Config.Memory","VM.Config.Network","VM.Config.HWType","VM.Config.Options","VM.Config.Cloudinit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"verb":"POST"},{"allow_token":true,"checksum":"cc3364d1fdae7db1baabbd5edf74c743563b0caa18d22941a6b44cb4624a117b","description":"Set virtual machine options (synchrounous API) - You should consider using the POST method instead for any actions involving hotplug or storage allocation.","extra":{"proxyto":"node"},"name":"update_vm","parameters":[{"definition":{"default":1,"description":"Enable/disable ACPI.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"acpi"},{"definition":{"description":"List of host cores used to execute guest processes, for example: 0,5,8-11","enum":[],"extra":{"typetext":""},"format":"pve-cpuset","optional":true,"properties":{},"type":"string"},"name":"affinity"},{"definition":{"description":"Enable/disable communication with the QEMU Guest Agent and its properties.","enum":[],"extra":{"typetext":"[enabled=]<1|0> [,freeze-fs-on-backup=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]"},"format":{"enabled":{"default":0,"default_key":1,"description":"Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.","type":"boolean"},"freeze-fs-on-backup":{"default":1,"description":"Freeze/thaw guest filesystems on backup for consistency.","optional":1,"type":"boolean"},"fstrim_cloned_disks":{"default":0,"description":"Run fstrim after moving a disk or migrating the VM.","optional":1,"type":"boolean"},"type":{"default":"virtio","description":"Select the agent type","enum":["virtio","isa"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"agent"},{"definition":{"description":"Virtual processor architecture. Defaults to the host.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"description":"Arbitrary arguments passed to kvm.","enum":[],"extra":{"typetext":"","verbose_description":"Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -no-hpet\n\nNOTE: this option is for experts only.\n"},"optional":true,"properties":{},"type":"string"},"name":"args"},{"definition":{"description":"Configure a audio device, useful in combination with QXL/Spice.","enum":[],"extra":{"typetext":"device= [,driver=]"},"format":{"device":{"description":"Configure an audio device.","enum":["ich9-intel-hda","intel-hda","AC97"],"type":"string"},"driver":{"default":"spice","description":"Driver backend for the audio device.","enum":["spice","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"audio0"},{"definition":{"default":0,"description":"Automatic restart after crash (currently ignored).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Amount of target RAM for the VM in MiB. Using zero disables the ballon driver.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"balloon"},{"definition":{"default":"seabios","description":"Select BIOS implementation.","enum":["seabios","ovmf"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bios"},{"definition":{"description":"Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.","enum":[],"extra":{"typetext":"[[legacy=]<[acdn]{1,4}>] [,order=]"},"format":"pve-qm-boot","optional":true,"properties":{},"type":"string"},"name":"boot"},{"definition":{"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","enum":[],"extra":{},"format":"pve-qm-bootdisk","optional":true,"pattern":"(ide|sata|scsi|virtio)\\d+","properties":{},"type":"string"},"name":"bootdisk"},{"definition":{"description":"This is an alias for option -ide2","enum":[],"extra":{"typetext":""},"format":"pve-qm-ide","optional":true,"properties":{},"type":"string"},"name":"cdrom"},{"definition":{"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","enum":[],"extra":{"typetext":"[meta=] [,network=] [,user=] [,vendor=]"},"format":"pve-qm-cicustom","optional":true,"properties":{},"type":"string"},"name":"cicustom"},{"definition":{"description":"cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cipassword"},{"definition":{"description":"Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.","enum":["configdrive2","nocloud","opennebula"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"citype"},{"definition":{"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ciuser"},{"definition":{"default":1,"description":"The number of cores per socket.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"description":"Emulated CPU type.","enum":[],"extra":{"typetext":"[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]"},"format":"pve-vm-cpu-conf","optional":true,"properties":{},"type":"string"},"name":"cpu"},{"definition":{"default":0,"description":"Limit of CPU usage.","enum":[],"extra":{"typetext":" (0 - 128)","verbose_description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit."},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"typetext":" (1 - 262144)","verbose_description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs."},"maximum":262144,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":8192,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,pre-enrolled-keys=<1|0>] [,size=]"},"format":{"efitype":{"default":"2m","description":"Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarc64 (ARM).","enum":["2m","4m"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"pre-enrolled-keys":{"default":0,"description":"Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.","optional":1,"type":"boolean"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"efidisk0"},{"definition":{"description":"Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.","enum":[],"extra":{"requires":"delete","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Freeze CPU at startup (use 'c' monitor command to start execution).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"freeze"},{"definition":{"description":"Script that will be executed during various steps in the vms lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Map host PCI devices into guest.","enum":[],"extra":{"typetext":"[host=] [,device-id=] [,legacy-igd=<1|0>] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]","verbose_description":"Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"format":"pve-qm-hostpci","optional":true,"properties":{},"type":"string"},"name":"hostpci[n]"},{"definition":{"default":"network,disk,usb","description":"Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.","enum":[],"extra":{"typetext":""},"format":"pve-hotplug-features","optional":true,"properties":{},"type":"string"},"name":"hotplug"},{"definition":{"description":"Enable/disable hugepages memory.","enum":["any","2","1024"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"hugepages"},{"definition":{"description":"Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"model":{"description":"The drive's reported model name, url-encoded, up to 40 bytes long.","format":"urlencoded","format_description":"model","maxLength":120,"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"ide[n]"},{"definition":{"description":"cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n","enum":[],"extra":{"typetext":"[gw=] [,gw6=] [,ip=] [,ip6=]"},"format":"pve-qm-ipconfig","optional":true,"properties":{},"type":"string"},"name":"ipconfig[n]"},{"definition":{"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host.","enum":[],"extra":{"typetext":"size= [,name=]"},"format":{"name":{"description":"The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.","format_description":"string","optional":1,"pattern":"[a-zA-Z0-9\\-]+","type":"string"},"size":{"description":"The size of the file in MB.","minimum":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"ivshmem"},{"definition":{"default":0,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keephugepages"},{"definition":{"description":"Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"keyboard"},{"definition":{"default":1,"description":"Enable/disable KVM hardware virtualization.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"kvm"},{"definition":{"description":"Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"localtime"},{"definition":{"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"description":"Specifies the QEMU machine type.","enum":[],"extra":{},"max_length":40,"optional":true,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","properties":{},"type":"string"},"name":"machine"},{"definition":{"default":512,"description":"Amount of RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.","enum":[],"extra":{"typetext":" (16 - N)"},"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"memory"},{"definition":{"default":0.1,"description":"Set maximum tolerated downtime (in seconds) for migrations.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"migrate_downtime"},{"definition":{"default":0,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"migrate_speed"},{"definition":{"description":"Set a name for the VM. Only used on the configuration web interface.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"format":"address-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specify network devices.","enum":[],"extra":{"typetext":"[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]"},"format":{"bridge":{"description":"Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n","format":"pve-bridge-id","format_description":"bridge","optional":1,"type":"string"},"e1000":{"alias":"macaddr","keyAlias":"model"},"e1000-82540em":{"alias":"macaddr","keyAlias":"model"},"e1000-82544gc":{"alias":"macaddr","keyAlias":"model"},"e1000-82545em":{"alias":"macaddr","keyAlias":"model"},"e1000e":{"alias":"macaddr","keyAlias":"model"},"firewall":{"description":"Whether this interface should be protected by the firewall.","optional":1,"type":"boolean"},"i82551":{"alias":"macaddr","keyAlias":"model"},"i82557b":{"alias":"macaddr","keyAlias":"model"},"i82559er":{"alias":"macaddr","keyAlias":"model"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"macaddr":{"description":"MAC address. That address must be unique withing your network. This is automatically generated if not specified.","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"model":{"default_key":1,"description":"Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.","enum":["e1000","e1000-82540em","e1000-82544gc","e1000-82545em","e1000e","i82551","i82557b","i82559er","ne2k_isa","ne2k_pci","pcnet","rtl8139","virtio","vmxnet3"],"type":"string"},"mtu":{"description":"Force MTU, for VirtIO only. Set to '1' to use the bridge MTU","maximum":65520,"minimum":1,"optional":1,"type":"integer"},"ne2k_isa":{"alias":"macaddr","keyAlias":"model"},"ne2k_pci":{"alias":"macaddr","keyAlias":"model"},"pcnet":{"alias":"macaddr","keyAlias":"model"},"queues":{"description":"Number of packet queues to be used on the device.","maximum":64,"minimum":0,"optional":1,"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":0,"optional":1,"type":"number"},"rtl8139":{"alias":"macaddr","keyAlias":"model"},"tag":{"description":"VLAN tag to apply to packets on this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN trunks to pass through this interface.","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"virtio":{"alias":"macaddr","keyAlias":"model"},"vmxnet3":{"alias":"macaddr","keyAlias":"model"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Enable/disable NUMA.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"numa"},{"definition":{"description":"NUMA topology.","enum":[],"extra":{"typetext":"cpus= [,hostnodes=] [,memory=] [,policy=]"},"format":{"cpus":{"description":"CPUs accessing this NUMA node.","format_description":"id[-id];...","pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"hostnodes":{"description":"Host NUMA nodes to use.","format_description":"id[-id];...","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"memory":{"description":"Amount of memory this NUMA node provides.","optional":1,"type":"number"},"policy":{"description":"NUMA allocation policy.","enum":["preferred","bind","interleave"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"numa[n]"},{"definition":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","win11","l24","l26","solaris"],"extra":{"verbose_description":"Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 6.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n"},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"description":"Map host parallel devices (n is 0 to 2).","enum":[],"extra":{"verbose_description":"Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"/dev/parport\\d+|/dev/usb/lp\\d+","properties":{},"type":"string"},"name":"parallel[n]"},{"definition":{"default":0,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"default":1,"description":"Allow reboot. If set to '0' the VM exit on reboot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"reboot"},{"definition":{"description":"Revert a pending change.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"revert"},{"definition":{"description":"Configure a VirtIO-based Random Number Generator.","enum":[],"extra":{"typetext":"[source=] [,max_bytes=] [,period=]"},"format":{"max_bytes":{"default":1024,"description":"Maximum bytes of entropy allowed to get injected into the guest every 'period' milliseconds. Prefer a lower value when using '/dev/random' as source. Use `0` to disable limiting (potentially dangerous!).","optional":1,"type":"integer"},"period":{"default":1000,"description":"Every 'period' milliseconds the entropy-injection quota is reset, allowing the guest to retrieve another 'max_bytes' of entropy.","optional":1,"type":"integer"},"source":{"default_key":1,"description":"The file on the host to gather entropy from. In most cases '/dev/urandom' should be preferred over '/dev/random' to avoid entropy-starvation issues on the host. Using urandom does *not* decrease security in any meaningful way, as it's still seeded from real entropy, and the bytes provided will most likely be mixed with real entropy on the guest as well. '/dev/hwrng' can be used to pass through a hardware RNG from the host.","enum":["/dev/urandom","/dev/random","/dev/hwrng"],"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"rng0"},{"definition":{"description":"Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"sata[n]"},{"definition":{"description":"Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"queues":{"description":"Number of queues.","minimum":2,"optional":1,"type":"integer"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"scsiblock":{"default":0,"description":"whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"scsi[n]"},{"definition":{"default":"lsi","description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scsihw"},{"definition":{"description":"cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Create a serial device inside the VM (n is 0 to 3)","enum":[],"extra":{"verbose_description":"Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"(/dev/.+|socket)","properties":{},"type":"string"},"name":"serial[n]"},{"definition":{"default":1000,"description":"Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.","enum":[],"extra":{"typetext":" (0 - 50000)"},"maximum":50000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"shares"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Specify SMBIOS type 1 fields.","enum":[],"extra":{"typetext":"[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]"},"format":"pve-qm-smbios1","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"smbios1"},{"definition":{"default":1,"description":"The number of CPUs. Please use option -sockets instead.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"smp"},{"definition":{"default":1,"description":"The number of CPU sockets.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"sockets"},{"definition":{"description":"Configure additional enhancements for SPICE.","enum":[],"extra":{"typetext":"[foldersharing=<1|0>] [,videostreaming=]"},"format":{"foldersharing":{"default":"0","description":"Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.","optional":1,"type":"boolean"},"videostreaming":{"default":"off","description":"Enable video streaming. Uses compression for detected video streams.","enum":["off","all","filter"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"spice_enhancements"},{"definition":{"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{"typetext":""},"format":"urlencoded","optional":true,"properties":{},"type":"string"},"name":"sshkeys"},{"definition":{"default":"now","description":"Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.","enum":[],"extra":{"typetext":"(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)"},"optional":true,"pattern":"(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)","properties":{},"type":"string"},"name":"startdate"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"default":1,"description":"Enable/disable the USB tablet device.","enum":[],"extra":{"typetext":"","verbose_description":"Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)."},"optional":true,"properties":{},"type":"boolean"},"name":"tablet"},{"definition":{"description":"Tags of the VM. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable time drift fix.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tdf"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,import-from=] [,size=] [,version=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"version":{"default":"v2.0","description":"The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.","enum":["v1.2","v2.0"],"optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"tpmstate0"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[file=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id","format_description":"volume","type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).","enum":[],"extra":{"typetext":"[host=] [,usb3=<1|0>]"},"format":{"host":{"default_key":1,"description":"The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadeciaml numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n","format":"pve-qm-usb-device","format_description":"HOSTUSBDEVICE|spice","type":"string"},"usb3":{"default":0,"description":"Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"usb[n]"},{"definition":{"default":0,"description":"Number of hotplugged vcpus.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vcpus"},{"definition":{"description":"Configure the VGA hardware.","enum":[],"extra":{"typetext":"[[type=]] [,memory=]","verbose_description":"Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal."},"format":{"memory":{"description":"Sets the VGA memory (in MiB). Has no effect with serial display.","maximum":512,"minimum":4,"optional":1,"type":"integer"},"type":{"default":"std","default_key":1,"description":"Select the VGA type.","enum":["cirrus","qxl","qxl2","qxl3","qxl4","none","serial0","serial1","serial2","serial3","std","virtio","virtio-gl","vmware"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"vga"},{"definition":{"description":"Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"virtio[n]"},{"definition":{"default":"1 (autogenerated)","description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","enum":[],"extra":{"format_description":"UUID","verbose_description":"The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file."},"optional":true,"pattern":"(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])","properties":{},"type":"string"},"name":"vmgenid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Default storage for VM state volumes/files.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"vmstatestorage"},{"definition":{"description":"Create a virtual hardware watchdog device.","enum":[],"extra":{"typetext":"[[model=]] [,action=]","verbose_description":"Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)"},"format":"pve-qm-watchdog","optional":true,"properties":{},"type":"string"},"name":"watchdog"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk","VM.Config.CDROM","VM.Config.CPU","VM.Config.Memory","VM.Config.Network","VM.Config.HWType","VM.Config.Options","VM.Config.Cloudinit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"cb23b43448aac18a116b878c559fe74daad5016f705d56baedea038aabac5c1e","description":"Check if feature for virtual machine is available.","extra":{"proxyto":"node"},"name":"vm_feature","parameters":[{"definition":{"description":"Feature to check.","enum":["snapshot","clone","copy"],"extra":{},"properties":{},"type":"string"},"name":"feature"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"hasFeature":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"nodes":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/feature"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5bb143c67c66cf5b8450a21b7962a9429555249c9a169a229e7745f9d8304495","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f3ade8db07d7e168cf2c244f2327d3845c4d148a021436cde1e65f01fcc58db7","description":"List aliases","extra":{},"name":"get_aliases","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"0d804bcfd2565a8543511d9fd83e3425760031b592c1d1e50326d6725d38c139","description":"Create IP or Network Alias.","extra":{},"name":"create_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/aliases"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5920ae6968407878a5b9eb64bd68e522549bb7009cd3895d915d8adbe17e161d","description":"Remove IP or Network alias.","extra":{},"name":"remove_alias","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"1858b8e7f12863024af22797024f75a6fdf6cda0c224f6a4ce9815d3a4cb483b","description":"Read alias.","extra":{},"name":"read_alias","parameters":[{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"7e9b6195d2cd189f3b1fa52dc54fb8369c0324de89694c2614fdb3e30409670f","description":"Update IP or Network alias.","extra":{},"name":"update_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Rename an existing alias.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"72f4e0abfc4fc1fc45cf29ac6cf40bb3810b4463327824ba821b6bd63d1ebc30","description":"List IPSets","extra":{},"name":"ipset_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"name":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"ca3a7645ec2c6c377c1ae0dfb99c5feec2ef5e9bf3aa743b44670f851374983b","description":"Create new IPSet","extra":{},"name":"create_ipset","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/ipset"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dc4ac4abdba8f718fb26da69b42d836063c338aa7d709b68db6e0d8cb1bebda7","description":"Delete IPSet","extra":{},"name":"delete_ipset","parameters":[{"definition":{"description":"Delete all members of the IPSet, if there are any.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"c14d95b34b1dcc471da836cadc0ac6dbc2b2fc74105df7ff98f5cfc6b133644d","description":"List IPSet content","extra":{},"name":"get_ipset","parameters":[{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cidr}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"nomatch":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"e9612cc0bf355acd89e38d888ee4f89a951948c0840cb620e55d6b7bfc2cfad7","description":"Add IP or Network to IPSet.","extra":{},"name":"create_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"17a70102f27b6d30ea52149ee3614d9b300342b77b66edfeccf9f0c6662ab255","description":"Remove IP or Network from IPSet.","extra":{},"name":"remove_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"a4e0753e2fa85678d8a8d5b232c4403e3ec801c1beb4fd8f537802b987df83a4","description":"Read IP or Network settings from IPSet.","extra":{},"name":"read_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"e033d28015b80e8073780c388cbec51e67f613039684b31d4e9a10aa02c1db33","description":"Update IP or Network settings","extra":{},"name":"update_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5fc42cab2dbf26a9e3bbde213139e3f5b4c46b1dabb3d101cc5fa06bfcc760b9","description":"Read firewall log","extra":{"proxyto":"node"},"name":"log","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Display log since this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"since"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"Display log until this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"until"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a8aae893a1eea32c7368a145bac302634ad742b680ce50f656b02b75a41fc5d3","description":"Get VM firewall options.","extra":{"proxyto":"node"},"name":"get_options","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"dhcp":{"default":0,"description":"Enable DHCP.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"enable":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ipfilter":{"description":"Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"log_level_in":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_level_out":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macfilter":{"default":1,"description":"Enable/disable MAC address filter.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ndp":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"policy_in":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"policy_out":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"radv":{"description":"Allow sending Router Advertisement.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"07114b02e0de67e410a7a6664ac411239cd2bd830835a78f93b826c8c6defb6e","description":"Set Firewall options.","extra":{"proxyto":"node"},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"default":0,"description":"Enable DHCP.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"dhcp"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ipfilter"},{"definition":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_in"},{"definition":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_out"},{"definition":{"default":1,"description":"Enable/disable MAC address filter.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"macfilter"},{"definition":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ndp"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_in"},{"definition":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_out"},{"definition":{"description":"Allow sending Router Advertisement.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"radv"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"37d9588c916a6008f684c9911b05557c57a0334b032dc6feadc90bdffbddf35a","description":"Lists possible IPSet/Alias reference which are allowed in source/dest properties.","extra":{},"name":"refs","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list references of specified type.","enum":["alias","ipset"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":["alias","ipset"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/refs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9aca6c2421abc582ee1474baf7a4e1986ba3cc546ff95ffe612bbe4a7806ac0e","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"75ede4f1c7a73875c879ec0593cdd560c143667747ade3b33132b57fd5de4ba8","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dad1a485162cfc3b459d6d3cb052c9be411bfd535ad8eec7eb1567ad899d3a47","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"74b69d51de0371ce4003eb94ff6ce4d0208d139b00d70d22cef90bc1c8693c46","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"869a4c60a0360a085c0354f1ac4c4b8987e6db1cfd7231cebf2e78a22c249e4e","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3eedd4e83d6ab27a2e0fd8190965c42356563500c3f55a2421267a3ad3ef3812","description":"Get preconditions for migration.","extra":{"proxyto":"node"},"name":"migrate_vm_precondition","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"allowed_nodes":{"description":"List nodes allowed for offline migration, only passed if VM is offline","enum":[],"extra":{},"optional":true,"properties":{},"type":"array"},"local_disks":{"description":"List local disks including CD-Rom, unsused and not referenced disks","enum":[],"extra":{},"properties":{},"type":"array"},"local_resources":{"description":"List local resources e.g. pci, usb","enum":[],"extra":{},"properties":{},"type":"array"},"not_allowed_nodes":{"description":"List not allowed nodes with additional informations, only passed if VM is offline","enum":[],"extra":{},"optional":true,"properties":{},"type":"object"},"running":{"enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"aaca3e138a5a0e727af51af6dd260180c2f68edb22b6fb90f9ac3b3cab5bbd46","description":"Migrate virtual machine. Creates a new migration task.","extra":{"proxyto":"node"},"name":"migrate_vm","parameters":[{"definition":{"default":"migrate limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"Allow to migrate VMs which use local devices. Only root may use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"CIDR of the (sub) network that is used for migration.","enum":[],"extra":{"typetext":""},"format":"CIDR","optional":true,"properties":{},"type":"string"},"name":"migration_network"},{"definition":{"description":"Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.","enum":["secure","insecure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"migration_type"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use online/live migration if VM is running. Ignored if VM is stopped.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"online"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storage-pair-list","optional":true,"properties":{},"type":"string"},"name":"targetstorage"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Enable live storage migration for local disk","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"with-local-disks"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"57d048eeb98de49c9cdb4fd7e4644250616e80c8cd41278cdbaa9a05440fcb8e","description":"Execute QEMU monitor commands.","extra":{"proxyto":"node"},"name":"monitor","parameters":[{"definition":{"description":"The monitor command.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"command"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"Sys.Modify is required for (sub)commands which are not read-only ('info *' and 'help')","expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/monitor"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b6559dad07dcd693b4845e31afa07e3a3fca4784ffd816dd64c8da28ea3fe342","description":"Move volume to different storage or to a different VM.","extra":{"proxyto":"node"},"name":"move_vm_disk","parameters":[{"definition":{"default":"move limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"default":0,"description":"Delete the original disk after successful copy. By default the original disk is kept as unused disk.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1\"\n\t\t .\" digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The disk you want to move.","enum":["ide0","ide1","ide2","ide3","scsi0","scsi1","scsi2","scsi3","scsi4","scsi5","scsi6","scsi7","scsi8","scsi9","scsi10","scsi11","scsi12","scsi13","scsi14","scsi15","scsi16","scsi17","scsi18","scsi19","scsi20","scsi21","scsi22","scsi23","scsi24","scsi25","scsi26","scsi27","scsi28","scsi29","scsi30","virtio0","virtio1","virtio2","virtio3","virtio4","virtio5","virtio6","virtio7","virtio8","virtio9","virtio10","virtio11","virtio12","virtio13","virtio14","virtio15","sata0","sata1","sata2","sata3","sata4","sata5","efidisk0","tpmstate0","unused0","unused1","unused2","unused3","unused4","unused5","unused6","unused7","unused8","unused9","unused10","unused11","unused12","unused13","unused14","unused15","unused16","unused17","unused18","unused19","unused20","unused21","unused22","unused23","unused24","unused25","unused26","unused27","unused28","unused29","unused30","unused31","unused32","unused33","unused34","unused35","unused36","unused37","unused38","unused39","unused40","unused41","unused42","unused43","unused44","unused45","unused46","unused47","unused48","unused49","unused50","unused51","unused52","unused53","unused54","unused55","unused56","unused57","unused58","unused59","unused60","unused61","unused62","unused63","unused64","unused65","unused66","unused67","unused68","unused69","unused70","unused71","unused72","unused73","unused74","unused75","unused76","unused77","unused78","unused79","unused80","unused81","unused82","unused83","unused84","unused85","unused86","unused87","unused88","unused89","unused90","unused91","unused92","unused93","unused94","unused95","unused96","unused97","unused98","unused99","unused100","unused101","unused102","unused103","unused104","unused105","unused106","unused107","unused108","unused109","unused110","unused111","unused112","unused113","unused114","unused115","unused116","unused117","unused118","unused119","unused120","unused121","unused122","unused123","unused124","unused125","unused126","unused127","unused128","unused129","unused130","unused131","unused132","unused133","unused134","unused135","unused136","unused137","unused138","unused139","unused140","unused141","unused142","unused143","unused144","unused145","unused146","unused147","unused148","unused149","unused150","unused151","unused152","unused153","unused154","unused155","unused156","unused157","unused158","unused159","unused160","unused161","unused162","unused163","unused164","unused165","unused166","unused167","unused168","unused169","unused170","unused171","unused172","unused173","unused174","unused175","unused176","unused177","unused178","unused179","unused180","unused181","unused182","unused183","unused184","unused185","unused186","unused187","unused188","unused189","unused190","unused191","unused192","unused193","unused194","unused195","unused196","unused197","unused198","unused199","unused200","unused201","unused202","unused203","unused204","unused205","unused206","unused207","unused208","unused209","unused210","unused211","unused212","unused213","unused214","unused215","unused216","unused217","unused218","unused219","unused220","unused221","unused222","unused223","unused224","unused225","unused226","unused227","unused228","unused229","unused230","unused231","unused232","unused233","unused234","unused235","unused236","unused237","unused238","unused239","unused240","unused241","unused242","unused243","unused244","unused245","unused246","unused247","unused248","unused249","unused250","unused251","unused252","unused253","unused254","unused255"],"extra":{},"properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"Target Format.","enum":["raw","qcow2","vmdk"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target storage.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Prevent changes if the current config file of the target VM has a\"\n\t\t .\" different SHA1 digest. This can be used to detect concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"target-digest"},{"definition":{"description":"The config key the disk will be moved to on the target VM (for example, ide0 or scsi1). Default is the source disk key.","enum":["ide0","ide1","ide2","ide3","scsi0","scsi1","scsi2","scsi3","scsi4","scsi5","scsi6","scsi7","scsi8","scsi9","scsi10","scsi11","scsi12","scsi13","scsi14","scsi15","scsi16","scsi17","scsi18","scsi19","scsi20","scsi21","scsi22","scsi23","scsi24","scsi25","scsi26","scsi27","scsi28","scsi29","scsi30","virtio0","virtio1","virtio2","virtio3","virtio4","virtio5","virtio6","virtio7","virtio8","virtio9","virtio10","virtio11","virtio12","virtio13","virtio14","virtio15","sata0","sata1","sata2","sata3","sata4","sata5","efidisk0","tpmstate0","unused0","unused1","unused2","unused3","unused4","unused5","unused6","unused7","unused8","unused9","unused10","unused11","unused12","unused13","unused14","unused15","unused16","unused17","unused18","unused19","unused20","unused21","unused22","unused23","unused24","unused25","unused26","unused27","unused28","unused29","unused30","unused31","unused32","unused33","unused34","unused35","unused36","unused37","unused38","unused39","unused40","unused41","unused42","unused43","unused44","unused45","unused46","unused47","unused48","unused49","unused50","unused51","unused52","unused53","unused54","unused55","unused56","unused57","unused58","unused59","unused60","unused61","unused62","unused63","unused64","unused65","unused66","unused67","unused68","unused69","unused70","unused71","unused72","unused73","unused74","unused75","unused76","unused77","unused78","unused79","unused80","unused81","unused82","unused83","unused84","unused85","unused86","unused87","unused88","unused89","unused90","unused91","unused92","unused93","unused94","unused95","unused96","unused97","unused98","unused99","unused100","unused101","unused102","unused103","unused104","unused105","unused106","unused107","unused108","unused109","unused110","unused111","unused112","unused113","unused114","unused115","unused116","unused117","unused118","unused119","unused120","unused121","unused122","unused123","unused124","unused125","unused126","unused127","unused128","unused129","unused130","unused131","unused132","unused133","unused134","unused135","unused136","unused137","unused138","unused139","unused140","unused141","unused142","unused143","unused144","unused145","unused146","unused147","unused148","unused149","unused150","unused151","unused152","unused153","unused154","unused155","unused156","unused157","unused158","unused159","unused160","unused161","unused162","unused163","unused164","unused165","unused166","unused167","unused168","unused169","unused170","unused171","unused172","unused173","unused174","unused175","unused176","unused177","unused178","unused179","unused180","unused181","unused182","unused183","unused184","unused185","unused186","unused187","unused188","unused189","unused190","unused191","unused192","unused193","unused194","unused195","unused196","unused197","unused198","unused199","unused200","unused201","unused202","unused203","unused204","unused205","unused206","unused207","unused208","unused209","unused210","unused211","unused212","unused213","unused214","unused215","unused216","unused217","unused218","unused219","unused220","unused221","unused222","unused223","unused224","unused225","unused226","unused227","unused228","unused229","unused230","unused231","unused232","unused233","unused234","unused235","unused236","unused237","unused238","unused239","unused240","unused241","unused242","unused243","unused244","unused245","unused246","unused247","unused248","unused249","unused250","unused251","unused252","unused253","unused254","unused255"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"target-disk"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"target-vmid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Config.Disk' permissions on /vms/{vmid}, and 'Datastore.AllocateSpace' permissions on the storage. To move a disk to another VM, you need the permissions on the target VM as well.","expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/move_disk"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3cae8ecff4d9d8264457c9acf62a250d46883a1a84ef1c8291c9273db2338b45","description":"Migration tunnel endpoint - only for internal use by VM migration.","extra":{},"name":"mtunnel","parameters":[{"definition":{"description":"List of network bridges to check availability. Will be checked again for actually used bridges during migration.","enum":[],"extra":{"typetext":""},"format":"pve-bridge-id-list","optional":true,"properties":{},"type":"string"},"name":"bridges"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"List of storages to check permission and availability. Will be checked again for all actually used storages during migration.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id-list","optional":true,"properties":{},"type":"string"},"name":"storages"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permissions on '/vms/{vmid}' and Sys.Incoming on '/'. Further permission checks happen during the actual migration.","expression":{"check":["and",["perm","/vms/{vmid}",["VM.Allocate"]],["perm","/",["Sys.Incoming"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"socket":{"enum":[],"extra":{},"properties":{},"type":"string"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/mtunnel"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e167ede2c65dbdab00d8fdd2d470e4eda018b889a4a2678d76a53898278943d9","description":"Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration.","extra":{},"name":"mtunnelwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"unix socket to forward to","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"socket"},{"definition":{"description":"ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"ticket"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need to pass a ticket valid for the selected socket. Tickets can be created via the mtunnel API call, which will check permissions accordingly.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"socket":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/mtunnelwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d62ea3ba04431111f19f812d7f791c36fe1a5ac0df962735e4655f8548e0f9d5","description":"Get the virtual machine configuration with both current and pending values.","extra":{"proxyto":"node"},"name":"vm_pending","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"delete":{"description":"Indicates a pending delete request if present and not 0. The value 2 indicates a force-delete request.","enum":[],"extra":{},"maximum":2,"minimum":0,"optional":true,"properties":{},"type":"integer"},"key":{"description":"Configuration option name.","enum":[],"extra":{},"properties":{},"type":"string"},"pending":{"description":"Pending value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"value":{"description":"Current value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/pending"},{"extra":{},"methods":[{"allow_token":true,"checksum":"126b173288c87775c3aeaab87ddb4cbbdb4bb900424f29d2bd0c3f1558f4b027","description":"Migrate virtual machine to a remote cluster. Creates a new migration task. EXPERIMENTAL feature!","extra":{"proxyto":"node"},"name":"remote_migrate_vm","parameters":[{"definition":{"default":"migrate limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"default":0,"description":"Delete the original VM and related data after successful migration. By default the original VM is kept on the source cluster in a stopped state.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use online/live migration if VM is running. Ignored if VM is stopped.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"online"},{"definition":{"description":"Mapping from source to target bridges. Providing only a single bridge ID maps all source bridges to that bridge. Providing the special value '1' will map each source bridge to itself.","enum":[],"extra":{"typetext":""},"format":"bridge-pair-list","properties":{},"type":"string"},"name":"target-bridge"},{"definition":{"description":"Remote target endpoint","enum":[],"extra":{"typetext":"apitoken= ,host= [,fingerprint=] [,port=]"},"format":"proxmox-remote","properties":{},"type":"string"},"name":"target-endpoint"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storage-pair-list","optional":false,"properties":{},"type":"string"},"name":"target-storage"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"target-vmid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/remote_migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e42088e79544fe1933952f61aa64a536db483510b9045e15bb07d0599ddba343","description":"Extend volume size.","extra":{"proxyto":"node"},"name":"resize_vm","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The disk you want to resize.","enum":["ide0","ide1","ide2","ide3","scsi0","scsi1","scsi2","scsi3","scsi4","scsi5","scsi6","scsi7","scsi8","scsi9","scsi10","scsi11","scsi12","scsi13","scsi14","scsi15","scsi16","scsi17","scsi18","scsi19","scsi20","scsi21","scsi22","scsi23","scsi24","scsi25","scsi26","scsi27","scsi28","scsi29","scsi30","virtio0","virtio1","virtio2","virtio3","virtio4","virtio5","virtio6","virtio7","virtio8","virtio9","virtio10","virtio11","virtio12","virtio13","virtio14","virtio15","sata0","sata1","sata2","sata3","sata4","sata5","efidisk0","tpmstate0"],"extra":{},"properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The new size. With the `+` sign the value is added to the actual size of the volume and without it, the value is taken as an absolute one. Shrinking disk size is not supported.","enum":[],"extra":{},"pattern":"\\+?\\d+(\\.\\d+)?[KMGT]?","properties":{},"type":"string"},"name":"size"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/resize"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4d311cc5db4c24ed1db63ef58b0d8f8e72b579d6828347fd89059bf258f8210e","description":"Read VM RRD statistics (returns PNG)","extra":{},"name":"rrd","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The list of datasources you want to display.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"ds"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/rrd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"53eace25a11ab03d9980fc2e58377060dd11abc1fa75a694adf1f2b2a88dcdf0","description":"Read VM RRD statistics","extra":{},"name":"rrddata","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/rrddata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"aa9948243349915ab716c1e9175955d01ccbc3052f0eb66f7a98986715c92219","description":"Send key event to virtual machine.","extra":{"proxyto":"node"},"name":"vm_sendkey","parameters":[{"definition":{"description":"The key (qemu monitor encoding).","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"key"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/sendkey"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0a3a5dba9c363cbb794fe03b7ec97105d6dd323226e8aa729628cebd941021c0","description":"List all snapshots.","extra":{"proxyto":"node"},"name":"snapshot_list","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"description":{"description":"Snapshot description.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Snapshot identifier. Value 'current' identifies the current VM.","enum":[],"extra":{},"properties":{},"type":"string"},"parent":{"description":"Parent snapshot identifier.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"snaptime":{"description":"Snapshot creation time","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"vmstate":{"description":"Snapshot includes RAM.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"10b32165392e243323c38c9aaf2be5fa2798cc638a05851aedc6c68941bb3c8d","description":"Snapshot a VM.","extra":{"proxyto":"node"},"name":"snapshot","parameters":[{"definition":{"description":"A textual description or comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Save the vmstate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"vmstate"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/snapshot"},{"extra":{},"methods":[{"allow_token":true,"checksum":"490232f284e83e267b2ba688eb683f392e0a66281482783c4f2c42ef54df441d","description":"Delete a VM snapshot.","extra":{"proxyto":"node"},"name":"delsnapshot","parameters":[{"definition":{"description":"For removal from config file, even if removing disk snapshots fails.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"3543f6f025f3e8edb235d3a81de6bc9ae888696632b72c8a0358c30d67d096cb","description":"","extra":{},"name":"snapshot_cmd_idx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cmd}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2e4c3ffc0a572cde350f82c1ed21f7483bdc0b55b3350b6c629ad4a87fce8660","description":"Get snapshot configuration","extra":{"proxyto":"node"},"name":"get_snapshot_config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback","VM.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"229bac50088cfccbb485c9371b58bfc8d8a4beddcc04c2ef4a88af7a288e62dc","description":"Update snapshot metadata.","extra":{"proxyto":"node"},"name":"update_snapshot_config","parameters":[{"definition":{"description":"A textual description or comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"185a7177f3570c897722ef405a2243251e2b6827437089c3e04a0daba3429eda","description":"Rollback VM state to specified snapshot.","extra":{"proxyto":"node"},"name":"rollback","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"default":0,"description":"Whether the VM should get started after rolling back successfully. (Note: VMs will be automatically started if the snapshot includes RAM.)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"start"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8f6d1ed8c139e695e0b24cc1a319e983f17e91d0a6c1ad223855a7d06f1eb5b3","description":"Returns a SPICE configuration to connect to the VM.","extra":{"proxyto":"node"},"name":"spiceproxy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).","enum":[],"extra":{"typetext":""},"format":"address","optional":true,"properties":{},"type":"string"},"name":"proxy"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"description":"Returned values can be directly passed to the 'remote-viewer' application.","enum":[],"extra":{"additionalProperties":1},"properties":{"host":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"enum":[],"extra":{},"properties":{},"type":"string"},"proxy":{"enum":[],"extra":{},"properties":{},"type":"string"},"tls-port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/spiceproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"94a0d535add5f584338da3a56b0765094683ec9f207cd53a95a4014fc19acdf6","description":"Directory index","extra":{"proxyto":"node"},"name":"vmcmdidx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f15593c05da4e8c0d987338b216181574fba284bb9ea35b2c2754f8ced62a633","description":"Get virtual machine status.","extra":{"proxyto":"node"},"name":"vm_status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"agent":{"description":"QEMU Guest Agent is enabled in config.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"cpus":{"description":"Maximum usable CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"ha":{"description":"HA manager service status.","enum":[],"extra":{},"properties":{},"type":"object"},"lock":{"description":"The current config lock, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxdisk":{"description":"Root disk size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Maximum memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"name":{"description":"VM name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pid":{"description":"PID of running qemu process.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"qmpstatus":{"description":"QEMU QMP agent status.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"running-machine":{"description":"The currently running machine type (if running).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"running-qemu":{"description":"The currently running QEMU version (if running).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"spice":{"description":"QEMU VGA configuration supports spice.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"status":{"description":"QEMU process status.","enum":["stopped","running"],"extra":{},"properties":{},"type":"string"},"tags":{"description":"The current configured tags, if any","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"uptime":{"description":"Uptime.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/status/current"},{"extra":{},"methods":[{"allow_token":true,"checksum":"aa0c51529af4ef2fcea52ef831f1fe91057969ab05438476e1c84c4989af484a","description":"Reboot the VM by shutting it down, and starting it again. Applies pending changes.","extra":{"proxyto":"node"},"name":"vm_reboot","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Wait maximal timeout seconds for the shutdown.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/reboot"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1871f485dbc7682d42ef0ea0e30f4f03de75168335e09f05f086080e56e7b0d0","description":"Reset virtual machine.","extra":{"proxyto":"node"},"name":"vm_reset","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/reset"},{"extra":{},"methods":[{"allow_token":true,"checksum":"78c150a6c15c671cbc5a81c6f91c1c56f9372d825c25a985f3b23720934ffc03","description":"Resume virtual machine.","extra":{"proxyto":"node"},"name":"vm_resume","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nocheck"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/resume"},{"extra":{},"methods":[{"allow_token":true,"checksum":"522428bc63ba96ef2e445a1071a5d6f9bf2f6f8be1a2c0a136cba4c5522ba134","description":"Shutdown virtual machine. This is similar to pressing the power button on a physical machine.This will send an ACPI event for the guest OS, which should then proceed to a clean shutdown.","extra":{"proxyto":"node"},"name":"vm_shutdown","parameters":[{"definition":{"default":0,"description":"Make sure the VM stops.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"forceStop"},{"definition":{"default":0,"description":"Do not deactivate storage volumes.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keepActive"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Wait maximal timeout seconds.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/shutdown"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8daa067c87d0c520cffe1545653046ff6ac2e3ffcf66069dbc236b9c9900aa61","description":"Start virtual machine.","extra":{"proxyto":"node"},"name":"vm_start","parameters":[{"definition":{"description":"Override QEMU's -cpu argument with the given string.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"force-cpu"},{"definition":{"description":"Specifies the QEMU machine type.","enum":[],"extra":{},"max_length":40,"optional":true,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","properties":{},"type":"string"},"name":"machine"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"migratedfrom"},{"definition":{"description":"CIDR of the (sub) network that is used for migration.","enum":[],"extra":{"typetext":""},"format":"CIDR","optional":true,"properties":{},"type":"string"},"name":"migration_network"},{"definition":{"description":"Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.","enum":["secure","insecure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"migration_type"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Some command save/restore state from this location.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"stateuri"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storage-pair-list","optional":true,"properties":{},"type":"string"},"name":"targetstorage"},{"definition":{"default":"max(30, vm memory in GiB)","description":"Wait maximal timeout seconds.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8b103e66ff8f578a991a9f66aad23def3df04e67eb8181fded08c4680ac024e3","description":"Stop virtual machine. The qemu process will exit immediately. Thisis akin to pulling the power plug of a running computer and may damage the VM data","extra":{"proxyto":"node"},"name":"vm_stop","parameters":[{"definition":{"default":0,"description":"Do not deactivate storage volumes.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keepActive"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"migratedfrom"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Wait maximal timeout seconds.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/stop"},{"extra":{},"methods":[{"allow_token":true,"checksum":"979226664217ce4fa592d874d27ef7cd5926ada7f510d1b4d13d9db910fa4b13","description":"Suspend virtual machine.","extra":{"proxyto":"node"},"name":"vm_suspend","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The storage for the VM state","enum":[],"extra":{"requires":"todisk","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"statestorage"},{"definition":{"default":0,"description":"If set, suspends the VM to disk. Will be resumed on next VM start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"todisk"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.PowerMgmt' on /vms/{vmid}, and if you have set 'todisk', you need also 'VM.Config.Disk' on /vms/{vmid} and 'Datastore.AllocateSpace' on the storage for the vmstate.","expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/suspend"},{"extra":{},"methods":[{"allow_token":true,"checksum":"557a6349994823010252f91e071e4096ecb65d92498d2a4d56c1ff4e1fbf830a","description":"Create a Template.","extra":{"proxyto":"node"},"name":"template","parameters":[{"definition":{"description":"If you want to convert only 1 disk to base image.","enum":["ide0","ide1","ide2","ide3","scsi0","scsi1","scsi2","scsi3","scsi4","scsi5","scsi6","scsi7","scsi8","scsi9","scsi10","scsi11","scsi12","scsi13","scsi14","scsi15","scsi16","scsi17","scsi18","scsi19","scsi20","scsi21","scsi22","scsi23","scsi24","scsi25","scsi26","scsi27","scsi28","scsi29","scsi30","virtio0","virtio1","virtio2","virtio3","virtio4","virtio5","virtio6","virtio7","virtio8","virtio9","virtio10","virtio11","virtio12","virtio13","virtio14","virtio15","sata0","sata1","sata2","sata3","sata4","sata5","efidisk0","tpmstate0"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permissions on /vms/{vmid}","expression":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/template"},{"extra":{},"methods":[{"allow_token":true,"checksum":"581bcc9a519fb4b422b3e0e599e45c64a0db57b56dac0ab3269915ad6c17eeca","description":"Creates a TCP proxy connections.","extra":{},"name":"termproxy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"opens a serial terminal (defaults to display)","enum":["serial0","serial1","serial2","serial3"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"serial"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/termproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4a2fb8e4da3f5127a7f9d56ae5999acd8ef738ba4f47cc0d3704787f3fcf9bf6","description":"Unlink/delete disk images.","extra":{"proxyto":"node"},"name":"unlink","parameters":[{"definition":{"description":"Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"A list of disk IDs you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"idlist"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/unlink"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9a5fcd951a70d86256acddf42be56b872795a3157a1eebbd6eebfef0a7927f13","description":"Creates a TCP VNC proxy connections.","extra":{},"name":"vncproxy","parameters":[{"definition":{"default":0,"description":"Generates a random password to be used as ticket instead of the API ticket.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"generate-password"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"starts websockify instead of vncproxy","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"websocket"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"cert":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"description":"Returned if requested with 'generate-password' param. Consists of printable ASCII characters ('!' .. '~').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/vncproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ee391a9db15bf946d3fcf3622e765d731bb78079d2394c583723f26e79101ac5","description":"Opens a weksocket for VNC traffic.","extra":{},"name":"vncwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Port number returned by previous vncproxy call.","enum":[],"extra":{"typetext":" (5900 - 5999)"},"maximum":5999,"minimum":5900,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Ticket from previous call to vncproxy.","enum":[],"extra":{"typetext":""},"max_length":512,"properties":{},"type":"string"},"name":"vncticket"}],"permissions":{"description":"You also need to pass a valid ticket (vncticket).","expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/vncwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"63ae82dac636729f44c5a236a35d96c5c8fd74a77e53b3893f951a7ce2688eae","description":"Query metadata of an URL: file size, file name and mime type.","extra":{"proxyto":"node"},"name":"query_url_metadata","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The URL to query the metadata from.","enum":[],"extra":{},"pattern":"https?://.*","properties":{},"type":"string"},"name":"url"},{"definition":{"default":1,"description":"If false, no SSL/TLS certificates will be verified.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify-certificates"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Sys.Modify"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mimetype":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"size":{"enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/query-url-metadata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"622b3aa84ae973517a0ec742be96c880d38bdacd2780b26fe82134224bca0d0e","description":"List status of all replication jobs on this node.","extra":{"proxyto":"node"},"name":"status","parameters":[{"definition":{"description":"Only list replication jobs for this guest.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"guest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires the VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/replication"},{"extra":{},"methods":[{"allow_token":true,"checksum":"201ac105a0b4f70bec7ac00e32a949db054741cbd2465d2f625462367edce6f7","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/replication/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6ffc6cc2602df84fe4f8eb72ae99567ce4f7fb02dec2ca8db396ff090772cd58","description":"Read replication job log.","extra":{"proxyto":"node"},"name":"read_job_log","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"}],"permissions":{"description":"Requires the VM.Audit permission on /vms/, or 'Sys.Audit' on '/nodes/'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/replication/{id}/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"77e6d9fc5931226e0ebc15d1967865306c48edb8c36e7ab4acd3c992bc22e6ef","description":"Schedule replication job to start as soon as possible.","extra":{"proxyto":"node"},"name":"schedule_now","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/replication/{id}/schedule_now"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4be58d6638ffb32fbaa33db58fac6d3964014ed3286339e84f35ca0cb6d006e1","description":"Get replication job status.","extra":{"proxyto":"node"},"name":"job_status","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires the VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/replication/{id}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0e37ddadedaa3a4ce296c24b888b12f7012e4e23b1732222e40075a4f8a9ed1f","description":"Gather various systems information about a node","extra":{"proxyto":"node"},"name":"report","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/report"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d974667aed5e89c095ef17a66fb4537d6dda82a55fa1ec5f1c05cba57f78464c","description":"Read node RRD statistics (returns PNG)","extra":{},"name":"rrd","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The list of datasources you want to display.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"ds"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/rrd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"766180222a6d70a2fd631255767fa56f8cd6a67cebf4530b038018cccd49487f","description":"Read node RRD statistics","extra":{},"name":"rrddata","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/rrddata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7cca8a7c1631d17653d463ea99f96401217997b7a680967bfc57a06b99302ff1","description":"Index of available scan methods","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{method}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"method":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2ec831a4ad191d89200069d552cc1eedbbe77316334360b9e98672a3d4cf3a94","description":"Scan remote CIFS server.","extra":{"proxyto":"node"},"name":"cifsscan","parameters":[{"definition":{"description":"SMB domain (Workgroup).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"User password.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"The server address (name or IP).","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","properties":{},"type":"string"},"name":"server"},{"definition":{"description":"User name.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"description":{"description":"Descriptive text from server.","enum":[],"extra":{},"properties":{},"type":"string"},"share":{"description":"The cifs share name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/cifs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"75c1967f47ee50cfdaf4558a4fa699bbdc9317e2fe69fd3ddccd30a2707dfe2d","description":"Scan remote GlusterFS server.","extra":{"proxyto":"node"},"name":"glusterfsscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The server address (name or IP).","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","properties":{},"type":"string"},"name":"server"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"volname":{"description":"The volume name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/glusterfs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f0b69d1299f3a287b51f9e20eddd3a6c423da92c62c5263da3308104c8f9e3d8","description":"Scan remote iSCSI server.","extra":{"proxyto":"node"},"name":"iscsiscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The iSCSI portal (IP or DNS name with optional port).","enum":[],"extra":{"typetext":""},"format":"pve-storage-portal-dns","properties":{},"type":"string"},"name":"portal"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"portal":{"description":"The iSCSI portal name.","enum":[],"extra":{},"properties":{},"type":"string"},"target":{"description":"The iSCSI target name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/iscsi"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ee58724ae9c2fbdaf09f891f8286f1c4a97862a33274213f55b64ef257c82810","description":"List local LVM volume groups.","extra":{"proxyto":"node"},"name":"lvmscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"vg":{"description":"The LVM logical volume group name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/lvm"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b85f98a17a9f58549d6a53aafbaf22bfdf0e5d1665f87e90bb69fd57fad754e8","description":"List local LVM Thin Pools.","extra":{"proxyto":"node"},"name":"lvmthinscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{},"max_length":100,"pattern":"[a-zA-Z0-9\\.\\+\\_][a-zA-Z0-9\\.\\+\\_\\-]+","properties":{},"type":"string"},"name":"vg"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"lv":{"description":"The LVM Thin Pool name (LVM logical volume).","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/lvmthin"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d9ddde30d7f532fbc6f06fbe726c2833705e8d4807f2c6cd617ee8fdae18d97d","description":"Scan remote NFS server.","extra":{"proxyto":"node"},"name":"nfsscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The server address (name or IP).","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","properties":{},"type":"string"},"name":"server"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"options":{"description":"NFS export options.","enum":[],"extra":{},"properties":{},"type":"string"},"path":{"description":"The exported path.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/nfs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3ce919d002c3d125b6b1ad3b5fd0cb889318319ec14cee96f7282ff12db0bda8","description":"Scan remote Proxmox Backup Server.","extra":{"proxyto":"node"},"name":"pbsscan","parameters":[{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"User password or API token secret.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"password"},{"definition":{"default":8007,"description":"Optional port.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The server address (name or IP).","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","properties":{},"type":"string"},"name":"server"},{"definition":{"description":"User-name or API token-ID.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"username"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"Comment from server.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"store":{"description":"The datastore name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/pbs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5742df84db0fb3e83b8a85993cee8d4667b1a311b08d135a1b751e04afd1caeb","description":"Scan zfs pool list on local node.","extra":{"proxyto":"node"},"name":"zfsscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"pool":{"description":"ZFS pool name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/zfs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ff83507bdfaa5cb101794ba2e4c40051a63c313286ecc2e102ae09a550357898","description":"SDN index.","extra":{},"name":"sdnindex","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn"},{"extra":{},"methods":[{"allow_token":true,"checksum":"12403a45a714d49c82c079929ecd505c3b507a59dc93a9d8179f4b90a7ce7318","description":"Get status for all zones.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{zone}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"status":{"description":"Status of zone","enum":["available","pending","error"],"extra":{},"properties":{},"type":"string"},"zone":{"description":"The SDN zone object identifier.","enum":[],"extra":{},"format":"pve-sdn-zone-id","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/zones"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8a85cf269cae44e965f4987f67477d55f9c0dbd96ca0ce98eeacd89f9c89084e","description":"","extra":{},"name":"diridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/zones/{zone}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"37027697e4ca9f13e96aaeed743d261261396e7f4689693272393d7d7c53e2ac","description":"List zone content.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{vnet}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"status":{"description":"Status.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"statusmsg":{"description":"Status details","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vnet":{"description":"Vnet identifier.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/zones/{zone}/content"},{"extra":{},"methods":[{"allow_token":true,"checksum":"28dfc7ff0d1244e9784ad47960d10b8e5aba10d904ddab0fc817befa32f29b9a","description":"Service list.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{service}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/services"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6f84ec756ee728f7f4edef6c7bf549b613c4bd317cc57b63c0f70ab219dd314e","description":"Directory index","extra":{},"name":"srvcmdidx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","postfix","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/services/{service}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c30eefe484f450f83ed4ab0eb9aa41fe5e4f1367b3332727b6da4dbe83bd43e0","description":"Reload service. Falls back to restart if service cannot be reloaded.","extra":{"proxyto":"node"},"name":"service_reload","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","postfix","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/services/{service}/reload"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1e658a77fb8d9cb4e603eebe1d318070b18df345eed31f24d3b146750c06ea6c","description":"Hard restart service. Use reload if you want to reduce interruptions.","extra":{"proxyto":"node"},"name":"service_restart","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","postfix","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/services/{service}/restart"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f03a14a7d7ddd10b28a73302d808652b26c74999d33365e69359255c538caaee","description":"Start service.","extra":{"proxyto":"node"},"name":"service_start","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","postfix","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/services/{service}/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"93adca1b678fcbdba8bd843e650534d9ba0cd5e4a2ff2ea165c52f454771ed77","description":"Read service properties","extra":{"proxyto":"node"},"name":"service_state","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","postfix","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/services/{service}/state"},{"extra":{},"methods":[{"allow_token":true,"checksum":"65d1bc2e276eaea3d9c9b76a2a243c4a255d7f1eaa782aeb4ebb8d46a8bffdd0","description":"Stop service.","extra":{"proxyto":"node"},"name":"service_stop","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","postfix","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/services/{service}/stop"},{"extra":{},"methods":[{"allow_token":true,"checksum":"494e106272f414b7cdcf8d35a869b76410cfc5ffb32635239515a70421bfe787","description":"Creates a SPICE shell.","extra":{"proxyto":"node"},"name":"spiceshell","parameters":[{"definition":{"default":"login","description":"Run specific command or default to login.","enum":["ceph_install","upgrade","login"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmd"},{"definition":{"default":"","description":"Add parameters to a command. Encoded as null terminated strings.","enum":[],"extra":{"requires":"cmd","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cmd-opts"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).","enum":[],"extra":{"typetext":""},"format":"address","optional":true,"properties":{},"type":"string"},"name":"proxy"}],"permissions":{"description":"Restricted to users on realm 'pam'","expression":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"description":"Returned values can be directly passed to the 'remote-viewer' application.","enum":[],"extra":{"additionalProperties":1},"properties":{"host":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"enum":[],"extra":{},"properties":{},"type":"string"},"proxy":{"enum":[],"extra":{},"properties":{},"type":"string"},"tls-port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/spiceshell"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ec80ea1c2fbaa0128ad1277e098081db8e1ed6887318cb24f7fe962dd1dc4bd6","description":"Start all VMs and containers located on this node (by default only those with onboot=1).","extra":{"proxyto":"node"},"name":"startall","parameters":[{"definition":{"default":"off","description":"Issue start command even if virtual guest have 'onboot' not set or set to off.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only consider guests from this comma separated list of VMIDs.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"}],"permissions":{"description":"The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/startall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"659246e0644de83bea8d5511eebd10913a9fbe0d55ce182936fb7d27a50e31bb","description":"Read node status","extra":{"proxyto":"node"},"name":"status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"f11d86bf5eb63c8f7c9cd23dd0579477ea908eb3b936d39f4f8c5a20bfd0bef7","description":"Reboot or shutdown a node.","extra":{"proxyto":"node"},"name":"node_cmd","parameters":[{"definition":{"description":"Specify the command.","enum":["reboot","shutdown"],"extra":{},"properties":{},"type":"string"},"name":"command"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f0bf330d9be14654c45843287074e32b7a4bac98bc5c440d3be95d31b993ac47","description":"Stop all VMs and Containers.","extra":{"proxyto":"node"},"name":"stopall","parameters":[{"definition":{"default":1,"description":"Force a hard-stop after the timeout.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force-stop"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":180,"description":"Timeout for each guest shutdown task. Depending on `force-stop`, the shutdown gets then simply aborted or a hard-stop is forced.","enum":[],"extra":{"typetext":" (0 - 7200)"},"maximum":7200,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"Only consider Guests with these IDs.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"}],"permissions":{"description":"The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/stopall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dd0ea4f574a7d8eb6c6e6e3f5c6e2be12fd4966ad5ea3801257c47d3d28f6e43","description":"Get status for all datastores.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"Only list stores which support this content type.","enum":[],"extra":{"typetext":""},"format":"pve-storage-content-list","optional":true,"properties":{},"type":"string"},"name":"content"},{"definition":{"default":0,"description":"Only list stores which are enabled (not disabled in config).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"default":0,"description":"Include information about formats","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"format"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list status for specified storage","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"If target is different to 'node', we only lists shared storages which content is accessible on this 'node' and the specified 'target' node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"}],"permissions":{"description":"Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{storage}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"active":{"description":"Set when storage is accessible.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"avail":{"description":"Available storage space in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"content":{"description":"Allowed storage content types.","enum":[],"extra":{},"format":"pve-storage-content-list","properties":{},"type":"string"},"enabled":{"description":"Set when storage is enabled (not disabled).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"shared":{"description":"Shared flag from storage configuration.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"storage":{"description":"The storage identifier.","enum":[],"extra":{},"format":"pve-storage-id","properties":{},"type":"string"},"total":{"description":"Total storage space in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"type":{"description":"Storage type.","enum":[],"extra":{},"properties":{},"type":"string"},"used":{"description":"Used storage space in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"used_fraction":{"description":"Used fraction (used/total).","enum":[],"extra":{"renderer":"fraction_as_percentage"},"optional":true,"properties":{},"type":"number"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage"},{"extra":{},"methods":[{"allow_token":true,"checksum":"377eba426d6b0285a1543e3fc7499e4b94d9087b39aa5222e568d0258071f5f6","description":"","extra":{},"name":"diridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"35fa4906a0cd148133529a553d544cceff1c139a7a47ea9573e896de22e3dd9e","description":"List storage content.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"Only list content of this type.","enum":[],"extra":{"typetext":""},"format":"pve-storage-content","optional":true,"properties":{},"type":"string"},"name":"content"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Only list images for this VM","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{volid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"ctime":{"description":"Creation time (seconds since the UNIX Epoch).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"encrypted":{"description":"If whole backup is encrypted, value is the fingerprint or '1' if encrypted. Only useful for the Proxmox Backup Server storage type.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"format":{"description":"Format identifier ('raw', 'qcow2', 'subvol', 'iso', 'tgz' ...)","enum":[],"extra":{},"properties":{},"type":"string"},"notes":{"description":"Optional notes. If they contain multiple lines, only the first one is returned here.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"parent":{"description":"Volume identifier of parent (for linked cloned).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"protected":{"description":"Protection status. Currently only supported for backups.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"size":{"description":"Volume size in bytes.","enum":[],"extra":{"renderer":"bytes"},"properties":{},"type":"integer"},"used":{"description":"Used space. Please note that most storage plugins do not report anything useful here.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"verification":{"description":"Last backup verification result, only useful for PBS storages.","enum":[],"extra":{},"optional":true,"properties":{"state":{"description":"Last backup verification state.","enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"description":"Last backup verification UPID.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"vmid":{"description":"Associated Owner VMID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"volid":{"description":"Volume identifier.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"0a214ab427deddf4376aa0cea9a1ad533d10456bfa2ab2b0d1bf7c95bec3c978","description":"Allocate disk images.","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"description":"The name of the file to create.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"filename"},{"definition":{"enum":["raw","qcow2","subvol"],"extra":{"requires":"size"},"optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Size in kilobyte (1024 bytes). Optional suffixes 'M' (megabyte, 1024K) and 'G' (gigabyte, 1024M)","enum":[],"extra":{},"pattern":"\\d+[MG]?","properties":{},"type":"string"},"name":"size"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Specify owner VM","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.AllocateSpace"]]},"extra":{}},"protected":true,"returns":{"description":"Volume identifier","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/storage/{storage}/content"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8c46146e5409364c21e9fabe66cda11271af6dbab1954a3bf6dfc76b5b5fb028","description":"Delete volume","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"description":"Time to wait for the task to finish. We return 'null' if the task finish within that time.","enum":[],"extra":{"typetext":" (1 - 30)"},"maximum":30,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"delay"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need 'Datastore.Allocate' privilege on the storage (or 'Datastore.AllocateSpace' for backup volumes if you have VM.Backup privilege on the VM).","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"ea6286a751e945a9a0d7610828fde72f58ddf3e7ca2c66f1e86001ea811b104d","description":"Get volume attributes","extra":{"proxyto":"node"},"name":"info","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"format":{"description":"Format identifier ('raw', 'qcow2', 'subvol', 'iso', 'tgz' ...)","enum":[],"extra":{},"properties":{},"type":"string"},"notes":{"description":"Optional notes.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"path":{"description":"The Path","enum":[],"extra":{},"properties":{},"type":"string"},"protected":{"description":"Protection status. Currently only supported for backups.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"size":{"description":"Volume size in bytes.","enum":[],"extra":{"renderer":"bytes"},"properties":{},"type":"integer"},"used":{"description":"Used space. Please note that most storage plugins do not report anything useful here.","enum":[],"extra":{"renderer":"bytes"},"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"1cc35ec5d8865c6efa9818c824f9593097c56ea1fe8d7e877d4e8b9127c5d27b","description":"Copy a volume. This is experimental code - do not use.","extra":{"proxyto":"node"},"name":"copy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Target volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Target node. Default is local node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target_node"},{"definition":{"description":"Source volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"},{"allow_token":true,"checksum":"d90f668cb99c142b1821bbc4209a6d11594eb5c96211fe0af3fe4a0db68dea6e","description":"Update volume attributes","extra":{"proxyto":"node"},"name":"updateattributes","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The new notes.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"notes"},{"definition":{"description":"Protection status. Currently only supported for backups.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protected"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/storage/{storage}/content/{volume}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"aec827f88f3f92d8428f9aca506ac8551b7b189fac32ea05b31051f076c46907","description":"Download templates and ISO images by using an URL.","extra":{"proxyto":"node"},"name":"download_url","parameters":[{"definition":{"description":"The expected checksum of the file.","enum":[],"extra":{"requires":"checksum-algorithm","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"checksum"},{"definition":{"description":"The algorithm to calculate the checksum of the file.","enum":["md5","sha1","sha224","sha256","sha384","sha512"],"extra":{"requires":"checksum"},"optional":true,"properties":{},"type":"string"},"name":"checksum-algorithm"},{"definition":{"description":"Content type.","enum":["iso","vztmpl"],"extra":{},"format":"pve-storage-content","properties":{},"type":"string"},"name":"content"},{"definition":{"description":"The name of the file to create. Caution: This will be normalized!","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"filename"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"The URL to download the file from.","enum":[],"extra":{},"pattern":"https?://.*","properties":{},"type":"string"},"name":"url"},{"definition":{"default":1,"description":"If false, no SSL/TLS certificates will be verified.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify-certificates"}],"permissions":{"expression":{"check":["and",["perm","/storage/{storage}",["Datastore.AllocateTemplate"]],["perm","/",["Sys.Audit","Sys.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/storage/{storage}/download-url"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a21cd4c6d6810844199101691a2a3e2395df2eb6e63f04faf9e5ff37c0ce3cc8","description":"Extract a file or directory (as zip archive) from a PBS backup.","extra":{"proxyto":"node"},"name":"download","parameters":[{"definition":{"description":"base64-path to the directory or file to download.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"filepath"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Backup volume ID or name. Currently only PBS snapshots are supported.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"any"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/file-restore/download"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ea83e757c302d00f12e115649c095a953dff5ce51794c0400f7eb7c0b64962a1","description":"List files and directories for single file restore under the given path.","extra":{"proxyto":"node"},"name":"list","parameters":[{"definition":{"description":"base64-path to the directory or file being listed, or \"/\".","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"filepath"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Backup volume ID or name. Currently only PBS snapshots are supported.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"filepath":{"description":"base64 path of the current entry","enum":[],"extra":{},"properties":{},"type":"string"},"leaf":{"description":"If this entry is a leaf in the directory graph.","enum":[],"extra":{},"properties":{},"type":"boolean"},"mtime":{"description":"Entry last-modified time (unix timestamp).","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"size":{"description":"Entry file size.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"text":{"description":"Entry display text.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"Entry type.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/file-restore/list"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c2906566c6309e1b09ec0a2b71f558d6d407831df276979d654d9100e5cd1b98","description":"Prune backups. Only those using the standard naming scheme are considered.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Either 'qemu' or 'lxc'. Only consider backups for guests of this type.","enum":["qemu","lxc"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"Only prune backups for this VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need the 'Datastore.Allocate' privilege on the storage (or if a VM ID is specified, 'Datastore.AllocateSpace' and 'VM.Backup' for the VM).","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"6a7c3c175e2e419242baaca4d5064658aa974bcfe76d200c6fd42603af453ab2","description":"Get prune information for backups. NOTE: this is only a preview and might not be what a subsequent prune call does if backups are removed/added in the meantime.","extra":{"proxyto":"node"},"name":"dryrun","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Either 'qemu' or 'lxc'. Only consider backups for guests of this type.","enum":["qemu","lxc"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"Only consider backups for this guest.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"ctime":{"description":"Creation time of the backup (seconds since the UNIX epoch).","enum":[],"extra":{},"properties":{},"type":"integer"},"mark":{"description":"Whether the backup would be kept or removed. Backups that are protected or don't use the standard naming scheme are not removed.","enum":["keep","remove","protected","renamed"],"extra":{},"properties":{},"type":"string"},"type":{"description":"One of 'qemu', 'lxc', 'openvz' or 'unknown'.","enum":[],"extra":{},"properties":{},"type":"string"},"vmid":{"description":"The VM the backup belongs to.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"volid":{"description":"Backup volume ID.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/prunebackups"},{"extra":{},"methods":[{"allow_token":true,"checksum":"20a583b925d3ab0aa787326c6b5e8a30b465daf2a1b9ddcff8072c987d2d1e29","description":"Read storage RRD statistics (returns PNG).","extra":{"proxyto":"node"},"name":"rrd","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The list of datasources you want to display.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"ds"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/rrd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e963d14fe33e85cd89f3e86ef8fce1f755ebd481fed7e11fe11d383f86a22990","description":"Read storage RRD statistics.","extra":{"proxyto":"node"},"name":"rrddata","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/rrddata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7c7877748327e646e17c62147e0e1f0148ea70a1237332b911aed87e646566c5","description":"Read storage status.","extra":{"proxyto":"node"},"name":"read_status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a71365c9ccbc117c1aedf1eddb4b592716cf986cc60ce99a3a8c637ff54d5208","description":"Upload templates and ISO images.","extra":{},"name":"upload","parameters":[{"definition":{"description":"The expected checksum of the file.","enum":[],"extra":{"requires":"checksum-algorithm","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"checksum"},{"definition":{"description":"The algorithm to calculate the checksum of the file.","enum":["md5","sha1","sha224","sha256","sha384","sha512"],"extra":{"requires":"checksum"},"optional":true,"properties":{},"type":"string"},"name":"checksum-algorithm"},{"definition":{"description":"Content type.","enum":["iso","vztmpl"],"extra":{},"format":"pve-storage-content","properties":{},"type":"string"},"name":"content"},{"definition":{"description":"The name of the file to create. Caution: This will be normalized!","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"filename"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"The source file name. This parameter is usually set by the REST handler. You can only overwrite it when connecting to the trusted port on localhost.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tmpfilename"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.AllocateTemplate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/storage/{storage}/upload"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f69a09923a7e070b2be36d4ccb06e891f14a3518902eee5f7f7c27f6c58e46e7","description":"Delete subscription key of this node.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"1a55d17c6b6fcc76f2402f862dc4fc65c3995774895bbd9aab17cc2b9d769a3d","description":"Read subscription info.","extra":{"proxyto":"node"},"name":"get","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"cc5b0bf0f8d6f80ad754ad3c7f8b34593adec2e6459e66a6a5836a1158298c93","description":"Update subscription info.","extra":{"proxyto":"node"},"name":"update","parameters":[{"definition":{"default":0,"description":"Always connect to server, even if we have up to date info inside local cache.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"0ddd0a712a57d76823789e28e78bf18e08b5ffca5d79831c496a264b5ff19605","description":"Set subscription key.","extra":{"proxyto":"node"},"name":"set","parameters":[{"definition":{"description":"Proxmox VE subscription key","enum":[],"extra":{},"max_length":32,"pattern":"pve([1248])([cbsp])-[0-9a-f]{10}","properties":{},"type":"string"},"name":"key"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/subscription"},{"extra":{},"methods":[{"allow_token":true,"checksum":"627733cfb797f5cb56b37117c3cd10de855d36183e4e87b8e57c0207e6238edd","description":"Read system log","extra":{"proxyto":"node"},"name":"syslog","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"service"},{"definition":{"description":"Display all log since this date-time string.","enum":[],"extra":{},"optional":true,"pattern":"^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$","properties":{},"type":"string"},"name":"since"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"Display all log until this date-time string.","enum":[],"extra":{},"optional":true,"pattern":"^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$","properties":{},"type":"string"},"name":"until"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/syslog"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6610d5de828a297659f50eae7e03046ee97299393033ddbfae95872ef9b18157","description":"Read task list for one node (finished tasks).","extra":{"proxyto":"node"},"name":"node_tasks","parameters":[{"definition":{"default":0,"description":"Only list tasks with a status of ERROR.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"errors"},{"definition":{"default":50,"description":"Only list this amount of tasks.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list tasks since this UNIX epoch.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"since"},{"definition":{"default":"archive","description":"List archived, active or all tasks.","enum":["archive","active","all"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"default":0,"description":"List tasks beginning from this offset.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"List of Task States that should be returned.","enum":[],"extra":{"typetext":""},"format":"pve-task-status-type-list","optional":true,"properties":{},"type":"string"},"name":"statusfilter"},{"definition":{"description":"Only list tasks of this type (e.g., vzstart, vzdump).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"typefilter"},{"definition":{"description":"Only list tasks until this UNIX epoch.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"until"},{"definition":{"description":"Only list tasks from this user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"userfilter"},{"definition":{"description":"Only list tasks for this VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"List task associated with the current user, or all task the user has 'Sys.Audit' permissions on /nodes/ (the the task runs on).","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{upid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"endtime":{"enum":[],"extra":{"title":"Endtime"},"optional":true,"properties":{},"type":"integer"},"id":{"enum":[],"extra":{"title":"ID"},"properties":{},"type":"string"},"node":{"enum":[],"extra":{"title":"Node"},"properties":{},"type":"string"},"pid":{"enum":[],"extra":{"title":"PID"},"properties":{},"type":"integer"},"pstart":{"enum":[],"extra":{},"properties":{},"type":"integer"},"starttime":{"enum":[],"extra":{"title":"Starttime"},"properties":{},"type":"integer"},"status":{"enum":[],"extra":{"title":"Status"},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{"title":"Type"},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{"title":"UPID"},"properties":{},"type":"string"},"user":{"enum":[],"extra":{"title":"User"},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/tasks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8858ff934ad9888088c08685fc89c7640b161692fc40eb48b890b6349353f5e3","description":"Stop a task.","extra":{"proxyto":"node"},"name":"stop_task","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"upid"}],"permissions":{"description":"The user needs 'Sys.Modify' permissions on '/nodes/' if they aren't the owner of the task.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"88930b3a0d6654f9ead4d8adc76725935668dd88774af0a950aa627485d41dbf","description":"","extra":{},"name":"upid_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"upid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/tasks/{upid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8fa054b2ba88000ffdeba77a60946e2d2a0a0dda24707e61b8a9444bc9b029c3","description":"Read task log.","extra":{"proxyto":"node"},"name":"read_task_log","parameters":[{"definition":{"description":"Whether the tasklog file should be downloaded. This parameter can't be used in conjunction with other parameters","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"download"},{"definition":{"default":50,"description":"The amount of lines to read from the tasklog.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Start at this line when reading the tasklog","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"The task's unique ID.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"upid"}],"permissions":{"description":"The user needs 'Sys.Audit' permissions on '/nodes/' if they aren't the owner of the task.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/tasks/{upid}/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5b025f6b44565cd57c0d3ca9d4b45146084806deb1adc68a44dd4b261d7289e6","description":"Read task status.","extra":{"proxyto":"node"},"name":"read_task_status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The task's unique ID.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"upid"}],"permissions":{"description":"The user needs 'Sys.Audit' permissions on '/nodes/' if they are not the owner of the task.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"exitstatus":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"node":{"enum":[],"extra":{},"properties":{},"type":"string"},"pid":{"enum":[],"extra":{},"properties":{},"type":"integer"},"starttime":{"enum":[],"extra":{},"properties":{},"type":"number"},"status":{"enum":["running","stopped"],"extra":{},"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/tasks/{upid}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8a255c52d0f648b45b9af5eba1f7e4bc7f10f2eefd463350db1c9c16685e5e5a","description":"Creates a VNC Shell proxy.","extra":{},"name":"termproxy","parameters":[{"definition":{"default":"login","description":"Run specific command or default to login.","enum":["ceph_install","upgrade","login"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmd"},{"definition":{"default":"","description":"Add parameters to a command. Encoded as null terminated strings.","enum":[],"extra":{"requires":"cmd","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cmd-opts"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Restricted to users on realm 'pam'","expression":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/termproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"15558dd947c7c5db6fd939f2882db13ec7cc1f3ed3889a21151f2ece44c27e19","description":"Read server time and time zone settings.","extra":{"proxyto":"node"},"name":"time","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"localtime":{"description":"Seconds since 1970-01-01 00:00:00 (local time)","enum":[],"extra":{"renderer":"timestamp_gmt"},"minimum":1297163644,"properties":{},"type":"integer"},"time":{"description":"Seconds since 1970-01-01 00:00:00 UTC.","enum":[],"extra":{"renderer":"timestamp"},"minimum":1297163644,"properties":{},"type":"integer"},"timezone":{"description":"Time zone","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"6e0e6c4e973322e4ff4de02a8f54fc9a9a9de171237797934f9056943f940639","description":"Set time zone.","extra":{"proxyto":"node"},"name":"set_timezone","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"timezone"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/time"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a2f20ffba970376ccb2903020b544f6ac94e79d7aaba8ea5df4a4cf3a2cfd266","description":"API version details","extra":{"proxyto":"node"},"name":"version","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"release":{"description":"The current installed Proxmox VE Release","enum":[],"extra":{},"properties":{},"type":"string"},"repoid":{"description":"The short git commit hash ID from which this version was build","enum":[],"extra":{},"properties":{},"type":"string"},"version":{"description":"The current installed pve-manager package version","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/version"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3595d1301e07dad826107da09ef2f06ec090fbbf9495e7304693d89cb6d71dcc","description":"Creates a VNC Shell proxy.","extra":{},"name":"vncshell","parameters":[{"definition":{"default":"login","description":"Run specific command or default to login.","enum":["ceph_install","upgrade","login"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmd"},{"definition":{"default":"","description":"Add parameters to a command. Encoded as null terminated strings.","enum":[],"extra":{"requires":"cmd","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cmd-opts"},{"definition":{"description":"sets the height of the console in pixels.","enum":[],"extra":{"typetext":" (16 - 2160)"},"maximum":2160,"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"height"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"use websocket instead of standard vnc.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"websocket"},{"definition":{"description":"sets the width of the console in pixels.","enum":[],"extra":{"typetext":" (16 - 4096)"},"maximum":4096,"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"width"}],"permissions":{"description":"Restricted to users on realm 'pam'","expression":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"cert":{"enum":[],"extra":{},"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/vncshell"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c897766540b83bf236fdd5a3d8984fd4090f1b3bc39ea49004a519cc5410636e","description":"Opens a websocket for VNC traffic.","extra":{},"name":"vncwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Port number returned by previous vncproxy call.","enum":[],"extra":{"typetext":" (5900 - 5999)"},"maximum":5999,"minimum":5900,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Ticket from previous call to vncproxy.","enum":[],"extra":{"typetext":""},"max_length":512,"properties":{},"type":"string"},"name":"vncticket"}],"permissions":{"description":"Restricted to users on realm 'pam'. You also need to pass a valid ticket (vncticket).","expression":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/vncwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6368d8e1387e5b51139409d057389814063dc3ca59364328c12e9ecbdca842a0","description":"Create backup.","extra":{"proxyto":"node"},"name":"vzdump","parameters":[{"definition":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"all"},{"definition":{"default":0,"description":"Limit I/O bandwidth (KBytes per second).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"compress"},{"definition":{"description":"Store resulting files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dumpdir"},{"definition":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"exclude"},{"definition":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{"typetext":""},"format":"string-alist","optional":true,"properties":{},"type":"string"},"name":"exclude-path"},{"definition":{"default":7,"description":"Set CFQ ionice priority.","enum":[],"extra":{"typetext":" (0 - 8)"},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"ionice"},{"definition":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"lockwait"},{"definition":{"default":"always","description":"Specify when to send an email","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mailnotification"},{"definition":{"description":"Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{"typetext":""},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"name":"mailto"},{"definition":{"description":"Deprecated: use 'prune-backups' instead. Maximal number of backup files per guest system.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxfiles"},{"definition":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"Only run if executed on this node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.","enum":[],"extra":{"requires":"storage","typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"notes-template"},{"definition":{"description":"Other performance-related settings.","enum":[],"extra":{"typetext":"[max-workers=]"},"format":"backup-performance","optional":true,"properties":{},"type":"string"},"name":"performance"},{"definition":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"pigz"},{"definition":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"If true, mark backup(s) as protected.","enum":[],"extra":{"requires":"storage","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protected"},{"definition":{"default":"keep-all=1","description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"default":0,"description":"Be quiet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"quiet"},{"definition":{"default":1,"description":"Prune older backups according to 'prune-backups'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove"},{"definition":{"description":"Use specified hook script.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"script"},{"definition":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stdexcludes"},{"definition":{"description":"Write tar to stdout, not to a file.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stdout"},{"definition":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stop"},{"definition":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"stopwait"},{"definition":{"description":"Store resulting file to this storage.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Store temporary files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tmpdir"},{"definition":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vmid"},{"definition":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, N>0 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"zstd"}],"permissions":{"description":"The user needs 'VM.Backup' permissions on any VM, and 'Datastore.AllocateSpace' on the backup storage. The 'tmpdir', 'dumpdir' and 'script' parameters are restricted to the 'root@pam' user. The 'maxfiles' and 'prune-backups' settings require 'Datastore.Allocate' on the backup storage. The 'bwlimit', 'performance' and 'ionice' parameters require 'Sys.Modify' on '/'.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/vzdump"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b4468def4c988ea5e1c226ba861f7a410b42fdb078291f3a3ec3916c3adcfc04","description":"Get the currently configured vzdump defaults.","extra":{"proxyto":"node"},"name":"defaults","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"}],"permissions":{"description":"The user needs 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions for the specified storage (or default storage if none specified). Some properties are only returned when the user has 'Sys.Audit' permissions for the node.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"all":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bwlimit":{"default":0,"description":"Limit I/O bandwidth (KBytes per second).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"compress":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"dumpdir":{"description":"Store resulting files to specified directory.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"exclude":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"exclude-path":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{},"format":"string-alist","optional":true,"properties":{},"type":"string"},"ionice":{"default":7,"description":"Set CFQ ionice priority.","enum":[],"extra":{},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"lockwait":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"mailnotification":{"default":"always","description":"Specify when to send an email","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"mailto":{"description":"Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"maxfiles":{"description":"Deprecated: use 'prune-backups' instead. Maximal number of backup files per guest system.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"mode":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"node":{"description":"Only run if executed on this node.","enum":[],"extra":{},"format":"pve-node","optional":true,"properties":{},"type":"string"},"notes-template":{"description":"Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.","enum":[],"extra":{"requires":"storage"},"max_length":1024,"optional":true,"properties":{},"type":"string"},"performance":{"description":"Other performance-related settings.","enum":[],"extra":{},"format":"backup-performance","optional":true,"properties":{},"type":"string"},"pigz":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"pool":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"protected":{"description":"If true, mark backup(s) as protected.","enum":[],"extra":{"requires":"storage"},"optional":true,"properties":{},"type":"boolean"},"prune-backups":{"default":"keep-all=1","description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"quiet":{"default":0,"description":"Be quiet.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"remove":{"default":1,"description":"Prune older backups according to 'prune-backups'.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"script":{"description":"Use specified hook script.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"stdexcludes":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"stop":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"stopwait":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"storage":{"description":"Store resulting file to this storage.","enum":[],"extra":{},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"tmpdir":{"description":"Store temporary files to specified directory.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vmid":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"zstd":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, N>0 uses N as thread count.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/vzdump/defaults"},{"extra":{},"methods":[{"allow_token":true,"checksum":"46b5389418506fa5f7d2d85017d6a32be6b0374dbb76191ec24067f39e16e8d9","description":"Extract configuration from vzdump backup archive.","extra":{"proxyto":"node"},"name":"extractconfig","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"The user needs 'VM.Backup' permissions on the backed up guest ID, and 'Datastore.AllocateSpace' on the backup storage.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/vzdump/extractconfig"},{"extra":{},"methods":[{"allow_token":true,"checksum":"08ea4b11d331163e4a96a0c898ba2d8587d9560fda14d97304383f4248499e0e","description":"Try to wake a node via 'wake on LAN' network packet.","extra":{},"name":"wakeonlan","parameters":[{"definition":{"description":"target node for wake on LAN packet","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"description":"MAC address used to assemble the WoL magic packet.","enum":[],"extra":{},"format":"mac-addr","properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/wakeonlan"},{"extra":{},"methods":[{"allow_token":true,"checksum":"aec12d7bad2993ba143fbbcda653242e63efdda978378d1ccdb5908ea79d7462","description":"Pool index.","extra":{},"name":"index","parameters":[],"permissions":{"description":"List all pools where you have Pool.Audit permissions on /pool/.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{poolid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"poolid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"a2cb3cd45802791e51049833b8254ee8828f1f7e701c0fad2bf797ed4c4ed346","description":"Create new pool.","extra":{},"name":"create_pool","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"}],"permissions":{"expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/pools"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f4566d45dc0a2a49009509edfd1756bd72eabd7f60446d1184660ea5bc43c1f7","description":"Delete pool.","extra":{},"name":"delete_pool","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"}],"permissions":{"description":"You can only delete empty pools (no members).","expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"9b7febc5eba84d27b0f28bbdf1679044ae427e4ee5f95e58649209f1fc38ba93","description":"Get pool configuration.","extra":{},"name":"read_pool","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"},{"definition":{"enum":["qemu","lxc","storage"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/pool/{poolid}",["Pool.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"members":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"node":{"enum":[],"extra":{},"properties":{},"type":"string"},"storage":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":["qemu","lxc","openvz","storage"],"extra":{},"properties":{},"type":"string"},"vmid":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"5d1092c81fe8cc5f00d2f51bca45b5cc0354a7c74896ae61002543445f11b894","description":"Update pool data.","extra":{},"name":"update_pool","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Remove vms/storage (instead of adding it).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"},{"definition":{"description":"List of storage IDs.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id-list","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"List of virtual machines.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"}],"permissions":{"description":"You also need the right to modify permissions on any object you add/delete.","expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/pools/{poolid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3f08bcb6cdcb64d4b27498bade278f3e0f4f4e8ea744bb16c8f18e744775cb9e","description":"Storage index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list storage of specific type","enum":["btrfs","cephfs","cifs","dir","glusterfs","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{storage}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"storage":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"3e7a40f43a7d98bc91000be1aff555b9af050f6bdbfe123fa4d6eb2abfb7d94a","description":"Create a new storage.","extra":{},"name":"create","parameters":[{"definition":{"description":"Authsupported.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"authsupported"},{"definition":{"description":"Base volume. This volume is automatically activated.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"base"},{"definition":{"description":"block size","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"blocksize"},{"definition":{"description":"Set bandwidth/io limits various operations.","enum":[],"extra":{"typetext":"[clone=] [,default=] [,migration=] [,move=] [,restore=]"},"format":{"clone":{"description":"bandwidth limit in KiB/s for cloning disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"default":{"description":"default bandwidth limit in KiB/s","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"migration":{"description":"bandwidth limit in KiB/s for migrating guests (including moving local disks)","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"move":{"description":"bandwidth limit in KiB/s for moving disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"restore":{"description":"bandwidth limit in KiB/s for restoring guests from backups","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"}},"optional":true,"properties":{},"type":"string"},"name":"bwlimit"},{"definition":{"description":"host group for comstar views","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comstar_hg"},{"definition":{"description":"target group for comstar views","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comstar_tg"},{"definition":{"description":"Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n","enum":[],"extra":{"typetext":""},"format":"pve-storage-content-list","optional":true,"properties":{},"type":"string"},"name":"content"},{"definition":{"description":"Overrides for default content type directories.","enum":[],"extra":{"typetext":""},"format":"pve-dir-override-list","optional":true,"properties":{},"type":"string"},"name":"content-dirs"},{"definition":{"description":"Data Pool (for erasure coding only)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"data-pool"},{"definition":{"description":"Proxmox Backup Server datastore name.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"datastore"},{"definition":{"description":"Flag to disable the storage.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"CIFS domain.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"Encryption key. Use 'autogen' to generate one automatically without passphrase.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"encryption-key"},{"definition":{"description":"NFS export path.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"export"},{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"Default image format.","enum":[],"extra":{"typetext":""},"format":"pve-storage-format","optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"The Ceph filesystem name.","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"fs-name"},{"definition":{"description":"Mount CephFS through FUSE.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"fuse"},{"definition":{"default":"no","description":"Assume the given path is an externally managed mountpoint and consider the storage offline if it is not mounted. Using a boolean (yes/no) value serves as a shortcut to using the target path in this field.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"is_mountpoint"},{"definition":{"description":"iscsi provider","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"iscsiprovider"},{"definition":{"description":"Client keyring contents (for external clusters).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"keyring"},{"definition":{"description":"Always access rbd through krbd kernel module.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"krbd"},{"definition":{"description":"target portal group for Linux LIO targets","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lio_tpg"},{"definition":{"description":"Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"master-pubkey"},{"definition":{"default":"Unlimited for users with Datastore.Allocate privilege, 5 for other users","description":"Maximal number of protected backups per guest. Use '-1' for unlimited.","enum":[],"extra":{"typetext":" (-1 - N)"},"minimum":-1,"optional":true,"properties":{},"type":"integer"},"name":"max-protected-backups"},{"definition":{"description":"Deprecated: use 'prune-backups' instead. Maximal number of backup files per VM. Use '0' for unlimited.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"maxfiles"},{"definition":{"default":"yes","description":"Create the directory if it doesn't exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"mkdir"},{"definition":{"description":"IP addresses of monitors (for external clusters).","enum":[],"extra":{"typetext":""},"format":"pve-storage-portal-dns-list","optional":true,"properties":{},"type":"string"},"name":"monhost"},{"definition":{"description":"mount point","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"mountpoint"},{"definition":{"description":"Namespace.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"namespace"},{"definition":{"default":0,"description":"Set the NOCOW flag on files. Disables data checksumming and causes data errors to be unrecoverable from while allowing direct I/O. Only use this if data does not need to be any more safe than on a single ext4 formatted disk with no underlying raid system.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nocow"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"disable write caching on the target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nowritecache"},{"definition":{"description":"NFS mount options (see 'man nfs')","enum":[],"extra":{"typetext":""},"format":"pve-storage-options","optional":true,"properties":{},"type":"string"},"name":"options"},{"definition":{"description":"Password for accessing the share/datastore.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"File system path.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"Pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"default":8007,"description":"For non default port.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"iSCSI portal (IP or DNS name with optional port).","enum":[],"extra":{"typetext":""},"format":"pve-storage-portal-dns","optional":true,"properties":{},"type":"string"},"name":"portal"},{"definition":{"default":"metadata","description":"Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off.","enum":["off","metadata","falloc","full"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"preallocation"},{"definition":{"description":"The retention options with shorter intervals are processed first with --keep-last being the very first one. Each option covers a specific period of time. We say that backups within this period are covered by this option. The next option does not take care of already covered backups and only considers older backups.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"description":"Zero-out data when removing LVs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"saferemove"},{"definition":{"description":"Wipe throughput (cstream -t parameter value).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"saferemove_throughput"},{"definition":{"description":"Server IP or DNS name.","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","optional":true,"properties":{},"type":"string"},"name":"server"},{"definition":{"description":"Backup volfile server IP or DNS name.","enum":[],"extra":{"requires":"server","typetext":""},"format":"pve-storage-server","optional":true,"properties":{},"type":"string"},"name":"server2"},{"definition":{"description":"CIFS share.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"share"},{"definition":{"description":"Mark storage as shared.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"shared"},{"definition":{"default":"default","description":"SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server.","enum":["default","2.0","2.1","3","3.0","3.11"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"smbversion"},{"definition":{"description":"use sparse volumes","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"sparse"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Subdir to mount.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"subdir"},{"definition":{"description":"Only use logical volumes tagged with 'pve-vm-ID'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tagged_only"},{"definition":{"description":"iSCSI target.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"LVM thin pool LV name.","enum":[],"extra":{"typetext":""},"format":"pve-storage-vgname","optional":true,"properties":{},"type":"string"},"name":"thinpool"},{"definition":{"description":"Gluster transport: tcp or rdma","enum":["tcp","rdma","unix"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"transport"},{"definition":{"description":"Storage type.","enum":["btrfs","cephfs","cifs","dir","glusterfs","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"RBD Id.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username"},{"definition":{"description":"Volume group name.","enum":[],"extra":{"typetext":""},"format":"pve-storage-vgname","optional":true,"properties":{},"type":"string"},"name":"vgname"},{"definition":{"description":"Glusterfs Volume.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"volume"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"config":{"description":"Partial, possible server generated, configuration properties.","enum":[],"extra":{"additionalProperties":1},"optional":true,"properties":{"encryption-key":{"description":"The, possible auto-generated, encryption-key.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"storage":{"description":"The ID of the created storage.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The type of the created storage.","enum":["btrfs","cephfs","cifs","dir","glusterfs","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"POST"}],"path":"/storage"},{"extra":{},"methods":[{"allow_token":true,"checksum":"07c09ccad12cdd559d663c2f45c8eb672506c8e764311ca5ccd2bd07698f0ce4","description":"Delete storage configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"5e124a73a6f726240a993f3e601a732af79e780bc88d085a5822c5170d7060b8","description":"Read storage configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"4dae34290b7c659babc0d0c24aba3ce8fc6e6b0ee69c6b0228f551a13a37cd8a","description":"Update storage configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"block size","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"blocksize"},{"definition":{"description":"Set bandwidth/io limits various operations.","enum":[],"extra":{"typetext":"[clone=] [,default=] [,migration=] [,move=] [,restore=]"},"format":{"clone":{"description":"bandwidth limit in KiB/s for cloning disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"default":{"description":"default bandwidth limit in KiB/s","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"migration":{"description":"bandwidth limit in KiB/s for migrating guests (including moving local disks)","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"move":{"description":"bandwidth limit in KiB/s for moving disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"restore":{"description":"bandwidth limit in KiB/s for restoring guests from backups","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"}},"optional":true,"properties":{},"type":"string"},"name":"bwlimit"},{"definition":{"description":"host group for comstar views","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comstar_hg"},{"definition":{"description":"target group for comstar views","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comstar_tg"},{"definition":{"description":"Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n","enum":[],"extra":{"typetext":""},"format":"pve-storage-content-list","optional":true,"properties":{},"type":"string"},"name":"content"},{"definition":{"description":"Overrides for default content type directories.","enum":[],"extra":{"typetext":""},"format":"pve-dir-override-list","optional":true,"properties":{},"type":"string"},"name":"content-dirs"},{"definition":{"description":"Data Pool (for erasure coding only)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"data-pool"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Flag to disable the storage.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"CIFS domain.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"Encryption key. Use 'autogen' to generate one automatically without passphrase.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"encryption-key"},{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"Default image format.","enum":[],"extra":{"typetext":""},"format":"pve-storage-format","optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"The Ceph filesystem name.","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"fs-name"},{"definition":{"description":"Mount CephFS through FUSE.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"fuse"},{"definition":{"default":"no","description":"Assume the given path is an externally managed mountpoint and consider the storage offline if it is not mounted. Using a boolean (yes/no) value serves as a shortcut to using the target path in this field.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"is_mountpoint"},{"definition":{"description":"Client keyring contents (for external clusters).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"keyring"},{"definition":{"description":"Always access rbd through krbd kernel module.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"krbd"},{"definition":{"description":"target portal group for Linux LIO targets","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lio_tpg"},{"definition":{"description":"Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"master-pubkey"},{"definition":{"default":"Unlimited for users with Datastore.Allocate privilege, 5 for other users","description":"Maximal number of protected backups per guest. Use '-1' for unlimited.","enum":[],"extra":{"typetext":" (-1 - N)"},"minimum":-1,"optional":true,"properties":{},"type":"integer"},"name":"max-protected-backups"},{"definition":{"description":"Deprecated: use 'prune-backups' instead. Maximal number of backup files per VM. Use '0' for unlimited.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"maxfiles"},{"definition":{"default":"yes","description":"Create the directory if it doesn't exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"mkdir"},{"definition":{"description":"IP addresses of monitors (for external clusters).","enum":[],"extra":{"typetext":""},"format":"pve-storage-portal-dns-list","optional":true,"properties":{},"type":"string"},"name":"monhost"},{"definition":{"description":"mount point","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"mountpoint"},{"definition":{"description":"Namespace.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"namespace"},{"definition":{"default":0,"description":"Set the NOCOW flag on files. Disables data checksumming and causes data errors to be unrecoverable from while allowing direct I/O. Only use this if data does not need to be any more safe than on a single ext4 formatted disk with no underlying raid system.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nocow"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"disable write caching on the target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nowritecache"},{"definition":{"description":"NFS mount options (see 'man nfs')","enum":[],"extra":{"typetext":""},"format":"pve-storage-options","optional":true,"properties":{},"type":"string"},"name":"options"},{"definition":{"description":"Password for accessing the share/datastore.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"default":8007,"description":"For non default port.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"default":"metadata","description":"Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off.","enum":["off","metadata","falloc","full"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"preallocation"},{"definition":{"description":"The retention options with shorter intervals are processed first with --keep-last being the very first one. Each option covers a specific period of time. We say that backups within this period are covered by this option. The next option does not take care of already covered backups and only considers older backups.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"description":"Zero-out data when removing LVs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"saferemove"},{"definition":{"description":"Wipe throughput (cstream -t parameter value).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"saferemove_throughput"},{"definition":{"description":"Server IP or DNS name.","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","optional":true,"properties":{},"type":"string"},"name":"server"},{"definition":{"description":"Backup volfile server IP or DNS name.","enum":[],"extra":{"requires":"server","typetext":""},"format":"pve-storage-server","optional":true,"properties":{},"type":"string"},"name":"server2"},{"definition":{"description":"Mark storage as shared.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"shared"},{"definition":{"default":"default","description":"SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server.","enum":["default","2.0","2.1","3","3.0","3.11"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"smbversion"},{"definition":{"description":"use sparse volumes","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"sparse"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Subdir to mount.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"subdir"},{"definition":{"description":"Only use logical volumes tagged with 'pve-vm-ID'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tagged_only"},{"definition":{"description":"Gluster transport: tcp or rdma","enum":["tcp","rdma","unix"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"transport"},{"definition":{"description":"RBD Id.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"config":{"description":"Partial, possible server generated, configuration properties.","enum":[],"extra":{"additionalProperties":1},"optional":true,"properties":{"encryption-key":{"description":"The, possible auto-generated, encryption-key.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"storage":{"description":"The ID of the created storage.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The type of the created storage.","enum":["btrfs","cephfs","cifs","dir","glusterfs","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"PUT"}],"path":"/storage/{storage}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"12fc0a9e2a3099bb432134fd12b05062497f41401846c722d06d3785d3fb1eab","description":"API version details, including some parts of the global datacenter config.","extra":{},"name":"version","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"console":{"description":"The default console viewer to use.","enum":["applet","vv","html5","xtermjs"],"extra":{},"optional":true,"properties":{},"type":"string"},"release":{"description":"The current Proxmox VE point release in `x.y` format.","enum":[],"extra":{},"properties":{},"type":"string"},"repoid":{"description":"The short git revision from which this version was build.","enum":[],"extra":{},"properties":{},"type":"string"},"version":{"description":"The full pve-manager package version of this node.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/version"}],"raw_sha256":"125f0af24951e901800e49559593678edd95af66da27c88311faecda708ebaf1","retrieved_at":"2026-07-15T10:49:39.339893Z","source_version":"7.4-16"} \ No newline at end of file diff --git a/contracts/96cd7121e75cdb3efd58f79ca988f6b235a2f28e6f7eae276ae243f65d8a6724/manifest.json b/contracts/96cd7121e75cdb3efd58f79ca988f6b235a2f28e6f7eae276ae243f65d8a6724/manifest.json new file mode 100644 index 0000000..4d730a7 --- /dev/null +++ b/contracts/96cd7121e75cdb3efd58f79ca988f6b235a2f28e6f7eae276ae243f65d8a6724/manifest.json @@ -0,0 +1 @@ +{"method_count":504,"path_count":338,"raw_sha256":"374156fc7188fb23c40982d0ff63fb7dce601f80f7319032bbb94882f47af69f","snapshot_sha256":"96cd7121e75cdb3efd58f79ca988f6b235a2f28e6f7eae276ae243f65d8a6724","source_version":"6.4-15"} \ No newline at end of file diff --git a/contracts/96cd7121e75cdb3efd58f79ca988f6b235a2f28e6f7eae276ae243f65d8a6724/raw.js b/contracts/96cd7121e75cdb3efd58f79ca988f6b235a2f28e6f7eae276ae243f65d8a6724/raw.js new file mode 100644 index 0000000..b286dcf --- /dev/null +++ b/contracts/96cd7121e75cdb3efd58f79ca988f6b235a2f28e6f7eae276ae243f65d8a6724/raw.js @@ -0,0 +1,45726 @@ +var pveapi = [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Mark replication job for removal.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "Will remove the jobconfig entry, but will not cleanup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "keep" : { + "default" : 0, + "description" : "Keep replicated data at target (do not remove).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read replication job configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/.", + "user" : "all" + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update replication job configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable/deactivate the entry.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 1, + "optional" : 1, + "type" : "number", + "typetext" : " (1 - N)" + }, + "remove_job" : { + "description" : "Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.", + "enum" : [ + "local", + "full" + ], + "optional" : 1, + "type" : "string" + }, + "schedule" : { + "default" : "*/15", + "description" : "Storage replication schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "For internal use, to detect if the guest was stolen.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/replication/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List replication jobs.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new replication job", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable/deactivate the entry.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 1, + "optional" : 1, + "type" : "number", + "typetext" : " (1 - N)" + }, + "remove_job" : { + "description" : "Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.", + "enum" : [ + "local", + "full" + ], + "optional" : 1, + "type" : "string" + }, + "schedule" : { + "default" : "*/15", + "description" : "Storage replication schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "For internal use, to detect if the guest was stolen.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Section type.", + "enum" : [ + "local" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/replication", + "text" : "replication" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove Metric server.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read metric server configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new external metric server config", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "api-path-prefix" : { + "description" : "An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bucket" : { + "description" : "The InfluxDB bucket/db. Only necessary when using the http v2 api.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the plugin.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the entry.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "influxdbproto" : { + "default" : "udp", + "enum" : [ + "udp", + "http", + "https" + ], + "optional" : 1, + "type" : "string" + }, + "max-body-size" : { + "default" : 25000000, + "description" : "InfluxDB max-body-size in bytes. Requests are batched up to this size.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mtu" : { + "default" : 1500, + "description" : "MTU for metrics transmission over UDP", + "maximum" : 65536, + "minimum" : 512, + "optional" : 1, + "type" : "integer", + "typetext" : " (512 - 65536)" + }, + "organization" : { + "description" : "The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "root graphite path (ex: proxmox.mycluster.mykey)", + "format" : "graphite-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "server network port", + "maximum" : 65536, + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - 65536)" + }, + "proto" : { + "description" : "Protocol to send graphite data. TCP or UDP (default)", + "enum" : [ + "udp", + "tcp" + ], + "optional" : 1, + "type" : "string" + }, + "server" : { + "description" : "server dns name or IP address", + "format" : "address", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 1, + "description" : "graphite TCP socket timeout (default=1)", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "token" : { + "description" : "The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "graphite", + "influxdb" + ], + "format" : "pve-configid", + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update metric server configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "api-path-prefix" : { + "description" : "An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bucket" : { + "description" : "The InfluxDB bucket/db. Only necessary when using the http v2 api.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the plugin.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the entry.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "influxdbproto" : { + "default" : "udp", + "enum" : [ + "udp", + "http", + "https" + ], + "optional" : 1, + "type" : "string" + }, + "max-body-size" : { + "default" : 25000000, + "description" : "InfluxDB max-body-size in bytes. Requests are batched up to this size.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mtu" : { + "default" : 1500, + "description" : "MTU for metrics transmission over UDP", + "maximum" : 65536, + "minimum" : 512, + "optional" : 1, + "type" : "integer", + "typetext" : " (512 - 65536)" + }, + "organization" : { + "description" : "The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "root graphite path (ex: proxmox.mycluster.mykey)", + "format" : "graphite-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "server network port", + "maximum" : 65536, + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - 65536)" + }, + "proto" : { + "description" : "Protocol to send graphite data. TCP or UDP (default)", + "enum" : [ + "udp", + "tcp" + ], + "optional" : 1, + "type" : "string" + }, + "server" : { + "description" : "server dns name or IP address", + "format" : "address", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 1, + "description" : "graphite TCP socket timeout (default=1)", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "token" : { + "description" : "The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/metrics/server/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List configured metric servers.", + "method" : "GET", + "name" : "server_index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "disable" : { + "description" : "Flag to disable the plugin.", + "type" : "boolean" + }, + "id" : { + "description" : "The ID of the entry.", + "type" : "string" + }, + "port" : { + "description" : "Server network port", + "type" : "integer" + }, + "server" : { + "description" : "Server dns name or IP address", + "type" : "string" + }, + "type" : { + "description" : "Plugin type.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/metrics/server", + "text" : "server" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Metrics index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/metrics", + "text" : "metrics" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Return the version of the cluster join API available on this node.", + "method" : "GET", + "name" : "join_api_version", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "description" : "Cluster Join API version, currently 1", + "minimum" : 0, + "type" : "integer" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/apiversion", + "text" : "apiversion" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Removes a node from the cluster configuration.", + "method" : "DELETE", + "name" : "delnode", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Adds a node to the cluster configuration. This call is for internal use.", + "method" : "POST", + "name" : "addnode", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "apiversion" : { + "description" : "The JOIN_API_VERSION of the new node.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "force" : { + "description" : "Do not throw error if node already exists.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "link[n]" : { + "description" : "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)", + "format" : { + "address" : { + "default_key" : 1, + "description" : "Hostname (or IP) of this corosync link address.", + "format" : "address", + "format_description" : "IP", + "type" : "string" + }, + "priority" : { + "default" : 0, + "description" : "The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.", + "maximum" : 255, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[address=] [,priority=]" + }, + "new_node_ip" : { + "description" : "IP Address of node to add. Used as fallback if no links are given.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nodeid" : { + "description" : "Node id for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "votes" : { + "description" : "Number of votes for this node", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "protected" : 1, + "returns" : { + "properties" : { + "corosync_authkey" : { + "type" : "string" + }, + "corosync_conf" : { + "type" : "string" + }, + "warnings" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/nodes/{node}", + "text" : "{node}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Corosync node list.", + "method" : "GET", + "name" : "nodes", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "node" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{node}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/config/nodes", + "text" : "nodes" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get information needed to join this cluster over the connected node.", + "method" : "GET", + "name" : "join_info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "default" : "current connected node", + "description" : "The node for which the joinee gets the nodeinfo. ", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "config_digest" : { + "type" : "string" + }, + "nodelist" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "name" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "nodeid" : { + "description" : "Node id for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "pve_addr" : { + "format" : "ip", + "type" : "string" + }, + "pve_fp" : { + "description" : "Certificate SHA 256 fingerprint.", + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "quorum_votes" : { + "minimum" : 0, + "type" : "integer" + }, + "ring0_addr" : { + "description" : "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)", + "format" : { + "address" : { + "default_key" : 1, + "description" : "Hostname (or IP) of this corosync link address.", + "format" : "address", + "format_description" : "IP", + "type" : "string" + }, + "priority" : { + "default" : 0, + "description" : "The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.", + "maximum" : 255, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "preferred_node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "totem" : { + "type" : "object" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Joins this node into an existing cluster. If no links are given, default to IP resolved by node's hostname on single link (fallback fails for clusters with multiple links).", + "method" : "POST", + "name" : "join", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "force" : { + "description" : "Do not throw error if node already exists.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hostname" : { + "description" : "Hostname (or IP) of an existing cluster member.", + "type" : "string", + "typetext" : "" + }, + "link[n]" : { + "description" : "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)", + "format" : { + "address" : { + "default_key" : 1, + "description" : "Hostname (or IP) of this corosync link address.", + "format" : "address", + "format_description" : "IP", + "type" : "string" + }, + "priority" : { + "default" : 0, + "description" : "The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.", + "maximum" : 255, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[address=] [,priority=]" + }, + "nodeid" : { + "description" : "Node id for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "password" : { + "description" : "Superuser (root) password of peer node.", + "maxLength" : 128, + "type" : "string", + "typetext" : "" + }, + "votes" : { + "description" : "Number of votes for this node", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/join", + "text" : "join" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get corosync totem protocol settings.", + "method" : "GET", + "name" : "totem", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/totem", + "text" : "totem" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get QDevice status", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/qdevice", + "text" : "qdevice" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Generate new cluster configuration. If no links given, default to local IP address as link0.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "clustername" : { + "description" : "The name of the cluster.", + "format" : "pve-node", + "maxLength" : 15, + "type" : "string", + "typetext" : "" + }, + "link[n]" : { + "description" : "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)", + "format" : { + "address" : { + "default_key" : 1, + "description" : "Hostname (or IP) of this corosync link address.", + "format" : "address", + "format_description" : "IP", + "type" : "string" + }, + "priority" : { + "default" : 0, + "description" : "The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.", + "maximum" : 255, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[address=] [,priority=]" + }, + "nodeid" : { + "description" : "Node id for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "votes" : { + "description" : "Number of votes for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/config", + "text" : "config" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "dest" : { + "optional" : 1, + "type" : "string" + }, + "dport" : { + "optional" : 1, + "type" : "string" + }, + "enable" : { + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "optional" : 1, + "type" : "string" + }, + "iface" : { + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "optional" : 1, + "type" : "string" + }, + "pos" : { + "type" : "integer" + }, + "proto" : { + "optional" : 1, + "type" : "string" + }, + "source" : { + "optional" : 1, + "type" : "string" + }, + "sport" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/groups/{group}/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete security group.", + "method" : "DELETE", + "name" : "delete_security_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "pos" : { + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 0, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/groups/{group}", + "text" : "{group}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List security groups.", + "method" : "GET", + "name" : "list_security_groups", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{group}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new security group.", + "method" : "POST", + "name" : "create_security_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "rename" : { + "description" : "Rename/update an existing security group. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing group.", + "maxLength" : 18, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/groups", + "text" : "groups" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "dest" : { + "optional" : 1, + "type" : "string" + }, + "dport" : { + "optional" : 1, + "type" : "string" + }, + "enable" : { + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "optional" : 1, + "type" : "string" + }, + "iface" : { + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "optional" : 1, + "type" : "string" + }, + "pos" : { + "type" : "integer" + }, + "proto" : { + "optional" : 1, + "type" : "string" + }, + "source" : { + "optional" : 1, + "type" : "string" + }, + "sport" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "pos" : { + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 0, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/rules", + "text" : "rules" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network from IPSet.", + "method" : "DELETE", + "name" : "remove_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read IP or Network settings from IPSet.", + "method" : "GET", + "name" : "read_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network settings", + "method" : "PUT", + "name" : "update_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/ipset/{name}/{cidr}", + "text" : "{cidr}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete IPSet", + "method" : "DELETE", + "name" : "delete_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List IPSet content", + "method" : "GET", + "name" : "get_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{cidr}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add IP or Network to IPSet.", + "method" : "POST", + "name" : "create_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/ipset/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List IPSets", + "method" : "GET", + "name" : "ipset_index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new IPSet", + "method" : "POST", + "name" : "create_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "rename" : { + "description" : "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/ipset", + "text" : "ipset" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network alias.", + "method" : "DELETE", + "name" : "remove_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read alias.", + "method" : "GET", + "name" : "read_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network alias.", + "method" : "PUT", + "name" : "update_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "rename" : { + "description" : "Rename an existing alias.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/aliases/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List aliases", + "method" : "GET", + "name" : "get_aliases", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create IP or Network Alias.", + "method" : "POST", + "name" : "create_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/aliases", + "text" : "aliases" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "properties" : { + "ebtables" : { + "default" : 1, + "description" : "Enable ebtables rules cluster wide.", + "optional" : 1, + "type" : "boolean" + }, + "enable" : { + "description" : "Enable or disable the firewall cluster wide.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "log_ratelimit" : { + "description" : "Log ratelimiting settings", + "format" : { + "burst" : { + "default" : 5, + "description" : "Initial burst of packages which will always get logged before the rate is applied", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "enable" : { + "default" : "1", + "default_key" : 1, + "description" : "Enable or disable log rate limiting", + "type" : "boolean" + }, + "rate" : { + "default" : "1/second", + "description" : "Frequency with which the burst bucket gets refilled", + "format_description" : "rate", + "optional" : 1, + "pattern" : "[1-9][0-9]*\\/(second|minute|hour|day)", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ebtables" : { + "default" : 1, + "description" : "Enable ebtables rules cluster wide.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "enable" : { + "description" : "Enable or disable the firewall cluster wide.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "log_ratelimit" : { + "description" : "Log ratelimiting settings", + "format" : { + "burst" : { + "default" : 5, + "description" : "Initial burst of packages which will always get logged before the rate is applied", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "enable" : { + "default" : "1", + "default_key" : 1, + "description" : "Enable or disable log rate limiting", + "type" : "boolean" + }, + "rate" : { + "default" : "1/second", + "description" : "Frequency with which the burst bucket gets refilled", + "format_description" : "rate", + "optional" : 1, + "pattern" : "[1-9][0-9]*\\/(second|minute|hour|day)", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[enable=]<1|0> [,burst=] [,rate=]" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List available macros", + "method" : "GET", + "name" : "get_macros", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "descr" : { + "description" : "More verbose description (if available).", + "type" : "string" + }, + "macro" : { + "description" : "Macro name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/macros", + "text" : "macros" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Lists possible IPSet/Alias reference which are allowed in source/dest properties.", + "method" : "GET", + "name" : "refs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list references of specified type.", + "enum" : [ + "alias", + "ipset" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "ref" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "alias", + "ipset" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/refs", + "text" : "refs" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall", + "text" : "firewall" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns included guests and the backup status of their disks. Optimized to be used in ExtJS tree views.", + "method" : "GET", + "name" : "get_volume_backup_included", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "Root node of the tree object. Children represent guests, grandchildren represent volumes of that guest.", + "properties" : { + "children" : { + "items" : { + "properties" : { + "children" : { + "description" : "The volumes of the guest with the information if they will be included in backups.", + "items" : { + "properties" : { + "id" : { + "description" : "Configuration key of the volume.", + "type" : "string" + }, + "included" : { + "description" : "Whether the volume is included in the backup or not.", + "type" : "boolean" + }, + "name" : { + "description" : "Name of the volume.", + "type" : "string" + }, + "reason" : { + "description" : "The reason why the volume is included (or excluded).", + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "id" : { + "description" : "VMID of the guest.", + "type" : "integer" + }, + "name" : { + "description" : "Name of the guest", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Type of the guest, VM, CT or unknown for removed but not purged guests.", + "enum" : [ + "qemu", + "lxc", + "unknown" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/backup/{id}/included_volumes", + "text" : "included_volumes" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete vzdump backup job definition.", + "method" : "DELETE", + "name" : "delete_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read vzdump backup job definition.", + "method" : "GET", + "name" : "read_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update vzdump backup job definition.", + "method" : "PUT", + "name" : "update_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (KBytes per second).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dow" : { + "description" : "Day of week selection.", + "format" : "pve-day-of-week-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enabled" : { + "default" : "1", + "description" : "Enable or disable the job.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "format" : "string-alist", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "type" : "string", + "typetext" : "" + }, + "ionice" : { + "default" : 7, + "description" : "Set CFQ ionice priority.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 8)" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mailnotification" : { + "default" : "always", + "description" : "Specify when to send an email", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "maxfiles" : { + "default" : 1, + "description" : "Maximal number of backup files per guest system.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "prune-backups" : { + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove" : { + "default" : 1, + "description" : "Remove old backup files if there are more than 'maxfiles' backup files.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "size" : { + "default" : 1024, + "description" : "Unused, will be removed in a future release.", + "minimum" : 500, + "optional" : 1, + "type" : "integer", + "typetext" : " (500 - N)" + }, + "starttime" : { + "description" : "Job Start time.", + "pattern" : "\\d{1,2}:\\d{1,2}", + "type" : "string", + "typetext" : "HH:MM" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, N>0 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/backup/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List vzdump backup schedule.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new vzdump backup job.", + "method" : "POST", + "name" : "create_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (KBytes per second).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "dow" : { + "default" : "mon,tue,wed,thu,fri,sat,sun", + "description" : "Day of week selection.", + "format" : "pve-day-of-week-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enabled" : { + "default" : "1", + "description" : "Enable or disable the job.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "format" : "string-alist", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ionice" : { + "default" : 7, + "description" : "Set CFQ ionice priority.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 8)" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mailnotification" : { + "default" : "always", + "description" : "Specify when to send an email", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "maxfiles" : { + "default" : 1, + "description" : "Maximal number of backup files per guest system.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "prune-backups" : { + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove" : { + "default" : 1, + "description" : "Remove old backup files if there are more than 'maxfiles' backup files.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "size" : { + "default" : 1024, + "description" : "Unused, will be removed in a future release.", + "minimum" : 500, + "optional" : 1, + "type" : "integer", + "typetext" : " (500 - N)" + }, + "starttime" : { + "description" : "Job Start time.", + "pattern" : "\\d{1,2}:\\d{1,2}", + "type" : "string", + "typetext" : "HH:MM" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, N>0 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/backup", + "text" : "backup" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Shows all guests which are not covered by any backup job.", + "method" : "GET", + "name" : "get_guests_not_in_backup", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "Contains the guest objects.", + "items" : { + "properties" : { + "name" : { + "description" : "Name of the guest", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Type of the guest.", + "enum" : [ + "qemu", + "lxc" + ], + "type" : "string" + }, + "vmid" : { + "description" : "VMID of the guest.", + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/backupinfo/not_backed_up", + "text" : "not_backed_up" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Stub, waits for future use.", + "method" : "GET", + "name" : "get_backupinfo", + "parameters" : { + "additionalProperties" : 0 + }, + "protected" : 1, + "returns" : { + "description" : "Shows stub message", + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/backupinfo", + "text" : "backupinfo" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Request resource migration (online) to another node.", + "method" : "POST", + "name" : "migrate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/resources/{sid}/migrate", + "text" : "migrate" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Request resource relocatzion to another node. This stops the service on the old node, and restarts it on the target node.", + "method" : "POST", + "name" : "relocate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/resources/{sid}/relocate", + "text" : "relocate" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete resource configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read resource configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "properties" : { + "comment" : { + "description" : "Description.", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Can be used to prevent concurrent modifications.", + "type" : "string" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string" + }, + "max_relocate" : { + "description" : "Maximal number of service relocate tries when a service failes to start.", + "optional" : 1, + "type" : "integer" + }, + "max_restart" : { + "description" : "Maximal number of tries to restart the service on a node after its start failed.", + "optional" : 1, + "type" : "integer" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + }, + "state" : { + "description" : "Requested resource state.", + "enum" : [ + "started", + "stopped", + "enabled", + "disabled", + "ignored" + ], + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "The type of the resources.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update resource configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "max_relocate" : { + "default" : 1, + "description" : "Maximal number of service relocate tries when a service failes to start.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "max_restart" : { + "default" : 1, + "description" : "Maximal number of tries to restart the service on a node after its start failed.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + }, + "state" : { + "default" : "started", + "description" : "Requested resource state.", + "enum" : [ + "started", + "stopped", + "enabled", + "disabled", + "ignored" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Requested resource state. The CRM reads this state and acts accordingly.\nPlease note that `enabled` is just an alias for `started`.\n\n`started`;;\n\nThe CRM tries to start the resource. Service state is\nset to `started` after successful start. On node failures, or when start\nfails, it tries to recover the resource. If everything fails, service\nstate it set to `error`.\n\n`stopped`;;\n\nThe CRM tries to keep the resource in `stopped` state, but it\nstill tries to relocate the resources on node failures.\n\n`disabled`;;\n\nThe CRM tries to put the resource in `stopped` state, but does not try\nto relocate the resources on node failures. The main purpose of this\nstate is error recovery, because it is the only way to move a resource out\nof the `error` state.\n\n`ignored`;;\n\nThe resource gets removed from the manager status and so the CRM and the LRM do\nnot touch the resource anymore. All {pve} API calls affecting this resource\nwill be executed, directly bypassing the HA stack. CRM commands will be thrown\naway while there source is in this state. The resource will not get relocated\non node failures.\n\n" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/resources/{sid}", + "text" : "{sid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List HA resources.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list resources of specific type", + "enum" : [ + "ct", + "vm" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "sid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{sid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new HA resource.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "max_relocate" : { + "default" : 1, + "description" : "Maximal number of service relocate tries when a service failes to start.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "max_restart" : { + "default" : 1, + "description" : "Maximal number of tries to restart the service on a node after its start failed.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + }, + "state" : { + "default" : "started", + "description" : "Requested resource state.", + "enum" : [ + "started", + "stopped", + "enabled", + "disabled", + "ignored" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Requested resource state. The CRM reads this state and acts accordingly.\nPlease note that `enabled` is just an alias for `started`.\n\n`started`;;\n\nThe CRM tries to start the resource. Service state is\nset to `started` after successful start. On node failures, or when start\nfails, it tries to recover the resource. If everything fails, service\nstate it set to `error`.\n\n`stopped`;;\n\nThe CRM tries to keep the resource in `stopped` state, but it\nstill tries to relocate the resources on node failures.\n\n`disabled`;;\n\nThe CRM tries to put the resource in `stopped` state, but does not try\nto relocate the resources on node failures. The main purpose of this\nstate is error recovery, because it is the only way to move a resource out\nof the `error` state.\n\n`ignored`;;\n\nThe resource gets removed from the manager status and so the CRM and the LRM do\nnot touch the resource anymore. All {pve} API calls affecting this resource\nwill be executed, directly bypassing the HA stack. CRM commands will be thrown\naway while there source is in this state. The resource will not get relocated\non node failures.\n\n" + }, + "type" : { + "description" : "Resource type.", + "enum" : [ + "ct", + "vm" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/resources", + "text" : "resources" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete ha group configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read ha group configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : {} + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update ha group configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names with optional priority.", + "format" : "pve-ha-group-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "[:]{,[:]}*", + "verbose_description" : "List of cluster node members, where a priority can be given to each node. A resource bound to a group will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the services will get distributed to those nodes. The priorities have a relative meaning only." + }, + "nofailback" : { + "default" : 0, + "description" : "The CRM tries to run services on the node with the highest priority. If a node with higher priority comes online, the CRM migrates the service to that node. Enabling nofailback prevents that behavior.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restricted" : { + "default" : 0, + "description" : "Resources bound to restricted groups may only run on nodes defined by the group.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Resources bound to restricted groups may only run on nodes defined by the group. The resource will be placed in the stopped state if no group node member is online. Resources on unrestricted groups may run on any cluster node if all group members are offline, but they will migrate back as soon as a group member comes online. One can implement a 'preferred node' behavior using an unrestricted group with only one member." + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/groups/{group}", + "text" : "{group}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get HA groups.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "group" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{group}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new HA group.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names with optional priority.", + "format" : "pve-ha-group-node-list", + "optional" : 0, + "type" : "string", + "typetext" : "[:]{,[:]}*", + "verbose_description" : "List of cluster node members, where a priority can be given to each node. A resource bound to a group will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the services will get distributed to those nodes. The priorities have a relative meaning only." + }, + "nofailback" : { + "default" : 0, + "description" : "The CRM tries to run services on the node with the highest priority. If a node with higher priority comes online, the CRM migrates the service to that node. Enabling nofailback prevents that behavior.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restricted" : { + "default" : 0, + "description" : "Resources bound to restricted groups may only run on nodes defined by the group.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Resources bound to restricted groups may only run on nodes defined by the group. The resource will be placed in the stopped state if no group node member is online. Resources on unrestricted groups may run on any cluster node if all group members are offline, but they will migrate back as soon as a group member comes online. One can implement a 'preferred node' behavior using an unrestricted group with only one member." + }, + "type" : { + "description" : "Group type.", + "enum" : [ + "group" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/groups", + "text" : "groups" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get HA manger status.", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/status/current", + "text" : "current" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get full HA manger status, including LRM status.", + "method" : "GET", + "name" : "manager_status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/status/manager_status", + "text" : "manager_status" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/status", + "text" : "status" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha", + "text" : "ha" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete ACME plugin configuration.", + "method" : "DELETE", + "name" : "delete_plugin", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Unique identifier for ACME plugin instance.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get ACME plugin configuration.", + "method" : "GET", + "name" : "get_plugin_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Unique identifier for ACME plugin instance.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update ACME plugin configuration.", + "method" : "PUT", + "name" : "update_plugin", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "api" : { + "description" : "API plugin name", + "enum" : [ + "1984hosting", + "acmedns", + "acmeproxy", + "active24", + "ad", + "ali", + "anx", + "arvan", + "aurora", + "autodns", + "aws", + "azure", + "cf", + "clouddns", + "cloudns", + "cn", + "conoha", + "constellix", + "cx", + "cyon", + "da", + "ddnss", + "desec", + "df", + "dgon", + "dnsimple", + "do", + "doapi", + "domeneshop", + "dp", + "dpi", + "dreamhost", + "duckdns", + "durabledns", + "dyn", + "dynu", + "dynv6", + "easydns", + "edgedns", + "euserv", + "exoscale", + "freedns", + "gandi_livedns", + "gcloud", + "gd", + "gdnsdk", + "he", + "hetzner", + "hexonet", + "hostingde", + "huaweicloud", + "infoblox", + "infomaniak", + "internetbs", + "inwx", + "ionos", + "ispconfig", + "jd", + "joker", + "kappernet", + "kas", + "kinghost", + "knot", + "leaseweb", + "lexicon", + "linode", + "linode_v4", + "loopia", + "lua", + "maradns", + "me", + "miab", + "misaka", + "myapi", + "mydevil", + "mydnsjp", + "namecheap", + "namecom", + "namesilo", + "nederhost", + "neodigit", + "netcup", + "netlify", + "nic", + "njalla", + "nm", + "nsd", + "nsone", + "nsupdate", + "nw", + "one", + "online", + "openprovider", + "openstack", + "opnsense", + "ovh", + "pdns", + "pleskxml", + "pointhq", + "porkbun", + "rackcorp", + "rackspace", + "rcode0", + "regru", + "scaleway", + "schlundtech", + "selectel", + "servercow", + "simply", + "tele3", + "transip", + "ultra", + "unoeuro", + "variomedia", + "vscale", + "vultr", + "websupport", + "world4you", + "yandex", + "zilore", + "zone", + "zonomi" + ], + "optional" : 1, + "type" : "string" + }, + "data" : { + "description" : "DNS plugin data. (base64 encoded)", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "ACME Plugin ID name", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "validation-delay" : { + "default" : 30, + "description" : "Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.", + "maximum" : 172800, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 172800)" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/plugins/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "ACME plugin index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list ACME plugins of a specific type", + "enum" : [ + "dns", + "standalone" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "plugin" : { + "description" : "Unique identifier for ACME plugin instance.", + "format" : "pve-configid", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{plugin}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add ACME plugin configuration.", + "method" : "POST", + "name" : "add_plugin", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "api" : { + "description" : "API plugin name", + "enum" : [ + "1984hosting", + "acmedns", + "acmeproxy", + "active24", + "ad", + "ali", + "anx", + "arvan", + "aurora", + "autodns", + "aws", + "azure", + "cf", + "clouddns", + "cloudns", + "cn", + "conoha", + "constellix", + "cx", + "cyon", + "da", + "ddnss", + "desec", + "df", + "dgon", + "dnsimple", + "do", + "doapi", + "domeneshop", + "dp", + "dpi", + "dreamhost", + "duckdns", + "durabledns", + "dyn", + "dynu", + "dynv6", + "easydns", + "edgedns", + "euserv", + "exoscale", + "freedns", + "gandi_livedns", + "gcloud", + "gd", + "gdnsdk", + "he", + "hetzner", + "hexonet", + "hostingde", + "huaweicloud", + "infoblox", + "infomaniak", + "internetbs", + "inwx", + "ionos", + "ispconfig", + "jd", + "joker", + "kappernet", + "kas", + "kinghost", + "knot", + "leaseweb", + "lexicon", + "linode", + "linode_v4", + "loopia", + "lua", + "maradns", + "me", + "miab", + "misaka", + "myapi", + "mydevil", + "mydnsjp", + "namecheap", + "namecom", + "namesilo", + "nederhost", + "neodigit", + "netcup", + "netlify", + "nic", + "njalla", + "nm", + "nsd", + "nsone", + "nsupdate", + "nw", + "one", + "online", + "openprovider", + "openstack", + "opnsense", + "ovh", + "pdns", + "pleskxml", + "pointhq", + "porkbun", + "rackcorp", + "rackspace", + "rcode0", + "regru", + "scaleway", + "schlundtech", + "selectel", + "servercow", + "simply", + "tele3", + "transip", + "ultra", + "unoeuro", + "variomedia", + "vscale", + "vultr", + "websupport", + "world4you", + "yandex", + "zilore", + "zone", + "zonomi" + ], + "optional" : 1, + "type" : "string" + }, + "data" : { + "description" : "DNS plugin data. (base64 encoded)", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "ACME Plugin ID name", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "ACME challenge type.", + "enum" : [ + "dns", + "standalone" + ], + "type" : "string" + }, + "validation-delay" : { + "default" : 30, + "description" : "Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.", + "maximum" : 172800, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 172800)" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/acme/plugins", + "text" : "plugins" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Deactivate existing ACME account at CA.", + "method" : "DELETE", + "name" : "deactivate_account", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Return existing ACME account information.", + "method" : "GET", + "name" : "get_account", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "account" : { + "optional" : 1, + "renderer" : "yaml", + "type" : "object" + }, + "directory" : { + "description" : "URL of ACME CA directory endpoint.", + "optional" : 1, + "pattern" : "^https?://.*", + "type" : "string" + }, + "location" : { + "optional" : 1, + "type" : "string" + }, + "tos" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update existing ACME account information with CA. Note: not specifying any new account information triggers a refresh.", + "method" : "PUT", + "name" : "update_account", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "contact" : { + "description" : "Contact email addresses.", + "format" : "email-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/account/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "ACMEAccount index.", + "method" : "GET", + "name" : "account_index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Register a new ACME account with CA.", + "method" : "POST", + "name" : "register_account", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "contact" : { + "description" : "Contact email addresses.", + "format" : "email-list", + "type" : "string", + "typetext" : "" + }, + "directory" : { + "default" : "https://acme-v02.api.letsencrypt.org/directory", + "description" : "URL of ACME CA directory endpoint.", + "optional" : 1, + "pattern" : "^https?://.*", + "type" : "string" + }, + "name" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tos_url" : { + "description" : "URL of CA TermsOfService - setting this indicates agreement.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/acme/account", + "text" : "account" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Retrieve ACME TermsOfService URL from CA.", + "method" : "GET", + "name" : "get_tos", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "directory" : { + "default" : "https://acme-v02.api.letsencrypt.org/directory", + "description" : "URL of ACME CA directory endpoint.", + "optional" : 1, + "pattern" : "^https?://.*", + "type" : "string" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "description" : "ACME TermsOfService URL.", + "optional" : 1, + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/tos", + "text" : "tos" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get named known ACME directory endpoints.", + "method" : "GET", + "name" : "get_directories", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "type" : "string" + }, + "url" : { + "description" : "URL of ACME CA directory endpoint.", + "pattern" : "^https?://.*", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/directories", + "text" : "directories" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get schema of ACME challenge types.", + "method" : "GET", + "name" : "challengeschema", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "type" : "string" + }, + "name" : { + "description" : "Human readable name, falls back to id", + "type" : "string" + }, + "schema" : { + "type" : "object" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/challenge-schema", + "text" : "challenge-schema" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "ACMEAccount index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/acme", + "text" : "acme" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get ceph metadata.", + "method" : "GET", + "name" : "metadata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "scope" : { + "default" : "all", + "enum" : [ + "all", + "versions" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ceph/metadata", + "text" : "metadata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get ceph status.", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ceph/status", + "text" : "status" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the status of a specific ceph flag.", + "method" : "GET", + "name" : "get_flag", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "flag" : { + "description" : "The name of the flag name to get.", + "enum" : [ + "nobackfill", + "nodeep-scrub", + "nodown", + "noin", + "noout", + "norebalance", + "norecover", + "noscrub", + "notieragent", + "noup", + "pause" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "boolean" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set or clear (unset) a specific ceph flag", + "method" : "PUT", + "name" : "update_flag", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "flag" : { + "description" : "The ceph flag to update", + "enum" : [ + "nobackfill", + "nodeep-scrub", + "nodown", + "noin", + "noout", + "norebalance", + "norecover", + "noscrub", + "notieragent", + "noup", + "pause" + ], + "type" : "string" + }, + "value" : { + "description" : "The new value of the flag", + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ceph/flags/{flag}", + "text" : "{flag}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "get the status of all ceph flags", + "method" : "GET", + "name" : "get_all_flags", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "name" : { + "description" : "Flag name.", + "enum" : [ + "nobackfill", + "nodeep-scrub", + "nodown", + "noin", + "noout", + "norebalance", + "norecover", + "noscrub", + "notieragent", + "noup", + "pause" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set/Unset multiple ceph flags at once.", + "method" : "PUT", + "name" : "set_flags", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "nobackfill" : { + "description" : "Backfilling of PGs is suspended.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nodeep-scrub" : { + "description" : "Deep Scrubbing is disabled.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nodown" : { + "description" : "OSD failure reports are being ignored, such that the monitors will not mark OSDs down.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "noin" : { + "description" : "OSDs that were previously marked out will not be marked back in when they start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "noout" : { + "description" : "OSDs will not automatically be marked out after the configured interval.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "norebalance" : { + "description" : "Rebalancing of PGs is suspended.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "norecover" : { + "description" : "Recovery of PGs is suspended.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "noscrub" : { + "description" : "Scrubbing is disabled.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "notieragent" : { + "description" : "Cache tiering activity is suspended.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "noup" : { + "description" : "OSDs are not allowed to start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "pause" : { + "description" : "Pauses read and writes.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ceph/flags", + "text" : "flags" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Cluster ceph index.", + "method" : "GET", + "name" : "cephindex", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ceph", + "text" : "ceph" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn subnet object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "subnet" : { + "description" : "The SDN subnet object identifier.", + "format" : "pve-sdn-subnet-id", + "type" : "string", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/vnets/{vnet}/subnets", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn subnet configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "subnet" : { + "description" : "The SDN subnet object identifier.", + "format" : "pve-sdn-subnet-id", + "type" : "string", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/vnets/{vnet}/subnets/{subnet}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn subnet object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dnszoneprefix" : { + "description" : "dns domain zone prefix ex: 'adm' -> .adm.mydomain.com", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway" : { + "description" : "Subnet Gateway: Will be assign on vnet for layer3 zones", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "snat" : { + "description" : "enable masquerade for this subnet if pve-firewall", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "subnet" : { + "description" : "The SDN subnet object identifier.", + "format" : "pve-sdn-subnet-id", + "type" : "string", + "typetext" : "" + }, + "vnet" : { + "description" : "associated vnet", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/vnets/{vnet}/subnets", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "text" : "{subnet}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN subnets index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/subnets/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{subnet}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn subnet object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dnszoneprefix" : { + "description" : "dns domain zone prefix ex: 'adm' -> .adm.mydomain.com", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway" : { + "description" : "Subnet Gateway: Will be assign on vnet for layer3 zones", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "snat" : { + "description" : "enable masquerade for this subnet if pve-firewall", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "subnet" : { + "description" : "The SDN subnet object identifier.", + "format" : "pve-sdn-subnet-id", + "type" : "string", + "typetext" : "" + }, + "type" : { + "enum" : [ + "subnet" + ], + "type" : "string" + }, + "vnet" : { + "description" : "associated vnet", + "optional" : 0, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/vnets/{vnet}/subnets", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/vnets/{vnet}/subnets", + "text" : "subnets" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn vnet object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/vnets", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn vnet configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/vnets/{vnet}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn vnet object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "alias" : { + "description" : "alias name of the vnet", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tag" : { + "description" : "vlan or vxlan id", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "vlanaware" : { + "description" : "Allow vm VLANs to pass through this vnet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "zone id", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/vnets", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/vnets/{vnet}", + "text" : "{vnet}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN vnets index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/vnets/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{vnet}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn vnet object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "alias" : { + "description" : "alias name of the vnet", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tag" : { + "description" : "vlan or vxlan id", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "type" : { + "description" : "Type", + "enum" : [ + "vnet" + ], + "optional" : 1, + "type" : "string" + }, + "vlanaware" : { + "description" : "Allow vm VLANs to pass through this vnet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "zone id", + "optional" : 0, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/vnets", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/vnets", + "text" : "vnets" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn zone object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn zone configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn zone object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bridge" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "controller" : { + "description" : "Frr router name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dns" : { + "description" : "dns api server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dnszone" : { + "description" : "dns domain zone ex: mydomain.com", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dp-id" : { + "description" : "Faucet dataplane id", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "exitnodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ipam" : { + "description" : "use a specific ipam", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mac" : { + "description" : "Anycast logical router mac address", + "format" : "mac-addr", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mtu" : { + "description" : "MTU", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peers" : { + "description" : "peers address list.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "reversedns" : { + "description" : "reverse dns api server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tag" : { + "description" : "Service-VLAN Tag", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vlan-protocol" : { + "default" : "802.1q", + "enum" : [ + "802.1q", + "802.1ad" + ], + "optional" : 1, + "type" : "string" + }, + "vrf-vxlan" : { + "description" : "l3vni.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/zones/{zone}", + "text" : "{zone}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN zones index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "type" : { + "description" : "Only list SDN zones of specific type", + "enum" : [ + "evpn", + "faucet", + "qinq", + "simple", + "vlan", + "vxlan" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "dns" : { + "optional" : 1, + "type" : "string" + }, + "dnszone" : { + "optional" : 1, + "type" : "string" + }, + "ipam" : { + "optional" : 1, + "type" : "string" + }, + "mtu" : { + "optional" : 1, + "type" : "integer" + }, + "nodes" : { + "optional" : 1, + "type" : "string" + }, + "pending" : { + "optional" : 1 + }, + "reversedns" : { + "optional" : 1, + "type" : "string" + }, + "state" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + }, + "zone" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{zone}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn zone object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bridge" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "controller" : { + "description" : "Frr router name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dns" : { + "description" : "dns api server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dnszone" : { + "description" : "dns domain zone ex: mydomain.com", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dp-id" : { + "description" : "Faucet dataplane id", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "exitnodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ipam" : { + "description" : "use a specific ipam", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mac" : { + "description" : "Anycast logical router mac address", + "format" : "mac-addr", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mtu" : { + "description" : "MTU", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peers" : { + "description" : "peers address list.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "reversedns" : { + "description" : "reverse dns api server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tag" : { + "description" : "Service-VLAN Tag", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "evpn", + "faucet", + "qinq", + "simple", + "vlan", + "vxlan" + ], + "format" : "pve-configid", + "type" : "string" + }, + "vlan-protocol" : { + "default" : "802.1q", + "enum" : [ + "802.1q", + "802.1ad" + ], + "optional" : 1, + "type" : "string" + }, + "vrf-vxlan" : { + "description" : "l3vni.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/zones", + "text" : "zones" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn controller object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "controller" : { + "description" : "The SDN controller object identifier.", + "format" : "pve-sdn-controller-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn controller configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "controller" : { + "description" : "The SDN controller object identifier.", + "format" : "pve-sdn-controller-id", + "type" : "string", + "typetext" : "" + }, + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/controllers/{controller}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn controller object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "asn" : { + "description" : "autonomous system number", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "controller" : { + "description" : "The SDN controller object identifier.", + "format" : "pve-sdn-controller-id", + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ebgp" : { + "description" : "Enable ebgp. (remote-as external)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ebgp-multihop" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "loopback" : { + "description" : "source loopback interface.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peers" : { + "description" : "peers address list.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/controllers/{controller}", + "text" : "{controller}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN controllers index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "type" : { + "description" : "Only list sdn controllers of specific type", + "enum" : [ + "bgp", + "evpn", + "faucet" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/controllers/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "controller" : { + "type" : "string" + }, + "pending" : { + "optional" : 1 + }, + "state" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{controller}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn controller object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "asn" : { + "description" : "autonomous system number", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "controller" : { + "description" : "The SDN controller object identifier.", + "format" : "pve-sdn-controller-id", + "type" : "string", + "typetext" : "" + }, + "ebgp" : { + "description" : "Enable ebgp. (remote-as external)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ebgp-multihop" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "loopback" : { + "description" : "source loopback interface.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peers" : { + "description" : "peers address list.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "bgp", + "evpn", + "faucet" + ], + "format" : "pve-configid", + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/controllers", + "text" : "controllers" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn ipam object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ipam" : { + "description" : "The SDN ipam object identifier.", + "format" : "pve-sdn-ipam-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn ipam configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ipam" : { + "description" : "The SDN ipam object identifier.", + "format" : "pve-sdn-ipam-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/ipams/{ipam}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn ipam object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ipam" : { + "description" : "The SDN ipam object identifier.", + "format" : "pve-sdn-ipam-id", + "type" : "string", + "typetext" : "" + }, + "section" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "token" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "url" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/ipams/{ipam}", + "text" : "{ipam}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN ipams index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list sdn ipams of specific type", + "enum" : [ + "netbox", + "phpipam", + "pve" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/ipams/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "ipam" : { + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{ipam}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn ipam object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ipam" : { + "description" : "The SDN ipam object identifier.", + "format" : "pve-sdn-ipam-id", + "type" : "string", + "typetext" : "" + }, + "section" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "token" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "netbox", + "phpipam", + "pve" + ], + "format" : "pve-configid", + "type" : "string" + }, + "url" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/ipams", + "text" : "ipams" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn dns object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dns" : { + "description" : "The SDN dns object identifier.", + "format" : "pve-sdn-dns-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn dns configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dns" : { + "description" : "The SDN dns object identifier.", + "format" : "pve-sdn-dns-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/dns/{dns}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn dns object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dns" : { + "description" : "The SDN dns object identifier.", + "format" : "pve-sdn-dns-id", + "type" : "string", + "typetext" : "" + }, + "key" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "reversemaskv6" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "ttl" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "url" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/dns/{dns}", + "text" : "{dns}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN dns index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list sdn dns of specific type", + "enum" : [ + "powerdns" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/dns/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "dns" : { + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{dns}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn dns object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dns" : { + "description" : "The SDN dns object identifier.", + "format" : "pve-sdn-dns-id", + "type" : "string", + "typetext" : "" + }, + "key" : { + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "reversemaskv6" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "reversev6mask" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "ttl" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "powerdns" + ], + "format" : "pve-configid", + "type" : "string" + }, + "url" : { + "optional" : 0, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/dns", + "text" : "dns" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "SDN.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Apply sdn controller changes && reload.", + "method" : "PUT", + "name" : "reload", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn", + "text" : "sdn" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read cluster log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "max" : { + "description" : "Maximum number of entries.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Resources index (cluster wide).", + "method" : "GET", + "name" : "resources", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "enum" : [ + "vm", + "storage", + "node", + "sdn" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "content" : { + "description" : "Allowed storage content types (when type == storage).", + "format" : "pve-storage-content-list", + "optional" : 1, + "type" : "string" + }, + "cpu" : { + "description" : "CPU utilization (when type in node,qemu,lxc).", + "optional" : 1, + "renderer" : "fraction_as_percentage", + "type" : "number" + }, + "disk" : { + "description" : "Used disk space in bytes (when type in storage), used root image spave for VMs (type in qemu,lxc).", + "optional" : 1, + "renderer" : "bytes", + "type" : "string" + }, + "hastate" : { + "description" : "HA service status (for HA managed VMs).", + "optional" : 1, + "type" : "string" + }, + "id" : { + "type" : "string" + }, + "level" : { + "description" : "Support level (when type == node).", + "optional" : 1, + "type" : "string" + }, + "maxcpu" : { + "description" : "Number of available CPUs (when type in node,qemu,lxc).", + "optional" : 1, + "type" : "number" + }, + "maxdisk" : { + "description" : "Storage size in bytes (when type in storage), root image size for VMs (type in qemu,lxc).", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Number of available memory in bytes (when type in node,qemu,lxc).", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "mem" : { + "description" : "Used memory in bytes (when type in node,qemu,lxc).", + "optional" : 1, + "renderer" : "bytes", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name (when type in node,storage,qemu,lxc).", + "format" : "pve-node", + "optional" : 1, + "type" : "string" + }, + "plugintype" : { + "description" : "More specific type, if available.", + "optional" : 1, + "type" : "string" + }, + "pool" : { + "description" : "The pool name (when type in pool,qemu,lxc).", + "optional" : 1, + "type" : "string" + }, + "status" : { + "description" : "Resource type dependent status.", + "optional" : 1, + "type" : "string" + }, + "storage" : { + "description" : "The storage identifier (when type == storage).", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Resource type.", + "enum" : [ + "node", + "storage", + "pool", + "qemu", + "lxc", + "openvz", + "sdn" + ], + "type" : "string" + }, + "uptime" : { + "description" : "Node uptime in seconds (when type in node,qemu,lxc).", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/resources", + "text" : "resources" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List recent tasks (cluster wide).", + "method" : "GET", + "name" : "tasks", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "upid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/tasks", + "text" : "tasks" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get datacenter options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set datacenter options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "description" : "Set bandwidth/io limits various operations.", + "format" : { + "clone" : { + "description" : "bandwidth limit in KiB/s for cloning disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "default" : { + "description" : "default bandwidth limit in KiB/s", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "migration" : { + "description" : "bandwidth limit in KiB/s for migrating guests (including moving local disks)", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "move" : { + "description" : "bandwidth limit in KiB/s for moving disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "restore" : { + "description" : "bandwidth limit in KiB/s for restoring guests from backups", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[clone=] [,default=] [,migration=] [,move=] [,restore=]" + }, + "console" : { + "description" : "Select the default Console viewer. You can either use the builtin java applet (VNC; deprecated and maps to html5), an external virt-viewer comtatible application (SPICE), an HTML5 based vnc viewer (noVNC), or an HTML5 based console client (xtermjs). If the selected viewer is not available (e.g. SPICE not activated for the VM), the fallback is noVNC.", + "enum" : [ + "applet", + "vv", + "html5", + "xtermjs" + ], + "optional" : 1, + "type" : "string" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "email_from" : { + "description" : "Specify email address to send notification from (default is root@$hostname)", + "format" : "email-opt", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fencing" : { + "default" : "watchdog", + "description" : "Set the fencing mode of the HA cluster. Hardware mode needs a valid configuration of fence devices in /etc/pve/ha/fence.cfg. With both all two modes are used.\n\nWARNING: 'hardware' and 'both' are EXPERIMENTAL & WIP", + "enum" : [ + "watchdog", + "hardware", + "both" + ], + "optional" : 1, + "type" : "string" + }, + "ha" : { + "description" : "Cluster wide HA settings.", + "format" : { + "shutdown_policy" : { + "default" : "conditional", + "description" : "The policy for HA services on node shutdown. 'freeze' disables auto-recovery, 'failover' ensures recovery, 'conditional' recovers on poweroff and freezes on reboot. 'migrate' will migrate running services to other nodes, if possible. With 'freeze' or 'failover', HA Services will always get stopped first on shutdown.", + "enum" : [ + "freeze", + "failover", + "conditional", + "migrate" + ], + "type" : "string", + "verbose_description" : "Describes the policy for handling HA services on poweroff or reboot of a node. Freeze will always freeze services which are still located on the node on shutdown, those services won't be recovered by the HA manager. Failover will not mark the services as frozen and thus the services will get recovered to other nodes, if the shutdown node does not come up again quickly (< 1min). 'conditional' chooses automatically depending on the type of shutdown, i.e., on a reboot the service will be frozen but on a poweroff the service will stay as is, and thus get recovered after about 2 minutes. Migrate will try to move all running services to another node when a reboot or shutdown was triggered. The poweroff process will only continue once no running services are located on the node anymore. If the node comes up again, the service will be moved back to the previously powered-off node, at least if no other migration, reloaction or recovery took place." + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "shutdown_policy=" + }, + "http_proxy" : { + "description" : "Specify external http proxy which is used for downloads (example: 'http://username:password@host:port/')", + "optional" : 1, + "pattern" : "http://.*", + "type" : "string" + }, + "keyboard" : { + "description" : "Default keybord layout for vnc server.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "language" : { + "description" : "Default GUI language.", + "enum" : [ + "ca", + "da", + "de", + "en", + "es", + "eu", + "fa", + "fr", + "he", + "it", + "ja", + "nb", + "nn", + "pl", + "pt_BR", + "ru", + "sl", + "sv", + "tr", + "zh_CN", + "zh_TW" + ], + "optional" : 1, + "type" : "string" + }, + "mac_prefix" : { + "description" : "Prefix for autogenerated MAC addresses.", + "format" : "mac-prefix", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "max_workers" : { + "description" : "Defines how many workers (per node) are maximal started on actions like 'stopall VMs' or task from the ha-manager.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "migration" : { + "description" : "For cluster wide migration settings.", + "format" : { + "network" : { + "description" : "CIDR of the (sub) network that is used for migration.", + "format" : "CIDR", + "format_description" : "CIDR", + "optional" : 1, + "type" : "string" + }, + "type" : { + "default" : "secure", + "default_key" : 1, + "description" : "Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.", + "enum" : [ + "secure", + "insecure" + ], + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[type=] [,network=]" + }, + "migration_unsecure" : { + "description" : "Migration is secure using SSH tunnel by default. For secure private networks you can disable it to speed up migration. Deprecated, use the 'migration' property instead!", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "u2f" : { + "description" : "u2f", + "format" : { + "appid" : { + "description" : "U2F AppId URL override. Defaults to the origin.", + "format_description" : "APPID", + "optional" : 1, + "type" : "string" + }, + "origin" : { + "description" : "U2F Origin override. Mostly useful for single nodes with a single URL.", + "format_description" : "URL", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[appid=] [,origin=]" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get cluster status information.", + "method" : "GET", + "name" : "get_status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + }, + "ip" : { + "description" : "[node] IP of the resolved nodename.", + "optional" : 1, + "type" : "string" + }, + "level" : { + "description" : "[node] Proxmox VE Subscription level, indicates if eligible for enterprise support as well as access to the stable Proxmox VE Enterprise Repository.", + "optional" : 1, + "type" : "string" + }, + "local" : { + "description" : "[node] Indicates if this is the responding node.", + "optional" : 1, + "type" : "boolean" + }, + "name" : { + "type" : "string" + }, + "nodeid" : { + "description" : "[node] ID of the node from the corosync configuration.", + "optional" : 1, + "type" : "integer" + }, + "nodes" : { + "description" : "[cluster] Nodes count, including offline nodes.", + "optional" : 1, + "type" : "integer" + }, + "online" : { + "description" : "[node] Indicates if the node is online or offline.", + "optional" : 1, + "type" : "boolean" + }, + "quorate" : { + "description" : "[cluster] Indicates if there is a majority of nodes online to make decisions", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "description" : "Indicates the type, either cluster or node. The type defines the object properties e.g. quorate available for type cluster.", + "enum" : [ + "cluster", + "node" + ], + "type" : "string" + }, + "version" : { + "description" : "[cluster] Current version of the corosync configuration file.", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get next free VMID. If you pass an VMID it will raise an error if the ID is already used.", + "method" : "GET", + "name" : "nextid", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "description" : "The next free VMID.", + "type" : "integer" + } + } + }, + "leaf" : 1, + "path" : "/cluster/nextid", + "text" : "nextid" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Cluster index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster", + "text" : "cluster" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "dest" : { + "optional" : 1, + "type" : "string" + }, + "dport" : { + "optional" : 1, + "type" : "string" + }, + "enable" : { + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "optional" : 1, + "type" : "string" + }, + "iface" : { + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "optional" : 1, + "type" : "string" + }, + "pos" : { + "type" : "integer" + }, + "proto" : { + "optional" : 1, + "type" : "string" + }, + "source" : { + "optional" : 1, + "type" : "string" + }, + "sport" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "pos" : { + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 0, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/rules", + "text" : "rules" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network alias.", + "method" : "DELETE", + "name" : "remove_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read alias.", + "method" : "GET", + "name" : "read_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network alias.", + "method" : "PUT", + "name" : "update_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "rename" : { + "description" : "Rename an existing alias.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List aliases", + "method" : "GET", + "name" : "get_aliases", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create IP or Network Alias.", + "method" : "POST", + "name" : "create_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/aliases", + "text" : "aliases" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network from IPSet.", + "method" : "DELETE", + "name" : "remove_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read IP or Network settings from IPSet.", + "method" : "GET", + "name" : "read_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network settings", + "method" : "PUT", + "name" : "update_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "text" : "{cidr}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete IPSet", + "method" : "DELETE", + "name" : "delete_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List IPSet content", + "method" : "GET", + "name" : "get_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{cidr}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add IP or Network to IPSet.", + "method" : "POST", + "name" : "create_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List IPSets", + "method" : "GET", + "name" : "ipset_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new IPSet", + "method" : "POST", + "name" : "create_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "rename" : { + "description" : "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/ipset", + "text" : "ipset" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get VM firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "dhcp" : { + "default" : 0, + "description" : "Enable DHCP.", + "optional" : 1, + "type" : "boolean" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean" + }, + "ipfilter" : { + "description" : "Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.", + "optional" : 1, + "type" : "boolean" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macfilter" : { + "default" : 0, + "description" : "Enable/disable MAC address filter.", + "optional" : 1, + "type" : "boolean" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "radv" : { + "description" : "Allow sending Router Advertisement.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp" : { + "default" : 0, + "description" : "Enable DHCP.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ipfilter" : { + "description" : "Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macfilter" : { + "default" : 0, + "description" : "Enable/disable MAC address filter.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "radv" : { + "description" : "Allow sending Router Advertisement.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read firewall log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Lists possible IPSet/Alias reference which are allowed in source/dest properties.", + "method" : "GET", + "name" : "refs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Only list references of specified type.", + "enum" : [ + "alias", + "ipset" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "alias", + "ipset" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/refs", + "text" : "refs" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall", + "text" : "firewall" + }, + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute fsfreeze-freeze.", + "method" : "POST", + "name" : "fsfreeze-freeze", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze", + "text" : "fsfreeze-freeze" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute fsfreeze-status.", + "method" : "POST", + "name" : "fsfreeze-status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status", + "text" : "fsfreeze-status" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute fsfreeze-thaw.", + "method" : "POST", + "name" : "fsfreeze-thaw", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw", + "text" : "fsfreeze-thaw" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute fstrim.", + "method" : "POST", + "name" : "fstrim", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/fstrim", + "text" : "fstrim" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-fsinfo.", + "method" : "GET", + "name" : "get-fsinfo", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-fsinfo", + "text" : "get-fsinfo" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-host-name.", + "method" : "GET", + "name" : "get-host-name", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-host-name", + "text" : "get-host-name" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-memory-block-info.", + "method" : "GET", + "name" : "get-memory-block-info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info", + "text" : "get-memory-block-info" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-memory-blocks.", + "method" : "GET", + "name" : "get-memory-blocks", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks", + "text" : "get-memory-blocks" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-osinfo.", + "method" : "GET", + "name" : "get-osinfo", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-osinfo", + "text" : "get-osinfo" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-time.", + "method" : "GET", + "name" : "get-time", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-time", + "text" : "get-time" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-timezone.", + "method" : "GET", + "name" : "get-timezone", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-timezone", + "text" : "get-timezone" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-users.", + "method" : "GET", + "name" : "get-users", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-users", + "text" : "get-users" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-vcpus.", + "method" : "GET", + "name" : "get-vcpus", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-vcpus", + "text" : "get-vcpus" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute info.", + "method" : "GET", + "name" : "info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/info", + "text" : "info" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute network-get-interfaces.", + "method" : "GET", + "name" : "network-get-interfaces", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces", + "text" : "network-get-interfaces" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute ping.", + "method" : "POST", + "name" : "ping", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/ping", + "text" : "ping" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute shutdown.", + "method" : "POST", + "name" : "shutdown", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/shutdown", + "text" : "shutdown" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute suspend-disk.", + "method" : "POST", + "name" : "suspend-disk", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/suspend-disk", + "text" : "suspend-disk" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute suspend-hybrid.", + "method" : "POST", + "name" : "suspend-hybrid", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid", + "text" : "suspend-hybrid" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute suspend-ram.", + "method" : "POST", + "name" : "suspend-ram", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/suspend-ram", + "text" : "suspend-ram" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Sets the password for the given user to the given password", + "method" : "POST", + "name" : "set-user-password", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "crypted" : { + "default" : 0, + "description" : "set to 1 if the password has already been passed through crypt()", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The new password.", + "maxLength" : 1024, + "minLength" : 5, + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "The user to set the password for.", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/set-user-password", + "text" : "set-user-password" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Executes the given command in the vm via the guest-agent and returns an object with the pid.", + "method" : "POST", + "name" : "exec", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "command" : { + "description" : "The command as a list of program + arguments", + "format" : "string-alist", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "input-data" : { + "description" : "Data to pass as 'input-data' to the guest. Usually treated as STDIN to 'command'.", + "maxLength" : 65536, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "pid" : { + "description" : "The PID of the process started by the guest-agent.", + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/exec", + "text" : "exec" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Gets the status of the given pid started by the guest-agent", + "method" : "GET", + "name" : "exec-status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pid" : { + "description" : "The PID to query", + "type" : "integer", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "err-data" : { + "description" : "stderr of the process", + "optional" : 1, + "type" : "string" + }, + "err-truncated" : { + "description" : "true if stderr was not fully captured", + "optional" : 1, + "type" : "boolean" + }, + "exitcode" : { + "description" : "process exit code if it was normally terminated.", + "optional" : 1, + "type" : "integer" + }, + "exited" : { + "description" : "Tells if the given command has exited yet.", + "type" : "boolean" + }, + "out-data" : { + "description" : "stdout of the process", + "optional" : 1, + "type" : "string" + }, + "out-truncated" : { + "description" : "true if stdout was not fully captured", + "optional" : 1, + "type" : "boolean" + }, + "signal" : { + "description" : "signal number or exception code if the process was abnormally terminated.", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/exec-status", + "text" : "exec-status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Reads the given file via guest agent. Is limited to 16777216 bytes.", + "method" : "GET", + "name" : "file-read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "file" : { + "description" : "The path to the file", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a `content` property.", + "properties" : { + "content" : { + "description" : "The content of the file, maximum 16777216", + "type" : "string" + }, + "truncated" : { + "description" : "If set to 1, the output is truncated and not complete", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/file-read", + "text" : "file-read" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Writes the given file via guest agent.", + "method" : "POST", + "name" : "file-write", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "content" : { + "description" : "The content to write into the file.", + "maxLength" : 61440, + "type" : "string", + "typetext" : "" + }, + "file" : { + "description" : "The path to the file.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/file-write", + "text" : "file-write" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Qemu Agent command index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 1, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "description" : "Returns the list of Qemu Agent commands", + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Execute Qemu Guest Agent commands.", + "method" : "POST", + "name" : "agent", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "command" : { + "description" : "The QGA command.", + "enum" : [ + "fsfreeze-freeze", + "fsfreeze-status", + "fsfreeze-thaw", + "fstrim", + "get-fsinfo", + "get-host-name", + "get-memory-block-info", + "get-memory-blocks", + "get-osinfo", + "get-time", + "get-timezone", + "get-users", + "get-vcpus", + "info", + "network-get-interfaces", + "ping", + "shutdown", + "suspend-disk", + "suspend-hybrid", + "suspend-ram" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/agent", + "text" : "agent" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read VM RRD statistics (returns PNG)", + "method" : "GET", + "name" : "rrd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "ds" : { + "description" : "The list of datasources you want to display.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "filename" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/rrd", + "text" : "rrd" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read VM RRD statistics", + "method" : "GET", + "name" : "rrddata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/rrddata", + "text" : "rrddata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the virtual machine configuration with pending configuration changes applied. Set the 'current' parameter to get the current configuration instead.", + "method" : "GET", + "name" : "vm_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "current" : { + "default" : 0, + "description" : "Get current values (instead of pending values).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapshot" : { + "description" : "Fetch config values from given snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "description" : "The VM configuration.", + "properties" : { + "acpi" : { + "default" : 1, + "description" : "Enable/disable ACPI.", + "optional" : 1, + "type" : "boolean" + }, + "agent" : { + "description" : "Enable/disable Qemu GuestAgent and its properties.", + "format" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable/disable Qemu GuestAgent.", + "type" : "boolean" + }, + "fstrim_cloned_disks" : { + "default" : 0, + "description" : "Run fstrim after moving a disk or migrating the VM.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default" : "virtio", + "description" : "Select the agent type", + "enum" : [ + "virtio", + "isa" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "args" : { + "description" : "Arbitrary arguments passed to kvm.", + "optional" : 1, + "type" : "string", + "verbose_description" : "Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -no-hpet\n\nNOTE: this option is for experts only.\n" + }, + "audio0" : { + "description" : "Configure a audio device, useful in combination with QXL/Spice.", + "format" : { + "device" : { + "description" : "Configure an audio device.", + "enum" : [ + "ich9-intel-hda", + "intel-hda", + "AC97" + ], + "type" : "string" + }, + "driver" : { + "default" : "spice", + "description" : "Driver backend for the audio device.", + "enum" : [ + "spice", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "autostart" : { + "default" : 0, + "description" : "Automatic restart after crash (currently ignored).", + "optional" : 1, + "type" : "boolean" + }, + "balloon" : { + "description" : "Amount of target RAM for the VM in MB. Using zero disables the ballon driver.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "bios" : { + "default" : "seabios", + "description" : "Select BIOS implementation.", + "enum" : [ + "seabios", + "ovmf" + ], + "optional" : 1, + "type" : "string" + }, + "boot" : { + "description" : "Specify guest boot order. Use with 'order=', usage with no key or 'legacy=' is deprecated.", + "format" : "pve-qm-boot", + "optional" : 1, + "type" : "string" + }, + "bootdisk" : { + "description" : "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format" : "pve-qm-bootdisk", + "optional" : 1, + "pattern" : "(ide|sata|scsi|virtio)\\d+", + "type" : "string" + }, + "cdrom" : { + "description" : "This is an alias for option -ide2", + "format" : "pve-qm-ide", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cicustom" : { + "description" : "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format" : "pve-qm-cicustom", + "optional" : 1, + "type" : "string" + }, + "cipassword" : { + "description" : "cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.", + "optional" : 1, + "type" : "string" + }, + "citype" : { + "description" : "Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.", + "enum" : [ + "configdrive2", + "nocloud", + "opennebula" + ], + "optional" : 1, + "type" : "string" + }, + "ciuser" : { + "description" : "cloud-init: User name to change ssh keys and password for instead of the image's configured default user.", + "optional" : 1, + "type" : "string" + }, + "cores" : { + "default" : 1, + "description" : "The number of cores per socket.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cpu" : { + "description" : "Emulated CPU type.", + "format" : "pve-vm-cpu-conf", + "optional" : 1, + "type" : "string" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "verbose_description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit." + }, + "cpuunits" : { + "default" : 1024, + "description" : "CPU weight for a VM.", + "maximum" : 262144, + "minimum" : 2, + "optional" : 1, + "type" : "integer", + "verbose_description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs." + }, + "description" : { + "description" : "Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "SHA1 digest of configuration file. This can be used to prevent concurrent modifications.", + "type" : "string" + }, + "efidisk0" : { + "description" : "Configure a Disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string" + }, + "freeze" : { + "description" : "Freeze CPU at startup (use 'c' monitor command to start execution).", + "optional" : 1, + "type" : "boolean" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the vms lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string" + }, + "hostpci[n]" : { + "description" : "Map host PCI devices into guest.", + "format" : "pve-qm-hostpci", + "optional" : 1, + "type" : "string", + "verbose_description" : "Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "hotplug" : { + "default" : "network,disk,usb", + "description" : "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory' and 'usb'. Use '0' to disable hotplug completely. Value '1' is an alias for the default 'network,disk,usb'.", + "format" : "pve-hotplug-features", + "optional" : 1, + "type" : "string" + }, + "hugepages" : { + "description" : "Enable/disable hugepages memory.", + "enum" : [ + "any", + "2", + "1024" + ], + "optional" : 1, + "type" : "string" + }, + "ide[n]" : { + "description" : "Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "model" : { + "description" : "The drive's reported model name, url-encoded, up to 40 bytes long.", + "format" : "urlencoded", + "format_description" : "model", + "maxLength" : 120, + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "ipconfig[n]" : { + "description" : "cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n", + "format" : "pve-qm-ipconfig", + "optional" : 1, + "type" : "string" + }, + "ivshmem" : { + "description" : "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + "format" : { + "name" : { + "description" : "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + "format_description" : "string", + "optional" : 1, + "pattern" : "[a-zA-Z0-9\\-]+", + "type" : "string" + }, + "size" : { + "description" : "The size of the file in MB.", + "minimum" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string" + }, + "keephugepages" : { + "default" : 0, + "description" : "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "optional" : 1, + "type" : "boolean" + }, + "keyboard" : { + "default" : null, + "description" : "Keybord layout for vnc server. Default is read from the '/etc/pve/datacenter.cfg' configuration file.It should not be necessary to set it.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "kvm" : { + "default" : 1, + "description" : "Enable/disable KVM hardware virtualization.", + "optional" : 1, + "type" : "boolean" + }, + "localtime" : { + "description" : "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.", + "optional" : 1, + "type" : "boolean" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ], + "optional" : 1, + "type" : "string" + }, + "machine" : { + "description" : "Specifies the Qemu machine type.", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.", + "minimum" : 16, + "optional" : 1, + "type" : "integer" + }, + "migrate_downtime" : { + "default" : 0.1, + "description" : "Set maximum tolerated downtime (in seconds) for migrations.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "migrate_speed" : { + "default" : 0, + "description" : "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "Set a name for the VM. Only used on the configuration web interface.", + "format" : "dns-name", + "optional" : 1, + "type" : "string" + }, + "nameserver" : { + "description" : "cloud-init: Sets DNS server IP address for a container. Create will'\n\t .' automatically use the setting from the host if neither searchdomain nor nameserver'\n\t .' are set.", + "format" : "address-list", + "optional" : 1, + "type" : "string" + }, + "net[n]" : { + "description" : "Specify network devices.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n", + "format_description" : "bridge", + "optional" : 1, + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "e1000" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82540em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82544gc" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82545em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "firewall" : { + "description" : "Whether this interface should be protected by the firewall.", + "optional" : 1, + "type" : "boolean" + }, + "i82551" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82557b" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82559er" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "macaddr" : { + "description" : "MAC address. That address must be unique withing your network. This is automatically generated if not specified.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "model" : { + "default_key" : 1, + "description" : "Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.", + "enum" : [ + "rtl8139", + "ne2k_pci", + "e1000", + "pcnet", + "virtio", + "ne2k_isa", + "i82551", + "i82557b", + "i82559er", + "vmxnet3", + "e1000-82540em", + "e1000-82544gc", + "e1000-82545em" + ], + "type" : "string" + }, + "mtu" : { + "description" : "Force MTU, for VirtIO only. Set to '1' to use the bridge MTU", + "maximum" : 65520, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "ne2k_isa" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "ne2k_pci" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "pcnet" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "queues" : { + "description" : "Number of packet queues to be used on the device.", + "maximum" : 16, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "rtl8139" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "tag" : { + "description" : "VLAN tag to apply to packets on this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN trunks to pass through this interface.", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "virtio" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "vmxnet3" : { + "alias" : "macaddr", + "keyAlias" : "model" + } + }, + "optional" : 1, + "type" : "string" + }, + "numa" : { + "default" : 0, + "description" : "Enable/disable NUMA.", + "optional" : 1, + "type" : "boolean" + }, + "numa[n]" : { + "description" : "NUMA topology.", + "format" : { + "cpus" : { + "description" : "CPUs accessing this NUMA node.", + "format_description" : "id[-id];...", + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "hostnodes" : { + "description" : "Host NUMA nodes to use.", + "format_description" : "id[-id];...", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "memory" : { + "description" : "Amount of memory this NUMA node provides.", + "optional" : 1, + "type" : "number" + }, + "policy" : { + "description" : "NUMA allocation policy.", + "enum" : [ + "preferred", + "bind", + "interleave" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean" + }, + "ostype" : { + "description" : "Specify guest operating system.", + "enum" : [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "l24", + "l26", + "solaris" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 5.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n" + }, + "parallel[n]" : { + "description" : "Map host parallel devices (n is 0 to 2).", + "optional" : 1, + "pattern" : "/dev/parport\\d+|/dev/usb/lp\\d+", + "type" : "string", + "verbose_description" : "Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "optional" : 1, + "type" : "boolean" + }, + "reboot" : { + "default" : 1, + "description" : "Allow reboot. If set to '0' the VM exit on reboot.", + "optional" : 1, + "type" : "boolean" + }, + "rng0" : { + "description" : "Configure a VirtIO-based Random Number Generator.", + "format" : { + "max_bytes" : { + "default" : 1024, + "description" : "Maximum bytes of entropy injected into the guest every 'period' milliseconds. Prefer a lower value when using /dev/random as source. Use 0 to disable limiting (potentially dangerous!).", + "optional" : 1, + "type" : "integer" + }, + "period" : { + "default" : 1000, + "description" : "Every 'period' milliseconds the entropy-injection quota is reset, allowing the guest to retrieve another 'max_bytes' of entropy.", + "optional" : 1, + "type" : "integer" + }, + "source" : { + "default_key" : 1, + "description" : "The file on the host to gather entropy from. In most cases /dev/urandom should be preferred over /dev/random to avoid entropy-starvation issues on the host. Using urandom does *not* decrease security in any meaningful way, as it's still seeded from real entropy, and the bytes provided will most likely be mixed with real entropy on the guest as well. /dev/hwrng can be used to pass through a hardware RNG from the host.", + "enum" : [ + "/dev/urandom", + "/dev/random", + "/dev/hwrng" + ], + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "sata[n]" : { + "description" : "Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "scsi[n]" : { + "description" : "Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "queues" : { + "description" : "Number of queues.", + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "scsiblock" : { + "default" : 0, + "description" : "whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "scsihw" : { + "default" : "lsi", + "description" : "SCSI controller model", + "enum" : [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "cloud-init: Sets DNS search domains for a container. Create will'\n\t .' automatically use the setting from the host if neither searchdomain nor nameserver'\n\t .' are set.", + "optional" : 1, + "type" : "string" + }, + "serial[n]" : { + "description" : "Create a serial device inside the VM (n is 0 to 3)", + "optional" : 1, + "pattern" : "(/dev/.+|socket)", + "type" : "string", + "verbose_description" : "Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "shares" : { + "default" : 1000, + "description" : "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.", + "maximum" : 50000, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "smbios1" : { + "description" : "Specify SMBIOS type 1 fields.", + "format" : "pve-qm-smbios1", + "maxLength" : 512, + "optional" : 1, + "type" : "string" + }, + "smp" : { + "default" : 1, + "description" : "The number of CPUs. Please use option -sockets instead.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "sockets" : { + "default" : 1, + "description" : "The number of CPU sockets.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "spice_enhancements" : { + "description" : "Configure additional enhancements for SPICE.", + "format" : { + "foldersharing" : { + "default" : "0", + "description" : "Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.", + "optional" : 1, + "type" : "boolean" + }, + "videostreaming" : { + "default" : "off", + "description" : "Enable video streaming. Uses compression for detected video streams.", + "enum" : [ + "off", + "all", + "filter" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "sshkeys" : { + "description" : "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format" : "urlencoded", + "optional" : 1, + "type" : "string" + }, + "startdate" : { + "default" : "now", + "description" : "Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.", + "optional" : 1, + "pattern" : "(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)", + "type" : "string", + "typetext" : "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "tablet" : { + "default" : 1, + "description" : "Enable/disable the USB tablet device.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)." + }, + "tags" : { + "description" : "Tags of the VM. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string" + }, + "tdf" : { + "default" : 0, + "description" : "Enable/disable time drift fix.", + "optional" : 1, + "type" : "boolean" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string" + }, + "usb[n]" : { + "description" : "Configure an USB device (n is 0 to 4).", + "format" : { + "host" : { + "default_key" : 1, + "description" : "The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadeciaml numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n", + "format" : "pve-qm-usb-device", + "format_description" : "HOSTUSBDEVICE|spice", + "type" : "string" + }, + "usb3" : { + "default" : 0, + "description" : "Specifies whether if given host option is a USB3 device or port.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string" + }, + "vcpus" : { + "default" : 0, + "description" : "Number of hotplugged vcpus.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "vga" : { + "description" : "Configure the VGA hardware.", + "format" : { + "memory" : { + "description" : "Sets the VGA memory (in MiB). Has no effect with serial display.", + "maximum" : 512, + "minimum" : 4, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "default" : "std", + "default_key" : 1, + "description" : "Select the VGA type.", + "enum" : [ + "cirrus", + "qxl", + "qxl2", + "qxl3", + "qxl4", + "none", + "serial0", + "serial1", + "serial2", + "serial3", + "std", + "virtio", + "vmware" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "verbose_description" : "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal." + }, + "virtio[n]" : { + "description" : "Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "vmgenid" : { + "default" : "1 (autogenerated)", + "description" : "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "format_description" : "UUID", + "optional" : 1, + "pattern" : "(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])", + "type" : "string", + "verbose_description" : "The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file." + }, + "vmstatestorage" : { + "description" : "Default storage for VM state volumes/files.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string" + }, + "watchdog" : { + "description" : "Create a virtual hardware watchdog device.", + "format" : "pve-qm-watchdog", + "optional" : 1, + "type" : "string", + "verbose_description" : "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Set virtual machine options (asynchrounous API).", + "method" : "POST", + "name" : "update_vm_async", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acpi" : { + "default" : 1, + "description" : "Enable/disable ACPI.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "agent" : { + "description" : "Enable/disable Qemu GuestAgent and its properties.", + "format" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable/disable Qemu GuestAgent.", + "type" : "boolean" + }, + "fstrim_cloned_disks" : { + "default" : 0, + "description" : "Run fstrim after moving a disk or migrating the VM.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default" : "virtio", + "description" : "Select the agent type", + "enum" : [ + "virtio", + "isa" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[enabled=]<1|0> [,fstrim_cloned_disks=<1|0>] [,type=]" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "args" : { + "description" : "Arbitrary arguments passed to kvm.", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -no-hpet\n\nNOTE: this option is for experts only.\n" + }, + "audio0" : { + "description" : "Configure a audio device, useful in combination with QXL/Spice.", + "format" : { + "device" : { + "description" : "Configure an audio device.", + "enum" : [ + "ich9-intel-hda", + "intel-hda", + "AC97" + ], + "type" : "string" + }, + "driver" : { + "default" : "spice", + "description" : "Driver backend for the audio device.", + "enum" : [ + "spice", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "device= [,driver=]" + }, + "autostart" : { + "default" : 0, + "description" : "Automatic restart after crash (currently ignored).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "background_delay" : { + "description" : "Time to wait for the task to finish. We return 'null' if the task finish within that time.", + "maximum" : 30, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 30)" + }, + "balloon" : { + "description" : "Amount of target RAM for the VM in MB. Using zero disables the ballon driver.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "bios" : { + "default" : "seabios", + "description" : "Select BIOS implementation.", + "enum" : [ + "seabios", + "ovmf" + ], + "optional" : 1, + "type" : "string" + }, + "boot" : { + "description" : "Specify guest boot order. Use with 'order=', usage with no key or 'legacy=' is deprecated.", + "format" : "pve-qm-boot", + "optional" : 1, + "type" : "string", + "typetext" : "[[legacy=]<[acdn]{1,4}>] [,order=]" + }, + "bootdisk" : { + "description" : "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format" : "pve-qm-bootdisk", + "optional" : 1, + "pattern" : "(ide|sata|scsi|virtio)\\d+", + "type" : "string" + }, + "cdrom" : { + "description" : "This is an alias for option -ide2", + "format" : "pve-qm-ide", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cicustom" : { + "description" : "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format" : "pve-qm-cicustom", + "optional" : 1, + "type" : "string", + "typetext" : "[meta=] [,network=] [,user=]" + }, + "cipassword" : { + "description" : "cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "citype" : { + "description" : "Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.", + "enum" : [ + "configdrive2", + "nocloud", + "opennebula" + ], + "optional" : 1, + "type" : "string" + }, + "ciuser" : { + "description" : "cloud-init: User name to change ssh keys and password for instead of the image's configured default user.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cores" : { + "default" : 1, + "description" : "The number of cores per socket.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "cpu" : { + "description" : "Emulated CPU type.", + "format" : "pve-vm-cpu-conf", + "optional" : 1, + "type" : "string", + "typetext" : "[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 128)", + "verbose_description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit." + }, + "cpuunits" : { + "default" : 1024, + "description" : "CPU weight for a VM.", + "maximum" : 262144, + "minimum" : 2, + "optional" : 1, + "type" : "integer", + "typetext" : " (2 - 262144)", + "verbose_description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs." + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "efidisk0" : { + "description" : "Configure a Disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,format=] [,size=]" + }, + "force" : { + "description" : "Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.", + "optional" : 1, + "requires" : "delete", + "type" : "boolean", + "typetext" : "" + }, + "freeze" : { + "description" : "Freeze CPU at startup (use 'c' monitor command to start execution).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the vms lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostpci[n]" : { + "description" : "Map host PCI devices into guest.", + "format" : "pve-qm-hostpci", + "optional" : 1, + "type" : "string", + "typetext" : "[host=] [,legacy-igd=<1|0>] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,x-vga=<1|0>]", + "verbose_description" : "Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "hotplug" : { + "default" : "network,disk,usb", + "description" : "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory' and 'usb'. Use '0' to disable hotplug completely. Value '1' is an alias for the default 'network,disk,usb'.", + "format" : "pve-hotplug-features", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hugepages" : { + "description" : "Enable/disable hugepages memory.", + "enum" : [ + "any", + "2", + "1024" + ], + "optional" : 1, + "type" : "string" + }, + "ide[n]" : { + "description" : "Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "model" : { + "description" : "The drive's reported model name, url-encoded, up to 40 bytes long.", + "format" : "urlencoded", + "format_description" : "model", + "maxLength" : 120, + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "ipconfig[n]" : { + "description" : "cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n", + "format" : "pve-qm-ipconfig", + "optional" : 1, + "type" : "string", + "typetext" : "[gw=] [,gw6=] [,ip=] [,ip6=]" + }, + "ivshmem" : { + "description" : "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + "format" : { + "name" : { + "description" : "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + "format_description" : "string", + "optional" : 1, + "pattern" : "[a-zA-Z0-9\\-]+", + "type" : "string" + }, + "size" : { + "description" : "The size of the file in MB.", + "minimum" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "size= [,name=]" + }, + "keephugepages" : { + "default" : 0, + "description" : "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "keyboard" : { + "default" : null, + "description" : "Keybord layout for vnc server. Default is read from the '/etc/pve/datacenter.cfg' configuration file.It should not be necessary to set it.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "kvm" : { + "default" : 1, + "description" : "Enable/disable KVM hardware virtualization.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "localtime" : { + "description" : "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ], + "optional" : 1, + "type" : "string" + }, + "machine" : { + "description" : "Specifies the Qemu machine type.", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.", + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - N)" + }, + "migrate_downtime" : { + "default" : 0.1, + "description" : "Set maximum tolerated downtime (in seconds) for migrations.", + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "migrate_speed" : { + "default" : 0, + "description" : "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "name" : { + "description" : "Set a name for the VM. Only used on the configuration web interface.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nameserver" : { + "description" : "cloud-init: Sets DNS server IP address for a container. Create will'\n\t .' automatically use the setting from the host if neither searchdomain nor nameserver'\n\t .' are set.", + "format" : "address-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specify network devices.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n", + "format_description" : "bridge", + "optional" : 1, + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "e1000" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82540em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82544gc" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82545em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "firewall" : { + "description" : "Whether this interface should be protected by the firewall.", + "optional" : 1, + "type" : "boolean" + }, + "i82551" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82557b" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82559er" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "macaddr" : { + "description" : "MAC address. That address must be unique withing your network. This is automatically generated if not specified.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "model" : { + "default_key" : 1, + "description" : "Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.", + "enum" : [ + "rtl8139", + "ne2k_pci", + "e1000", + "pcnet", + "virtio", + "ne2k_isa", + "i82551", + "i82557b", + "i82559er", + "vmxnet3", + "e1000-82540em", + "e1000-82544gc", + "e1000-82545em" + ], + "type" : "string" + }, + "mtu" : { + "description" : "Force MTU, for VirtIO only. Set to '1' to use the bridge MTU", + "maximum" : 65520, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "ne2k_isa" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "ne2k_pci" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "pcnet" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "queues" : { + "description" : "Number of packet queues to be used on the device.", + "maximum" : 16, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "rtl8139" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "tag" : { + "description" : "VLAN tag to apply to packets on this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN trunks to pass through this interface.", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "virtio" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "vmxnet3" : { + "alias" : "macaddr", + "keyAlias" : "model" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "numa" : { + "default" : 0, + "description" : "Enable/disable NUMA.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "numa[n]" : { + "description" : "NUMA topology.", + "format" : { + "cpus" : { + "description" : "CPUs accessing this NUMA node.", + "format_description" : "id[-id];...", + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "hostnodes" : { + "description" : "Host NUMA nodes to use.", + "format_description" : "id[-id];...", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "memory" : { + "description" : "Amount of memory this NUMA node provides.", + "optional" : 1, + "type" : "number" + }, + "policy" : { + "description" : "NUMA allocation policy.", + "enum" : [ + "preferred", + "bind", + "interleave" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "cpus= [,hostnodes=] [,memory=] [,policy=]" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostype" : { + "description" : "Specify guest operating system.", + "enum" : [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "l24", + "l26", + "solaris" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 5.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n" + }, + "parallel[n]" : { + "description" : "Map host parallel devices (n is 0 to 2).", + "optional" : 1, + "pattern" : "/dev/parport\\d+|/dev/usb/lp\\d+", + "type" : "string", + "verbose_description" : "Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "reboot" : { + "default" : 1, + "description" : "Allow reboot. If set to '0' the VM exit on reboot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "revert" : { + "description" : "Revert a pending change.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rng0" : { + "description" : "Configure a VirtIO-based Random Number Generator.", + "format" : { + "max_bytes" : { + "default" : 1024, + "description" : "Maximum bytes of entropy injected into the guest every 'period' milliseconds. Prefer a lower value when using /dev/random as source. Use 0 to disable limiting (potentially dangerous!).", + "optional" : 1, + "type" : "integer" + }, + "period" : { + "default" : 1000, + "description" : "Every 'period' milliseconds the entropy-injection quota is reset, allowing the guest to retrieve another 'max_bytes' of entropy.", + "optional" : 1, + "type" : "integer" + }, + "source" : { + "default_key" : 1, + "description" : "The file on the host to gather entropy from. In most cases /dev/urandom should be preferred over /dev/random to avoid entropy-starvation issues on the host. Using urandom does *not* decrease security in any meaningful way, as it's still seeded from real entropy, and the bytes provided will most likely be mixed with real entropy on the guest as well. /dev/hwrng can be used to pass through a hardware RNG from the host.", + "enum" : [ + "/dev/urandom", + "/dev/random", + "/dev/hwrng" + ], + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[source=] [,max_bytes=] [,period=]" + }, + "sata[n]" : { + "description" : "Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "scsi[n]" : { + "description" : "Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "queues" : { + "description" : "Number of queues.", + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "scsiblock" : { + "default" : 0, + "description" : "whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,queues=] [,replicate=<1|0>] [,rerror=] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "scsihw" : { + "default" : "lsi", + "description" : "SCSI controller model", + "enum" : [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "cloud-init: Sets DNS search domains for a container. Create will'\n\t .' automatically use the setting from the host if neither searchdomain nor nameserver'\n\t .' are set.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "serial[n]" : { + "description" : "Create a serial device inside the VM (n is 0 to 3)", + "optional" : 1, + "pattern" : "(/dev/.+|socket)", + "type" : "string", + "verbose_description" : "Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "shares" : { + "default" : 1000, + "description" : "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.", + "maximum" : 50000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 50000)" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "smbios1" : { + "description" : "Specify SMBIOS type 1 fields.", + "format" : "pve-qm-smbios1", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]" + }, + "smp" : { + "default" : 1, + "description" : "The number of CPUs. Please use option -sockets instead.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "sockets" : { + "default" : 1, + "description" : "The number of CPU sockets.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "spice_enhancements" : { + "description" : "Configure additional enhancements for SPICE.", + "format" : { + "foldersharing" : { + "default" : "0", + "description" : "Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.", + "optional" : 1, + "type" : "boolean" + }, + "videostreaming" : { + "default" : "off", + "description" : "Enable video streaming. Uses compression for detected video streams.", + "enum" : [ + "off", + "all", + "filter" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[foldersharing=<1|0>] [,videostreaming=]" + }, + "sshkeys" : { + "description" : "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format" : "urlencoded", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "startdate" : { + "default" : "now", + "description" : "Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.", + "optional" : 1, + "pattern" : "(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)", + "type" : "string", + "typetext" : "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "tablet" : { + "default" : 1, + "description" : "Enable/disable the USB tablet device.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)." + }, + "tags" : { + "description" : "Tags of the VM. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tdf" : { + "default" : 0, + "description" : "Enable/disable time drift fix.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=]" + }, + "usb[n]" : { + "description" : "Configure an USB device (n is 0 to 4).", + "format" : { + "host" : { + "default_key" : 1, + "description" : "The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadeciaml numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n", + "format" : "pve-qm-usb-device", + "format_description" : "HOSTUSBDEVICE|spice", + "type" : "string" + }, + "usb3" : { + "default" : 0, + "description" : "Specifies whether if given host option is a USB3 device or port.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[host=] [,usb3=<1|0>]" + }, + "vcpus" : { + "default" : 0, + "description" : "Number of hotplugged vcpus.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vga" : { + "description" : "Configure the VGA hardware.", + "format" : { + "memory" : { + "description" : "Sets the VGA memory (in MiB). Has no effect with serial display.", + "maximum" : 512, + "minimum" : 4, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "default" : "std", + "default_key" : 1, + "description" : "Select the VGA type.", + "enum" : [ + "cirrus", + "qxl", + "qxl2", + "qxl3", + "qxl4", + "none", + "serial0", + "serial1", + "serial2", + "serial3", + "std", + "virtio", + "vmware" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,memory=]", + "verbose_description" : "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal." + }, + "virtio[n]" : { + "description" : "Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]" + }, + "vmgenid" : { + "default" : "1 (autogenerated)", + "description" : "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "format_description" : "UUID", + "optional" : 1, + "pattern" : "(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])", + "type" : "string", + "verbose_description" : "The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file." + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vmstatestorage" : { + "description" : "Default storage for VM state volumes/files.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "watchdog" : { + "description" : "Create a virtual hardware watchdog device.", + "format" : "pve-qm-watchdog", + "optional" : 1, + "type" : "string", + "typetext" : "[[model=]] [,action=]", + "verbose_description" : "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk", + "VM.Config.CDROM", + "VM.Config.CPU", + "VM.Config.Memory", + "VM.Config.Network", + "VM.Config.HWType", + "VM.Config.Options", + "VM.Config.Cloudinit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "optional" : 1, + "type" : "string" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set virtual machine options (synchrounous API) - You should consider using the POST method instead for any actions involving hotplug or storage allocation.", + "method" : "PUT", + "name" : "update_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acpi" : { + "default" : 1, + "description" : "Enable/disable ACPI.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "agent" : { + "description" : "Enable/disable Qemu GuestAgent and its properties.", + "format" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable/disable Qemu GuestAgent.", + "type" : "boolean" + }, + "fstrim_cloned_disks" : { + "default" : 0, + "description" : "Run fstrim after moving a disk or migrating the VM.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default" : "virtio", + "description" : "Select the agent type", + "enum" : [ + "virtio", + "isa" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[enabled=]<1|0> [,fstrim_cloned_disks=<1|0>] [,type=]" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "args" : { + "description" : "Arbitrary arguments passed to kvm.", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -no-hpet\n\nNOTE: this option is for experts only.\n" + }, + "audio0" : { + "description" : "Configure a audio device, useful in combination with QXL/Spice.", + "format" : { + "device" : { + "description" : "Configure an audio device.", + "enum" : [ + "ich9-intel-hda", + "intel-hda", + "AC97" + ], + "type" : "string" + }, + "driver" : { + "default" : "spice", + "description" : "Driver backend for the audio device.", + "enum" : [ + "spice", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "device= [,driver=]" + }, + "autostart" : { + "default" : 0, + "description" : "Automatic restart after crash (currently ignored).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "balloon" : { + "description" : "Amount of target RAM for the VM in MB. Using zero disables the ballon driver.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "bios" : { + "default" : "seabios", + "description" : "Select BIOS implementation.", + "enum" : [ + "seabios", + "ovmf" + ], + "optional" : 1, + "type" : "string" + }, + "boot" : { + "description" : "Specify guest boot order. Use with 'order=', usage with no key or 'legacy=' is deprecated.", + "format" : "pve-qm-boot", + "optional" : 1, + "type" : "string", + "typetext" : "[[legacy=]<[acdn]{1,4}>] [,order=]" + }, + "bootdisk" : { + "description" : "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format" : "pve-qm-bootdisk", + "optional" : 1, + "pattern" : "(ide|sata|scsi|virtio)\\d+", + "type" : "string" + }, + "cdrom" : { + "description" : "This is an alias for option -ide2", + "format" : "pve-qm-ide", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cicustom" : { + "description" : "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format" : "pve-qm-cicustom", + "optional" : 1, + "type" : "string", + "typetext" : "[meta=] [,network=] [,user=]" + }, + "cipassword" : { + "description" : "cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "citype" : { + "description" : "Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.", + "enum" : [ + "configdrive2", + "nocloud", + "opennebula" + ], + "optional" : 1, + "type" : "string" + }, + "ciuser" : { + "description" : "cloud-init: User name to change ssh keys and password for instead of the image's configured default user.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cores" : { + "default" : 1, + "description" : "The number of cores per socket.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "cpu" : { + "description" : "Emulated CPU type.", + "format" : "pve-vm-cpu-conf", + "optional" : 1, + "type" : "string", + "typetext" : "[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 128)", + "verbose_description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit." + }, + "cpuunits" : { + "default" : 1024, + "description" : "CPU weight for a VM.", + "maximum" : 262144, + "minimum" : 2, + "optional" : 1, + "type" : "integer", + "typetext" : " (2 - 262144)", + "verbose_description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs." + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "efidisk0" : { + "description" : "Configure a Disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,format=] [,size=]" + }, + "force" : { + "description" : "Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.", + "optional" : 1, + "requires" : "delete", + "type" : "boolean", + "typetext" : "" + }, + "freeze" : { + "description" : "Freeze CPU at startup (use 'c' monitor command to start execution).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the vms lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostpci[n]" : { + "description" : "Map host PCI devices into guest.", + "format" : "pve-qm-hostpci", + "optional" : 1, + "type" : "string", + "typetext" : "[host=] [,legacy-igd=<1|0>] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,x-vga=<1|0>]", + "verbose_description" : "Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "hotplug" : { + "default" : "network,disk,usb", + "description" : "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory' and 'usb'. Use '0' to disable hotplug completely. Value '1' is an alias for the default 'network,disk,usb'.", + "format" : "pve-hotplug-features", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hugepages" : { + "description" : "Enable/disable hugepages memory.", + "enum" : [ + "any", + "2", + "1024" + ], + "optional" : 1, + "type" : "string" + }, + "ide[n]" : { + "description" : "Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "model" : { + "description" : "The drive's reported model name, url-encoded, up to 40 bytes long.", + "format" : "urlencoded", + "format_description" : "model", + "maxLength" : 120, + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "ipconfig[n]" : { + "description" : "cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n", + "format" : "pve-qm-ipconfig", + "optional" : 1, + "type" : "string", + "typetext" : "[gw=] [,gw6=] [,ip=] [,ip6=]" + }, + "ivshmem" : { + "description" : "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + "format" : { + "name" : { + "description" : "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + "format_description" : "string", + "optional" : 1, + "pattern" : "[a-zA-Z0-9\\-]+", + "type" : "string" + }, + "size" : { + "description" : "The size of the file in MB.", + "minimum" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "size= [,name=]" + }, + "keephugepages" : { + "default" : 0, + "description" : "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "keyboard" : { + "default" : null, + "description" : "Keybord layout for vnc server. Default is read from the '/etc/pve/datacenter.cfg' configuration file.It should not be necessary to set it.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "kvm" : { + "default" : 1, + "description" : "Enable/disable KVM hardware virtualization.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "localtime" : { + "description" : "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ], + "optional" : 1, + "type" : "string" + }, + "machine" : { + "description" : "Specifies the Qemu machine type.", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.", + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - N)" + }, + "migrate_downtime" : { + "default" : 0.1, + "description" : "Set maximum tolerated downtime (in seconds) for migrations.", + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "migrate_speed" : { + "default" : 0, + "description" : "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "name" : { + "description" : "Set a name for the VM. Only used on the configuration web interface.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nameserver" : { + "description" : "cloud-init: Sets DNS server IP address for a container. Create will'\n\t .' automatically use the setting from the host if neither searchdomain nor nameserver'\n\t .' are set.", + "format" : "address-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specify network devices.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n", + "format_description" : "bridge", + "optional" : 1, + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "e1000" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82540em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82544gc" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82545em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "firewall" : { + "description" : "Whether this interface should be protected by the firewall.", + "optional" : 1, + "type" : "boolean" + }, + "i82551" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82557b" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82559er" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "macaddr" : { + "description" : "MAC address. That address must be unique withing your network. This is automatically generated if not specified.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "model" : { + "default_key" : 1, + "description" : "Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.", + "enum" : [ + "rtl8139", + "ne2k_pci", + "e1000", + "pcnet", + "virtio", + "ne2k_isa", + "i82551", + "i82557b", + "i82559er", + "vmxnet3", + "e1000-82540em", + "e1000-82544gc", + "e1000-82545em" + ], + "type" : "string" + }, + "mtu" : { + "description" : "Force MTU, for VirtIO only. Set to '1' to use the bridge MTU", + "maximum" : 65520, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "ne2k_isa" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "ne2k_pci" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "pcnet" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "queues" : { + "description" : "Number of packet queues to be used on the device.", + "maximum" : 16, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "rtl8139" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "tag" : { + "description" : "VLAN tag to apply to packets on this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN trunks to pass through this interface.", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "virtio" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "vmxnet3" : { + "alias" : "macaddr", + "keyAlias" : "model" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "numa" : { + "default" : 0, + "description" : "Enable/disable NUMA.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "numa[n]" : { + "description" : "NUMA topology.", + "format" : { + "cpus" : { + "description" : "CPUs accessing this NUMA node.", + "format_description" : "id[-id];...", + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "hostnodes" : { + "description" : "Host NUMA nodes to use.", + "format_description" : "id[-id];...", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "memory" : { + "description" : "Amount of memory this NUMA node provides.", + "optional" : 1, + "type" : "number" + }, + "policy" : { + "description" : "NUMA allocation policy.", + "enum" : [ + "preferred", + "bind", + "interleave" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "cpus= [,hostnodes=] [,memory=] [,policy=]" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostype" : { + "description" : "Specify guest operating system.", + "enum" : [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "l24", + "l26", + "solaris" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 5.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n" + }, + "parallel[n]" : { + "description" : "Map host parallel devices (n is 0 to 2).", + "optional" : 1, + "pattern" : "/dev/parport\\d+|/dev/usb/lp\\d+", + "type" : "string", + "verbose_description" : "Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "reboot" : { + "default" : 1, + "description" : "Allow reboot. If set to '0' the VM exit on reboot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "revert" : { + "description" : "Revert a pending change.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rng0" : { + "description" : "Configure a VirtIO-based Random Number Generator.", + "format" : { + "max_bytes" : { + "default" : 1024, + "description" : "Maximum bytes of entropy injected into the guest every 'period' milliseconds. Prefer a lower value when using /dev/random as source. Use 0 to disable limiting (potentially dangerous!).", + "optional" : 1, + "type" : "integer" + }, + "period" : { + "default" : 1000, + "description" : "Every 'period' milliseconds the entropy-injection quota is reset, allowing the guest to retrieve another 'max_bytes' of entropy.", + "optional" : 1, + "type" : "integer" + }, + "source" : { + "default_key" : 1, + "description" : "The file on the host to gather entropy from. In most cases /dev/urandom should be preferred over /dev/random to avoid entropy-starvation issues on the host. Using urandom does *not* decrease security in any meaningful way, as it's still seeded from real entropy, and the bytes provided will most likely be mixed with real entropy on the guest as well. /dev/hwrng can be used to pass through a hardware RNG from the host.", + "enum" : [ + "/dev/urandom", + "/dev/random", + "/dev/hwrng" + ], + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[source=] [,max_bytes=] [,period=]" + }, + "sata[n]" : { + "description" : "Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "scsi[n]" : { + "description" : "Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "queues" : { + "description" : "Number of queues.", + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "scsiblock" : { + "default" : 0, + "description" : "whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,queues=] [,replicate=<1|0>] [,rerror=] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "scsihw" : { + "default" : "lsi", + "description" : "SCSI controller model", + "enum" : [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "cloud-init: Sets DNS search domains for a container. Create will'\n\t .' automatically use the setting from the host if neither searchdomain nor nameserver'\n\t .' are set.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "serial[n]" : { + "description" : "Create a serial device inside the VM (n is 0 to 3)", + "optional" : 1, + "pattern" : "(/dev/.+|socket)", + "type" : "string", + "verbose_description" : "Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "shares" : { + "default" : 1000, + "description" : "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.", + "maximum" : 50000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 50000)" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "smbios1" : { + "description" : "Specify SMBIOS type 1 fields.", + "format" : "pve-qm-smbios1", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]" + }, + "smp" : { + "default" : 1, + "description" : "The number of CPUs. Please use option -sockets instead.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "sockets" : { + "default" : 1, + "description" : "The number of CPU sockets.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "spice_enhancements" : { + "description" : "Configure additional enhancements for SPICE.", + "format" : { + "foldersharing" : { + "default" : "0", + "description" : "Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.", + "optional" : 1, + "type" : "boolean" + }, + "videostreaming" : { + "default" : "off", + "description" : "Enable video streaming. Uses compression for detected video streams.", + "enum" : [ + "off", + "all", + "filter" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[foldersharing=<1|0>] [,videostreaming=]" + }, + "sshkeys" : { + "description" : "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format" : "urlencoded", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "startdate" : { + "default" : "now", + "description" : "Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.", + "optional" : 1, + "pattern" : "(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)", + "type" : "string", + "typetext" : "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "tablet" : { + "default" : 1, + "description" : "Enable/disable the USB tablet device.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)." + }, + "tags" : { + "description" : "Tags of the VM. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tdf" : { + "default" : 0, + "description" : "Enable/disable time drift fix.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=]" + }, + "usb[n]" : { + "description" : "Configure an USB device (n is 0 to 4).", + "format" : { + "host" : { + "default_key" : 1, + "description" : "The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadeciaml numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n", + "format" : "pve-qm-usb-device", + "format_description" : "HOSTUSBDEVICE|spice", + "type" : "string" + }, + "usb3" : { + "default" : 0, + "description" : "Specifies whether if given host option is a USB3 device or port.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[host=] [,usb3=<1|0>]" + }, + "vcpus" : { + "default" : 0, + "description" : "Number of hotplugged vcpus.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vga" : { + "description" : "Configure the VGA hardware.", + "format" : { + "memory" : { + "description" : "Sets the VGA memory (in MiB). Has no effect with serial display.", + "maximum" : 512, + "minimum" : 4, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "default" : "std", + "default_key" : 1, + "description" : "Select the VGA type.", + "enum" : [ + "cirrus", + "qxl", + "qxl2", + "qxl3", + "qxl4", + "none", + "serial0", + "serial1", + "serial2", + "serial3", + "std", + "virtio", + "vmware" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,memory=]", + "verbose_description" : "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal." + }, + "virtio[n]" : { + "description" : "Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]" + }, + "vmgenid" : { + "default" : "1 (autogenerated)", + "description" : "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "format_description" : "UUID", + "optional" : 1, + "pattern" : "(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])", + "type" : "string", + "verbose_description" : "The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file." + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vmstatestorage" : { + "description" : "Default storage for VM state volumes/files.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "watchdog" : { + "description" : "Create a virtual hardware watchdog device.", + "format" : "pve-qm-watchdog", + "optional" : 1, + "type" : "string", + "typetext" : "[[model=]] [,action=]", + "verbose_description" : "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk", + "VM.Config.CDROM", + "VM.Config.CPU", + "VM.Config.Memory", + "VM.Config.Network", + "VM.Config.HWType", + "VM.Config.Options", + "VM.Config.Cloudinit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/config", + "text" : "config" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the virtual machine configuration with both current and pending values.", + "method" : "GET", + "name" : "vm_pending", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "delete" : { + "description" : "Indicates a pending delete request if present and not 0. The value 2 indicates a force-delete request.", + "maximum" : 2, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "key" : { + "description" : "Configuration option name.", + "type" : "string" + }, + "pending" : { + "description" : "Pending value.", + "optional" : 1, + "type" : "string" + }, + "value" : { + "description" : "Current value.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/pending", + "text" : "pending" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Unlink/delete disk images.", + "method" : "PUT", + "name" : "unlink", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "idlist" : { + "description" : "A list of disk IDs you want to delete.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/unlink", + "text" : "unlink" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a TCP VNC proxy connections.", + "method" : "POST", + "name" : "vncproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "generate-password" : { + "default" : 0, + "description" : "Generates a random password to be used as ticket instead of the API ticket.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "websocket" : { + "description" : "starts websockify instead of vncproxy", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "cert" : { + "type" : "string" + }, + "password" : { + "description" : "Returned if requested with 'generate-password' param. Consists of printable ASCII characters ('!' .. '~').", + "optional" : 1, + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/vncproxy", + "text" : "vncproxy" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a TCP proxy connections.", + "method" : "POST", + "name" : "termproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "serial" : { + "description" : "opens a serial terminal (defaults to display)", + "enum" : [ + "serial0", + "serial1", + "serial2", + "serial3" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/termproxy", + "text" : "termproxy" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Opens a weksocket for VNC traffic.", + "method" : "GET", + "name" : "vncwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Port number returned by previous vncproxy call.", + "maximum" : 5999, + "minimum" : 5900, + "type" : "integer", + "typetext" : " (5900 - 5999)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vncticket" : { + "description" : "Ticket from previous call to vncproxy.", + "maxLength" : 512, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ], + "description" : "You also need to pass a valid ticket (vncticket)." + }, + "returns" : { + "properties" : { + "port" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/vncwebsocket", + "text" : "vncwebsocket" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Returns a SPICE configuration to connect to the VM.", + "method" : "POST", + "name" : "spiceproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "proxy" : { + "description" : "SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).", + "format" : "address", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 1, + "description" : "Returned values can be directly passed to the 'remote-viewer' application.", + "properties" : { + "host" : { + "type" : "string" + }, + "password" : { + "type" : "string" + }, + "proxy" : { + "type" : "string" + }, + "tls-port" : { + "type" : "integer" + }, + "type" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/spiceproxy", + "text" : "spiceproxy" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get virtual machine status.", + "method" : "GET", + "name" : "vm_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "agent" : { + "description" : "Qemu GuestAgent enabled in config.", + "optional" : 1, + "type" : "boolean" + }, + "cpus" : { + "description" : "Maximum usable CPUs.", + "optional" : 1, + "type" : "number" + }, + "ha" : { + "description" : "HA manager service status.", + "type" : "object" + }, + "lock" : { + "description" : "The current config lock, if any.", + "optional" : 1, + "type" : "string" + }, + "maxdisk" : { + "description" : "Root disk size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Maximum memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "VM name.", + "optional" : 1, + "type" : "string" + }, + "pid" : { + "description" : "PID of running qemu process.", + "optional" : 1, + "type" : "integer" + }, + "qmpstatus" : { + "description" : "Qemu QMP agent status.", + "optional" : 1, + "type" : "string" + }, + "running-machine" : { + "description" : "The currently running machine type (if running).", + "optional" : 1, + "type" : "string" + }, + "running-qemu" : { + "description" : "The currently running QEMU version (if running).", + "optional" : 1, + "type" : "string" + }, + "spice" : { + "description" : "Qemu VGA configuration supports spice.", + "optional" : 1, + "type" : "boolean" + }, + "status" : { + "description" : "Qemu process status.", + "enum" : [ + "stopped", + "running" + ], + "type" : "string" + }, + "tags" : { + "description" : "The current configured tags, if any", + "optional" : 1, + "type" : "string" + }, + "uptime" : { + "description" : "Uptime.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/current", + "text" : "current" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start virtual machine.", + "method" : "POST", + "name" : "vm_start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force-cpu" : { + "description" : "Override QEMU's -cpu argument with the given string.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "machine" : { + "description" : "Specifies the Qemu machine type.", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "migratedfrom" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "migration_network" : { + "description" : "CIDR of the (sub) network that is used for migration.", + "format" : "CIDR", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "migration_type" : { + "description" : "Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.", + "enum" : [ + "secure", + "insecure" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stateuri" : { + "description" : "Some command save/restore state from this location.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "targetstorage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storagepair-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : "max(30, vm memory in GiB)", + "description" : "Wait maximal timeout seconds.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop virtual machine. The qemu process will exit immediately. Thisis akin to pulling the power plug of a running computer and may damage the VM data", + "method" : "POST", + "name" : "vm_stop", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "keepActive" : { + "default" : 0, + "description" : "Do not deactivate storage volumes.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "migratedfrom" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "timeout" : { + "description" : "Wait maximal timeout seconds.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/stop", + "text" : "stop" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Reset virtual machine.", + "method" : "POST", + "name" : "vm_reset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/reset", + "text" : "reset" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Shutdown virtual machine. This is similar to pressing the power button on a physical machine.This will send an ACPI event for the guest OS, which should then proceed to a clean shutdown.", + "method" : "POST", + "name" : "vm_shutdown", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "forceStop" : { + "default" : 0, + "description" : "Make sure the VM stops.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "keepActive" : { + "default" : 0, + "description" : "Do not deactivate storage volumes.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "timeout" : { + "description" : "Wait maximal timeout seconds.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/shutdown", + "text" : "shutdown" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Reboot the VM by shutting it down, and starting it again. Applies pending changes.", + "method" : "POST", + "name" : "vm_reboot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "description" : "Wait maximal timeout seconds for the shutdown.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/reboot", + "text" : "reboot" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Suspend virtual machine.", + "method" : "POST", + "name" : "vm_suspend", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "statestorage" : { + "description" : "The storage for the VM state", + "format" : "pve-storage-id", + "optional" : 1, + "requires" : "todisk", + "type" : "string", + "typetext" : "" + }, + "todisk" : { + "default" : 0, + "description" : "If set, suspends the VM to disk. Will be resumed on next VM start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ], + "description" : "You need 'VM.PowerMgmt' on /vms/{vmid}, and if you have set 'todisk', you need also 'VM.Config.Disk' on /vms/{vmid} and 'Datastore.AllocateSpace' on the storage for the vmstate." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/suspend", + "text" : "suspend" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Resume virtual machine.", + "method" : "POST", + "name" : "vm_resume", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "nocheck" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/resume", + "text" : "resume" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "vmcmdidx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/status", + "text" : "status" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Send key event to virtual machine.", + "method" : "PUT", + "name" : "vm_sendkey", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "key" : { + "description" : "The key (qemu monitor encoding).", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/sendkey", + "text" : "sendkey" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Check if feature for virtual machine is available.", + "method" : "GET", + "name" : "vm_feature", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "feature" : { + "description" : "Feature to check.", + "enum" : [ + "snapshot", + "clone", + "copy" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "hasFeature" : { + "type" : "boolean" + }, + "nodes" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/feature", + "text" : "feature" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a copy of virtual machine/template.", + "method" : "POST", + "name" : "clone_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "clone limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "description" : { + "description" : "Description for the new VM.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "format" : { + "description" : "Target format for file storage. Only valid for full clone.", + "enum" : [ + "raw", + "qcow2", + "vmdk" + ], + "optional" : 1, + "type" : "string" + }, + "full" : { + "description" : "Create a full copy of all disks. This is always done when you clone a normal VM. For VM templates, we try to create a linked clone by default.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "Set a name for the new VM.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "newid" : { + "description" : "VMID for the clone.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Add the new VM to the specified pool.", + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Target storage for full clone.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node. Only allowed if the original VM is on shared storage.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/vms/{vmid}", + [ + "VM.Clone" + ] + ], + [ + "or", + [ + "perm", + "/vms/{newid}", + [ + "VM.Allocate" + ] + ], + [ + "perm", + "/pool/{pool}", + [ + "VM.Allocate" + ], + "require_param", + "pool" + ] + ] + ], + "description" : "You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions on /vms/{newid} (or on the VM pool /pool/{pool}). You also need 'Datastore.AllocateSpace' on any used storage." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/clone", + "text" : "clone" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Move volume to different storage.", + "method" : "POST", + "name" : "move_vm_disk", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "move limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "delete" : { + "default" : 0, + "description" : "Delete the original disk after successful copy. By default the original disk is kept as unused disk.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disk" : { + "description" : "The disk you want to move.", + "enum" : [ + "ide0", + "ide1", + "ide2", + "ide3", + "scsi0", + "scsi1", + "scsi2", + "scsi3", + "scsi4", + "scsi5", + "scsi6", + "scsi7", + "scsi8", + "scsi9", + "scsi10", + "scsi11", + "scsi12", + "scsi13", + "scsi14", + "scsi15", + "scsi16", + "scsi17", + "scsi18", + "scsi19", + "scsi20", + "scsi21", + "scsi22", + "scsi23", + "scsi24", + "scsi25", + "scsi26", + "scsi27", + "scsi28", + "scsi29", + "scsi30", + "virtio0", + "virtio1", + "virtio2", + "virtio3", + "virtio4", + "virtio5", + "virtio6", + "virtio7", + "virtio8", + "virtio9", + "virtio10", + "virtio11", + "virtio12", + "virtio13", + "virtio14", + "virtio15", + "sata0", + "sata1", + "sata2", + "sata3", + "sata4", + "sata5", + "efidisk0" + ], + "type" : "string" + }, + "format" : { + "description" : "Target Format.", + "enum" : [ + "raw", + "qcow2", + "vmdk" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Target storage.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ], + [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateSpace" + ] + ] + ], + "description" : "You need 'VM.Config.Disk' permissions on /vms/{vmid}, and 'Datastore.AllocateSpace' permissions on the storage." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/move_disk", + "text" : "move_disk" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get preconditions for migration.", + "method" : "GET", + "name" : "migrate_vm_precondition", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "allowed_nodes" : { + "description" : "List nodes allowed for offline migration, only passed if VM is offline", + "optional" : 1, + "type" : "array" + }, + "local_disks" : { + "description" : "List local disks including CD-Rom, unsused and not referenced disks", + "type" : "array" + }, + "local_resources" : { + "description" : "List local resources e.g. pci, usb", + "type" : "array" + }, + "not_allowed_nodes" : { + "description" : "List not allowed nodes with additional informations, only passed if VM is offline", + "optional" : 1, + "type" : "object" + }, + "running" : { + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Migrate virtual machine. Creates a new migration task.", + "method" : "POST", + "name" : "migrate_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "migrate limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "force" : { + "description" : "Allow to migrate VMs which use local devices. Only root may use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "migration_network" : { + "description" : "CIDR of the (sub) network that is used for migration.", + "format" : "CIDR", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "migration_type" : { + "description" : "Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.", + "enum" : [ + "secure", + "insecure" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "online" : { + "description" : "Use online/live migration if VM is running. Ignored if VM is stopped.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "targetstorage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storagepair-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "with-local-disks" : { + "description" : "Enable live storage migration for local disk", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/migrate", + "text" : "migrate" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute Qemu monitor commands.", + "method" : "POST", + "name" : "monitor", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "command" : { + "description" : "The monitor command.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ], + "description" : "Sys.Modify is required for (sub)commands which are not read-only ('info *' and 'help')" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/monitor", + "text" : "monitor" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Extend volume size.", + "method" : "PUT", + "name" : "resize_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disk" : { + "description" : "The disk you want to resize.", + "enum" : [ + "ide0", + "ide1", + "ide2", + "ide3", + "scsi0", + "scsi1", + "scsi2", + "scsi3", + "scsi4", + "scsi5", + "scsi6", + "scsi7", + "scsi8", + "scsi9", + "scsi10", + "scsi11", + "scsi12", + "scsi13", + "scsi14", + "scsi15", + "scsi16", + "scsi17", + "scsi18", + "scsi19", + "scsi20", + "scsi21", + "scsi22", + "scsi23", + "scsi24", + "scsi25", + "scsi26", + "scsi27", + "scsi28", + "scsi29", + "scsi30", + "virtio0", + "virtio1", + "virtio2", + "virtio3", + "virtio4", + "virtio5", + "virtio6", + "virtio7", + "virtio8", + "virtio9", + "virtio10", + "virtio11", + "virtio12", + "virtio13", + "virtio14", + "virtio15", + "sata0", + "sata1", + "sata2", + "sata3", + "sata4", + "sata5", + "efidisk0" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "size" : { + "description" : "The new size. With the `+` sign the value is added to the actual size of the volume and without it, the value is taken as an absolute one. Shrinking disk size is not supported.", + "pattern" : "\\+?\\d+(\\.\\d+)?[KMGT]?", + "type" : "string" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/resize", + "text" : "resize" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get snapshot configuration", + "method" : "GET", + "name" : "get_snapshot_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback", + "VM.Audit" + ], + "any", + 1 + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update snapshot metadata.", + "method" : "PUT", + "name" : "update_snapshot_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A textual description or comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "text" : "config" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Rollback VM state to specified snapshot.", + "method" : "POST", + "name" : "rollback", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback", + "text" : "rollback" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete a VM snapshot.", + "method" : "DELETE", + "name" : "delsnapshot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "For removal from config file, even if removing disk snapshots fails.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "snapshot_cmd_idx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{cmd}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "text" : "{snapname}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all snapshots.", + "method" : "GET", + "name" : "snapshot_list", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "description" : { + "description" : "Snapshot description.", + "type" : "string" + }, + "name" : { + "description" : "Snapshot identifier. Value 'current' identifies the current VM.", + "type" : "string" + }, + "parent" : { + "description" : "Parent snapshot identifier.", + "optional" : 1, + "type" : "string" + }, + "snaptime" : { + "description" : "Snapshot creation time", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "vmstate" : { + "description" : "Snapshot includes RAM.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Snapshot a VM.", + "method" : "POST", + "name" : "snapshot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A textual description or comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vmstate" : { + "description" : "Save the vmstate", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/snapshot", + "text" : "snapshot" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a Template.", + "method" : "POST", + "name" : "template", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "disk" : { + "description" : "If you want to convert only 1 disk to base image.", + "enum" : [ + "ide0", + "ide1", + "ide2", + "ide3", + "scsi0", + "scsi1", + "scsi2", + "scsi3", + "scsi4", + "scsi5", + "scsi6", + "scsi7", + "scsi8", + "scsi9", + "scsi10", + "scsi11", + "scsi12", + "scsi13", + "scsi14", + "scsi15", + "scsi16", + "scsi17", + "scsi18", + "scsi19", + "scsi20", + "scsi21", + "scsi22", + "scsi23", + "scsi24", + "scsi25", + "scsi26", + "scsi27", + "scsi28", + "scsi29", + "scsi30", + "virtio0", + "virtio1", + "virtio2", + "virtio3", + "virtio4", + "virtio5", + "virtio6", + "virtio7", + "virtio8", + "virtio9", + "virtio10", + "virtio11", + "virtio12", + "virtio13", + "virtio14", + "virtio15", + "sata0", + "sata1", + "sata2", + "sata3", + "sata4", + "sata5", + "efidisk0" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + "description" : "You need 'VM.Allocate' permissions on /vms/{vmid}" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/template", + "text" : "template" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get automatically generated cloudinit config.", + "method" : "GET", + "name" : "cloudinit_generated_config_dump", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Config type.", + "enum" : [ + "user", + "network", + "meta" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/cloudinit/dump", + "text" : "dump" + } + ], + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/cloudinit", + "text" : "cloudinit" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy the VM and all used/owned volumes. Removes any VM specific permissions and firewall rules", + "method" : "DELETE", + "name" : "destroy_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "destroy-unreferenced-disks" : { + "default" : 1, + "description" : "If set, destroy additionally all disks not referenced in the config but with a matching VMID from all enabled storages.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "purge" : { + "description" : "Remove VMID from configurations, like backup & replication jobs and HA.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "vmdiridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}", + "text" : "{vmid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Virtual machine index (per node).", + "method" : "GET", + "name" : "vmlist", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "full" : { + "description" : "Determine the full status of active VMs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list VMs where you have VM.Audit permissons on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "cpus" : { + "description" : "Maximum usable CPUs.", + "optional" : 1, + "type" : "number" + }, + "lock" : { + "description" : "The current config lock, if any.", + "optional" : 1, + "type" : "string" + }, + "maxdisk" : { + "description" : "Root disk size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Maximum memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "VM name.", + "optional" : 1, + "type" : "string" + }, + "pid" : { + "description" : "PID of running qemu process.", + "optional" : 1, + "type" : "integer" + }, + "qmpstatus" : { + "description" : "Qemu QMP agent status.", + "optional" : 1, + "type" : "string" + }, + "running-machine" : { + "description" : "The currently running machine type (if running).", + "optional" : 1, + "type" : "string" + }, + "running-qemu" : { + "description" : "The currently running QEMU version (if running).", + "optional" : 1, + "type" : "string" + }, + "status" : { + "description" : "Qemu process status.", + "enum" : [ + "stopped", + "running" + ], + "type" : "string" + }, + "tags" : { + "description" : "The current configured tags, if any", + "optional" : 1, + "type" : "string" + }, + "uptime" : { + "description" : "Uptime.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{vmid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create or restore a virtual machine.", + "method" : "POST", + "name" : "create_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acpi" : { + "default" : 1, + "description" : "Enable/disable ACPI.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "agent" : { + "description" : "Enable/disable Qemu GuestAgent and its properties.", + "format" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable/disable Qemu GuestAgent.", + "type" : "boolean" + }, + "fstrim_cloned_disks" : { + "default" : 0, + "description" : "Run fstrim after moving a disk or migrating the VM.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default" : "virtio", + "description" : "Select the agent type", + "enum" : [ + "virtio", + "isa" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[enabled=]<1|0> [,fstrim_cloned_disks=<1|0>] [,type=]" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "archive" : { + "description" : "The backup archive. Either the file system path to a .tar or .vma file (use '-' to pipe data from stdin) or a proxmox storage backup volume identifier.", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "args" : { + "description" : "Arbitrary arguments passed to kvm.", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -no-hpet\n\nNOTE: this option is for experts only.\n" + }, + "audio0" : { + "description" : "Configure a audio device, useful in combination with QXL/Spice.", + "format" : { + "device" : { + "description" : "Configure an audio device.", + "enum" : [ + "ich9-intel-hda", + "intel-hda", + "AC97" + ], + "type" : "string" + }, + "driver" : { + "default" : "spice", + "description" : "Driver backend for the audio device.", + "enum" : [ + "spice", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "device= [,driver=]" + }, + "autostart" : { + "default" : 0, + "description" : "Automatic restart after crash (currently ignored).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "balloon" : { + "description" : "Amount of target RAM for the VM in MB. Using zero disables the ballon driver.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "bios" : { + "default" : "seabios", + "description" : "Select BIOS implementation.", + "enum" : [ + "seabios", + "ovmf" + ], + "optional" : 1, + "type" : "string" + }, + "boot" : { + "description" : "Specify guest boot order. Use with 'order=', usage with no key or 'legacy=' is deprecated.", + "format" : "pve-qm-boot", + "optional" : 1, + "type" : "string", + "typetext" : "[[legacy=]<[acdn]{1,4}>] [,order=]" + }, + "bootdisk" : { + "description" : "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format" : "pve-qm-bootdisk", + "optional" : 1, + "pattern" : "(ide|sata|scsi|virtio)\\d+", + "type" : "string" + }, + "bwlimit" : { + "default" : "restore limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "cdrom" : { + "description" : "This is an alias for option -ide2", + "format" : "pve-qm-ide", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cicustom" : { + "description" : "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format" : "pve-qm-cicustom", + "optional" : 1, + "type" : "string", + "typetext" : "[meta=] [,network=] [,user=]" + }, + "cipassword" : { + "description" : "cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "citype" : { + "description" : "Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.", + "enum" : [ + "configdrive2", + "nocloud", + "opennebula" + ], + "optional" : 1, + "type" : "string" + }, + "ciuser" : { + "description" : "cloud-init: User name to change ssh keys and password for instead of the image's configured default user.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cores" : { + "default" : 1, + "description" : "The number of cores per socket.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "cpu" : { + "description" : "Emulated CPU type.", + "format" : "pve-vm-cpu-conf", + "optional" : 1, + "type" : "string", + "typetext" : "[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 128)", + "verbose_description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit." + }, + "cpuunits" : { + "default" : 1024, + "description" : "CPU weight for a VM.", + "maximum" : 262144, + "minimum" : 2, + "optional" : 1, + "type" : "integer", + "typetext" : " (2 - 262144)", + "verbose_description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs." + }, + "description" : { + "description" : "Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "efidisk0" : { + "description" : "Configure a Disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,format=] [,size=]" + }, + "force" : { + "description" : "Allow to overwrite existing VM.", + "optional" : 1, + "requires" : "archive", + "type" : "boolean", + "typetext" : "" + }, + "freeze" : { + "description" : "Freeze CPU at startup (use 'c' monitor command to start execution).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the vms lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostpci[n]" : { + "description" : "Map host PCI devices into guest.", + "format" : "pve-qm-hostpci", + "optional" : 1, + "type" : "string", + "typetext" : "[host=] [,legacy-igd=<1|0>] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,x-vga=<1|0>]", + "verbose_description" : "Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "hotplug" : { + "default" : "network,disk,usb", + "description" : "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory' and 'usb'. Use '0' to disable hotplug completely. Value '1' is an alias for the default 'network,disk,usb'.", + "format" : "pve-hotplug-features", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hugepages" : { + "description" : "Enable/disable hugepages memory.", + "enum" : [ + "any", + "2", + "1024" + ], + "optional" : 1, + "type" : "string" + }, + "ide[n]" : { + "description" : "Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "model" : { + "description" : "The drive's reported model name, url-encoded, up to 40 bytes long.", + "format" : "urlencoded", + "format_description" : "model", + "maxLength" : 120, + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "ipconfig[n]" : { + "description" : "cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n", + "format" : "pve-qm-ipconfig", + "optional" : 1, + "type" : "string", + "typetext" : "[gw=] [,gw6=] [,ip=] [,ip6=]" + }, + "ivshmem" : { + "description" : "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + "format" : { + "name" : { + "description" : "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + "format_description" : "string", + "optional" : 1, + "pattern" : "[a-zA-Z0-9\\-]+", + "type" : "string" + }, + "size" : { + "description" : "The size of the file in MB.", + "minimum" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "size= [,name=]" + }, + "keephugepages" : { + "default" : 0, + "description" : "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "keyboard" : { + "default" : null, + "description" : "Keybord layout for vnc server. Default is read from the '/etc/pve/datacenter.cfg' configuration file.It should not be necessary to set it.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "kvm" : { + "default" : 1, + "description" : "Enable/disable KVM hardware virtualization.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "live-restore" : { + "description" : "Start the VM immediately from the backup and restore in background. PBS only.", + "optional" : 1, + "requires" : "archive", + "type" : "boolean", + "typetext" : "" + }, + "localtime" : { + "description" : "Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ], + "optional" : 1, + "type" : "string" + }, + "machine" : { + "description" : "Specifies the Qemu machine type.", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.", + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - N)" + }, + "migrate_downtime" : { + "default" : 0.1, + "description" : "Set maximum tolerated downtime (in seconds) for migrations.", + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "migrate_speed" : { + "default" : 0, + "description" : "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "name" : { + "description" : "Set a name for the VM. Only used on the configuration web interface.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nameserver" : { + "description" : "cloud-init: Sets DNS server IP address for a container. Create will'\n\t .' automatically use the setting from the host if neither searchdomain nor nameserver'\n\t .' are set.", + "format" : "address-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specify network devices.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n", + "format_description" : "bridge", + "optional" : 1, + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "e1000" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82540em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82544gc" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82545em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "firewall" : { + "description" : "Whether this interface should be protected by the firewall.", + "optional" : 1, + "type" : "boolean" + }, + "i82551" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82557b" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82559er" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "macaddr" : { + "description" : "MAC address. That address must be unique withing your network. This is automatically generated if not specified.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "model" : { + "default_key" : 1, + "description" : "Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.", + "enum" : [ + "rtl8139", + "ne2k_pci", + "e1000", + "pcnet", + "virtio", + "ne2k_isa", + "i82551", + "i82557b", + "i82559er", + "vmxnet3", + "e1000-82540em", + "e1000-82544gc", + "e1000-82545em" + ], + "type" : "string" + }, + "mtu" : { + "description" : "Force MTU, for VirtIO only. Set to '1' to use the bridge MTU", + "maximum" : 65520, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "ne2k_isa" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "ne2k_pci" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "pcnet" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "queues" : { + "description" : "Number of packet queues to be used on the device.", + "maximum" : 16, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "rtl8139" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "tag" : { + "description" : "VLAN tag to apply to packets on this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN trunks to pass through this interface.", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "virtio" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "vmxnet3" : { + "alias" : "macaddr", + "keyAlias" : "model" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "numa" : { + "default" : 0, + "description" : "Enable/disable NUMA.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "numa[n]" : { + "description" : "NUMA topology.", + "format" : { + "cpus" : { + "description" : "CPUs accessing this NUMA node.", + "format_description" : "id[-id];...", + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "hostnodes" : { + "description" : "Host NUMA nodes to use.", + "format_description" : "id[-id];...", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "memory" : { + "description" : "Amount of memory this NUMA node provides.", + "optional" : 1, + "type" : "number" + }, + "policy" : { + "description" : "NUMA allocation policy.", + "enum" : [ + "preferred", + "bind", + "interleave" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "cpus= [,hostnodes=] [,memory=] [,policy=]" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostype" : { + "description" : "Specify guest operating system.", + "enum" : [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "l24", + "l26", + "solaris" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 5.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n" + }, + "parallel[n]" : { + "description" : "Map host parallel devices (n is 0 to 2).", + "optional" : 1, + "pattern" : "/dev/parport\\d+|/dev/usb/lp\\d+", + "type" : "string", + "verbose_description" : "Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "pool" : { + "description" : "Add the VM to the specified pool.", + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "reboot" : { + "default" : 1, + "description" : "Allow reboot. If set to '0' the VM exit on reboot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "rng0" : { + "description" : "Configure a VirtIO-based Random Number Generator.", + "format" : { + "max_bytes" : { + "default" : 1024, + "description" : "Maximum bytes of entropy injected into the guest every 'period' milliseconds. Prefer a lower value when using /dev/random as source. Use 0 to disable limiting (potentially dangerous!).", + "optional" : 1, + "type" : "integer" + }, + "period" : { + "default" : 1000, + "description" : "Every 'period' milliseconds the entropy-injection quota is reset, allowing the guest to retrieve another 'max_bytes' of entropy.", + "optional" : 1, + "type" : "integer" + }, + "source" : { + "default_key" : 1, + "description" : "The file on the host to gather entropy from. In most cases /dev/urandom should be preferred over /dev/random to avoid entropy-starvation issues on the host. Using urandom does *not* decrease security in any meaningful way, as it's still seeded from real entropy, and the bytes provided will most likely be mixed with real entropy on the guest as well. /dev/hwrng can be used to pass through a hardware RNG from the host.", + "enum" : [ + "/dev/urandom", + "/dev/random", + "/dev/hwrng" + ], + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[source=] [,max_bytes=] [,period=]" + }, + "sata[n]" : { + "description" : "Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "scsi[n]" : { + "description" : "Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "queues" : { + "description" : "Number of queues.", + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "scsiblock" : { + "default" : 0, + "description" : "whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,queues=] [,replicate=<1|0>] [,rerror=] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "scsihw" : { + "default" : "lsi", + "description" : "SCSI controller model", + "enum" : [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "cloud-init: Sets DNS search domains for a container. Create will'\n\t .' automatically use the setting from the host if neither searchdomain nor nameserver'\n\t .' are set.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "serial[n]" : { + "description" : "Create a serial device inside the VM (n is 0 to 3)", + "optional" : 1, + "pattern" : "(/dev/.+|socket)", + "type" : "string", + "verbose_description" : "Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "shares" : { + "default" : 1000, + "description" : "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.", + "maximum" : 50000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 50000)" + }, + "smbios1" : { + "description" : "Specify SMBIOS type 1 fields.", + "format" : "pve-qm-smbios1", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]" + }, + "smp" : { + "default" : 1, + "description" : "The number of CPUs. Please use option -sockets instead.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "sockets" : { + "default" : 1, + "description" : "The number of CPU sockets.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "spice_enhancements" : { + "description" : "Configure additional enhancements for SPICE.", + "format" : { + "foldersharing" : { + "default" : "0", + "description" : "Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.", + "optional" : 1, + "type" : "boolean" + }, + "videostreaming" : { + "default" : "off", + "description" : "Enable video streaming. Uses compression for detected video streams.", + "enum" : [ + "off", + "all", + "filter" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[foldersharing=<1|0>] [,videostreaming=]" + }, + "sshkeys" : { + "description" : "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format" : "urlencoded", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Start VM after it was created successfully.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "startdate" : { + "default" : "now", + "description" : "Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.", + "optional" : 1, + "pattern" : "(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)", + "type" : "string", + "typetext" : "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "storage" : { + "description" : "Default storage.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tablet" : { + "default" : 1, + "description" : "Enable/disable the USB tablet device.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)." + }, + "tags" : { + "description" : "Tags of the VM. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tdf" : { + "default" : 0, + "description" : "Enable/disable time drift fix.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "unique" : { + "description" : "Assign a unique random ethernet address.", + "optional" : 1, + "requires" : "archive", + "type" : "boolean", + "typetext" : "" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=]" + }, + "usb[n]" : { + "description" : "Configure an USB device (n is 0 to 4).", + "format" : { + "host" : { + "default_key" : 1, + "description" : "The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadeciaml numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n", + "format" : "pve-qm-usb-device", + "format_description" : "HOSTUSBDEVICE|spice", + "type" : "string" + }, + "usb3" : { + "default" : 0, + "description" : "Specifies whether if given host option is a USB3 device or port.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[host=] [,usb3=<1|0>]" + }, + "vcpus" : { + "default" : 0, + "description" : "Number of hotplugged vcpus.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vga" : { + "description" : "Configure the VGA hardware.", + "format" : { + "memory" : { + "description" : "Sets the VGA memory (in MiB). Has no effect with serial display.", + "maximum" : 512, + "minimum" : 4, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "default" : "std", + "default_key" : 1, + "description" : "Select the VGA type.", + "enum" : [ + "cirrus", + "qxl", + "qxl2", + "qxl3", + "qxl4", + "none", + "serial0", + "serial1", + "serial2", + "serial3", + "std", + "virtio", + "vmware" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,memory=]", + "verbose_description" : "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal." + }, + "virtio[n]" : { + "description" : "Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "cow", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]" + }, + "vmgenid" : { + "default" : "1 (autogenerated)", + "description" : "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "format_description" : "UUID", + "optional" : 1, + "pattern" : "(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])", + "type" : "string", + "verbose_description" : "The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file." + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vmstatestorage" : { + "description" : "Default storage for VM state volumes/files.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "watchdog" : { + "description" : "Create a virtual hardware watchdog device.", + "format" : "pve-qm-watchdog", + "optional" : 1, + "type" : "string", + "typetext" : "[[model=]] [,action=]", + "verbose_description" : "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)" + } + } + }, + "permissions" : { + "description" : "You need 'VM.Allocate' permissions on /vms/{vmid} or on the VM pool /pool/{pool}. For restore (option 'archive'), it is enough if the user has 'VM.Backup' permission and the VM already exists. If you create disks you need 'Datastore.AllocateSpace' on any used storage.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu", + "text" : "qemu" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all custom and default CPU models.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only returns custom models when the current user has Sys.Audit on /nodes.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "custom" : { + "description" : "True if this is a custom CPU model.", + "type" : "boolean" + }, + "name" : { + "description" : "Name of the CPU model. Identifies it for subsequent API calls. Prefixed with 'custom-' for custom models.", + "type" : "string" + }, + "vendor" : { + "description" : "CPU vendor visible to the guest when this model is selected. Vendor of 'reported-model' in case of custom models.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/cpu", + "text" : "cpu" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get container configuration.", + "method" : "GET", + "name" : "vm_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "current" : { + "default" : 0, + "description" : "Get current values (instead of pending values).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapshot" : { + "description" : "Fetch config values from given snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "arch" : { + "default" : "amd64", + "description" : "OS architecture type.", + "enum" : [ + "amd64", + "i386", + "arm64", + "armhf" + ], + "optional" : 1, + "type" : "string" + }, + "cmode" : { + "default" : "tty", + "description" : "Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).", + "enum" : [ + "shell", + "console", + "tty" + ], + "optional" : 1, + "type" : "string" + }, + "console" : { + "default" : 1, + "description" : "Attach a console device (/dev/console) to the container.", + "optional" : 1, + "type" : "boolean" + }, + "cores" : { + "description" : "The number of cores assigned to the container. A container can use all available cores by default.", + "maximum" : 8192, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.", + "maximum" : 8192, + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "cpuunits" : { + "default" : 1024, + "description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to the weights of all the other running VMs.\n\nNOTE: You can disable fair-scheduler configuration by setting this to 0.", + "maximum" : 500000, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "debug" : { + "default" : 0, + "description" : "Try to be more verbose. For now this only enables debug log-level on start.", + "optional" : 1, + "type" : "boolean" + }, + "description" : { + "description" : "Container description. Only used on the configuration web interface.", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "SHA1 digest of configuration file. This can be used to prevent concurrent modifications.", + "type" : "string" + }, + "features" : { + "description" : "Allow containers access to advanced features.", + "format" : { + "force_rw_sys" : { + "default" : 0, + "description" : "Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.", + "optional" : 1, + "type" : "boolean" + }, + "fuse" : { + "default" : 0, + "description" : "Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.", + "optional" : 1, + "type" : "boolean" + }, + "keyctl" : { + "default" : 0, + "description" : "For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.", + "optional" : 1, + "type" : "boolean" + }, + "mknod" : { + "default" : 0, + "description" : "Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.", + "optional" : 1, + "type" : "boolean" + }, + "mount" : { + "description" : "Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.", + "format_description" : "fstype;fstype;...", + "optional" : 1, + "pattern" : "(?^:[a-zA-Z0-9_; ]+)", + "type" : "string" + }, + "nesting" : { + "default" : 0, + "description" : "Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string" + }, + "hookscript" : { + "description" : "Script that will be exectued during various steps in the containers lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string" + }, + "hostname" : { + "description" : "Set a host name for the container.", + "format" : "dns-name", + "maxLength" : 255, + "optional" : 1, + "type" : "string" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "create", + "destroyed", + "disk", + "fstrim", + "migrate", + "mounted", + "rollback", + "snapshot", + "snapshot-delete" + ], + "optional" : 1, + "type" : "string" + }, + "lxc" : { + "description" : "Array of lxc low-level configurations ([[key1, value1], [key2, value2] ...]).", + "items" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "optional" : 1, + "type" : "array" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the VM in MB.", + "minimum" : 16, + "optional" : 1, + "type" : "integer" + }, + "mp[n]" : { + "description" : "Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "backup" : { + "description" : "Whether to include the mount point in backups.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Whether to include the mount point in backups (only used for volume mount points)." + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(noatime|nodev|nosuid|noexec))(;(?^:(noatime|nodev|nosuid|noexec)))*)", + "type" : "string" + }, + "mp" : { + "description" : "Path to the mount point as seen from inside the container (must not contain symlinks).", + "format" : "pve-lxc-mp-string", + "format_description" : "Path", + "type" : "string", + "verbose_description" : "Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons." + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "nameserver" : { + "description" : "Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "lxc-ip-with-ll-iface-list", + "optional" : 1, + "type" : "string" + }, + "net[n]" : { + "description" : "Specifies network interfaces for the container.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to.", + "format_description" : "bridge", + "optional" : 1, + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "firewall" : { + "description" : "Controls whether this interface's firewall rules should be used.", + "optional" : 1, + "type" : "boolean" + }, + "gw" : { + "description" : "Default gateway for IPv4 traffic.", + "format" : "ipv4", + "format_description" : "GatewayIPv4", + "optional" : 1, + "type" : "string" + }, + "gw6" : { + "description" : "Default gateway for IPv6 traffic.", + "format" : "ipv6", + "format_description" : "GatewayIPv6", + "optional" : 1, + "type" : "string" + }, + "hwaddr" : { + "description" : "The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "ip" : { + "description" : "IPv4 address in CIDR format.", + "format" : "pve-ipv4-config", + "format_description" : "(IPv4/CIDR|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address in CIDR format.", + "format" : "pve-ipv6-config", + "format_description" : "(IPv6/CIDR|auto|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "mtu" : { + "description" : "Maximum transfer unit of the interface. (lxc.network.mtu)", + "minimum" : 64, + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "Name of the network device as seen from inside the container. (lxc.network.name)", + "format_description" : "string", + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "rate" : { + "description" : "Apply rate limiting to the interface", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "tag" : { + "description" : "VLAN tag for this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN ids to pass through the interface", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:;\\d+)*)", + "type" : "string" + }, + "type" : { + "description" : "Network interface type.", + "enum" : [ + "veth" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean" + }, + "ostype" : { + "description" : "OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.", + "enum" : [ + "debian", + "devuan", + "ubuntu", + "centos", + "fedora", + "opensuse", + "archlinux", + "alpine", + "gentoo", + "unmanaged" + ], + "optional" : 1, + "type" : "string" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.", + "optional" : 1, + "type" : "boolean" + }, + "rootfs" : { + "description" : "Use volume as container root.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(noatime|nodev|nosuid|noexec))(;(?^:(noatime|nodev|nosuid|noexec)))*)", + "type" : "string" + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "dns-name-list", + "optional" : 1, + "type" : "string" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "swap" : { + "default" : 512, + "description" : "Amount of SWAP for the VM in MB.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "tags" : { + "description" : "Tags of the Container. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean" + }, + "timezone" : { + "description" : "Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab", + "format" : "pve-ct-timezone", + "optional" : 1, + "type" : "string" + }, + "tty" : { + "default" : 2, + "description" : "Specify the number of tty available to the container", + "maximum" : 6, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "unprivileged" : { + "default" : 0, + "description" : "Makes the container run as unprivileged user. (Should not be modified manually.)", + "optional" : 1, + "type" : "boolean" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "volume" : { + "default_key" : 1, + "description" : "The volume that is not used currently.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set container options.", + "method" : "PUT", + "name" : "update_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "arch" : { + "default" : "amd64", + "description" : "OS architecture type.", + "enum" : [ + "amd64", + "i386", + "arm64", + "armhf" + ], + "optional" : 1, + "type" : "string" + }, + "cmode" : { + "default" : "tty", + "description" : "Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).", + "enum" : [ + "shell", + "console", + "tty" + ], + "optional" : 1, + "type" : "string" + }, + "console" : { + "default" : 1, + "description" : "Attach a console device (/dev/console) to the container.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cores" : { + "description" : "The number of cores assigned to the container. A container can use all available cores by default.", + "maximum" : 8192, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 8192)" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.", + "maximum" : 8192, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 8192)" + }, + "cpuunits" : { + "default" : 1024, + "description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to the weights of all the other running VMs.\n\nNOTE: You can disable fair-scheduler configuration by setting this to 0.", + "maximum" : 500000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 500000)" + }, + "debug" : { + "default" : 0, + "description" : "Try to be more verbose. For now this only enables debug log-level on start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Container description. Only used on the configuration web interface.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "features" : { + "description" : "Allow containers access to advanced features.", + "format" : { + "force_rw_sys" : { + "default" : 0, + "description" : "Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.", + "optional" : 1, + "type" : "boolean" + }, + "fuse" : { + "default" : 0, + "description" : "Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.", + "optional" : 1, + "type" : "boolean" + }, + "keyctl" : { + "default" : 0, + "description" : "For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.", + "optional" : 1, + "type" : "boolean" + }, + "mknod" : { + "default" : 0, + "description" : "Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.", + "optional" : 1, + "type" : "boolean" + }, + "mount" : { + "description" : "Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.", + "format_description" : "fstype;fstype;...", + "optional" : 1, + "pattern" : "(?^:[a-zA-Z0-9_; ]+)", + "type" : "string" + }, + "nesting" : { + "default" : 0, + "description" : "Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[force_rw_sys=<1|0>] [,fuse=<1|0>] [,keyctl=<1|0>] [,mknod=<1|0>] [,mount=] [,nesting=<1|0>]" + }, + "hookscript" : { + "description" : "Script that will be exectued during various steps in the containers lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostname" : { + "description" : "Set a host name for the container.", + "format" : "dns-name", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "create", + "destroyed", + "disk", + "fstrim", + "migrate", + "mounted", + "rollback", + "snapshot", + "snapshot-delete" + ], + "optional" : 1, + "type" : "string" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the VM in MB.", + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - N)" + }, + "mp[n]" : { + "description" : "Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "backup" : { + "description" : "Whether to include the mount point in backups.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Whether to include the mount point in backups (only used for volume mount points)." + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(noatime|nodev|nosuid|noexec))(;(?^:(noatime|nodev|nosuid|noexec)))*)", + "type" : "string" + }, + "mp" : { + "description" : "Path to the mount point as seen from inside the container (must not contain symlinks).", + "format" : "pve-lxc-mp-string", + "format_description" : "Path", + "type" : "string", + "verbose_description" : "Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons." + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=] ,mp= [,acl=<1|0>] [,backup=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]" + }, + "nameserver" : { + "description" : "Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "lxc-ip-with-ll-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specifies network interfaces for the container.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to.", + "format_description" : "bridge", + "optional" : 1, + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "firewall" : { + "description" : "Controls whether this interface's firewall rules should be used.", + "optional" : 1, + "type" : "boolean" + }, + "gw" : { + "description" : "Default gateway for IPv4 traffic.", + "format" : "ipv4", + "format_description" : "GatewayIPv4", + "optional" : 1, + "type" : "string" + }, + "gw6" : { + "description" : "Default gateway for IPv6 traffic.", + "format" : "ipv6", + "format_description" : "GatewayIPv6", + "optional" : 1, + "type" : "string" + }, + "hwaddr" : { + "description" : "The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "ip" : { + "description" : "IPv4 address in CIDR format.", + "format" : "pve-ipv4-config", + "format_description" : "(IPv4/CIDR|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address in CIDR format.", + "format" : "pve-ipv6-config", + "format_description" : "(IPv6/CIDR|auto|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "mtu" : { + "description" : "Maximum transfer unit of the interface. (lxc.network.mtu)", + "minimum" : 64, + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "Name of the network device as seen from inside the container. (lxc.network.name)", + "format_description" : "string", + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "rate" : { + "description" : "Apply rate limiting to the interface", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "tag" : { + "description" : "VLAN tag for this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN ids to pass through the interface", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:;\\d+)*)", + "type" : "string" + }, + "type" : { + "description" : "Network interface type.", + "enum" : [ + "veth" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "name= [,bridge=] [,firewall=<1|0>] [,gw=] [,gw6=] [,hwaddr=] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=<(IPv6/CIDR|auto|dhcp|manual)>] [,mtu=] [,rate=] [,tag=] [,trunks=] [,type=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostype" : { + "description" : "OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.", + "enum" : [ + "debian", + "devuan", + "ubuntu", + "centos", + "fedora", + "opensuse", + "archlinux", + "alpine", + "gentoo", + "unmanaged" + ], + "optional" : 1, + "type" : "string" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "revert" : { + "description" : "Revert a pending change.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rootfs" : { + "description" : "Use volume as container root.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(noatime|nodev|nosuid|noexec))(;(?^:(noatime|nodev|nosuid|noexec)))*)", + "type" : "string" + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=] [,acl=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]" + }, + "searchdomain" : { + "description" : "Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "dns-name-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "swap" : { + "default" : 512, + "description" : "Amount of SWAP for the VM in MB.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "tags" : { + "description" : "Tags of the Container. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "timezone" : { + "description" : "Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab", + "format" : "pve-ct-timezone", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tty" : { + "default" : 2, + "description" : "Specify the number of tty available to the container", + "maximum" : 6, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 6)" + }, + "unprivileged" : { + "default" : 0, + "description" : "Makes the container run as unprivileged user. (Should not be modified manually.)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "volume" : { + "default_key" : 1, + "description" : "The volume that is not used currently.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=]" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk", + "VM.Config.CPU", + "VM.Config.Memory", + "VM.Config.Network", + "VM.Config.Options" + ], + "any", + 1 + ], + "description" : "non-volume mount points in rootfs and mp[n] are restricted to root@pam" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/config", + "text" : "config" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get virtual machine status.", + "method" : "GET", + "name" : "vm_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "cpus" : { + "description" : "Maximum usable CPUs.", + "optional" : 1, + "type" : "number" + }, + "ha" : { + "description" : "HA manager service status.", + "type" : "object" + }, + "lock" : { + "description" : "The current config lock, if any.", + "optional" : 1, + "type" : "string" + }, + "maxdisk" : { + "description" : "Root disk size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Maximum memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxswap" : { + "description" : "Maximum SWAP memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "Container name.", + "optional" : 1, + "type" : "string" + }, + "status" : { + "description" : "LXC Container status.", + "enum" : [ + "stopped", + "running" + ], + "type" : "string" + }, + "tags" : { + "description" : "The current configured tags, if any.", + "optional" : 1, + "type" : "string" + }, + "uptime" : { + "description" : "Uptime.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/current", + "text" : "current" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start the container.", + "method" : "POST", + "name" : "vm_start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "debug" : { + "default" : 0, + "description" : "If set, enables very verbose debug log-level on start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop the container. This will abruptly stop all processes running in the container.", + "method" : "POST", + "name" : "vm_stop", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/stop", + "text" : "stop" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Shutdown the container. This will trigger a clean shutdown of the container, see lxc-stop(1) for details.", + "method" : "POST", + "name" : "vm_shutdown", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "forceStop" : { + "default" : 0, + "description" : "Make sure the Container stops.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 60, + "description" : "Wait maximal timeout seconds.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/shutdown", + "text" : "shutdown" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Suspend the container.", + "method" : "POST", + "name" : "vm_suspend", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/suspend", + "text" : "suspend" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Resume the container.", + "method" : "POST", + "name" : "vm_resume", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/resume", + "text" : "resume" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Reboot the container by shutting it down, and starting it again. Applies pending changes.", + "method" : "POST", + "name" : "vm_reboot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "description" : "Wait maximal timeout seconds for the shutdown.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/reboot", + "text" : "reboot" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "vmcmdidx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/status", + "text" : "status" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Rollback LXC state to specified snapshot.", + "method" : "POST", + "name" : "rollback", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback", + "text" : "rollback" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get snapshot configuration", + "method" : "GET", + "name" : "get_snapshot_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback", + "VM.Audit" + ], + "any", + 1 + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update snapshot metadata.", + "method" : "PUT", + "name" : "update_snapshot_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A textual description or comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "text" : "config" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete a LXC snapshot.", + "method" : "DELETE", + "name" : "delsnapshot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "For removal from config file, even if removing disk snapshots fails.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "snapshot_cmd_idx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{cmd}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "text" : "{snapname}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all snapshots.", + "method" : "GET", + "name" : "list", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "description" : { + "description" : "Snapshot description.", + "type" : "string" + }, + "name" : { + "description" : "Snapshot identifier. Value 'current' identifies the current VM.", + "type" : "string" + }, + "parent" : { + "description" : "Parent snapshot identifier.", + "optional" : 1, + "type" : "string" + }, + "snaptime" : { + "description" : "Snapshot creation time", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Snapshot a container.", + "method" : "POST", + "name" : "snapshot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A textual description or comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/snapshot", + "text" : "snapshot" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "dest" : { + "optional" : 1, + "type" : "string" + }, + "dport" : { + "optional" : 1, + "type" : "string" + }, + "enable" : { + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "optional" : 1, + "type" : "string" + }, + "iface" : { + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "optional" : 1, + "type" : "string" + }, + "pos" : { + "type" : "integer" + }, + "proto" : { + "optional" : 1, + "type" : "string" + }, + "source" : { + "optional" : 1, + "type" : "string" + }, + "sport" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "pos" : { + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 0, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/rules", + "text" : "rules" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network alias.", + "method" : "DELETE", + "name" : "remove_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read alias.", + "method" : "GET", + "name" : "read_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network alias.", + "method" : "PUT", + "name" : "update_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "rename" : { + "description" : "Rename an existing alias.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List aliases", + "method" : "GET", + "name" : "get_aliases", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create IP or Network Alias.", + "method" : "POST", + "name" : "create_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/aliases", + "text" : "aliases" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network from IPSet.", + "method" : "DELETE", + "name" : "remove_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read IP or Network settings from IPSet.", + "method" : "GET", + "name" : "read_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network settings", + "method" : "PUT", + "name" : "update_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "text" : "{cidr}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete IPSet", + "method" : "DELETE", + "name" : "delete_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List IPSet content", + "method" : "GET", + "name" : "get_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{cidr}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add IP or Network to IPSet.", + "method" : "POST", + "name" : "create_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List IPSets", + "method" : "GET", + "name" : "ipset_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 0, + "type" : "string" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new IPSet", + "method" : "POST", + "name" : "create_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "rename" : { + "description" : "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/ipset", + "text" : "ipset" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get VM firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "dhcp" : { + "default" : 0, + "description" : "Enable DHCP.", + "optional" : 1, + "type" : "boolean" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean" + }, + "ipfilter" : { + "description" : "Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.", + "optional" : 1, + "type" : "boolean" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macfilter" : { + "default" : 0, + "description" : "Enable/disable MAC address filter.", + "optional" : 1, + "type" : "boolean" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "radv" : { + "description" : "Allow sending Router Advertisement.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp" : { + "default" : 0, + "description" : "Enable DHCP.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ipfilter" : { + "description" : "Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macfilter" : { + "default" : 0, + "description" : "Enable/disable MAC address filter.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "radv" : { + "description" : "Allow sending Router Advertisement.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read firewall log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Lists possible IPSet/Alias reference which are allowed in source/dest properties.", + "method" : "GET", + "name" : "refs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Only list references of specified type.", + "enum" : [ + "alias", + "ipset" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "alias", + "ipset" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/refs", + "text" : "refs" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall", + "text" : "firewall" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read VM RRD statistics (returns PNG)", + "method" : "GET", + "name" : "rrd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "ds" : { + "description" : "The list of datasources you want to display.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "filename" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/rrd", + "text" : "rrd" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read VM RRD statistics", + "method" : "GET", + "name" : "rrddata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/rrddata", + "text" : "rrddata" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a TCP VNC proxy connections.", + "method" : "POST", + "name" : "vncproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "height" : { + "description" : "sets the height of the console in pixels.", + "maximum" : 2160, + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - 2160)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "websocket" : { + "description" : "use websocket instead of standard VNC.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "width" : { + "description" : "sets the width of the console in pixels.", + "maximum" : 4096, + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - 4096)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "cert" : { + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/vncproxy", + "text" : "vncproxy" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a TCP proxy connection.", + "method" : "POST", + "name" : "termproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/termproxy", + "text" : "termproxy" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Opens a weksocket for VNC traffic.", + "method" : "GET", + "name" : "vncwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Port number returned by previous vncproxy call.", + "maximum" : 5999, + "minimum" : 5900, + "type" : "integer", + "typetext" : " (5900 - 5999)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vncticket" : { + "description" : "Ticket from previous call to vncproxy.", + "maxLength" : 512, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ], + "description" : "You also need to pass a valid ticket (vncticket)." + }, + "returns" : { + "properties" : { + "port" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/vncwebsocket", + "text" : "vncwebsocket" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Returns a SPICE configuration to connect to the CT.", + "method" : "POST", + "name" : "spiceproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "proxy" : { + "description" : "SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).", + "format" : "address", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 1, + "description" : "Returned values can be directly passed to the 'remote-viewer' application.", + "properties" : { + "host" : { + "type" : "string" + }, + "password" : { + "type" : "string" + }, + "proxy" : { + "type" : "string" + }, + "tls-port" : { + "type" : "integer" + }, + "type" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/spiceproxy", + "text" : "spiceproxy" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migrate the container to another node. Creates a new migration task.", + "method" : "POST", + "name" : "migrate_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "migrate limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "force" : { + "description" : "Force migration despite local bind / device mounts. NOTE: deprecated, use 'shared' property of mount point instead.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "online" : { + "description" : "Use online/live migration.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restart" : { + "description" : "Use restart migration", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 180, + "description" : "Timeout in seconds for shutdown for restart migration", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/migrate", + "text" : "migrate" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Check if feature for virtual machine is available.", + "method" : "GET", + "name" : "vm_feature", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "feature" : { + "description" : "Feature to check.", + "enum" : [ + "snapshot", + "clone", + "copy" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "hasFeature" : { + "type" : "boolean" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/feature", + "text" : "feature" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a Template.", + "method" : "POST", + "name" : "template", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + "description" : "You need 'VM.Allocate' permissions on /vms/{vmid}" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/template", + "text" : "template" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a container clone/copy", + "method" : "POST", + "name" : "clone_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "clone limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "description" : { + "description" : "Description for the new CT.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "full" : { + "description" : "Create a full copy of all disks. This is always done when you clone a normal CT. For CT templates, we try to create a linked clone by default.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hostname" : { + "description" : "Set a hostname for the new CT.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "newid" : { + "description" : "VMID for the clone.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Add the new CT to the specified pool.", + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Target storage for full clone.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node. Only allowed if the original VM is on shared storage.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/vms/{vmid}", + [ + "VM.Clone" + ] + ], + [ + "or", + [ + "perm", + "/vms/{newid}", + [ + "VM.Allocate" + ] + ], + [ + "perm", + "/pool/{pool}", + [ + "VM.Allocate" + ], + "require_param", + "pool" + ] + ] + ], + "description" : "You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions on /vms/{newid} (or on the VM pool /pool/{pool}). You also need 'Datastore.AllocateSpace' on any used storage." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/clone", + "text" : "clone" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Resize a container mount point.", + "method" : "PUT", + "name" : "resize_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disk" : { + "description" : "The disk you want to resize.", + "enum" : [ + "rootfs", + "mp0", + "mp1", + "mp2", + "mp3", + "mp4", + "mp5", + "mp6", + "mp7", + "mp8", + "mp9", + "mp10", + "mp11", + "mp12", + "mp13", + "mp14", + "mp15", + "mp16", + "mp17", + "mp18", + "mp19", + "mp20", + "mp21", + "mp22", + "mp23", + "mp24", + "mp25", + "mp26", + "mp27", + "mp28", + "mp29", + "mp30", + "mp31", + "mp32", + "mp33", + "mp34", + "mp35", + "mp36", + "mp37", + "mp38", + "mp39", + "mp40", + "mp41", + "mp42", + "mp43", + "mp44", + "mp45", + "mp46", + "mp47", + "mp48", + "mp49", + "mp50", + "mp51", + "mp52", + "mp53", + "mp54", + "mp55", + "mp56", + "mp57", + "mp58", + "mp59", + "mp60", + "mp61", + "mp62", + "mp63", + "mp64", + "mp65", + "mp66", + "mp67", + "mp68", + "mp69", + "mp70", + "mp71", + "mp72", + "mp73", + "mp74", + "mp75", + "mp76", + "mp77", + "mp78", + "mp79", + "mp80", + "mp81", + "mp82", + "mp83", + "mp84", + "mp85", + "mp86", + "mp87", + "mp88", + "mp89", + "mp90", + "mp91", + "mp92", + "mp93", + "mp94", + "mp95", + "mp96", + "mp97", + "mp98", + "mp99", + "mp100", + "mp101", + "mp102", + "mp103", + "mp104", + "mp105", + "mp106", + "mp107", + "mp108", + "mp109", + "mp110", + "mp111", + "mp112", + "mp113", + "mp114", + "mp115", + "mp116", + "mp117", + "mp118", + "mp119", + "mp120", + "mp121", + "mp122", + "mp123", + "mp124", + "mp125", + "mp126", + "mp127", + "mp128", + "mp129", + "mp130", + "mp131", + "mp132", + "mp133", + "mp134", + "mp135", + "mp136", + "mp137", + "mp138", + "mp139", + "mp140", + "mp141", + "mp142", + "mp143", + "mp144", + "mp145", + "mp146", + "mp147", + "mp148", + "mp149", + "mp150", + "mp151", + "mp152", + "mp153", + "mp154", + "mp155", + "mp156", + "mp157", + "mp158", + "mp159", + "mp160", + "mp161", + "mp162", + "mp163", + "mp164", + "mp165", + "mp166", + "mp167", + "mp168", + "mp169", + "mp170", + "mp171", + "mp172", + "mp173", + "mp174", + "mp175", + "mp176", + "mp177", + "mp178", + "mp179", + "mp180", + "mp181", + "mp182", + "mp183", + "mp184", + "mp185", + "mp186", + "mp187", + "mp188", + "mp189", + "mp190", + "mp191", + "mp192", + "mp193", + "mp194", + "mp195", + "mp196", + "mp197", + "mp198", + "mp199", + "mp200", + "mp201", + "mp202", + "mp203", + "mp204", + "mp205", + "mp206", + "mp207", + "mp208", + "mp209", + "mp210", + "mp211", + "mp212", + "mp213", + "mp214", + "mp215", + "mp216", + "mp217", + "mp218", + "mp219", + "mp220", + "mp221", + "mp222", + "mp223", + "mp224", + "mp225", + "mp226", + "mp227", + "mp228", + "mp229", + "mp230", + "mp231", + "mp232", + "mp233", + "mp234", + "mp235", + "mp236", + "mp237", + "mp238", + "mp239", + "mp240", + "mp241", + "mp242", + "mp243", + "mp244", + "mp245", + "mp246", + "mp247", + "mp248", + "mp249", + "mp250", + "mp251", + "mp252", + "mp253", + "mp254", + "mp255" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "size" : { + "description" : "The new size. With the '+' sign the value is added to the actual size of the volume and without it, the value is taken as an absolute one. Shrinking disk size is not supported.", + "pattern" : "\\+?\\d+(\\.\\d+)?[KMGT]?", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/resize", + "text" : "resize" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Move a rootfs-/mp-volume to a different storage", + "method" : "POST", + "name" : "move_volume", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "clone limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "delete" : { + "default" : 0, + "description" : "Delete the original volume after successful copy. By default the original is kept as an unused volume entry.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Target Storage.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "volume" : { + "description" : "Volume which will be moved.", + "enum" : [ + "rootfs", + "mp0", + "mp1", + "mp2", + "mp3", + "mp4", + "mp5", + "mp6", + "mp7", + "mp8", + "mp9", + "mp10", + "mp11", + "mp12", + "mp13", + "mp14", + "mp15", + "mp16", + "mp17", + "mp18", + "mp19", + "mp20", + "mp21", + "mp22", + "mp23", + "mp24", + "mp25", + "mp26", + "mp27", + "mp28", + "mp29", + "mp30", + "mp31", + "mp32", + "mp33", + "mp34", + "mp35", + "mp36", + "mp37", + "mp38", + "mp39", + "mp40", + "mp41", + "mp42", + "mp43", + "mp44", + "mp45", + "mp46", + "mp47", + "mp48", + "mp49", + "mp50", + "mp51", + "mp52", + "mp53", + "mp54", + "mp55", + "mp56", + "mp57", + "mp58", + "mp59", + "mp60", + "mp61", + "mp62", + "mp63", + "mp64", + "mp65", + "mp66", + "mp67", + "mp68", + "mp69", + "mp70", + "mp71", + "mp72", + "mp73", + "mp74", + "mp75", + "mp76", + "mp77", + "mp78", + "mp79", + "mp80", + "mp81", + "mp82", + "mp83", + "mp84", + "mp85", + "mp86", + "mp87", + "mp88", + "mp89", + "mp90", + "mp91", + "mp92", + "mp93", + "mp94", + "mp95", + "mp96", + "mp97", + "mp98", + "mp99", + "mp100", + "mp101", + "mp102", + "mp103", + "mp104", + "mp105", + "mp106", + "mp107", + "mp108", + "mp109", + "mp110", + "mp111", + "mp112", + "mp113", + "mp114", + "mp115", + "mp116", + "mp117", + "mp118", + "mp119", + "mp120", + "mp121", + "mp122", + "mp123", + "mp124", + "mp125", + "mp126", + "mp127", + "mp128", + "mp129", + "mp130", + "mp131", + "mp132", + "mp133", + "mp134", + "mp135", + "mp136", + "mp137", + "mp138", + "mp139", + "mp140", + "mp141", + "mp142", + "mp143", + "mp144", + "mp145", + "mp146", + "mp147", + "mp148", + "mp149", + "mp150", + "mp151", + "mp152", + "mp153", + "mp154", + "mp155", + "mp156", + "mp157", + "mp158", + "mp159", + "mp160", + "mp161", + "mp162", + "mp163", + "mp164", + "mp165", + "mp166", + "mp167", + "mp168", + "mp169", + "mp170", + "mp171", + "mp172", + "mp173", + "mp174", + "mp175", + "mp176", + "mp177", + "mp178", + "mp179", + "mp180", + "mp181", + "mp182", + "mp183", + "mp184", + "mp185", + "mp186", + "mp187", + "mp188", + "mp189", + "mp190", + "mp191", + "mp192", + "mp193", + "mp194", + "mp195", + "mp196", + "mp197", + "mp198", + "mp199", + "mp200", + "mp201", + "mp202", + "mp203", + "mp204", + "mp205", + "mp206", + "mp207", + "mp208", + "mp209", + "mp210", + "mp211", + "mp212", + "mp213", + "mp214", + "mp215", + "mp216", + "mp217", + "mp218", + "mp219", + "mp220", + "mp221", + "mp222", + "mp223", + "mp224", + "mp225", + "mp226", + "mp227", + "mp228", + "mp229", + "mp230", + "mp231", + "mp232", + "mp233", + "mp234", + "mp235", + "mp236", + "mp237", + "mp238", + "mp239", + "mp240", + "mp241", + "mp242", + "mp243", + "mp244", + "mp245", + "mp246", + "mp247", + "mp248", + "mp249", + "mp250", + "mp251", + "mp252", + "mp253", + "mp254", + "mp255" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ], + [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateSpace" + ] + ] + ], + "description" : "You need 'VM.Config.Disk' permissions on /vms/{vmid}, and 'Datastore.AllocateSpace' permissions on the storage." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/move_volume", + "text" : "move_volume" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get container configuration, including pending changes.", + "method" : "GET", + "name" : "vm_pending", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "delete" : { + "description" : "Indicates a pending delete request if present and not 0.", + "maximum" : 2, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "key" : { + "description" : "Configuration option name.", + "type" : "string" + }, + "pending" : { + "description" : "Pending value.", + "optional" : 1, + "type" : "string" + }, + "value" : { + "description" : "Current value.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/pending", + "text" : "pending" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy the container (also delete all uses files).", + "method" : "DELETE", + "name" : "destroy_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "destroy-unreferenced-disks" : { + "description" : "If set, destroy additionally all disks with the VMID from all enabled storages which are not referenced in the config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "force" : { + "default" : 0, + "description" : "Force destroy, even if running.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "purge" : { + "default" : 0, + "description" : "Remove container from all related configurations. For example, backup jobs, replication jobs or HA. Related ACLs and Firewall entries will *always* be removed.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "vmdiridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}", + "text" : "{vmid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "LXC container index (per node).", + "method" : "GET", + "name" : "vmlist", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list CTs where you have VM.Audit permissons on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "cpus" : { + "description" : "Maximum usable CPUs.", + "optional" : 1, + "type" : "number" + }, + "lock" : { + "description" : "The current config lock, if any.", + "optional" : 1, + "type" : "string" + }, + "maxdisk" : { + "description" : "Root disk size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Maximum memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxswap" : { + "description" : "Maximum SWAP memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "Container name.", + "optional" : 1, + "type" : "string" + }, + "status" : { + "description" : "LXC Container status.", + "enum" : [ + "stopped", + "running" + ], + "type" : "string" + }, + "tags" : { + "description" : "The current configured tags, if any.", + "optional" : 1, + "type" : "string" + }, + "uptime" : { + "description" : "Uptime.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{vmid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create or restore a container.", + "method" : "POST", + "name" : "create_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "arch" : { + "default" : "amd64", + "description" : "OS architecture type.", + "enum" : [ + "amd64", + "i386", + "arm64", + "armhf" + ], + "optional" : 1, + "type" : "string" + }, + "bwlimit" : { + "default" : "restore limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "cmode" : { + "default" : "tty", + "description" : "Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).", + "enum" : [ + "shell", + "console", + "tty" + ], + "optional" : 1, + "type" : "string" + }, + "console" : { + "default" : 1, + "description" : "Attach a console device (/dev/console) to the container.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cores" : { + "description" : "The number of cores assigned to the container. A container can use all available cores by default.", + "maximum" : 8192, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 8192)" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.", + "maximum" : 8192, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 8192)" + }, + "cpuunits" : { + "default" : 1024, + "description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to the weights of all the other running VMs.\n\nNOTE: You can disable fair-scheduler configuration by setting this to 0.", + "maximum" : 500000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 500000)" + }, + "debug" : { + "default" : 0, + "description" : "Try to be more verbose. For now this only enables debug log-level on start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "description" : { + "description" : "Container description. Only used on the configuration web interface.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "features" : { + "description" : "Allow containers access to advanced features.", + "format" : { + "force_rw_sys" : { + "default" : 0, + "description" : "Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.", + "optional" : 1, + "type" : "boolean" + }, + "fuse" : { + "default" : 0, + "description" : "Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.", + "optional" : 1, + "type" : "boolean" + }, + "keyctl" : { + "default" : 0, + "description" : "For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.", + "optional" : 1, + "type" : "boolean" + }, + "mknod" : { + "default" : 0, + "description" : "Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.", + "optional" : 1, + "type" : "boolean" + }, + "mount" : { + "description" : "Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.", + "format_description" : "fstype;fstype;...", + "optional" : 1, + "pattern" : "(?^:[a-zA-Z0-9_; ]+)", + "type" : "string" + }, + "nesting" : { + "default" : 0, + "description" : "Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[force_rw_sys=<1|0>] [,fuse=<1|0>] [,keyctl=<1|0>] [,mknod=<1|0>] [,mount=] [,nesting=<1|0>]" + }, + "force" : { + "description" : "Allow to overwrite existing container.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hookscript" : { + "description" : "Script that will be exectued during various steps in the containers lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostname" : { + "description" : "Set a host name for the container.", + "format" : "dns-name", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ignore-unpack-errors" : { + "description" : "Ignore errors when extracting the template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "create", + "destroyed", + "disk", + "fstrim", + "migrate", + "mounted", + "rollback", + "snapshot", + "snapshot-delete" + ], + "optional" : 1, + "type" : "string" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the VM in MB.", + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - N)" + }, + "mp[n]" : { + "description" : "Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "backup" : { + "description" : "Whether to include the mount point in backups.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Whether to include the mount point in backups (only used for volume mount points)." + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(noatime|nodev|nosuid|noexec))(;(?^:(noatime|nodev|nosuid|noexec)))*)", + "type" : "string" + }, + "mp" : { + "description" : "Path to the mount point as seen from inside the container (must not contain symlinks).", + "format" : "pve-lxc-mp-string", + "format_description" : "Path", + "type" : "string", + "verbose_description" : "Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons." + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=] ,mp= [,acl=<1|0>] [,backup=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]" + }, + "nameserver" : { + "description" : "Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "lxc-ip-with-ll-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specifies network interfaces for the container.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to.", + "format_description" : "bridge", + "optional" : 1, + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "firewall" : { + "description" : "Controls whether this interface's firewall rules should be used.", + "optional" : 1, + "type" : "boolean" + }, + "gw" : { + "description" : "Default gateway for IPv4 traffic.", + "format" : "ipv4", + "format_description" : "GatewayIPv4", + "optional" : 1, + "type" : "string" + }, + "gw6" : { + "description" : "Default gateway for IPv6 traffic.", + "format" : "ipv6", + "format_description" : "GatewayIPv6", + "optional" : 1, + "type" : "string" + }, + "hwaddr" : { + "description" : "The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "ip" : { + "description" : "IPv4 address in CIDR format.", + "format" : "pve-ipv4-config", + "format_description" : "(IPv4/CIDR|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address in CIDR format.", + "format" : "pve-ipv6-config", + "format_description" : "(IPv6/CIDR|auto|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "mtu" : { + "description" : "Maximum transfer unit of the interface. (lxc.network.mtu)", + "minimum" : 64, + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "Name of the network device as seen from inside the container. (lxc.network.name)", + "format_description" : "string", + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "rate" : { + "description" : "Apply rate limiting to the interface", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "tag" : { + "description" : "VLAN tag for this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN ids to pass through the interface", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:;\\d+)*)", + "type" : "string" + }, + "type" : { + "description" : "Network interface type.", + "enum" : [ + "veth" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "name= [,bridge=] [,firewall=<1|0>] [,gw=] [,gw6=] [,hwaddr=] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=<(IPv6/CIDR|auto|dhcp|manual)>] [,mtu=] [,rate=] [,tag=] [,trunks=] [,type=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostemplate" : { + "description" : "The OS template or backup file.", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + }, + "ostype" : { + "description" : "OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.", + "enum" : [ + "debian", + "devuan", + "ubuntu", + "centos", + "fedora", + "opensuse", + "archlinux", + "alpine", + "gentoo", + "unmanaged" + ], + "optional" : 1, + "type" : "string" + }, + "password" : { + "description" : "Sets root password inside container.", + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Add the VM to the specified pool.", + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restore" : { + "description" : "Mark this as restore task.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "rootfs" : { + "description" : "Use volume as container root.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(noatime|nodev|nosuid|noexec))(;(?^:(noatime|nodev|nosuid|noexec)))*)", + "type" : "string" + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=] [,acl=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]" + }, + "searchdomain" : { + "description" : "Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "dns-name-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ssh-public-keys" : { + "description" : "Setup public SSH keys (one key per line, OpenSSH format).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Start the CT after its creation finished successfully.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "storage" : { + "default" : "local", + "description" : "Default Storage.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "swap" : { + "default" : 512, + "description" : "Amount of SWAP for the VM in MB.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "tags" : { + "description" : "Tags of the Container. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "timezone" : { + "description" : "Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab", + "format" : "pve-ct-timezone", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tty" : { + "default" : 2, + "description" : "Specify the number of tty available to the container", + "maximum" : 6, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 6)" + }, + "unique" : { + "description" : "Assign a unique random ethernet address.", + "optional" : 1, + "requires" : "restore", + "type" : "boolean", + "typetext" : "" + }, + "unprivileged" : { + "default" : 0, + "description" : "Makes the container run as unprivileged user. (Should not be modified manually.)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "volume" : { + "default_key" : 1, + "description" : "The volume that is not used currently.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=]" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "description" : "You need 'VM.Allocate' permissions on /vms/{vmid} or on the VM pool /pool/{pool}. For restore, it is enough if the user has 'VM.Backup' permission and the VM already exists. You also need 'Datastore.AllocateSpace' permissions on the storage.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc", + "text" : "lxc" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "ceph osd in", + "method" : "POST", + "name" : "in", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/in", + "text" : "in" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "ceph osd out", + "method" : "POST", + "name" : "out", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/out", + "text" : "out" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Instruct the OSD to scrub.", + "method" : "POST", + "name" : "scrub", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "deep" : { + "default" : 0, + "description" : "If set, instructs a deep scrub instead of a normal one.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/scrub", + "text" : "scrub" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy OSD", + "method" : "DELETE", + "name" : "destroyosd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cleanup" : { + "default" : 0, + "description" : "If set, we remove partition table entries.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/osd/{osdid}", + "text" : "{osdid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Ceph osd list/tree.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create OSD", + "method" : "POST", + "name" : "createosd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "crush-device-class" : { + "description" : "Set the device class of the OSD in crush.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "db_dev" : { + "description" : "Block device name for block.db.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "db_size" : { + "default" : "bluestore_block_db_size or 10% of OSD size", + "description" : "Size in GiB for block.db.", + "minimum" : 1, + "optional" : 1, + "requires" : "db_dev", + "type" : "number", + "typetext" : " (1 - N)", + "verbose_description" : "If a block.db is requested but the size is not given, will be automatically selected by: bluestore_block_db_size from the ceph database (osd or global section) or config (osd or global section)in that order. If this is not available, it will be sized 10% of the size of the OSD device. Fails if the available size is not enough." + }, + "dev" : { + "description" : "Block device name.", + "type" : "string", + "typetext" : "" + }, + "encrypted" : { + "default" : 0, + "description" : "Enables encryption of the OSD.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "wal_dev" : { + "description" : "Block device name for block.wal.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "wal_size" : { + "default" : "bluestore_block_wal_size or 1% of OSD size", + "description" : "Size in GiB for block.wal.", + "minimum" : 0.5, + "optional" : 1, + "requires" : "wal_dev", + "type" : "number", + "typetext" : " (0.5 - N)", + "verbose_description" : "If a block.wal is requested but the size is not given, will be automatically selected by: bluestore_block_wal_size from the ceph database (osd or global section) or config (osd or global section)in that order. If this is not available, it will be sized 1% of the size of the OSD device. Fails if the available size is not enough." + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/osd", + "text" : "osd" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy Ceph Metadata Server", + "method" : "DELETE", + "name" : "destroymds", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The name (ID) of the mds", + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Ceph Metadata Server (MDS)", + "method" : "POST", + "name" : "createmds", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "hotstandby" : { + "default" : "0", + "description" : "Determines whether a ceph-mds daemon should poll and replay the log of an active MDS. Faster switch on MDS failure, but needs more idle resources.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "default" : "nodename", + "description" : "The ID for the mds, when omitted the same as the nodename", + "maxLength" : 200, + "optional" : 1, + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/mds/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "MDS directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "addr" : { + "optional" : 1, + "type" : "string" + }, + "host" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name (ID) for the MDS" + }, + "rank" : { + "optional" : 1, + "type" : "integer" + }, + "standby_replay" : { + "description" : "If true, the standby MDS is polling the active MDS for faster recovery (hot standby).", + "optional" : 1, + "type" : "boolean" + }, + "state" : { + "description" : "State of the MDS", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/mds", + "text" : "mds" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy Ceph Manager.", + "method" : "DELETE", + "name" : "destroymgr", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The ID of the manager", + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Ceph Manager", + "method" : "POST", + "name" : "createmgr", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The ID for the manager, when omitted the same as the nodename", + "maxLength" : 200, + "optional" : 1, + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/mgr/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "MGR directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "addr" : { + "optional" : 1, + "type" : "string" + }, + "host" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name (ID) for the MGR" + }, + "state" : { + "description" : "State of the MGR", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/mgr", + "text" : "mgr" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy Ceph Monitor and Manager.", + "method" : "DELETE", + "name" : "destroymon", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "monid" : { + "description" : "Monitor ID", + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Ceph Monitor and Manager", + "method" : "POST", + "name" : "createmon", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "mon-address" : { + "description" : "Overwrites autodetected monitor IP address. Must be in the public network of ceph.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "monid" : { + "description" : "The ID for the monitor, when omitted the same as the nodename", + "maxLength" : 200, + "optional" : 1, + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/mon/{monid}", + "text" : "{monid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Ceph monitor list.", + "method" : "GET", + "name" : "listmon", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "addr" : { + "optional" : 1, + "type" : "string" + }, + "host" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/mon", + "text" : "mon" + }, + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a Ceph filesystem", + "method" : "POST", + "name" : "createfs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add-storage" : { + "default" : 0, + "description" : "Configure the created CephFS as storage for this cluster.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "default" : "cephfs", + "description" : "The ceph filesystem name.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_num" : { + "default" : 128, + "description" : "Number of placement groups for the backing data pool. The metadata pool will use a quarter of this.", + "maximum" : 32768, + "minimum" : 8, + "optional" : 1, + "type" : "integer", + "typetext" : " (8 - 32768)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/fs/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "data_pool" : { + "description" : "The name of the data pool.", + "type" : "string" + }, + "metadata_pool" : { + "description" : "The name of the metadata pool.", + "type" : "string" + }, + "name" : { + "description" : "The ceph filesystem name.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/fs", + "text" : "fs" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy pool", + "method" : "DELETE", + "name" : "destroypool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "If true, destroys pool even if in use", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "remove_storages" : { + "default" : 0, + "description" : "Remove all pveceph-managed storages configured for this pool", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List pool settings.", + "method" : "GET", + "name" : "getpool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The name of the pool. It must be unique.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "verbose" : { + "default" : 0, + "description" : "If enabled, will display additional data(eg. statistics).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "application" : { + "default" : "rbd", + "description" : "The application of the pool.", + "enum" : [ + "rbd", + "cephfs", + "rgw" + ], + "optional" : 1, + "title" : "Application", + "type" : "string" + }, + "application_list" : { + "optional" : 1, + "title" : "Application", + "type" : "array" + }, + "autoscale_status" : { + "optional" : 1, + "title" : "Autoscale Status", + "type" : "object" + }, + "crush_rule" : { + "description" : "The rule to use for mapping object placement in the cluster.", + "optional" : 1, + "title" : "Crush Rule Name", + "type" : "string" + }, + "fast_read" : { + "title" : "Fast Read", + "type" : "boolean" + }, + "hashpspool" : { + "title" : "hashpspool", + "type" : "boolean" + }, + "id" : { + "title" : "ID", + "type" : "integer" + }, + "min_size" : { + "default" : 2, + "description" : "Minimum number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Min Size", + "type" : "integer" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "title" : "Name", + "type" : "string" + }, + "nodeep-scrub" : { + "title" : "nodeep-scrub", + "type" : "boolean" + }, + "nodelete" : { + "title" : "nodelete", + "type" : "boolean" + }, + "nopgchange" : { + "title" : "nopgchange", + "type" : "boolean" + }, + "noscrub" : { + "title" : "noscrub", + "type" : "boolean" + }, + "nosizechange" : { + "title" : "nosizechange", + "type" : "boolean" + }, + "pg_autoscale_mode" : { + "default" : "warn", + "description" : "The automatic PG scaling mode of the pool.", + "enum" : [ + "on", + "off", + "warn" + ], + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "default" : 128, + "description" : "Number of placement groups.", + "maximum" : 32768, + "minimum" : 1, + "optional" : 1, + "title" : "PG Num", + "type" : "integer" + }, + "pg_num_min" : { + "description" : "Minimal number of placement groups.", + "maximum" : 32768, + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer" + }, + "pgp_num" : { + "title" : "PGP num", + "type" : "integer" + }, + "size" : { + "default" : 3, + "description" : "Number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Size", + "type" : "integer" + }, + "statistics" : { + "optional" : 1, + "title" : "Statistics", + "type" : "object" + }, + "target_size" : { + "description" : "The estimated target size of the pool for the PG autoscaler.", + "optional" : 1, + "pattern" : "^(\\d+(\\.\\d+)?)([KMGT])?$", + "title" : "PG Autoscale Target Size", + "type" : "string" + }, + "target_size_ratio" : { + "description" : "The estimated target ratio of the pool for the PG autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number" + }, + "use_gmt_hitset" : { + "title" : "use_gmt_hitset", + "type" : "boolean" + }, + "write_fadvise_dontneed" : { + "title" : "write_fadvise_dontneed", + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Change POOL settings", + "method" : "PUT", + "name" : "setpool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "application" : { + "description" : "The application of the pool.", + "enum" : [ + "rbd", + "cephfs", + "rgw" + ], + "optional" : 1, + "title" : "Application", + "type" : "string" + }, + "crush_rule" : { + "description" : "The rule to use for mapping object placement in the cluster.", + "optional" : 1, + "title" : "Crush Rule Name", + "type" : "string", + "typetext" : "" + }, + "min_size" : { + "description" : "Minimum number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Min Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "title" : "Name", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_autoscale_mode" : { + "description" : "The automatic PG scaling mode of the pool.", + "enum" : [ + "on", + "off", + "warn" + ], + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "description" : "Number of placement groups.", + "maximum" : 32768, + "minimum" : 1, + "optional" : 1, + "title" : "PG Num", + "type" : "integer", + "typetext" : " (1 - 32768)" + }, + "pg_num_min" : { + "description" : "Minimal number of placement groups.", + "maximum" : 32768, + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer", + "typetext" : " (-N - 32768)" + }, + "size" : { + "description" : "Number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "target_size" : { + "description" : "The estimated target size of the pool for the PG autoscaler.", + "optional" : 1, + "pattern" : "^(\\d+(\\.\\d+)?)([KMGT])?$", + "title" : "PG Autoscale Target Size", + "type" : "string" + }, + "target_size_ratio" : { + "description" : "The estimated target ratio of the pool for the PG autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/pools/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all pools.", + "method" : "GET", + "name" : "lspools", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "autoscale_status" : { + "optional" : 1, + "title" : "Autoscale Status", + "type" : "object" + }, + "bytes_used" : { + "title" : "Used", + "type" : "integer" + }, + "crush_rule" : { + "title" : "Crush Rule", + "type" : "integer" + }, + "crush_rule_name" : { + "title" : "Crush Rule Name", + "type" : "string" + }, + "min_size" : { + "title" : "Min Size", + "type" : "integer" + }, + "percent_used" : { + "title" : "%-Used", + "type" : "number" + }, + "pg_autoscale_mode" : { + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "title" : "PG Num", + "type" : "integer" + }, + "pg_num_final" : { + "optional" : 1, + "title" : "Optimal PG Num", + "type" : "integer" + }, + "pg_num_min" : { + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer" + }, + "pool" : { + "title" : "ID", + "type" : "integer" + }, + "pool_name" : { + "title" : "Name", + "type" : "string" + }, + "size" : { + "title" : "Size", + "type" : "integer" + }, + "target_size" : { + "optional" : 1, + "title" : "PG Autoscale Target Size", + "type" : "integer" + }, + "target_size_ratio" : { + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pool_name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create POOL", + "method" : "POST", + "name" : "createpool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storages" : { + "description" : "Configure VM and CT storage using the new pool.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "application" : { + "default" : "rbd", + "description" : "The application of the pool.", + "enum" : [ + "rbd", + "cephfs", + "rgw" + ], + "optional" : 1, + "title" : "Application", + "type" : "string" + }, + "crush_rule" : { + "description" : "The rule to use for mapping object placement in the cluster.", + "optional" : 1, + "title" : "Crush Rule Name", + "type" : "string", + "typetext" : "" + }, + "min_size" : { + "default" : 2, + "description" : "Minimum number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Min Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "title" : "Name", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_autoscale_mode" : { + "default" : "warn", + "description" : "The automatic PG scaling mode of the pool.", + "enum" : [ + "on", + "off", + "warn" + ], + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "default" : 128, + "description" : "Number of placement groups.", + "maximum" : 32768, + "minimum" : 1, + "optional" : 1, + "title" : "PG Num", + "type" : "integer", + "typetext" : " (1 - 32768)" + }, + "pg_num_min" : { + "description" : "Minimal number of placement groups.", + "maximum" : 32768, + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer", + "typetext" : " (-N - 32768)" + }, + "size" : { + "default" : 3, + "description" : "Number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "target_size" : { + "description" : "The estimated target size of the pool for the PG autoscaler.", + "optional" : 1, + "pattern" : "^(\\d+(\\.\\d+)?)([KMGT])?$", + "title" : "PG Autoscale Target Size", + "type" : "string" + }, + "target_size_ratio" : { + "description" : "The estimated target ratio of the pool for the PG autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/pools", + "text" : "pools" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local disks.", + "method" : "GET", + "name" : "disks", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Only list specific types of disks.", + "enum" : [ + "unused", + "journal_disks" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "dev" : { + "type" : "string" + }, + "gpt" : { + "type" : "boolean" + }, + "model" : { + "optional" : 1, + "type" : "string" + }, + "osdid" : { + "type" : "integer" + }, + "serial" : { + "optional" : 1, + "type" : "string" + }, + "size" : { + "type" : "integer" + }, + "used" : { + "optional" : 1, + "type" : "string" + }, + "vendor" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/disks", + "text" : "disks" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Ceph configuration.", + "method" : "GET", + "name" : "config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/config", + "text" : "config" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Ceph configuration database.", + "method" : "GET", + "name" : "configdb", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "can_update_at_runtime" : { + "type" : "boolean" + }, + "level" : { + "type" : "string" + }, + "mask" : { + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "section" : { + "type" : "string" + }, + "value" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/configdb", + "text" : "configdb" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create initial ceph default configuration and setup symlinks.", + "method" : "POST", + "name" : "init", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cluster-network" : { + "description" : "Declare a separate cluster network, OSDs will routeheartbeat, object replication and recovery traffic over it", + "format" : "CIDR", + "maxLength" : 128, + "optional" : 1, + "requires" : "network", + "type" : "string", + "typetext" : "" + }, + "disable_cephx" : { + "default" : 0, + "description" : "Disable cephx authentication.\n\nWARNING: cephx is a security feature protecting against man-in-the-middle attacks. Only consider disabling cephx if your network is private!", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "min_size" : { + "default" : 2, + "description" : "Minimum number of available replicas per object to allow I/O", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "network" : { + "description" : "Use specific network for all ceph related traffic", + "format" : "CIDR", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_bits" : { + "default" : 6, + "description" : "Placement group bits, used to specify the default number of placement groups.\n\nNOTE: 'osd pool default pg num' does not work for default pools.", + "maximum" : 14, + "minimum" : 6, + "optional" : 1, + "type" : "integer", + "typetext" : " (6 - 14)" + }, + "size" : { + "default" : 3, + "description" : "Targeted number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 7)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/init", + "text" : "init" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop ceph services.", + "method" : "POST", + "name" : "stop", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "default" : "ceph.target", + "description" : "Ceph service name.", + "optional" : 1, + "pattern" : "(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/stop", + "text" : "stop" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start ceph services.", + "method" : "POST", + "name" : "start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "default" : "ceph.target", + "description" : "Ceph service name.", + "optional" : 1, + "pattern" : "(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Restart ceph services.", + "method" : "POST", + "name" : "restart", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "default" : "ceph.target", + "description" : "Ceph service name.", + "optional" : 1, + "pattern" : "(mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/restart", + "text" : "restart" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get ceph status.", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/status", + "text" : "status" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Unset a ceph flag", + "method" : "DELETE", + "name" : "unset_flag", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "flag" : { + "description" : "The ceph flag to unset", + "enum" : [ + "nobackfill", + "nodeep-scrub", + "nodown", + "noin", + "noout", + "norebalance", + "norecover", + "noscrub", + "notieragent", + "noup", + "pause" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Set a specific ceph flag", + "method" : "POST", + "name" : "set_flag", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "flag" : { + "description" : "The ceph flag to set", + "enum" : [ + "nobackfill", + "nodeep-scrub", + "nodown", + "noin", + "noout", + "norebalance", + "norecover", + "noscrub", + "notieragent", + "noup", + "pause" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/flags/{flag}", + "text" : "{flag}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "get all set ceph flags", + "method" : "GET", + "name" : "get_flags", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/flags", + "text" : "flags" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get OSD crush map", + "method" : "GET", + "name" : "crush", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/crush", + "text" : "crush" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read ceph log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List ceph rules.", + "method" : "GET", + "name" : "rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/rules", + "text" : "rules" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph", + "text" : "ceph" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the currently configured vzdump defaults.", + "method" : "GET", + "name" : "defaults", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions for the specified storage (or default storage if none specified). Some properties are only returned when the user has 'Sys.Audit' permissions for the node.", + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (KBytes per second).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "format" : "string-alist", + "optional" : 1, + "type" : "string" + }, + "ionice" : { + "default" : 7, + "description" : "Set CFQ ionice priority.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "mailnotification" : { + "default" : "always", + "description" : "Specify when to send an email", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string" + }, + "maxfiles" : { + "default" : 1, + "description" : "Maximal number of backup files per guest system.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string" + }, + "prune-backups" : { + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean" + }, + "remove" : { + "default" : 1, + "description" : "Remove old backup files if there are more than 'maxfiles' backup files.", + "optional" : 1, + "type" : "boolean" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string" + }, + "size" : { + "default" : 1024, + "description" : "Unused, will be removed in a future release.", + "minimum" : 500, + "optional" : 1, + "type" : "integer" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, N>0 uses N as thread count.", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/vzdump/defaults", + "text" : "defaults" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Extract configuration from vzdump backup archive.", + "method" : "GET", + "name" : "extractconfig", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'VM.Backup' permissions on the backed up guest ID, and 'Datastore.AllocateSpace' on the backup storage.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/vzdump/extractconfig", + "text" : "extractconfig" + } + ], + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create backup.", + "method" : "POST", + "name" : "vzdump", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (KBytes per second).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "format" : "string-alist", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ionice" : { + "default" : 7, + "description" : "Set CFQ ionice priority.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 8)" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mailnotification" : { + "default" : "always", + "description" : "Specify when to send an email", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "maxfiles" : { + "default" : 1, + "description" : "Maximal number of backup files per guest system.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "prune-backups" : { + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove" : { + "default" : 1, + "description" : "Remove old backup files if there are more than 'maxfiles' backup files.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "size" : { + "default" : 1024, + "description" : "Unused, will be removed in a future release.", + "minimum" : 500, + "optional" : 1, + "type" : "integer", + "typetext" : " (500 - N)" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stdout" : { + "description" : "Write tar to stdout, not to a file.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, N>0 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'VM.Backup' permissions on any VM, and 'Datastore.AllocateSpace' on the backup storage. The 'maxfiles', 'prune-backups', 'tmpdir', 'dumpdir', 'script', 'bwlimit' and 'ionice' parameters are restricted to the 'root@pam' user.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/vzdump", + "text" : "vzdump" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read service properties", + "method" : "GET", + "name" : "service_state", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "pveproxy", + "pvedaemon", + "spiceproxy", + "pvestatd", + "pve-cluster", + "corosync", + "pve-firewall", + "pvefw-logger", + "pve-ha-crm", + "pve-ha-lrm", + "sshd", + "syslog", + "cron", + "postfix", + "ksmtuned", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/state", + "text" : "state" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start service.", + "method" : "POST", + "name" : "service_start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "pveproxy", + "pvedaemon", + "spiceproxy", + "pvestatd", + "pve-cluster", + "corosync", + "pve-firewall", + "pvefw-logger", + "pve-ha-crm", + "pve-ha-lrm", + "sshd", + "syslog", + "cron", + "postfix", + "ksmtuned", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop service.", + "method" : "POST", + "name" : "service_stop", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "pveproxy", + "pvedaemon", + "spiceproxy", + "pvestatd", + "pve-cluster", + "corosync", + "pve-firewall", + "pvefw-logger", + "pve-ha-crm", + "pve-ha-lrm", + "sshd", + "syslog", + "cron", + "postfix", + "ksmtuned", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/stop", + "text" : "stop" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Hard restart service. Use reload if you want to reduce interruptions.", + "method" : "POST", + "name" : "service_restart", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "pveproxy", + "pvedaemon", + "spiceproxy", + "pvestatd", + "pve-cluster", + "corosync", + "pve-firewall", + "pvefw-logger", + "pve-ha-crm", + "pve-ha-lrm", + "sshd", + "syslog", + "cron", + "postfix", + "ksmtuned", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/restart", + "text" : "restart" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Reload service. Falls back to restart if service cannot be reloaded.", + "method" : "POST", + "name" : "service_reload", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "pveproxy", + "pvedaemon", + "spiceproxy", + "pvestatd", + "pve-cluster", + "corosync", + "pve-firewall", + "pvefw-logger", + "pve-ha-crm", + "pve-ha-lrm", + "sshd", + "syslog", + "cron", + "postfix", + "ksmtuned", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/reload", + "text" : "reload" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "srvcmdidx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "pveproxy", + "pvedaemon", + "spiceproxy", + "pvestatd", + "pve-cluster", + "corosync", + "pve-firewall", + "pvefw-logger", + "pve-ha-crm", + "pve-ha-lrm", + "sshd", + "syslog", + "cron", + "postfix", + "ksmtuned", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/services/{service}", + "text" : "{service}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Service list.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{service}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/services", + "text" : "services" + }, + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete subscription key of this node.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read subscription info.", + "method" : "GET", + "name" : "get", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Update subscription info.", + "method" : "POST", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "Always connect to server, even if we have up to date info inside local cache.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set subscription key.", + "method" : "PUT", + "name" : "set", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "key" : { + "description" : "Proxmox VE subscription key", + "maxLength" : 32, + "pattern" : "pve([1248])([cbsp])-[0-9a-f]{10}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/subscription", + "text" : "subscription" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete network device configuration", + "method" : "DELETE", + "name" : "delete_network", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read network device configuration", + "method" : "GET", + "name" : "network_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "method" : { + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update network device configuration", + "method" : "PUT", + "name" : "update_network", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "address" : { + "description" : "IP address.", + "format" : "ipv4", + "optional" : 1, + "requires" : "netmask", + "type" : "string", + "typetext" : "" + }, + "address6" : { + "description" : "IP address.", + "format" : "ipv6", + "optional" : 1, + "requires" : "netmask6", + "type" : "string", + "typetext" : "" + }, + "autostart" : { + "description" : "Automatically start interface on boot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bond-primary" : { + "description" : "Specify the primary interface for active-backup bond.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bond_mode" : { + "description" : "Bonding mode.", + "enum" : [ + "balance-rr", + "active-backup", + "balance-xor", + "broadcast", + "802.3ad", + "balance-tlb", + "balance-alb", + "balance-slb", + "lacp-balance-slb", + "lacp-balance-tcp" + ], + "optional" : 1, + "type" : "string" + }, + "bond_xmit_hash_policy" : { + "description" : "Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.", + "enum" : [ + "layer2", + "layer2+3", + "layer3+4" + ], + "optional" : 1, + "type" : "string" + }, + "bridge_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge_vlan_aware" : { + "description" : "Enable bridge vlan support.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cidr" : { + "description" : "IPv4 CIDR.", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cidr6" : { + "description" : "IPv6 CIDR.", + "format" : "CIDRv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comments" : { + "description" : "Comments", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comments6" : { + "description" : "Comments", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway" : { + "description" : "Default gateway address.", + "format" : "ipv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway6" : { + "description" : "Default ipv6 gateway address.", + "format" : "ipv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string", + "typetext" : "" + }, + "mtu" : { + "description" : "MTU.", + "maximum" : 65520, + "minimum" : 1280, + "optional" : 1, + "type" : "integer", + "typetext" : " (1280 - 65520)" + }, + "netmask" : { + "description" : "Network mask.", + "format" : "ipv4mask", + "optional" : 1, + "requires" : "address", + "type" : "string", + "typetext" : "" + }, + "netmask6" : { + "description" : "Network mask.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "requires" : "address6", + "type" : "integer", + "typetext" : " (0 - 128)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "ovs_bonds" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_bridge" : { + "description" : "The OVS bridge associated with a OVS port. This is required when you create an OVS port.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_options" : { + "description" : "OVS interface options.", + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_tag" : { + "description" : "Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4094)" + }, + "slaves" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Network interface type", + "enum" : [ + "bridge", + "bond", + "eth", + "alias", + "vlan", + "OVSBridge", + "OVSBond", + "OVSPort", + "OVSIntPort", + "unknown" + ], + "type" : "string" + }, + "vlan-id" : { + "description" : "vlan-id for a custom named vlan interface (ifupdown2 only).", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4094)" + }, + "vlan-raw-device" : { + "description" : "Specify the raw interface for the vlan interface.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/network/{iface}", + "text" : "{iface}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Revert network configuration changes.", + "method" : "DELETE", + "name" : "revert_network_changes", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List available networks", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Only list specific interface types.", + "enum" : [ + "bridge", + "bond", + "eth", + "alias", + "vlan", + "OVSBridge", + "OVSBond", + "OVSPort", + "OVSIntPort", + "any_bridge" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{iface}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create network device configuration", + "method" : "POST", + "name" : "create_network", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "address" : { + "description" : "IP address.", + "format" : "ipv4", + "optional" : 1, + "requires" : "netmask", + "type" : "string", + "typetext" : "" + }, + "address6" : { + "description" : "IP address.", + "format" : "ipv6", + "optional" : 1, + "requires" : "netmask6", + "type" : "string", + "typetext" : "" + }, + "autostart" : { + "description" : "Automatically start interface on boot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bond-primary" : { + "description" : "Specify the primary interface for active-backup bond.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bond_mode" : { + "description" : "Bonding mode.", + "enum" : [ + "balance-rr", + "active-backup", + "balance-xor", + "broadcast", + "802.3ad", + "balance-tlb", + "balance-alb", + "balance-slb", + "lacp-balance-slb", + "lacp-balance-tcp" + ], + "optional" : 1, + "type" : "string" + }, + "bond_xmit_hash_policy" : { + "description" : "Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.", + "enum" : [ + "layer2", + "layer2+3", + "layer3+4" + ], + "optional" : 1, + "type" : "string" + }, + "bridge_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge_vlan_aware" : { + "description" : "Enable bridge vlan support.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cidr" : { + "description" : "IPv4 CIDR.", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cidr6" : { + "description" : "IPv6 CIDR.", + "format" : "CIDRv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comments" : { + "description" : "Comments", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comments6" : { + "description" : "Comments", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway" : { + "description" : "Default gateway address.", + "format" : "ipv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway6" : { + "description" : "Default ipv6 gateway address.", + "format" : "ipv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string", + "typetext" : "" + }, + "mtu" : { + "description" : "MTU.", + "maximum" : 65520, + "minimum" : 1280, + "optional" : 1, + "type" : "integer", + "typetext" : " (1280 - 65520)" + }, + "netmask" : { + "description" : "Network mask.", + "format" : "ipv4mask", + "optional" : 1, + "requires" : "address", + "type" : "string", + "typetext" : "" + }, + "netmask6" : { + "description" : "Network mask.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "requires" : "address6", + "type" : "integer", + "typetext" : " (0 - 128)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "ovs_bonds" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_bridge" : { + "description" : "The OVS bridge associated with a OVS port. This is required when you create an OVS port.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_options" : { + "description" : "OVS interface options.", + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_tag" : { + "description" : "Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4094)" + }, + "slaves" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Network interface type", + "enum" : [ + "bridge", + "bond", + "eth", + "alias", + "vlan", + "OVSBridge", + "OVSBond", + "OVSPort", + "OVSIntPort", + "unknown" + ], + "type" : "string" + }, + "vlan-id" : { + "description" : "vlan-id for a custom named vlan interface (ifupdown2 only).", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4094)" + }, + "vlan-raw-device" : { + "description" : "Specify the raw interface for the vlan interface.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Reload network configuration", + "method" : "PUT", + "name" : "reload_network_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/network", + "text" : "network" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read task log.", + "method" : "GET", + "name" : "read_task_log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "default" : 50, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "upid" : { + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'Sys.Audit' permissions on '/nodes/' if the task does not belong to him.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/tasks/{upid}/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read task status.", + "method" : "GET", + "name" : "read_task_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "upid" : { + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'Sys.Audit' permissions on '/nodes/' if the task does not belong to him.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "pid" : { + "type" : "integer" + }, + "status" : { + "enum" : [ + "running", + "stopped" + ], + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/tasks/{upid}/status", + "text" : "status" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Stop a task.", + "method" : "DELETE", + "name" : "stop_task", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "upid" : { + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'Sys.Modify' permissions on '/nodes/' if the task does not belong to him.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "upid_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "upid" : { + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/tasks/{upid}", + "text" : "{upid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read task list for one node (finished tasks).", + "method" : "GET", + "name" : "node_tasks", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "errors" : { + "default" : 0, + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "limit" : { + "default" : 50, + "description" : "Only list this amount of tasks.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "source" : { + "default" : "archive", + "description" : "List archived, active or all tasks.", + "enum" : [ + "archive", + "active", + "all" + ], + "optional" : 1, + "type" : "string" + }, + "start" : { + "default" : 0, + "description" : "List tasks beginning from this offset.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "typefilter" : { + "description" : "Only list tasks of this type (e.g., vzstart, vzdump).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userfilter" : { + "description" : "Only list tasks from this user.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "Only list tasks for this VM.", + "format" : "pve-vmid", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "description" : "List task associated with the current user, or all task the user has 'Sys.Audit' permissions on /nodes/ (the the task runs on).", + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "endtime" : { + "optional" : 1, + "title" : "Endtime", + "type" : "integer" + }, + "id" : { + "title" : "ID", + "type" : "string" + }, + "node" : { + "title" : "Node", + "type" : "string" + }, + "pid" : { + "title" : "PID", + "type" : "integer" + }, + "pstart" : { + "type" : "integer" + }, + "starttime" : { + "title" : "Starttime", + "type" : "integer" + }, + "status" : { + "optional" : 1, + "title" : "Status", + "type" : "string" + }, + "type" : { + "title" : "Type", + "type" : "string" + }, + "upid" : { + "title" : "UPID", + "type" : "string" + }, + "user" : { + "title" : "User", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{upid}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/tasks", + "text" : "tasks" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote NFS server.", + "method" : "GET", + "name" : "nfsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "The server address (name or IP).", + "format" : "pve-storage-server", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "options" : { + "description" : "NFS export options.", + "type" : "string" + }, + "path" : { + "description" : "The exported path.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/nfs", + "text" : "nfs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote CIFS server.", + "method" : "GET", + "name" : "cifsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "domain" : { + "description" : "SMB domain (Workgroup).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "User password.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "The server address (name or IP).", + "format" : "pve-storage-server", + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "User name.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "description" : { + "description" : "Descriptive text from server.", + "type" : "string" + }, + "share" : { + "description" : "The cifs share name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/cifs", + "text" : "cifs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote Proxmox Backup Server.", + "method" : "GET", + "name" : "pbsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "User password or API token secret.", + "type" : "string", + "typetext" : "" + }, + "port" : { + "default" : 8007, + "description" : "Optional port.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "server" : { + "description" : "The server address (name or IP).", + "format" : "pve-storage-server", + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "User-name or API token-ID.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "Comment from server.", + "optional" : 1, + "type" : "string" + }, + "store" : { + "description" : "The datastore name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/pbs", + "text" : "pbs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote GlusterFS server.", + "method" : "GET", + "name" : "glusterfsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "The server address (name or IP).", + "format" : "pve-storage-server", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "volname" : { + "description" : "The volume name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/glusterfs", + "text" : "glusterfs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote iSCSI server.", + "method" : "GET", + "name" : "iscsiscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "portal" : { + "description" : "The iSCSI portal (IP or DNS name with optional port).", + "format" : "pve-storage-portal-dns", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "portal" : { + "description" : "The iSCSI portal name.", + "type" : "string" + }, + "target" : { + "description" : "The iSCSI target name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/iscsi", + "text" : "iscsi" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local LVM volume groups.", + "method" : "GET", + "name" : "lvmscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "vg" : { + "description" : "The LVM logical volume group name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/lvm", + "text" : "lvm" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local LVM Thin Pools.", + "method" : "GET", + "name" : "lvmthinscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vg" : { + "maxLength" : 100, + "pattern" : "[a-zA-Z0-9\\.\\+\\_][a-zA-Z0-9\\.\\+\\_\\-]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "lv" : { + "description" : "The LVM Thin Pool name (LVM logical volume).", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/lvmthin", + "text" : "lvmthin" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan zfs pool list on local node.", + "method" : "GET", + "name" : "zfsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "pool" : { + "description" : "ZFS pool name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/zfs", + "text" : "zfs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local USB devices.", + "method" : "GET", + "name" : "usbscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "busnum" : { + "type" : "integer" + }, + "class" : { + "type" : "integer" + }, + "devnum" : { + "type" : "integer" + }, + "level" : { + "type" : "integer" + }, + "manufacturer" : { + "optional" : 1, + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "prodid" : { + "type" : "string" + }, + "product" : { + "optional" : 1, + "type" : "string" + }, + "serial" : { + "optional" : 1, + "type" : "string" + }, + "speed" : { + "type" : "string" + }, + "usbpath" : { + "optional" : 1, + "type" : "string" + }, + "vendid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/usb", + "text" : "usb" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index of available scan methods", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "method" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{method}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/scan", + "text" : "scan" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List mediated device types for given PCI device.", + "method" : "GET", + "name" : "mdevscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pciid" : { + "description" : "The PCI ID to list the mdev types for.", + "pattern" : "(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\\.[0-9a-fA-F]", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "available" : { + "description" : "The number of still available instances of this type.", + "type" : "integer" + }, + "description" : { + "type" : "string" + }, + "type" : { + "description" : "The name of the mdev type.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/hardware/pci/{pciid}/mdev", + "text" : "mdev" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index of available pci methods", + "method" : "GET", + "name" : "pciindex", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pciid" : { + "pattern" : "(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\\.[0-9a-fA-F]", + "type" : "string" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "method" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{method}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/hardware/pci/{pciid}", + "text" : "{pciid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local PCI devices.", + "method" : "GET", + "name" : "pciscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pci-class-blacklist" : { + "default" : "05;06;08;0b", + "description" : "A list of blacklisted PCI classes, which will not be returned. Following are filtered by default: Memory Controller (05), Bridge (06), Generic System Peripheral (08) and Processor (0b).", + "format" : "string-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "verbose" : { + "default" : 1, + "description" : "If disabled, does only print the PCI IDs. Otherwise, additional information like vendor and device will be returned.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "class" : { + "description" : "The PCI Class of the device.", + "type" : "string" + }, + "device" : { + "description" : "The Device ID.", + "type" : "string" + }, + "device_name" : { + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "The PCI ID.", + "type" : "string" + }, + "iommugroup" : { + "description" : "The IOMMU group in which the device is in. If no IOMMU group is detected, it is set to -1.", + "type" : "integer" + }, + "mdev" : { + "description" : "If set, marks that the device is capable of creating mediated devices.", + "optional" : 1, + "type" : "boolean" + }, + "subsystem_device" : { + "description" : "The Subsystem Device ID.", + "optional" : 1, + "type" : "string" + }, + "subsystem_device_name" : { + "optional" : 1, + "type" : "string" + }, + "subsystem_vendor" : { + "description" : "The Subsystem Vendor ID.", + "optional" : 1, + "type" : "string" + }, + "subsystem_vendor_name" : { + "optional" : 1, + "type" : "string" + }, + "vendor" : { + "description" : "The Vendor ID.", + "type" : "string" + }, + "vendor_name" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/hardware/pci", + "text" : "pci" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local USB devices.", + "method" : "GET", + "name" : "usbscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "busnum" : { + "type" : "integer" + }, + "class" : { + "type" : "integer" + }, + "devnum" : { + "type" : "integer" + }, + "level" : { + "type" : "integer" + }, + "manufacturer" : { + "optional" : 1, + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "prodid" : { + "type" : "string" + }, + "product" : { + "optional" : 1, + "type" : "string" + }, + "serial" : { + "optional" : 1, + "type" : "string" + }, + "speed" : { + "type" : "string" + }, + "usbpath" : { + "optional" : 1, + "type" : "string" + }, + "vendid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/hardware/usb", + "text" : "usb" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index of hardware types", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{type}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/hardware", + "text" : "hardware" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get available QEMU/KVM machine types.", + "method" : "GET", + "name" : "types", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "id" : { + "description" : "Full name of machine type and version.", + "type" : "string" + }, + "type" : { + "description" : "The machine type.", + "enum" : [ + "q35", + "i440fx" + ], + "type" : "string" + }, + "version" : { + "description" : "The machine version.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/capabilities/qemu/machines", + "text" : "machines" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "QEMU capabilities index.", + "method" : "GET", + "name" : "qemu_caps_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/capabilities/qemu", + "text" : "qemu" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Node capabilities index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/capabilities", + "text" : "capabilities" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Prune backups. Only those using the standard naming scheme are considered.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "prune-backups" : { + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Either 'qemu' or 'lxc'. Only consider backups for guests of this type.", + "enum" : [ + "qemu", + "lxc" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "Only prune backups for this VM.", + "format" : "pve-vmid", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "description" : "You need the 'Datastore.Allocate' privilege on the storage (or if a VM ID is specified, 'Datastore.AllocateSpace' and 'VM.Backup' for the VM).", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get prune information for backups. NOTE: this is only a preview and might not be what a subsequent prune call does if backups are removed/added in the meantime.", + "method" : "GET", + "name" : "dryrun", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "prune-backups" : { + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Either 'qemu' or 'lxc'. Only consider backups for guests of this type.", + "enum" : [ + "qemu", + "lxc" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "Only consider backups for this guest.", + "format" : "pve-vmid", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "ctime" : { + "description" : "Creation time of the backup (seconds since the UNIX epoch).", + "type" : "integer" + }, + "mark" : { + "description" : "Whether the backup would be kept or removed. For backups that don't use the standard naming scheme, it's 'protected'.", + "type" : "string" + }, + "type" : { + "description" : "One of 'qemu', 'lxc', 'openvz' or 'unknown'.", + "type" : "string" + }, + "vmid" : { + "description" : "The VM the backup belongs to.", + "optional" : 1, + "type" : "integer" + }, + "volid" : { + "description" : "Backup volume ID.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/prunebackups", + "text" : "prunebackups" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete volume", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delay" : { + "description" : "Time to wait for the task to finish. We return 'null' if the task finish within that time.", + "maximum" : 30, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 30)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need 'Datastore.Allocate' privilege on the storage (or 'Datastore.AllocateSpace' for backup volumes if you have VM.Backup privilege on the VM).", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "optional" : 1, + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get volume attributes", + "method" : "GET", + "name" : "info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "format" : { + "description" : "Format identifier ('raw', 'qcow2', 'subvol', 'iso', 'tgz' ...)", + "type" : "string" + }, + "notes" : { + "description" : "Optional notes.", + "optional" : 1, + "type" : "string" + }, + "path" : { + "description" : "The Path", + "type" : "string" + }, + "size" : { + "description" : "Volume size in bytes.", + "renderer" : "bytes", + "type" : "integer" + }, + "used" : { + "description" : "Used space. Please note that most storage plugins do not report anything useful here.", + "renderer" : "bytes", + "type" : "integer" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Copy a volume. This is experimental code - do not use.", + "method" : "POST", + "name" : "copy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target volume identifier", + "type" : "string", + "typetext" : "" + }, + "target_node" : { + "description" : "Target node. Default is local node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Source volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update volume attributes", + "method" : "PUT", + "name" : "updateattributes", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "notes" : { + "description" : "The new notes.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/content/{volume}", + "text" : "{volume}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List storage content.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "content" : { + "description" : "Only list content of this type.", + "format" : "pve-storage-content", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "Only list images for this VM", + "format" : "pve-vmid", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "ctime" : { + "description" : "Creation time (seconds since the UNIX Epoch).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "encrypted" : { + "description" : "If whole backup is encrypted, value is the fingerprint or '1' if encrypted. Only useful for the Proxmox Backup Server storage type.", + "optional" : 1, + "type" : "string" + }, + "format" : { + "description" : "Format identifier ('raw', 'qcow2', 'subvol', 'iso', 'tgz' ...)", + "type" : "string" + }, + "notes" : { + "description" : "Optional notes. If they contain multiple lines, only the first one is returned here.", + "optional" : 1, + "type" : "string" + }, + "parent" : { + "description" : "Volume identifier of parent (for linked cloned).", + "optional" : 1, + "type" : "string" + }, + "size" : { + "description" : "Volume size in bytes.", + "renderer" : "bytes", + "type" : "integer" + }, + "used" : { + "description" : "Used space. Please note that most storage plugins do not report anything useful here.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "verification" : { + "description" : "Last backup verification result, only useful for PBS storages.", + "optional" : 1, + "properties" : { + "state" : { + "description" : "Last backup verification state.", + "type" : "string" + }, + "upid" : { + "description" : "Last backup verification UPID.", + "type" : "string" + } + }, + "type" : "object" + }, + "vmid" : { + "description" : "Associated Owner VMID.", + "optional" : 1, + "type" : "integer" + }, + "volid" : { + "description" : "Volume identifier.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{volid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Allocate disk images.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "filename" : { + "description" : "The name of the file to create.", + "type" : "string", + "typetext" : "" + }, + "format" : { + "enum" : [ + "raw", + "qcow2", + "subvol" + ], + "optional" : 1, + "requires" : "size", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "size" : { + "description" : "Size in kilobyte (1024 bytes). Optional suffixes 'M' (megabyte, 1024K) and 'G' (gigabyte, 1024M)", + "pattern" : "\\d+[MG]?", + "type" : "string" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "Specify owner VM", + "format" : "pve-vmid", + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateSpace" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Volume identifier", + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/storage/{storage}/content", + "text" : "content" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List files and directories for single file restore under the given path.", + "method" : "GET", + "name" : "list", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "filepath" : { + "description" : "base64-path to the directory or file being listed, or \"/\".", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Backup volume ID or name. Currently only PBS snapshots are supported.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "filepath" : { + "description" : "base64 path of the current entry", + "type" : "string" + }, + "leaf" : { + "description" : "If this entry is a leaf in the directory graph.", + "type" : "boolean" + }, + "mtime" : { + "description" : "Entry last-modified time (unix timestamp).", + "optional" : 1, + "type" : "integer" + }, + "size" : { + "description" : "Entry file size.", + "optional" : 1, + "type" : "integer" + }, + "text" : { + "description" : "Entry display text.", + "type" : "string" + }, + "type" : { + "description" : "Entry type.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/file-restore/list", + "text" : "list" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Extract a file or directory (as zip archive) from a PBS backup.", + "method" : "GET", + "name" : "download", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "filepath" : { + "description" : "base64-path to the directory or file to download.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Backup volume ID or name. Currently only PBS snapshots are supported.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "any" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/file-restore/download", + "text" : "download" + } + ], + "leaf" : 0, + "path" : "/nodes/{node}/storage/{storage}/file-restore", + "text" : "file-restore" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read storage status.", + "method" : "GET", + "name" : "read_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read storage RRD statistics (returns PNG).", + "method" : "GET", + "name" : "rrd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "ds" : { + "description" : "The list of datasources you want to display.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "filename" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/rrd", + "text" : "rrd" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read storage RRD statistics.", + "method" : "GET", + "name" : "rrddata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/rrddata", + "text" : "rrddata" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Upload templates and ISO images.", + "method" : "POST", + "name" : "upload", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "content" : { + "description" : "Content type.", + "format" : "pve-storage-content", + "type" : "string", + "typetext" : "" + }, + "filename" : { + "description" : "The name of the file to create.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "tmpfilename" : { + "description" : "The source file name. This parameter is usually set by the REST handler. You can only overwrite it when connecting to the trusted port on localhost.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/upload", + "text" : "upload" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "diridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/storage/{storage}", + "text" : "{storage}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get status for all datastores.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "content" : { + "description" : "Only list stores which support this content type.", + "format" : "pve-storage-content-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enabled" : { + "default" : 0, + "description" : "Only list stores which are enabled (not disabled in config).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "format" : { + "default" : 0, + "description" : "Include information about formats", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Only list status for specified storage", + "format" : "pve-storage-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "If target is different to 'node', we only lists shared storages which content is accessible on this 'node' and the specified 'target' node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "active" : { + "description" : "Set when storage is accessible.", + "optional" : 1, + "type" : "boolean" + }, + "avail" : { + "description" : "Available storage space in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "content" : { + "description" : "Allowed storage content types.", + "format" : "pve-storage-content-list", + "type" : "string" + }, + "enabled" : { + "description" : "Set when storage is enabled (not disabled).", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "description" : "Shared flag from storage configuration.", + "optional" : 1, + "type" : "boolean" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string" + }, + "total" : { + "description" : "Total storage space in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "type" : { + "description" : "Storage type.", + "type" : "string" + }, + "used" : { + "description" : "Used storage space in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "used_fraction" : { + "description" : "Used fraction (used/total).", + "optional" : 1, + "renderer" : "fraction_as_percentage", + "type" : "number" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{storage}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/storage", + "text" : "storage" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List LVM Volume Groups", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "children" : { + "items" : { + "properties" : { + "children" : { + "description" : "The underlying physical volumes", + "items" : { + "properties" : { + "free" : { + "description" : "The free bytes in the physical volume", + "type" : "integer" + }, + "leaf" : { + "type" : "boolean" + }, + "name" : { + "description" : "The name of the physical volume", + "type" : "string" + }, + "size" : { + "description" : "The size of the physical volume in bytes", + "type" : "integer" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "free" : { + "description" : "The free bytes in the volume group", + "type" : "integer" + }, + "leaf" : { + "type" : "boolean" + }, + "name" : { + "description" : "The name of the volume group", + "type" : "string" + }, + "size" : { + "description" : "The size of the volume group in bytes", + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "leaf" : { + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create an LVM Volume Group", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storage" : { + "default" : 0, + "description" : "Configure storage using the Volume Group", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "device" : { + "description" : "The block device you want to create the volume group on", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify", + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/lvm", + "text" : "lvm" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List LVM thinpools", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "lv" : { + "description" : "The name of the thinpool.", + "type" : "string" + }, + "lv_size" : { + "description" : "The size of the thinpool in bytes.", + "type" : "integer" + }, + "metadata_size" : { + "description" : "The size of the metadata lv in bytes.", + "type" : "integer" + }, + "metadata_used" : { + "description" : "The used bytes of the metadata lv.", + "type" : "integer" + }, + "used" : { + "description" : "The used bytes of the thinpool.", + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create an LVM thinpool", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storage" : { + "default" : 0, + "description" : "Configure storage using the thinpool.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "device" : { + "description" : "The block device you want to create the thinpool on.", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify", + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/lvmthin", + "text" : "lvmthin" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "PVE Managed Directory storages.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "device" : { + "description" : "The mounted device.", + "type" : "string" + }, + "options" : { + "description" : "The mount options.", + "type" : "string" + }, + "path" : { + "description" : "The mount path.", + "type" : "string" + }, + "type" : { + "description" : "The filesystem type.", + "type" : "string" + }, + "unitfile" : { + "description" : "The path of the mount unit.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a Filesystem on an unused disk. Will be mounted under '/mnt/pve/NAME'.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storage" : { + "default" : 0, + "description" : "Configure storage using the directory.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "device" : { + "description" : "The block device you want to create the filesystem on.", + "type" : "string", + "typetext" : "" + }, + "filesystem" : { + "default" : "ext4", + "description" : "The desired filesystem.", + "enum" : [ + "ext4", + "xfs" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify", + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/directory", + "text" : "directory" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get details about a zpool.", + "method" : "GET", + "name" : "detail", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "action" : { + "description" : "Information about the recommended action to fix the state.", + "optional" : 1, + "type" : "string" + }, + "children" : { + "description" : "The pool configuration information, including the vdevs for each section (e.g. spares, cache), may be nested.", + "items" : { + "properties" : { + "cksum" : { + "optional" : 1, + "type" : "number" + }, + "msg" : { + "description" : "An optional message about the vdev.", + "type" : "string" + }, + "name" : { + "description" : "The name of the vdev or section.", + "type" : "string" + }, + "read" : { + "optional" : 1, + "type" : "number" + }, + "state" : { + "description" : "The state of the vdev.", + "optional" : 1, + "type" : "string" + }, + "write" : { + "optional" : 1, + "type" : "number" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "errors" : { + "description" : "Information about the errors on the zpool.", + "type" : "string" + }, + "name" : { + "description" : "The name of the zpool.", + "type" : "string" + }, + "scan" : { + "description" : "Information about the last/current scrub.", + "optional" : 1, + "type" : "string" + }, + "state" : { + "description" : "The state of the zpool.", + "type" : "string" + }, + "status" : { + "description" : "Information about the state of the zpool.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/zfs/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List Zpools.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "alloc" : { + "description" : "", + "type" : "integer" + }, + "dedup" : { + "description" : "", + "type" : "number" + }, + "frag" : { + "description" : "", + "type" : "integer" + }, + "free" : { + "description" : "", + "type" : "integer" + }, + "health" : { + "description" : "", + "type" : "string" + }, + "name" : { + "description" : "", + "type" : "string" + }, + "size" : { + "description" : "", + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a ZFS pool.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storage" : { + "default" : 0, + "description" : "Configure storage using the zpool.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ashift" : { + "default" : 12, + "description" : "Pool sector size exponent.", + "maximum" : 16, + "minimum" : 9, + "optional" : 1, + "type" : "integer", + "typetext" : " (9 - 16)" + }, + "compression" : { + "default" : "on", + "description" : "The compression algorithm to use.", + "enum" : [ + "on", + "off", + "gzip", + "lz4", + "lzjb", + "zle" + ], + "optional" : 1, + "type" : "string" + }, + "devices" : { + "description" : "The block devices you want to create the zpool on.", + "format" : "string-list", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "raidlevel" : { + "description" : "The RAID level to use.", + "enum" : [ + "single", + "mirror", + "raid10", + "raidz", + "raidz2", + "raidz3" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify", + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks/zfs", + "text" : "zfs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local disks.", + "method" : "GET", + "name" : "list", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "include-partitions" : { + "default" : 0, + "description" : "Also include partitions.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skipsmart" : { + "default" : 0, + "description" : "Skip smart checks.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "type" : { + "description" : "Only list specific types of disks.", + "enum" : [ + "unused", + "journal_disks" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "devpath" : { + "description" : "The device path", + "type" : "string" + }, + "gpt" : { + "type" : "boolean" + }, + "health" : { + "optional" : 1, + "type" : "string" + }, + "model" : { + "optional" : 1, + "type" : "string" + }, + "osdid" : { + "type" : "integer" + }, + "parent" : { + "description" : "For partitions only. The device path of the disk the partition resides on.", + "optional" : 1, + "type" : "string" + }, + "serial" : { + "optional" : 1, + "type" : "string" + }, + "size" : { + "type" : "integer" + }, + "used" : { + "optional" : 1, + "type" : "string" + }, + "vendor" : { + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/list", + "text" : "list" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get SMART Health of a disk.", + "method" : "GET", + "name" : "smart", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "disk" : { + "description" : "Block device name", + "pattern" : "^/dev/[a-zA-Z0-9\\/]+$", + "type" : "string" + }, + "healthonly" : { + "description" : "If true returns only the health status", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "attributes" : { + "optional" : 1, + "type" : "array" + }, + "health" : { + "type" : "string" + }, + "text" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/smart", + "text" : "smart" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Initialize Disk with GPT", + "method" : "POST", + "name" : "initgpt", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "disk" : { + "description" : "Block device name", + "pattern" : "^/dev/[a-zA-Z0-9\\/]+$", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "uuid" : { + "description" : "UUID for the GPT table", + "maxLength" : 36, + "optional" : 1, + "pattern" : "[a-fA-F0-9\\-]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/initgpt", + "text" : "initgpt" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Node index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks", + "text" : "disks" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List available updates.", + "method" : "GET", + "name" : "list_updates", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "This is used to resynchronize the package index files from their sources (apt-get update).", + "method" : "POST", + "name" : "update_database", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "notify" : { + "default" : 0, + "description" : "Send notification mail about new packages (to email address specified for user 'root@pam').", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "quiet" : { + "default" : 0, + "description" : "Only produces output suitable for logging, omitting progress indicators.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/apt/update", + "text" : "update" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get package changelogs.", + "method" : "GET", + "name" : "changelog", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Package name.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "version" : { + "description" : "Package version.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/apt/changelog", + "text" : "changelog" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get package information for important Proxmox packages.", + "method" : "GET", + "name" : "versions", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/apt/versions", + "text" : "versions" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index for apt (Advanced Package Tool).", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/apt", + "text" : "apt" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "action" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "dest" : { + "optional" : 1, + "type" : "string" + }, + "dport" : { + "optional" : 1, + "type" : "string" + }, + "enable" : { + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "optional" : 1, + "type" : "string" + }, + "iface" : { + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "optional" : 1, + "type" : "string" + }, + "pos" : { + "type" : "integer" + }, + "proto" : { + "optional" : 1, + "type" : "string" + }, + "source" : { + "optional" : 1, + "type" : "string" + }, + "sport" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "pos" : { + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "group" + ], + "optional" : 0, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/firewall/rules", + "text" : "rules" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get host firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "enable" : { + "description" : "Enable host firewall rules.", + "optional" : 1, + "type" : "boolean" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_nf_conntrack" : { + "default" : 0, + "description" : "Enable logging of conntrack information.", + "optional" : 1, + "type" : "boolean" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean" + }, + "nf_conntrack_allow_invalid" : { + "default" : 0, + "description" : "Allow invalid packets on connection tracking.", + "optional" : 1, + "type" : "boolean" + }, + "nf_conntrack_max" : { + "default" : 262144, + "description" : "Maximum number of tracked connections.", + "minimum" : 32768, + "optional" : 1, + "type" : "integer" + }, + "nf_conntrack_tcp_timeout_established" : { + "default" : 432000, + "description" : "Conntrack established timeout.", + "minimum" : 7875, + "optional" : 1, + "type" : "integer" + }, + "nf_conntrack_tcp_timeout_syn_recv" : { + "default" : 60, + "description" : "Conntrack syn recv timeout.", + "maximum" : 60, + "minimum" : 30, + "optional" : 1, + "type" : "integer" + }, + "nosmurfs" : { + "description" : "Enable SMURFS filter.", + "optional" : 1, + "type" : "boolean" + }, + "protection_synflood" : { + "default" : 0, + "description" : "Enable synflood protection", + "optional" : 1, + "type" : "boolean" + }, + "protection_synflood_burst" : { + "default" : 1000, + "description" : "Synflood protection rate burst by ip src.", + "optional" : 1, + "type" : "integer" + }, + "protection_synflood_rate" : { + "default" : 200, + "description" : "Synflood protection rate syn/sec by ip src.", + "optional" : 1, + "type" : "integer" + }, + "smurf_log_level" : { + "description" : "Log level for SMURFS filter.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "tcp_flags_log_level" : { + "description" : "Log level for illegal tcp flags filter.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "tcpflags" : { + "default" : 0, + "description" : "Filter illegal combinations of TCP flags.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Enable host firewall rules.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_nf_conntrack" : { + "default" : 0, + "description" : "Enable logging of conntrack information.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nf_conntrack_allow_invalid" : { + "default" : 0, + "description" : "Allow invalid packets on connection tracking.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nf_conntrack_max" : { + "default" : 262144, + "description" : "Maximum number of tracked connections.", + "minimum" : 32768, + "optional" : 1, + "type" : "integer", + "typetext" : " (32768 - N)" + }, + "nf_conntrack_tcp_timeout_established" : { + "default" : 432000, + "description" : "Conntrack established timeout.", + "minimum" : 7875, + "optional" : 1, + "type" : "integer", + "typetext" : " (7875 - N)" + }, + "nf_conntrack_tcp_timeout_syn_recv" : { + "default" : 60, + "description" : "Conntrack syn recv timeout.", + "maximum" : 60, + "minimum" : 30, + "optional" : 1, + "type" : "integer", + "typetext" : " (30 - 60)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nosmurfs" : { + "description" : "Enable SMURFS filter.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "protection_synflood" : { + "default" : 0, + "description" : "Enable synflood protection", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "protection_synflood_burst" : { + "default" : 1000, + "description" : "Synflood protection rate burst by ip src.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "protection_synflood_rate" : { + "default" : 200, + "description" : "Synflood protection rate syn/sec by ip src.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "smurf_log_level" : { + "description" : "Log level for SMURFS filter.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "tcp_flags_log_level" : { + "description" : "Log level for illegal tcp flags filter.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "tcpflags" : { + "default" : 0, + "description" : "Filter illegal combinations of TCP flags.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/firewall/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read firewall log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/firewall/log", + "text" : "log" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/firewall", + "text" : "firewall" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get replication job status.", + "method" : "GET", + "name" : "job_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/replication/{id}/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read replication job log.", + "method" : "GET", + "name" : "read_job_log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/, or 'Sys.Audit' on '/nodes/'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/replication/{id}/log", + "text" : "log" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Schedule replication job to start as soon as possible.", + "method" : "POST", + "name" : "schedule_now", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/replication/{id}/schedule_now", + "text" : "schedule_now" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/replication/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List status of all replication jobs on this node.", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "guest" : { + "description" : "Only list replication jobs for this guest.", + "format" : "pve-vmid", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/replication", + "text" : "replication" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Revoke existing certificate from CA.", + "method" : "DELETE", + "name" : "revoke_certificate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Order a new certificate from ACME-compatible CA.", + "method" : "POST", + "name" : "new_certificate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "Overwrite existing custom certificate.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Renew existing certificate from CA.", + "method" : "PUT", + "name" : "renew_certificate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "Force renewal even if expiry is more than 30 days away.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/certificates/acme/certificate", + "text" : "certificate" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "ACME index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/certificates/acme", + "text" : "acme" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get information about node's certificates.", + "method" : "GET", + "name" : "info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "filename" : { + "optional" : 1, + "type" : "string" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "issuer" : { + "description" : "Certificate issuer name.", + "optional" : 1, + "type" : "string" + }, + "notafter" : { + "description" : "Certificate's notAfter timestamp (UNIX epoch).", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "notbefore" : { + "description" : "Certificate's notBefore timestamp (UNIX epoch).", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "pem" : { + "description" : "Certificate in PEM format", + "format" : "pem-certificate", + "optional" : 1, + "type" : "string" + }, + "public-key-bits" : { + "description" : "Certificate's public key size", + "optional" : 1, + "type" : "integer" + }, + "public-key-type" : { + "description" : "Certificate's public key algorithm", + "optional" : 1, + "type" : "string" + }, + "san" : { + "description" : "List of Certificate's SubjectAlternativeName entries.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "renderer" : "yaml", + "type" : "array" + }, + "subject" : { + "description" : "Certificate subject name.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/certificates/info", + "text" : "info" + }, + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "DELETE custom certificate chain and key.", + "method" : "DELETE", + "name" : "remove_custom_cert", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "restart" : { + "default" : 0, + "description" : "Restart pveproxy.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Upload or update custom certificate chain and key.", + "method" : "POST", + "name" : "upload_custom_cert", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "certificates" : { + "description" : "PEM encoded certificate (chain).", + "format" : "pem-certificate-chain", + "type" : "string", + "typetext" : "" + }, + "force" : { + "default" : 0, + "description" : "Overwrite existing custom or ACME certificate files.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "key" : { + "description" : "PEM encoded private key.", + "format" : "pem-string", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "restart" : { + "default" : 0, + "description" : "Restart pveproxy.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "filename" : { + "optional" : 1, + "type" : "string" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "issuer" : { + "description" : "Certificate issuer name.", + "optional" : 1, + "type" : "string" + }, + "notafter" : { + "description" : "Certificate's notAfter timestamp (UNIX epoch).", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "notbefore" : { + "description" : "Certificate's notBefore timestamp (UNIX epoch).", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "pem" : { + "description" : "Certificate in PEM format", + "format" : "pem-certificate", + "optional" : 1, + "type" : "string" + }, + "public-key-bits" : { + "description" : "Certificate's public key size", + "optional" : 1, + "type" : "integer" + }, + "public-key-type" : { + "description" : "Certificate's public key algorithm", + "optional" : 1, + "type" : "string" + }, + "san" : { + "description" : "List of Certificate's SubjectAlternativeName entries.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "renderer" : "yaml", + "type" : "array" + }, + "subject" : { + "description" : "Certificate subject name.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/certificates/custom", + "text" : "custom" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Node index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/certificates", + "text" : "certificates" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get node configuration options.", + "method" : "GET", + "name" : "get_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "property" : { + "default" : "all", + "description" : "Return only a specific property from the node configuration.", + "enum" : [ + "acme", + "acmedomain0", + "acmedomain1", + "acmedomain2", + "acmedomain3", + "acmedomain4", + "acmedomain5", + "description", + "startall-onboot-delay", + "wakeonlan" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set node configuration options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acme" : { + "description" : "Node specific ACME settings.", + "format" : { + "account" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string" + }, + "domains" : { + "description" : "List of domains for this node's ACME certificate", + "format" : "pve-acme-domain-list", + "format_description" : "domain[;domain;...]", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[account=] [,domains=]" + }, + "acmedomain[n]" : { + "description" : "ACME domain and validation plugin", + "format" : { + "alias" : { + "description" : "Alias for the Domain to verify ACME Challenge over DNS", + "format" : "pve-acme-alias", + "format_description" : "domain", + "optional" : 1, + "type" : "string" + }, + "domain" : { + "default_key" : 1, + "description" : "domain for this node's ACME certificate", + "format" : "pve-acme-domain", + "format_description" : "domain", + "type" : "string" + }, + "plugin" : { + "default" : "standalone", + "description" : "The ACME plugin ID", + "format" : "pve-configid", + "format_description" : "name of the plugin configuration", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[domain=] [,alias=] [,plugin=]" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Node description/comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "startall-onboot-delay" : { + "default" : 0, + "description" : "Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.", + "maximum" : 300, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 300)" + }, + "wakeonlan" : { + "description" : "MAC address for wake on LAN", + "format" : "mac-addr", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/config", + "text" : "config" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List zone content.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "status" : { + "description" : "Status.", + "optional" : 1, + "type" : "string" + }, + "statusmsg" : { + "description" : "Status details", + "optional" : 1, + "type" : "string" + }, + "vnet" : { + "description" : "Vnet identifier.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{vnet}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/sdn/zones/{zone}/content", + "text" : "content" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "diridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ], + "any", + 1 + ] + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/sdn/zones/{zone}", + "text" : "{zone}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get status for all zones.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "status" : { + "description" : "Status of zone", + "enum" : [ + "available", + "pending", + "error" + ], + "type" : "string" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{zone}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/sdn/zones", + "text" : "zones" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN index.", + "method" : "GET", + "name" : "sdnindex", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/sdn", + "text" : "sdn" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "API version details", + "method" : "GET", + "name" : "version", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "release" : { + "description" : "The current installed Proxmox VE Release", + "type" : "string" + }, + "repoid" : { + "description" : "The short git commit hash ID from which this version was build", + "type" : "string" + }, + "version" : { + "description" : "The current installed pve-manager package version", + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/version", + "text" : "version" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read node status", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Reboot or shutdown a node.", + "method" : "POST", + "name" : "node_cmd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "command" : { + "description" : "Specify the command.", + "enum" : [ + "reboot", + "shutdown" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read tap/vm network device interface counters", + "method" : "GET", + "name" : "netstat", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/netstat", + "text" : "netstat" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute multiple commands in order.", + "method" : "POST", + "name" : "execute", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "commands" : { + "description" : "JSON encoded array of commands.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/execute", + "text" : "execute" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Try to wake a node via 'wake on LAN' network packet.", + "method" : "POST", + "name" : "wakeonlan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "target node for wake on LAN packet", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.PowerMgmt" + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "MAC address used to assemble the WoL magic packet.", + "format" : "mac-addr", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/wakeonlan", + "text" : "wakeonlan" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read node RRD statistics (returns PNG)", + "method" : "GET", + "name" : "rrd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "ds" : { + "description" : "The list of datasources you want to display.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "filename" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/rrd", + "text" : "rrd" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read node RRD statistics", + "method" : "GET", + "name" : "rrddata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/rrddata", + "text" : "rrddata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read system log", + "method" : "GET", + "name" : "syslog", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display all log since this date-time string.", + "optional" : 1, + "pattern" : "^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$", + "type" : "string" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "until" : { + "description" : "Display all log until this date-time string.", + "optional" : 1, + "pattern" : "^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/syslog", + "text" : "syslog" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read Journal", + "method" : "GET", + "name" : "journal", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "endcursor" : { + "description" : "End before the given Cursor. Conflicts with 'until'", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lastentries" : { + "description" : "Limit to the last X lines. Conflicts with a range.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display all log since this UNIX epoch. Conflicts with 'startcursor'.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "startcursor" : { + "description" : "Start after the given Cursor. Conflicts with 'since'", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "until" : { + "description" : "Display all log until this UNIX epoch. Conflicts with 'endcursor'.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/journal", + "text" : "journal" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a VNC Shell proxy.", + "method" : "POST", + "name" : "vncshell", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cmd" : { + "default" : "login", + "description" : "Run specific command or default to login.", + "enum" : [ + "upgrade", + "ceph_install", + "login" + ], + "optional" : 1, + "type" : "string" + }, + "cmd-opts" : { + "default" : "", + "description" : "Add parameters to a command. Encoded as null terminated strings.", + "optional" : 1, + "requires" : "cmd", + "type" : "string", + "typetext" : "" + }, + "height" : { + "description" : "sets the height of the console in pixels.", + "maximum" : 2160, + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - 2160)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "upgrade" : { + "default" : 0, + "description" : "Deprecated, use the 'cmd' property instead! Run 'apt-get dist-upgrade' instead of normal shell.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "websocket" : { + "description" : "use websocket instead of standard vnc.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "width" : { + "description" : "sets the width of the console in pixels.", + "maximum" : 4096, + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - 4096)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ], + "description" : "Restricted to users on realm 'pam'" + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "cert" : { + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/vncshell", + "text" : "vncshell" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a VNC Shell proxy.", + "method" : "POST", + "name" : "termproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cmd" : { + "default" : "login", + "description" : "Run specific command or default to login.", + "enum" : [ + "upgrade", + "ceph_install", + "login" + ], + "optional" : 1, + "type" : "string" + }, + "cmd-opts" : { + "default" : "", + "description" : "Add parameters to a command. Encoded as null terminated strings.", + "optional" : 1, + "requires" : "cmd", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "upgrade" : { + "default" : 0, + "description" : "Deprecated, use the 'cmd' property instead! Run 'apt-get dist-upgrade' instead of normal shell.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ], + "description" : "Restricted to users on realm 'pam'" + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/termproxy", + "text" : "termproxy" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Opens a weksocket for VNC traffic.", + "method" : "GET", + "name" : "vncwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Port number returned by previous vncproxy call.", + "maximum" : 5999, + "minimum" : 5900, + "type" : "integer", + "typetext" : " (5900 - 5999)" + }, + "vncticket" : { + "description" : "Ticket from previous call to vncproxy.", + "maxLength" : 512, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ], + "description" : "Restricted to users on realm 'pam'. You also need to pass a valid ticket (vncticket)." + }, + "returns" : { + "properties" : { + "port" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/vncwebsocket", + "text" : "vncwebsocket" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a SPICE shell.", + "method" : "POST", + "name" : "spiceshell", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cmd" : { + "default" : "login", + "description" : "Run specific command or default to login.", + "enum" : [ + "upgrade", + "ceph_install", + "login" + ], + "optional" : 1, + "type" : "string" + }, + "cmd-opts" : { + "default" : "", + "description" : "Add parameters to a command. Encoded as null terminated strings.", + "optional" : 1, + "requires" : "cmd", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "proxy" : { + "description" : "SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).", + "format" : "address", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "upgrade" : { + "default" : 0, + "description" : "Deprecated, use the 'cmd' property instead! Run 'apt-get dist-upgrade' instead of normal shell.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ], + "description" : "Restricted to users on realm 'pam'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 1, + "description" : "Returned values can be directly passed to the 'remote-viewer' application.", + "properties" : { + "host" : { + "type" : "string" + }, + "password" : { + "type" : "string" + }, + "proxy" : { + "type" : "string" + }, + "tls-port" : { + "type" : "integer" + }, + "type" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/spiceshell", + "text" : "spiceshell" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read DNS settings.", + "method" : "GET", + "name" : "dns", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "properties" : { + "dns1" : { + "description" : "First name server IP address.", + "optional" : 1, + "type" : "string" + }, + "dns2" : { + "description" : "Second name server IP address.", + "optional" : 1, + "type" : "string" + }, + "dns3" : { + "description" : "Third name server IP address.", + "optional" : 1, + "type" : "string" + }, + "search" : { + "description" : "Search domain for host-name lookup.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Write DNS settings.", + "method" : "PUT", + "name" : "update_dns", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dns1" : { + "description" : "First name server IP address.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dns2" : { + "description" : "Second name server IP address.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dns3" : { + "description" : "Third name server IP address.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "search" : { + "description" : "Search domain for host-name lookup.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/dns", + "text" : "dns" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read server time and time zone settings.", + "method" : "GET", + "name" : "time", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "properties" : { + "localtime" : { + "description" : "Seconds since 1970-01-01 00:00:00 (local time)", + "minimum" : 1297163644, + "renderer" : "timestamp_gmt", + "type" : "integer" + }, + "time" : { + "description" : "Seconds since 1970-01-01 00:00:00 UTC.", + "minimum" : 1297163644, + "renderer" : "timestamp", + "type" : "integer" + }, + "timezone" : { + "description" : "Time zone", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set time zone.", + "method" : "PUT", + "name" : "set_timezone", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timezone" : { + "description" : "Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/time", + "text" : "time" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get list of appliances.", + "method" : "GET", + "name" : "aplinfo", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Download appliance templates.", + "method" : "POST", + "name" : "apl_download", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage where the template will be stored", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "template" : { + "description" : "The template which will downloaded", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/aplinfo", + "text" : "aplinfo" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Gather various systems information about a node", + "method" : "GET", + "name" : "report", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/report", + "text" : "report" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start all VMs and containers located on this node (by default only those with onboot=1).", + "method" : "POST", + "name" : "startall", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : "off", + "description" : "Issue start command even if virtual guest have 'onboot' not set or set to off.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "Only consider guests from this comma separated list of VMIDs.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/startall", + "text" : "startall" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop all VMs and Containers.", + "method" : "POST", + "name" : "stopall", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "Only consider Guests with these IDs.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/stopall", + "text" : "stopall" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migrate all VMs and Containers.", + "method" : "POST", + "name" : "migrateall", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "maxworkers" : { + "description" : "Maximal number of parallel migration job. If not set use 'max_workers' from datacenter.cfg, one of both must be set!", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "Only consider Guests with these IDs.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "with-local-disks" : { + "description" : "Enable live storage migration for local disk", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/migrateall", + "text" : "migrateall" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the content of /etc/hosts.", + "method" : "GET", + "name" : "get_etc_hosts", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "data" : { + "description" : "The content of /etc/hosts.", + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Write /etc/hosts.", + "method" : "POST", + "name" : "write_etc_hosts", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "data" : { + "description" : "The target content of /etc/hosts.", + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/hosts", + "text" : "hosts" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Node index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}", + "text" : "{node}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Cluster node index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "cpu" : { + "description" : "CPU utilization.", + "optional" : 1, + "renderer" : "fraction_as_percentage", + "type" : "number" + }, + "level" : { + "description" : "Support level.", + "optional" : 1, + "type" : "string" + }, + "maxcpu" : { + "description" : "Number of available CPUs.", + "optional" : 1, + "type" : "integer" + }, + "maxmem" : { + "description" : "Number of available memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "mem" : { + "description" : "Used memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "ssl_fingerprint" : { + "description" : "The SSL fingerprint for the node certificate.", + "optional" : 1, + "type" : "string" + }, + "status" : { + "description" : "Node status.", + "enum" : [ + "unknown", + "online", + "offline" + ], + "type" : "string" + }, + "uptime" : { + "description" : "Node uptime in seconds.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{node}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes", + "text" : "nodes" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete storage configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read storage configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update storage configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "blocksize" : { + "description" : "block size", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bwlimit" : { + "description" : "Set bandwidth/io limits various operations.", + "format" : { + "clone" : { + "description" : "bandwidth limit in KiB/s for cloning disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "default" : { + "description" : "default bandwidth limit in KiB/s", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "migration" : { + "description" : "bandwidth limit in KiB/s for migrating guests (including moving local disks)", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "move" : { + "description" : "bandwidth limit in KiB/s for moving disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "restore" : { + "description" : "bandwidth limit in KiB/s for restoring guests from backups", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[clone=] [,default=] [,migration=] [,move=] [,restore=]" + }, + "comstar_hg" : { + "description" : "host group for comstar views", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comstar_tg" : { + "description" : "target group for comstar views", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "content" : { + "description" : "Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n", + "format" : "pve-storage-content-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the storage.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "domain" : { + "description" : "CIFS domain.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "encryption-key" : { + "description" : "Encryption key. Use 'autogen' to generate one automatically without passphrase.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "format" : { + "description" : "Default image format.", + "format" : "pve-storage-format", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fuse" : { + "description" : "Mount CephFS through FUSE.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "is_mountpoint" : { + "default" : "no", + "description" : "Assume the given path is an externally managed mountpoint and consider the storage offline if it is not mounted. Using a boolean (yes/no) value serves as a shortcut to using the target path in this field.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "krbd" : { + "description" : "Always access rbd through krbd kernel module.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lio_tpg" : { + "description" : "target portal group for Linux LIO targets", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "master-pubkey" : { + "description" : "Base64-encoded, PEM-formatted public RSA key. Used tp encrypt a copy of the encryption-key which will be added to each encrypted backup.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "maxfiles" : { + "description" : "Maximal number of backup files per VM. Use '0' for unlimted.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mkdir" : { + "default" : "yes", + "description" : "Create the directory if it doesn't exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "monhost" : { + "description" : "IP addresses of monitors (for external clusters).", + "format" : "pve-storage-portal-dns-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mountpoint" : { + "description" : "mount point", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "namespace" : { + "description" : "RBD Namespace.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nowritecache" : { + "description" : "disable write caching on the target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "options" : { + "description" : "NFS mount options (see 'man nfs')", + "format" : "pve-storage-options", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "Password for accessing the share/datastore.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "default" : 8007, + "description" : "For non default port.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "prune-backups" : { + "description" : "The retention options with shorter intervals are processed first with --keep-last being the very first one. Each option covers a specific period of time. We say that backups within this period are covered by this option. The next option does not take care of already covered backups and only considers older backups.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "redundancy" : { + "default" : 2, + "description" : "The redundancy count specifies the number of nodes to which the resource should be deployed. It must be at least 1 and at most the number of nodes in the cluster.", + "maximum" : 16, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 16)" + }, + "saferemove" : { + "description" : "Zero-out data when removing LVs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "saferemove_throughput" : { + "description" : "Wipe throughput (cstream -t parameter value).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "Server IP or DNS name.", + "format" : "pve-storage-server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server2" : { + "description" : "Backup volfile server IP or DNS name.", + "format" : "pve-storage-server", + "optional" : 1, + "requires" : "server", + "type" : "string", + "typetext" : "" + }, + "shared" : { + "description" : "Mark storage as shared.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "smbversion" : { + "description" : "SMB protocol version", + "enum" : [ + "2.0", + "2.1", + "3.0" + ], + "optional" : 1, + "type" : "string" + }, + "sparse" : { + "description" : "use sparse volumes", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "subdir" : { + "description" : "Subdir to mount.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tagged_only" : { + "description" : "Only use logical volumes tagged with 'pve-vm-ID'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "transport" : { + "description" : "Gluster transport: tcp or rdma", + "enum" : [ + "tcp", + "rdma", + "unix" + ], + "optional" : 1, + "type" : "string" + }, + "username" : { + "description" : "RBD Id.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "config" : { + "additionalProperties" : 1, + "description" : "Partial, possible server generated, configuration properties.", + "optional" : 1, + "properties" : { + "encryption-key" : { + "description" : "The, possible auto-generated, encryption-key.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "storage" : { + "description" : "The ID of the created storage.", + "type" : "string" + }, + "type" : { + "description" : "The type of the created storage.", + "enum" : [ + "cephfs", + "cifs", + "dir", + "drbd", + "glusterfs", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/storage/{storage}", + "text" : "{storage}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Storage index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list storage of specific type", + "enum" : [ + "cephfs", + "cifs", + "dir", + "drbd", + "glusterfs", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "storage" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{storage}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new storage.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "authsupported" : { + "description" : "Authsupported.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "base" : { + "description" : "Base volume. This volume is automatically activated.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "blocksize" : { + "description" : "block size", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bwlimit" : { + "description" : "Set bandwidth/io limits various operations.", + "format" : { + "clone" : { + "description" : "bandwidth limit in KiB/s for cloning disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "default" : { + "description" : "default bandwidth limit in KiB/s", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "migration" : { + "description" : "bandwidth limit in KiB/s for migrating guests (including moving local disks)", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "move" : { + "description" : "bandwidth limit in KiB/s for moving disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "restore" : { + "description" : "bandwidth limit in KiB/s for restoring guests from backups", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[clone=] [,default=] [,migration=] [,move=] [,restore=]" + }, + "comstar_hg" : { + "description" : "host group for comstar views", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comstar_tg" : { + "description" : "target group for comstar views", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "content" : { + "description" : "Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n", + "format" : "pve-storage-content-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "datastore" : { + "description" : "Proxmox Backup Server datastore name.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the storage.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "domain" : { + "description" : "CIFS domain.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "encryption-key" : { + "description" : "Encryption key. Use 'autogen' to generate one automatically without passphrase.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "export" : { + "description" : "NFS export path.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "format" : { + "description" : "Default image format.", + "format" : "pve-storage-format", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fuse" : { + "description" : "Mount CephFS through FUSE.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "is_mountpoint" : { + "default" : "no", + "description" : "Assume the given path is an externally managed mountpoint and consider the storage offline if it is not mounted. Using a boolean (yes/no) value serves as a shortcut to using the target path in this field.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iscsiprovider" : { + "description" : "iscsi provider", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "krbd" : { + "description" : "Always access rbd through krbd kernel module.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lio_tpg" : { + "description" : "target portal group for Linux LIO targets", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "master-pubkey" : { + "description" : "Base64-encoded, PEM-formatted public RSA key. Used tp encrypt a copy of the encryption-key which will be added to each encrypted backup.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "maxfiles" : { + "description" : "Maximal number of backup files per VM. Use '0' for unlimted.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mkdir" : { + "default" : "yes", + "description" : "Create the directory if it doesn't exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "monhost" : { + "description" : "IP addresses of monitors (for external clusters).", + "format" : "pve-storage-portal-dns-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mountpoint" : { + "description" : "mount point", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "namespace" : { + "description" : "RBD Namespace.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nowritecache" : { + "description" : "disable write caching on the target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "options" : { + "description" : "NFS mount options (see 'man nfs')", + "format" : "pve-storage-options", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "Password for accessing the share/datastore.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "File system path.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "default" : 8007, + "description" : "For non default port.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "portal" : { + "description" : "iSCSI portal (IP or DNS name with optional port).", + "format" : "pve-storage-portal-dns", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "prune-backups" : { + "description" : "The retention options with shorter intervals are processed first with --keep-last being the very first one. Each option covers a specific period of time. We say that backups within this period are covered by this option. The next option does not take care of already covered backups and only considers older backups.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "redundancy" : { + "default" : 2, + "description" : "The redundancy count specifies the number of nodes to which the resource should be deployed. It must be at least 1 and at most the number of nodes in the cluster.", + "maximum" : 16, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 16)" + }, + "saferemove" : { + "description" : "Zero-out data when removing LVs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "saferemove_throughput" : { + "description" : "Wipe throughput (cstream -t parameter value).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "Server IP or DNS name.", + "format" : "pve-storage-server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server2" : { + "description" : "Backup volfile server IP or DNS name.", + "format" : "pve-storage-server", + "optional" : 1, + "requires" : "server", + "type" : "string", + "typetext" : "" + }, + "share" : { + "description" : "CIFS share.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "shared" : { + "description" : "Mark storage as shared.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "smbversion" : { + "description" : "SMB protocol version", + "enum" : [ + "2.0", + "2.1", + "3.0" + ], + "optional" : 1, + "type" : "string" + }, + "sparse" : { + "description" : "use sparse volumes", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "type" : "string", + "typetext" : "" + }, + "subdir" : { + "description" : "Subdir to mount.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tagged_only" : { + "description" : "Only use logical volumes tagged with 'pve-vm-ID'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target" : { + "description" : "iSCSI target.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "thinpool" : { + "description" : "LVM thin pool LV name.", + "format" : "pve-storage-vgname", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "transport" : { + "description" : "Gluster transport: tcp or rdma", + "enum" : [ + "tcp", + "rdma", + "unix" + ], + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Storage type.", + "enum" : [ + "cephfs", + "cifs", + "dir", + "drbd", + "glusterfs", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "type" : "string" + }, + "username" : { + "description" : "RBD Id.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vgname" : { + "description" : "Volume group name.", + "format" : "pve-storage-vgname", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Glusterfs Volume.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "config" : { + "additionalProperties" : 1, + "description" : "Partial, possible server generated, configuration properties.", + "optional" : 1, + "properties" : { + "encryption-key" : { + "description" : "The, possible auto-generated, encryption-key.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "storage" : { + "description" : "The ID of the created storage.", + "type" : "string" + }, + "type" : { + "description" : "The type of the created storage.", + "enum" : [ + "cephfs", + "cifs", + "dir", + "drbd", + "glusterfs", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 0, + "path" : "/storage", + "text" : "storage" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get user TFA types (Personal and Realm).", + "method" : "GET", + "name" : "read_user_tfa_type", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "User ID", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "realm" : { + "description" : "The type of TFA the users realm has set, if any.", + "enum" : [ + "oath", + "yubico" + ], + "optional" : 1, + "type" : "string" + }, + "user" : { + "description" : "The type of TFA the user has set, if any.", + "enum" : [ + "oath", + "u2f" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/users/{userid}/tfa", + "text" : "tfa" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove API token for a specific user.", + "method" : "DELETE", + "name" : "remove_token", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "userid" : { + "description" : "User ID", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "perm", + "/access/users/{userid}", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get specific API token information.", + "method" : "GET", + "name" : "read_token", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "userid" : { + "description" : "User ID", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "perm", + "/access/users/{userid}", + [ + "User.Modify" + ] + ] + ] + }, + "returns" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Generate a new API token for a specific user. NOTE: returns API token value, which needs to be stored as it cannot be retrieved afterwards!", + "method" : "POST", + "name" : "generate_token", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "userid" : { + "description" : "User ID", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "perm", + "/access/users/{userid}", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "full-tokenid" : { + "description" : "The full token id.", + "format_description" : "!", + "type" : "string" + }, + "info" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "value" : { + "description" : "API token value used for authentication.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update API token for a specific user.", + "method" : "PUT", + "name" : "update_token_info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "userid" : { + "description" : "User ID", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "perm", + "/access/users/{userid}", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "Updated token information.", + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/users/{userid}/token/{tokenid}", + "text" : "{tokenid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get user API tokens.", + "method" : "GET", + "name" : "token_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "User ID", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "perm", + "/access/users/{userid}", + [ + "User.Modify" + ] + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + }, + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{tokenid}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/access/users/{userid}/token", + "text" : "token" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete user.", + "method" : "DELETE", + "name" : "delete_user", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "User ID", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get user configuration.", + "method" : "GET", + "name" : "read_user", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "User ID", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "email" : { + "format" : "email-opt", + "optional" : 1, + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Enable the account (default). You can set this to '0' to disable the account", + "optional" : 1, + "type" : "boolean" + }, + "expire" : { + "description" : "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "firstname" : { + "optional" : 1, + "type" : "string" + }, + "groups" : { + "items" : { + "format" : "pve-groupid", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "keys" : { + "description" : "Keys for two factor auth (yubico).", + "optional" : 1, + "type" : "string" + }, + "lastname" : { + "optional" : 1, + "type" : "string" + }, + "tokens" : { + "optional" : 1, + "type" : "object" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update user configuration.", + "method" : "PUT", + "name" : "update_user", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "append" : { + "optional" : 1, + "requires" : "groups", + "type" : "boolean", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "email" : { + "format" : "email-opt", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 1, + "description" : "Enable the account (default). You can set this to '0' to disable the account", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "expire" : { + "description" : "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "firstname" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groups" : { + "format" : "pve-groupid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "keys" : { + "description" : "Keys for two factor auth (yubico).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lastname" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "User ID", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "userid-group", + [ + "User.Modify" + ], + "groups_param", + 1 + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/users/{userid}", + "text" : "{userid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "User index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "enabled" : { + "description" : "Optional filter for enable property.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "full" : { + "default" : 0, + "description" : "Include group and token information.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The returned list is restricted to users where you have 'User.Modify' or 'Sys.Audit' permissions on '/access/groups' or on a group the user belongs too. But it always includes the current (authenticated) user.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "email" : { + "format" : "email-opt", + "optional" : 1, + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Enable the account (default). You can set this to '0' to disable the account", + "optional" : 1, + "type" : "boolean" + }, + "expire" : { + "description" : "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "firstname" : { + "optional" : 1, + "type" : "string" + }, + "groups" : { + "format" : "pve-groupid-list", + "optional" : 1, + "type" : "string" + }, + "keys" : { + "description" : "Keys for two factor auth (yubico).", + "optional" : 1, + "type" : "string" + }, + "lastname" : { + "optional" : 1, + "type" : "string" + }, + "tokens" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + }, + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "userid" : { + "description" : "User ID", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{userid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new user.", + "method" : "POST", + "name" : "create_user", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "email" : { + "format" : "email-opt", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 1, + "description" : "Enable the account (default). You can set this to '0' to disable the account", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "expire" : { + "description" : "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "firstname" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groups" : { + "format" : "pve-groupid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "keys" : { + "description" : "Keys for two factor auth (yubico).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lastname" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "Initial password.", + "maxLength" : 64, + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "User ID", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ], + "groups_param", + 1 + ] + ], + "description" : "You need 'Realm.AllocateUser' on '/access/realm/' on the realm of user , and 'User.Modify' permissions to '/access/groups/' for any group specified (or 'User.Modify' on '/access/groups' if you pass no groups." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/users", + "text" : "users" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete group.", + "method" : "DELETE", + "name" : "delete_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "groupid" : { + "format" : "pve-groupid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get group configuration.", + "method" : "GET", + "name" : "read_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "groupid" : { + "format" : "pve-groupid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/groups", + [ + "Sys.Audit", + "Group.Allocate" + ], + "any", + 1 + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "members" : { + "items" : { + "description" : "User ID", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update group data.", + "method" : "PUT", + "name" : "update_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groupid" : { + "format" : "pve-groupid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/groups/{groupid}", + "text" : "{groupid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Group index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "The returned list is restricted to groups where you have 'User.Modify', 'Sys.Audit' or 'Group.Allocate' permissions on /access/groups/.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "groupid" : { + "format" : "pve-groupid", + "type" : "string" + }, + "users" : { + "description" : "list of users which form this group", + "format" : "pve-userid-list", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{groupid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new group.", + "method" : "POST", + "name" : "create_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groupid" : { + "format" : "pve-groupid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/groups", + "text" : "groups" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete role.", + "method" : "DELETE", + "name" : "delete_role", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "roleid" : { + "format" : "pve-roleid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get role configuration.", + "method" : "GET", + "name" : "read_role", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "roleid" : { + "format" : "pve-roleid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "Datastore.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "Datastore.AllocateSpace" : { + "optional" : 1, + "type" : "boolean" + }, + "Datastore.AllocateTemplate" : { + "optional" : 1, + "type" : "boolean" + }, + "Datastore.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "Group.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "Permissions.Modify" : { + "optional" : 1, + "type" : "boolean" + }, + "Pool.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "Realm.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "Realm.AllocateUser" : { + "optional" : 1, + "type" : "boolean" + }, + "SDN.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "SDN.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Console" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Modify" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.PowerMgmt" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Syslog" : { + "optional" : 1, + "type" : "boolean" + }, + "User.Modify" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Backup" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Clone" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.CDROM" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.CPU" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Cloudinit" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Disk" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.HWType" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Memory" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Network" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Options" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Console" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Migrate" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Monitor" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.PowerMgmt" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Snapshot" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Snapshot.Rollback" : { + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update an existing role.", + "method" : "PUT", + "name" : "update_role", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "append" : { + "optional" : 1, + "requires" : "privs", + "type" : "boolean", + "typetext" : "" + }, + "privs" : { + "format" : "pve-priv-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "roleid" : { + "format" : "pve-roleid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/roles/{roleid}", + "text" : "{roleid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Role index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "privs" : { + "format" : "pve-priv-list", + "optional" : 1, + "type" : "string" + }, + "roleid" : { + "format" : "pve-roleid", + "type" : "string" + }, + "special" : { + "default" : 0, + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{roleid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new role.", + "method" : "POST", + "name" : "create_role", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "privs" : { + "format" : "pve-priv-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "roleid" : { + "format" : "pve-roleid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/roles", + "text" : "roles" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Access Control List (ACLs).", + "method" : "GET", + "name" : "read_acl", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "The returned list is restricted to objects where you have rights to modify permissions.", + "user" : "all" + }, + "returns" : { + "items" : { + "additionalProperties" : 0, + "properties" : { + "path" : { + "description" : "Access control path", + "type" : "string" + }, + "propagate" : { + "default" : 1, + "description" : "Allow to propagate (inherit) permissions.", + "optional" : 1, + "type" : "boolean" + }, + "roleid" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "user", + "group", + "token" + ], + "type" : "string" + }, + "ugid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update Access Control List (add or remove permissions).", + "method" : "PUT", + "name" : "update_acl", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "Remove permissions (instead of adding it).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "groups" : { + "description" : "List of groups.", + "format" : "pve-groupid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "Access control path", + "type" : "string", + "typetext" : "" + }, + "propagate" : { + "default" : 1, + "description" : "Allow to propagate (inherit) permissions.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "roles" : { + "description" : "List of roles.", + "format" : "pve-roleid-list", + "type" : "string", + "typetext" : "" + }, + "tokens" : { + "description" : "List of API tokens.", + "format" : "pve-tokenid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "users" : { + "description" : "List of users.", + "format" : "pve-userid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm-modify", + "{path}" + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/acl", + "text" : "acl" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Syncs users and/or groups from the configured LDAP to user.cfg. NOTE: Synced groups will have the name 'name-$realm', so make sure those groups do not exist to prevent overwriting.", + "method" : "POST", + "name" : "sync", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dry-run" : { + "default" : 0, + "description" : "If set, does not write anything.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "enable-new" : { + "default" : "1", + "description" : "Enable newly synced users immediately.", + "optional" : "1", + "type" : "boolean", + "typetext" : "" + }, + "full" : { + "description" : "If set, uses the LDAP Directory as source of truth, deleting users or groups not returned from the sync. Otherwise only syncs information which is not already present, and does not deletes or modifies anything else.", + "optional" : "1", + "type" : "boolean", + "typetext" : "" + }, + "purge" : { + "description" : "Remove ACLs for users or groups which were removed from the config during a sync.", + "optional" : "1", + "type" : "boolean", + "typetext" : "" + }, + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + }, + "scope" : { + "description" : "Select what to sync.", + "enum" : [ + "users", + "groups", + "both" + ], + "optional" : "1", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ], + "description" : "'Realm.AllocateUser' on '/access/realm/' and 'User.Modify' permissions to '/access/groups/'." + }, + "protected" : 1, + "returns" : { + "description" : "Worker Task-UPID", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/access/domains/{realm}/sync", + "text" : "sync" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete an authentication server.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get auth server configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/realm", + [ + "Realm.Allocate", + "Sys.Audit" + ], + "any", + 1 + ] + }, + "returns" : {} + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update authentication server settings.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "base_dn" : { + "description" : "LDAP base domain name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\w+=[^,]+(,\\s*\\w+=[^,]+)*", + "type" : "string" + }, + "bind_dn" : { + "description" : "LDAP bind domain name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\w+=[^,]+(,\\s*\\w+=[^,]+)*", + "type" : "string" + }, + "capath" : { + "default" : "/etc/ssl/certs", + "description" : "Path to the CA certificate store", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "case-sensitive" : { + "default" : 1, + "description" : "username is case-sensitive", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cert" : { + "description" : "Path to the client certificate", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "certkey" : { + "description" : "Path to the client certificate key", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "default" : { + "description" : "Use this as default realm", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "domain" : { + "description" : "AD domain name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\S+", + "type" : "string" + }, + "filter" : { + "description" : "LDAP filter for user sync.", + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_classes" : { + "default" : "groupOfNames, group, univentionGroup, ipausergroup", + "description" : "The objectclasses for groups.", + "format" : "ldap-simple-attr-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_dn" : { + "description" : "LDAP base domain name for group sync. If not set, the base_dn will be used.", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\w+=[^,]+(,\\s*\\w+=[^,]+)*", + "type" : "string" + }, + "group_filter" : { + "description" : "LDAP filter for group sync.", + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_name_attr" : { + "description" : "LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.", + "format" : "ldap-simple-attr", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mode" : { + "default" : "ldap", + "description" : "LDAP protocol mode.", + "enum" : [ + "ldap", + "ldaps", + "ldap+starttls" + ], + "optional" : 1, + "type" : "string" + }, + "password" : { + "description" : "LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Server port.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + }, + "secure" : { + "description" : "Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "server1" : { + "description" : "Server IP address (or DNS name)", + "format" : "address", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server2" : { + "description" : "Fallback Server IP address (or DNS name)", + "format" : "address", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sslversion" : { + "description" : "LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!", + "enum" : [ + "tlsv1", + "tlsv1_1", + "tlsv1_2", + "tlsv1_3" + ], + "optional" : 1, + "type" : "string" + }, + "sync-defaults-options" : { + "description" : "The default options for behavior of synchronizations.", + "format" : "realm-sync-options", + "optional" : 1, + "type" : "string", + "typetext" : "[enable-new=<1|0>] [,full=<1|0>] [,purge=<1|0>] [,scope=]" + }, + "sync_attributes" : { + "description" : "Comma separated list of key=value pairs for specifying which LDAP attributes map to which PVE user field. For example, to map the LDAP attribute 'mail' to PVEs 'email', write 'email=mail'. By default, each PVE user field is represented by an LDAP attribute of the same name.", + "optional" : 1, + "pattern" : "\\w+=[^,]+(,\\s*\\w+=[^,]+)*", + "type" : "string" + }, + "tfa" : { + "description" : "Use Two-factor authentication.", + "format" : "pve-tfa-config", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "type= [,digits=] [,id=] [,key=] [,step=] [,url=]" + }, + "user_attr" : { + "description" : "LDAP user attribute name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\S{2,}", + "type" : "string" + }, + "user_classes" : { + "default" : "inetorgperson, posixaccount, person, user", + "description" : "The objectclasses for users.", + "format" : "ldap-simple-attr-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "verify" : { + "default" : 0, + "description" : "Verify the server's SSL certificate", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/domains/{realm}", + "text" : "{realm}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Authentication domain index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "Anyone can access that, because we need that list for the login box (before the user is authenticated).", + "user" : "world" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "A comment. The GUI use this text when you select a domain (Realm) on the login window.", + "optional" : 1, + "type" : "string" + }, + "realm" : { + "type" : "string" + }, + "tfa" : { + "description" : "Two-factor authentication provider.", + "enum" : [ + "yubico", + "oath" + ], + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{realm}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add an authentication server.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "base_dn" : { + "description" : "LDAP base domain name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\w+=[^,]+(,\\s*\\w+=[^,]+)*", + "type" : "string" + }, + "bind_dn" : { + "description" : "LDAP bind domain name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\w+=[^,]+(,\\s*\\w+=[^,]+)*", + "type" : "string" + }, + "capath" : { + "default" : "/etc/ssl/certs", + "description" : "Path to the CA certificate store", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "case-sensitive" : { + "default" : 1, + "description" : "username is case-sensitive", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cert" : { + "description" : "Path to the client certificate", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "certkey" : { + "description" : "Path to the client certificate key", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "default" : { + "description" : "Use this as default realm", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "domain" : { + "description" : "AD domain name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\S+", + "type" : "string" + }, + "filter" : { + "description" : "LDAP filter for user sync.", + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_classes" : { + "default" : "groupOfNames, group, univentionGroup, ipausergroup", + "description" : "The objectclasses for groups.", + "format" : "ldap-simple-attr-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_dn" : { + "description" : "LDAP base domain name for group sync. If not set, the base_dn will be used.", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\w+=[^,]+(,\\s*\\w+=[^,]+)*", + "type" : "string" + }, + "group_filter" : { + "description" : "LDAP filter for group sync.", + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_name_attr" : { + "description" : "LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.", + "format" : "ldap-simple-attr", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mode" : { + "default" : "ldap", + "description" : "LDAP protocol mode.", + "enum" : [ + "ldap", + "ldaps", + "ldap+starttls" + ], + "optional" : 1, + "type" : "string" + }, + "password" : { + "description" : "LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Server port.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + }, + "secure" : { + "description" : "Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "server1" : { + "description" : "Server IP address (or DNS name)", + "format" : "address", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server2" : { + "description" : "Fallback Server IP address (or DNS name)", + "format" : "address", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sslversion" : { + "description" : "LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!", + "enum" : [ + "tlsv1", + "tlsv1_1", + "tlsv1_2", + "tlsv1_3" + ], + "optional" : 1, + "type" : "string" + }, + "sync-defaults-options" : { + "description" : "The default options for behavior of synchronizations.", + "format" : "realm-sync-options", + "optional" : 1, + "type" : "string", + "typetext" : "[enable-new=<1|0>] [,full=<1|0>] [,purge=<1|0>] [,scope=]" + }, + "sync_attributes" : { + "description" : "Comma separated list of key=value pairs for specifying which LDAP attributes map to which PVE user field. For example, to map the LDAP attribute 'mail' to PVEs 'email', write 'email=mail'. By default, each PVE user field is represented by an LDAP attribute of the same name.", + "optional" : 1, + "pattern" : "\\w+=[^,]+(,\\s*\\w+=[^,]+)*", + "type" : "string" + }, + "tfa" : { + "description" : "Use Two-factor authentication.", + "format" : "pve-tfa-config", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "type= [,digits=] [,id=] [,key=] [,step=] [,url=]" + }, + "type" : { + "description" : "Realm type.", + "enum" : [ + "ad", + "ldap", + "pam", + "pve" + ], + "type" : "string" + }, + "user_attr" : { + "description" : "LDAP user attribute name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\S{2,}", + "type" : "string" + }, + "user_classes" : { + "default" : "inetorgperson, posixaccount, person, user", + "description" : "The objectclasses for users.", + "format" : "ldap-simple-attr-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "verify" : { + "default" : 0, + "description" : "Verify the server's SSL certificate", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/domains", + "text" : "domains" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Dummy. Useful for formatters which want to provide a login page.", + "method" : "GET", + "name" : "get_ticket", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "world" + }, + "returns" : { + "type" : "null" + } + }, + "POST" : { + "allowtoken" : 0, + "description" : "Create or verify authentication ticket.", + "method" : "POST", + "name" : "create_ticket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "otp" : { + "description" : "One-time password for Two-factor authentication.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The secret password. This can also be a valid ticket.", + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "Verify ticket, and check if user have access 'privs' on 'path'", + "maxLength" : 64, + "optional" : 1, + "requires" : "privs", + "type" : "string", + "typetext" : "" + }, + "privs" : { + "description" : "Verify ticket, and check if user have access 'privs' on 'path'", + "format" : "pve-priv-list", + "maxLength" : 64, + "optional" : 1, + "requires" : "path", + "type" : "string", + "typetext" : "" + }, + "realm" : { + "description" : "You can optionally pass the realm using this parameter. Normally the realm is simply added to the username @.", + "format" : "pve-realm", + "maxLength" : 32, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "User name", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need to pass valid credientials.", + "user" : "world" + }, + "protected" : 1, + "returns" : { + "properties" : { + "CSRFPreventionToken" : { + "optional" : 1, + "type" : "string" + }, + "clustername" : { + "optional" : 1, + "type" : "string" + }, + "ticket" : { + "optional" : 1, + "type" : "string" + }, + "username" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/ticket", + "text" : "ticket" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 0, + "description" : "Change user password.", + "method" : "PUT", + "name" : "change_password", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "password" : { + "description" : "The new password.", + "maxLength" : 64, + "minLength" : 5, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "User ID", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + ], + "description" : "Each user is allowed to change his own password. A user can change the password of another user if he has 'Realm.AllocateUser' (on the realm of user ) and 'User.Modify' permission on /access/groups/ on a group where user is member of." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/password", + "text" : "password" + }, + { + "info" : { + "POST" : { + "allowtoken" : 0, + "description" : "Finish a u2f challenge.", + "method" : "POST", + "name" : "verify_tfa", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "response" : { + "description" : "The response to the current authentication challenge.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "protected" : 1, + "returns" : { + "properties" : { + "ticket" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 0, + "description" : "Change user u2f authentication.", + "method" : "PUT", + "name" : "change_tfa", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "The action to perform", + "enum" : [ + "delete", + "new", + "confirm" + ], + "type" : "string" + }, + "config" : { + "description" : "A TFA configuration. This must currently be of type TOTP of not set at all.", + "format" : "pve-tfa-config", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "type= [,digits=] [,id=] [,key=] [,step=] [,url=]" + }, + "key" : { + "description" : "When adding TOTP, the shared secret value.", + "format" : "pve-tfa-secret", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The current password.", + "maxLength" : 64, + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "response" : { + "description" : "Either the the response to the current u2f registration challenge, or, when adding TOTP, the currently valid TOTP value.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "User ID", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + ], + "description" : "A user can change their own u2f or totp token." + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/tfa", + "text" : "tfa" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Retrieve effective permissions of given user/token.", + "method" : "GET", + "name" : "permissions", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "path" : { + "description" : "Only dump this specific path, not the whole tree.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "User ID or full API token ID", + "optional" : 1, + "pattern" : "(?^:^(?^:[^\\s:/]+)\\@(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)(?:!(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+))?$)", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Each user/token is allowed to dump their own permissions. A user can dump the permissions of another user if they have 'Sys.Audit' permission on /access.", + "user" : "all" + }, + "returns" : { + "description" : "Map of \"path\" => (Map of \"privilege\" => \"propagate boolean\").", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/permissions", + "text" : "permissions" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/access", + "text" : "access" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete pool.", + "method" : "DELETE", + "name" : "delete_pool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description" : "You can only delete empty pools (no members)." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get pool configuration.", + "method" : "GET", + "name" : "read_pool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "members" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "id" : { + "type" : "string" + }, + "node" : { + "type" : "string" + }, + "storage" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "enum" : [ + "qemu", + "lxc", + "openvz", + "storage" + ], + "type" : "string" + }, + "vmid" : { + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update pool data.", + "method" : "PUT", + "name" : "update_pool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "Remove vms/storage (instead of adding it).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "List of storage IDs.", + "format" : "pve-storage-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "List of virtual machines.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description" : "You also need the right to modify permissions on any object you add/delete." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/pools/{poolid}", + "text" : "{poolid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Pool index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "List all pools where you have Pool.Allocate or VM.Allocate permissions on /pool/.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "poolid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{poolid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new pool.", + "method" : "POST", + "name" : "create_pool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/pools", + "text" : "pools" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "API version details. The result also includes the global datacenter confguration.", + "method" : "GET", + "name" : "version", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "properties" : { + "release" : { + "type" : "string" + }, + "repoid" : { + "type" : "string" + }, + "version" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/version", + "text" : "version" + } +] +; + +// avoid errors when running without development tools +if (!Ext.isDefined(Ext.global.console)) { + var console = { + dir: function() {}, + log: function() {} + }; +} + +Ext.onReady(function() { + + Ext.define('pve-param-schema', { + extend: 'Ext.data.Model', + fields: [ + 'name', 'type', 'typetext', 'description', 'verbose_description', + 'enum', 'minimum', 'maximum', 'minLength', 'maxLength', + 'pattern', 'title', 'requires', 'format', 'default', + 'disallow', 'extends', 'links', + { + name: 'optional', + type: 'boolean' + } + ] + }); + + var store = Ext.define('pve-updated-treestore', { + extend: 'Ext.data.TreeStore', + model: Ext.define('pve-api-doc', { + extend: 'Ext.data.Model', + fields: [ + 'path', 'info', 'text', + ] + }), + proxy: { + type: 'memory', + data: pveapi + }, + sorters: [{ + property: 'leaf', + direction: 'ASC' + }, { + property: 'text', + direction: 'ASC' + }], + filterer: 'bottomup', + doFilter: function(node) { + this.filterNodes(node, this.getFilters().getFilterFn(), true); + }, + + filterNodes: function(node, filterFn, parentVisible) { + var me = this, + bottomUpFiltering = me.filterer === 'bottomup', + match = filterFn(node) && parentVisible || (node.isRoot() && !me.getRootVisible()), + childNodes = node.childNodes, + len = childNodes && childNodes.length, i, matchingChildren; + + if (len) { + for (i = 0; i < len; ++i) { + matchingChildren = me.filterNodes(childNodes[i], filterFn, match || bottomUpFiltering) || matchingChildren; + } + if (bottomUpFiltering) { + match = matchingChildren || match; + } + } + + node.set("visible", match, me._silentOptions); + return match; + }, + + }).create(); + + var render_description = function(value, metaData, record) { + var pdef = record.data; + + value = pdef.verbose_description || value; + + // TODO: try to render asciidoc correctly + + metaData.style = 'white-space:pre-wrap;' + + return Ext.htmlEncode(value); + }; + + var render_type = function(value, metaData, record) { + var pdef = record.data; + + return pdef['enum'] ? 'enum' : (pdef.type || 'string'); + }; + + var render_format = function(value, metaData, record) { + var pdef = record.data; + + metaData.style = 'white-space:normal;' + + if (pdef.typetext) + return Ext.htmlEncode(pdef.typetext); + + if (pdef['enum']) + return pdef['enum'].join(' | '); + + if (pdef.format) + return pdef.format; + + if (pdef.pattern) + return Ext.htmlEncode(pdef.pattern); + + return ''; + }; + + var render_docu = function(data) { + var md = data.info; + + // console.dir(data); + + var items = []; + + var clicmdhash = { + GET: 'get', + POST: 'create', + PUT: 'set', + DELETE: 'delete' + }; + + Ext.Array.each(['GET', 'POST', 'PUT', 'DELETE'], function(method) { + var info = md[method]; + if (info) { + + var usage = ""; + + usage += "
HTTP:   `; + usage += `${method} /api2/json${endpoint}
"; + usage += "
HTTP:   " + method + " /api2/json" + data.path + "
 
CLI:pvesh " + clicmdhash[method] + " " + data.path + "
"; + + var sections = [ + { + title: 'Description', + html: Ext.htmlEncode(info.description), + bodyPadding: 10 + }, + { + title: 'Usage', + html: usage, + bodyPadding: 10 + } + ]; + + if (info.parameters && info.parameters.properties) { + + var pstore = Ext.create('Ext.data.Store', { + model: 'pve-param-schema', + proxy: { + type: 'memory' + }, + groupField: 'optional', + sorters: [ + { + property: 'name', + direction: 'ASC' + } + ] + }); + + Ext.Object.each(info.parameters.properties, function(name, pdef) { + pdef.name = name; + pstore.add(pdef); + }); + + pstore.sort(); + + var groupingFeature = Ext.create('Ext.grid.feature.Grouping',{ + enableGroupingMenu: false, + groupHeaderTpl: 'OptionalRequired' + }); + + sections.push({ + xtype: 'gridpanel', + title: 'Parameters', + features: [groupingFeature], + store: pstore, + viewConfig: { + trackOver: false, + stripeRows: true + }, + columns: [ + { + header: 'Name', + dataIndex: 'name', + flex: 1 + }, + { + header: 'Type', + dataIndex: 'type', + renderer: render_type, + flex: 1 + }, + { + header: 'Default', + dataIndex: 'default', + flex: 1 + }, + { + header: 'Format', + dataIndex: 'type', + renderer: render_format, + flex: 2 + }, + { + header: 'Description', + dataIndex: 'description', + renderer: render_description, + flex: 6 + } + ] + }); + + } + + if (info.returns) { + + var retinf = info.returns; + var rtype = retinf.type; + if (!rtype && retinf.items) + rtype = 'array'; + if (!rtype) + rtype = 'object'; + + var rpstore = Ext.create('Ext.data.Store', { + model: 'pve-param-schema', + proxy: { + type: 'memory' + }, + groupField: 'optional', + sorters: [ + { + property: 'name', + direction: 'ASC' + } + ] + }); + + var properties; + if (rtype === 'array' && retinf.items.properties) { + properties = retinf.items.properties; + } + + if (rtype === 'object' && retinf.properties) { + properties = retinf.properties; + } + + Ext.Object.each(properties, function(name, pdef) { + pdef.name = name; + rpstore.add(pdef); + }); + + rpstore.sort(); + + var groupingFeature = Ext.create('Ext.grid.feature.Grouping',{ + enableGroupingMenu: false, + groupHeaderTpl: 'OptionalObligatory' + }); + var returnhtml; + if (retinf.items) { + returnhtml = '
items: ' + Ext.htmlEncode(JSON.stringify(retinf.items, null, 4)) + '
'; + } + + if (retinf.properties) { + returnhtml = returnhtml || ''; + returnhtml += '
properties:' + Ext.htmlEncode(JSON.stringify(retinf.properties, null, 4)) + '
'; + } + + var rawSection = Ext.create('Ext.panel.Panel', { + bodyPadding: '0px 10px 10px 10px', + html: returnhtml, + hidden: true + }); + + sections.push({ + xtype: 'gridpanel', + title: 'Returns: ' + rtype, + features: [groupingFeature], + store: rpstore, + viewConfig: { + trackOver: false, + stripeRows: true + }, + columns: [ + { + header: 'Name', + dataIndex: 'name', + flex: 1 + }, + { + header: 'Type', + dataIndex: 'type', + renderer: render_type, + flex: 1 + }, + { + header: 'Default', + dataIndex: 'default', + flex: 1 + }, + { + header: 'Format', + dataIndex: 'type', + renderer: render_format, + flex: 2 + }, + { + header: 'Description', + dataIndex: 'description', + renderer: render_description, + flex: 6 + } + ], + bbar: [ + { + xtype: 'button', + text: 'Show RAW', + handler: function(btn) { + rawSection.setVisible(!rawSection.isVisible()); + btn.setText(rawSection.isVisible() ? 'Hide RAW' : 'Show RAW'); + }} + ] + }); + + sections.push(rawSection); + + + } + + var permhtml = ''; + if (!info.permissions) { + permhtml = "Root only."; + } else { + if (info.permissions.description) { + permhtml += "
" + + Ext.htmlEncode(info.permissions.description) + "
"; + } + + if (info.permissions.user) { + if (!info.permissions.description) { + if (info.permissions.user === 'world') { + permhtml += "Accessible without any authentication."; + } else if (info.permissions.user === 'all') { + permhtml += "Accessible by all authenticated users."; + } else { + permhtml += 'Onyl accessible by user "' + + info.permissions.user + '"'; + } + } + } else if (info.permissions.check) { + permhtml += "
Check: " +
+			    Ext.htmlEncode(Ext.JSON.encode(info.permissions.check))  + "
"; + } else { + permhtml += "Unknown systax!"; + } + } + if (!info.allowtoken) { + permhtml += "
This API endpoint is not available for API tokens." + } + + sections.push({ + title: 'Required permissions', + bodyPadding: 10, + html: permhtml + }); + + + items.push({ + title: method, + autoScroll: true, + defaults: { + border: false + }, + items: sections + }); + } + }); + + var ct = Ext.getCmp('docview'); + ct.setTitle("Path: " + data.path); + ct.removeAll(true); + ct.add(items); + ct.setActiveTab(0); + }; + + Ext.define('Ext.form.SearchField', { + extend: 'Ext.form.field.Text', + alias: 'widget.searchfield', + + emptyText: 'Search...', + + flex: 1, + + inputType: 'search', + listeners: { + 'change': function(){ + + var value = this.getValue(); + if (!Ext.isEmpty(value)) { + store.filter({ + property: 'path', + value: value, + anyMatch: true + }); + } else { + store.clearFilter(); + } + } + } + }); + + var tree = Ext.create('Ext.tree.Panel', { + title: 'Resource Tree', + tbar: [ + { + xtype: 'searchfield', + } + ], + tools: [ + { + type: 'expand', + tooltip: 'Expand all', + tooltipType: 'title', + callback: (tree) => tree.expandAll(), + }, + { + type: 'collapse', + tooltip: 'Collapse all', + tooltipType: 'title', + callback: (tree) => tree.collapseAll(), + }, + ], + store: store, + width: 200, + region: 'west', + split: true, + margins: '5 0 5 5', + rootVisible: false, + listeners: { + selectionchange: function(v, selections) { + if (!selections[0]) + return; + var rec = selections[0]; + render_docu(rec.data); + location.hash = '#' + rec.data.path; + } + } + }); + + Ext.create('Ext.container.Viewport', { + layout: 'border', + renderTo: Ext.getBody(), + items: [ + tree, + { + xtype: 'tabpanel', + title: 'Documentation', + id: 'docview', + region: 'center', + margins: '5 5 5 0', + layout: 'fit', + items: [] + } + ] + }); + + var deepLink = function() { + var path = window.location.hash.substring(1).replace(/\/\s*$/, '') + var endpoint = store.findNode('path', path); + + if (endpoint) { + tree.getSelectionModel().select(endpoint); + tree.expandPath(endpoint.getPath()); + render_docu(endpoint.data); + } + } + window.onhashchange = deepLink; + + deepLink(); + +}); diff --git a/contracts/96cd7121e75cdb3efd58f79ca988f6b235a2f28e6f7eae276ae243f65d8a6724/snapshot.json b/contracts/96cd7121e75cdb3efd58f79ca988f6b235a2f28e6f7eae276ae243f65d8a6724/snapshot.json new file mode 100644 index 0000000..1aef1b2 --- /dev/null +++ b/contracts/96cd7121e75cdb3efd58f79ca988f6b235a2f28e6f7eae276ae243f65d8a6724/snapshot.json @@ -0,0 +1 @@ +{"extra":{"warning_count":0},"format_version":1,"method_count":504,"path_count":338,"paths":[{"extra":{},"methods":[{"allow_token":true,"checksum":"381dbe2603a3fe4644aef5716358b57a8c8df69ae5476d4204ec50da62e28f19","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/access"},{"extra":{},"methods":[{"allow_token":true,"checksum":"69d1196ad983a4e9b6440c4dc7050a74d305be5327ff2b7231df69a5f7300f0a","description":"Get Access Control List (ACLs).","extra":{},"name":"read_acl","parameters":[],"permissions":{"description":"The returned list is restricted to objects where you have rights to modify permissions.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":0},"properties":{"path":{"description":"Access control path","enum":[],"extra":{},"properties":{},"type":"string"},"propagate":{"default":1,"description":"Allow to propagate (inherit) permissions.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"roleid":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":["user","group","token"],"extra":{},"properties":{},"type":"string"},"ugid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f303163fa6559541cc81fcd57689b33e3ed216ea236d34d63cd9d35e3fce947a","description":"Update Access Control List (add or remove permissions).","extra":{},"name":"update_acl","parameters":[{"definition":{"description":"Remove permissions (instead of adding it).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"List of groups.","enum":[],"extra":{"typetext":""},"format":"pve-groupid-list","optional":true,"properties":{},"type":"string"},"name":"groups"},{"definition":{"description":"Access control path","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"path"},{"definition":{"default":1,"description":"Allow to propagate (inherit) permissions.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"propagate"},{"definition":{"description":"List of roles.","enum":[],"extra":{"typetext":""},"format":"pve-roleid-list","properties":{},"type":"string"},"name":"roles"},{"definition":{"description":"List of API tokens.","enum":[],"extra":{"typetext":""},"format":"pve-tokenid-list","optional":true,"properties":{},"type":"string"},"name":"tokens"},{"definition":{"description":"List of users.","enum":[],"extra":{"typetext":""},"format":"pve-userid-list","optional":true,"properties":{},"type":"string"},"name":"users"}],"permissions":{"expression":{"check":["perm-modify","{path}"]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/acl"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f6bd08a792d4f4d22aac7aaddba3d623b96b8333f6e0e464a8782c3ebc6c764b","description":"Authentication domain index.","extra":{},"name":"index","parameters":[],"permissions":{"description":"Anyone can access that, because we need that list for the login box (before the user is authenticated).","expression":{},"extra":{},"user":"world"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{realm}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"A comment. The GUI use this text when you select a domain (Realm) on the login window.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"realm":{"enum":[],"extra":{},"properties":{},"type":"string"},"tfa":{"description":"Two-factor authentication provider.","enum":["yubico","oath"],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"bac235dade082eb4a1619ea09c3b46ce82a0ee40268c35a85760b04251b768e2","description":"Add an authentication server.","extra":{},"name":"create","parameters":[{"definition":{"description":"LDAP base domain name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\w+=[^,]+(,\\s*\\w+=[^,]+)*","properties":{},"type":"string"},"name":"base_dn"},{"definition":{"description":"LDAP bind domain name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\w+=[^,]+(,\\s*\\w+=[^,]+)*","properties":{},"type":"string"},"name":"bind_dn"},{"definition":{"default":"/etc/ssl/certs","description":"Path to the CA certificate store","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"capath"},{"definition":{"default":1,"description":"username is case-sensitive","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"case-sensitive"},{"definition":{"description":"Path to the client certificate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cert"},{"definition":{"description":"Path to the client certificate key","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"certkey"},{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Use this as default realm","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"default"},{"definition":{"description":"AD domain name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\S+","properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"LDAP filter for user sync.","enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"filter"},{"definition":{"default":"groupOfNames, group, univentionGroup, ipausergroup","description":"The objectclasses for groups.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr-list","optional":true,"properties":{},"type":"string"},"name":"group_classes"},{"definition":{"description":"LDAP base domain name for group sync. If not set, the base_dn will be used.","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\w+=[^,]+(,\\s*\\w+=[^,]+)*","properties":{},"type":"string"},"name":"group_dn"},{"definition":{"description":"LDAP filter for group sync.","enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"group_filter"},{"definition":{"description":"LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"group_name_attr"},{"definition":{"default":"ldap","description":"LDAP protocol mode.","enum":["ldap","ldaps","ldap+starttls"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Server port.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"},{"definition":{"description":"Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"secure"},{"definition":{"description":"Server IP address (or DNS name)","enum":[],"extra":{"typetext":""},"format":"address","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"server1"},{"definition":{"description":"Fallback Server IP address (or DNS name)","enum":[],"extra":{"typetext":""},"format":"address","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"server2"},{"definition":{"description":"LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!","enum":["tlsv1","tlsv1_1","tlsv1_2","tlsv1_3"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"sslversion"},{"definition":{"description":"The default options for behavior of synchronizations.","enum":[],"extra":{"typetext":"[enable-new=<1|0>] [,full=<1|0>] [,purge=<1|0>] [,scope=]"},"format":"realm-sync-options","optional":true,"properties":{},"type":"string"},"name":"sync-defaults-options"},{"definition":{"description":"Comma separated list of key=value pairs for specifying which LDAP attributes map to which PVE user field. For example, to map the LDAP attribute 'mail' to PVEs 'email', write 'email=mail'. By default, each PVE user field is represented by an LDAP attribute of the same name.","enum":[],"extra":{},"optional":true,"pattern":"\\w+=[^,]+(,\\s*\\w+=[^,]+)*","properties":{},"type":"string"},"name":"sync_attributes"},{"definition":{"description":"Use Two-factor authentication.","enum":[],"extra":{"typetext":"type= [,digits=] [,id=] [,key=] [,step=] [,url=]"},"format":"pve-tfa-config","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"tfa"},{"definition":{"description":"Realm type.","enum":["ad","ldap","pam","pve"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"LDAP user attribute name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\S{2,}","properties":{},"type":"string"},"name":"user_attr"},{"definition":{"default":"inetorgperson, posixaccount, person, user","description":"The objectclasses for users.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr-list","optional":true,"properties":{},"type":"string"},"name":"user_classes"},{"definition":{"default":0,"description":"Verify the server's SSL certificate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify"}],"permissions":{"expression":{"check":["perm","/access/realm",["Realm.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/domains"},{"extra":{},"methods":[{"allow_token":true,"checksum":"67ef2d8bf073fff13e3d81cd559ffa0c8d70b56f153a1a682bf52b5e6068f2ee","description":"Delete an authentication server.","extra":{},"name":"delete","parameters":[{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"}],"permissions":{"expression":{"check":["perm","/access/realm",["Realm.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"68ad3629142a043ace8f38217d65a6ecf29d34a83d21ff690c0def6efcdabd7c","description":"Get auth server configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"}],"permissions":{"expression":{"check":["perm","/access/realm",["Realm.Allocate","Sys.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{}},"verb":"GET"},{"allow_token":true,"checksum":"c0bc948639061533484b5c1acec43439cf7427f071a9b6b932c48e1f913c0953","description":"Update authentication server settings.","extra":{},"name":"update","parameters":[{"definition":{"description":"LDAP base domain name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\w+=[^,]+(,\\s*\\w+=[^,]+)*","properties":{},"type":"string"},"name":"base_dn"},{"definition":{"description":"LDAP bind domain name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\w+=[^,]+(,\\s*\\w+=[^,]+)*","properties":{},"type":"string"},"name":"bind_dn"},{"definition":{"default":"/etc/ssl/certs","description":"Path to the CA certificate store","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"capath"},{"definition":{"default":1,"description":"username is case-sensitive","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"case-sensitive"},{"definition":{"description":"Path to the client certificate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cert"},{"definition":{"description":"Path to the client certificate key","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"certkey"},{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Use this as default realm","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"default"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"AD domain name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\S+","properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"LDAP filter for user sync.","enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"filter"},{"definition":{"default":"groupOfNames, group, univentionGroup, ipausergroup","description":"The objectclasses for groups.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr-list","optional":true,"properties":{},"type":"string"},"name":"group_classes"},{"definition":{"description":"LDAP base domain name for group sync. If not set, the base_dn will be used.","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\w+=[^,]+(,\\s*\\w+=[^,]+)*","properties":{},"type":"string"},"name":"group_dn"},{"definition":{"description":"LDAP filter for group sync.","enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"group_filter"},{"definition":{"description":"LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"group_name_attr"},{"definition":{"default":"ldap","description":"LDAP protocol mode.","enum":["ldap","ldaps","ldap+starttls"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Server port.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"},{"definition":{"description":"Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"secure"},{"definition":{"description":"Server IP address (or DNS name)","enum":[],"extra":{"typetext":""},"format":"address","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"server1"},{"definition":{"description":"Fallback Server IP address (or DNS name)","enum":[],"extra":{"typetext":""},"format":"address","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"server2"},{"definition":{"description":"LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!","enum":["tlsv1","tlsv1_1","tlsv1_2","tlsv1_3"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"sslversion"},{"definition":{"description":"The default options for behavior of synchronizations.","enum":[],"extra":{"typetext":"[enable-new=<1|0>] [,full=<1|0>] [,purge=<1|0>] [,scope=]"},"format":"realm-sync-options","optional":true,"properties":{},"type":"string"},"name":"sync-defaults-options"},{"definition":{"description":"Comma separated list of key=value pairs for specifying which LDAP attributes map to which PVE user field. For example, to map the LDAP attribute 'mail' to PVEs 'email', write 'email=mail'. By default, each PVE user field is represented by an LDAP attribute of the same name.","enum":[],"extra":{},"optional":true,"pattern":"\\w+=[^,]+(,\\s*\\w+=[^,]+)*","properties":{},"type":"string"},"name":"sync_attributes"},{"definition":{"description":"Use Two-factor authentication.","enum":[],"extra":{"typetext":"type= [,digits=] [,id=] [,key=] [,step=] [,url=]"},"format":"pve-tfa-config","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"tfa"},{"definition":{"description":"LDAP user attribute name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\S{2,}","properties":{},"type":"string"},"name":"user_attr"},{"definition":{"default":"inetorgperson, posixaccount, person, user","description":"The objectclasses for users.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr-list","optional":true,"properties":{},"type":"string"},"name":"user_classes"},{"definition":{"default":0,"description":"Verify the server's SSL certificate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify"}],"permissions":{"expression":{"check":["perm","/access/realm",["Realm.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/domains/{realm}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1a235bfe21da580204749b540d1871cf96755fca39116d59db0b267b1a6e4ac9","description":"Syncs users and/or groups from the configured LDAP to user.cfg. NOTE: Synced groups will have the name 'name-$realm', so make sure those groups do not exist to prevent overwriting.","extra":{},"name":"sync","parameters":[{"definition":{"default":0,"description":"If set, does not write anything.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"dry-run"},{"definition":{"default":"1","description":"Enable newly synced users immediately.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable-new"},{"definition":{"description":"If set, uses the LDAP Directory as source of truth, deleting users or groups not returned from the sync. Otherwise only syncs information which is not already present, and does not deletes or modifies anything else.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"},{"definition":{"description":"Remove ACLs for users or groups which were removed from the config during a sync.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"purge"},{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"},{"definition":{"description":"Select what to sync.","enum":["users","groups","both"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scope"}],"permissions":{"description":"'Realm.AllocateUser' on '/access/realm/' and 'User.Modify' permissions to '/access/groups/'.","expression":{"check":["and",["userid-param","Realm.AllocateUser"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"description":"Worker Task-UPID","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/access/domains/{realm}/sync"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4c91cdccabc91aef686778145ca3abfc7c583221f55d71a6a63742c0c9e8620e","description":"Group index.","extra":{},"name":"index","parameters":[],"permissions":{"description":"The returned list is restricted to groups where you have 'User.Modify', 'Sys.Audit' or 'Group.Allocate' permissions on /access/groups/.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{groupid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"groupid":{"enum":[],"extra":{},"format":"pve-groupid","properties":{},"type":"string"},"users":{"description":"list of users which form this group","enum":[],"extra":{},"format":"pve-userid-list","optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f98ce64f3980dff63659bf39b78cfd90bc57491d5a6b16adf211ad89cb5bacbf","description":"Create new group.","extra":{},"name":"create_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid","properties":{},"type":"string"},"name":"groupid"}],"permissions":{"expression":{"check":["perm","/access/groups",["Group.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/groups"},{"extra":{},"methods":[{"allow_token":true,"checksum":"da8c8fd5b71fd2ffb0d9a877a6a55bf3fece5793e6e84103fd32ce8393b143a9","description":"Delete group.","extra":{},"name":"delete_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid","properties":{},"type":"string"},"name":"groupid"}],"permissions":{"expression":{"check":["perm","/access/groups",["Group.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"799fdd9c33b5554f718d81299c8f85acf80eb8723c53db37be1dd4f2aa92dc2a","description":"Get group configuration.","extra":{},"name":"read_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid","properties":{},"type":"string"},"name":"groupid"}],"permissions":{"expression":{"check":["perm","/access/groups",["Sys.Audit","Group.Allocate"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"members":{"enum":[],"extra":{},"items":{"description":"User ID","enum":[],"extra":{},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"acae7739337fa0edb0e0a31549c4d29be7fdf80fd872c3b0e65f946d447c8570","description":"Update group data.","extra":{},"name":"update_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid","properties":{},"type":"string"},"name":"groupid"}],"permissions":{"expression":{"check":["perm","/access/groups",["Group.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/groups/{groupid}"},{"extra":{},"methods":[{"allow_token":false,"checksum":"d782dd568f0d893a2d1b2d8697f694d74b07510cc0b505b8dbf25e2591f65f26","description":"Change user password.","extra":{},"name":"change_password","parameters":[{"definition":{"description":"The new password.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":5,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"User ID","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"description":"Each user is allowed to change his own password. A user can change the password of another user if he has 'Realm.AllocateUser' (on the realm of user ) and 'User.Modify' permission on /access/groups/ on a group where user is member of.","expression":{"check":["or",["userid-param","self"],["and",["userid-param","Realm.AllocateUser"],["userid-group",["User.Modify"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/password"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4aac04b822f3f74be0f263ff09f286b4faa9ab89e430d6d635783be4935ad0a9","description":"Retrieve effective permissions of given user/token.","extra":{},"name":"permissions","parameters":[{"definition":{"description":"Only dump this specific path, not the whole tree.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"User ID or full API token ID","enum":[],"extra":{},"optional":true,"pattern":"(?^:^(?^:[^\\s:/]+)\\@(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)(?:!(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+))?$)","properties":{},"type":"string"},"name":"userid"}],"permissions":{"description":"Each user/token is allowed to dump their own permissions. A user can dump the permissions of another user if they have 'Sys.Audit' permission on /access.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"Map of \"path\" => (Map of \"privilege\" => \"propagate boolean\").","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/access/permissions"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7d4735a632ce33c51d1e2e47102b18f3b391b730e88f11993ab2319447462466","description":"Role index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{roleid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"privs":{"enum":[],"extra":{},"format":"pve-priv-list","optional":true,"properties":{},"type":"string"},"roleid":{"enum":[],"extra":{},"format":"pve-roleid","properties":{},"type":"string"},"special":{"default":0,"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f57a81b3de7e8d88ea26453fd9bf5d26eb5b707474daa5d903df0fd5883860d5","description":"Create new role.","extra":{},"name":"create_role","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-priv-list","optional":true,"properties":{},"type":"string"},"name":"privs"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-roleid","properties":{},"type":"string"},"name":"roleid"}],"permissions":{"expression":{"check":["perm","/access",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/roles"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f1877684ae2970429259e20a70086722eda0e3fbd75ec22dc770adfed8cdad01","description":"Delete role.","extra":{},"name":"delete_role","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-roleid","properties":{},"type":"string"},"name":"roleid"}],"permissions":{"expression":{"check":["perm","/access",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"2ba47a515f5a42c5d91adc736f0eaa28c8a96d70165f46f39b46a3b54742f7b6","description":"Get role configuration.","extra":{},"name":"read_role","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-roleid","properties":{},"type":"string"},"name":"roleid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"Datastore.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Datastore.AllocateSpace":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Datastore.AllocateTemplate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Datastore.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Group.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Permissions.Modify":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Pool.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Realm.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Realm.AllocateUser":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"SDN.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"SDN.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Console":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Modify":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.PowerMgmt":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Syslog":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"User.Modify":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Backup":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Clone":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.CDROM":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.CPU":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Cloudinit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Disk":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.HWType":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Memory":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Network":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Options":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Console":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Migrate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Monitor":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.PowerMgmt":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Snapshot":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Snapshot.Rollback":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"de543d90c405a031a8d83dba37eaf7b9faa4301cd0cac388ad12bc18dfdeb306","description":"Update an existing role.","extra":{},"name":"update_role","parameters":[{"definition":{"enum":[],"extra":{"requires":"privs","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"append"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-priv-list","optional":true,"properties":{},"type":"string"},"name":"privs"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-roleid","properties":{},"type":"string"},"name":"roleid"}],"permissions":{"expression":{"check":["perm","/access",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/roles/{roleid}"},{"extra":{},"methods":[{"allow_token":false,"checksum":"31ea74e0ee99e322f30f18a289573617242eb338a8f4465ba2c512f018f6a12e","description":"Finish a u2f challenge.","extra":{},"name":"verify_tfa","parameters":[{"definition":{"description":"The response to the current authentication challenge.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"response"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"POST"},{"allow_token":false,"checksum":"cfef6f3305c429d214ed03caadd2c07a05b141d0a0d77d32fbffb834b818f45f","description":"Change user u2f authentication.","extra":{},"name":"change_tfa","parameters":[{"definition":{"description":"The action to perform","enum":["delete","new","confirm"],"extra":{},"properties":{},"type":"string"},"name":"action"},{"definition":{"description":"A TFA configuration. This must currently be of type TOTP of not set at all.","enum":[],"extra":{"typetext":"type= [,digits=] [,id=] [,key=] [,step=] [,url=]"},"format":"pve-tfa-config","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"config"},{"definition":{"description":"When adding TOTP, the shared secret value.","enum":[],"extra":{"typetext":""},"format":"pve-tfa-secret","optional":true,"properties":{},"type":"string"},"name":"key"},{"definition":{"description":"The current password.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Either the the response to the current u2f registration challenge, or, when adding TOTP, the currently valid TOTP value.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"response"},{"definition":{"description":"User ID","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"description":"A user can change their own u2f or totp token.","expression":{"check":["or",["userid-param","self"],["and",["userid-param","Realm.AllocateUser"],["userid-group",["User.Modify"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"PUT"}],"path":"/access/tfa"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b7321acfd13335fc9d66fb47358fa1b8f0ec6775a3c1733a8cdc617c3f9778b8","description":"Dummy. Useful for formatters which want to provide a login page.","extra":{},"name":"get_ticket","parameters":[],"permissions":{"expression":{},"extra":{},"user":"world"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"GET"},{"allow_token":false,"checksum":"821e671e831cfe53a3a9b5160eb5daaaf676dad61020d261fbe1297bf780b43d","description":"Create or verify authentication ticket.","extra":{},"name":"create_ticket","parameters":[{"definition":{"description":"One-time password for Two-factor authentication.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"otp"},{"definition":{"description":"The secret password. This can also be a valid ticket.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Verify ticket, and check if user have access 'privs' on 'path'","enum":[],"extra":{"requires":"privs","typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"Verify ticket, and check if user have access 'privs' on 'path'","enum":[],"extra":{"requires":"path","typetext":""},"format":"pve-priv-list","max_length":64,"optional":true,"properties":{},"type":"string"},"name":"privs"},{"definition":{"description":"You can optionally pass the realm using this parameter. Normally the realm is simply added to the username @.","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"optional":true,"properties":{},"type":"string"},"name":"realm"},{"definition":{"description":"User name","enum":[],"extra":{"typetext":""},"max_length":64,"properties":{},"type":"string"},"name":"username"}],"permissions":{"description":"You need to pass valid credientials.","expression":{},"extra":{},"user":"world"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"CSRFPreventionToken":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"clustername":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ticket":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"username":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"POST"}],"path":"/access/ticket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a31dd20940ccc78cb4994e03bec1d70dd33dd1b50bfd48e136155d8f74308866","description":"User index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Optional filter for enable property.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"default":0,"description":"Include group and token information.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"}],"permissions":{"description":"The returned list is restricted to users where you have 'User.Modify' or 'Sys.Audit' permissions on '/access/groups' or on a group the user belongs too. But it always includes the current (authenticated) user.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{userid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"email":{"enum":[],"extra":{},"format":"email-opt","optional":true,"properties":{},"type":"string"},"enable":{"default":1,"description":"Enable the account (default). You can set this to '0' to disable the account","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"expire":{"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"firstname":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"groups":{"enum":[],"extra":{},"format":"pve-groupid-list","optional":true,"properties":{},"type":"string"},"keys":{"description":"Keys for two factor auth (yubico).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"lastname":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"tokens":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"tokenid":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"userid":{"description":"User ID","enum":[],"extra":{},"format":"pve-userid","max_length":64,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"18aac06e794ddb35a28aa9d37d8045f13fd1c684c7a2ace6e37bcfe2d501fe4f","description":"Create new user.","extra":{},"name":"create_user","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"email-opt","optional":true,"properties":{},"type":"string"},"name":"email"},{"definition":{"default":1,"description":"Enable the account (default). You can set this to '0' to disable the account","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"expire"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"firstname"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid-list","optional":true,"properties":{},"type":"string"},"name":"groups"},{"definition":{"description":"Keys for two factor auth (yubico).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"keys"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lastname"},{"definition":{"description":"Initial password.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"User ID","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"description":"You need 'Realm.AllocateUser' on '/access/realm/' on the realm of user , and 'User.Modify' permissions to '/access/groups/' for any group specified (or 'User.Modify' on '/access/groups' if you pass no groups.","expression":{"check":["and",["userid-param","Realm.AllocateUser"],["userid-group",["User.Modify"],"groups_param",1]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/users"},{"extra":{},"methods":[{"allow_token":true,"checksum":"433d395101c9417a27268e52ad262e039b40a05e24ebc2f8afcd755d87131919","description":"Delete user.","extra":{},"name":"delete_user","parameters":[{"definition":{"description":"User ID","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["and",["userid-param","Realm.AllocateUser"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"8e37538c7eac404f7059abe708bf84edea3394ceca89fc1da889a44387596aaa","description":"Get user configuration.","extra":{},"name":"read_user","parameters":[{"definition":{"description":"User ID","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["userid-group",["User.Modify","Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"email":{"enum":[],"extra":{},"format":"email-opt","optional":true,"properties":{},"type":"string"},"enable":{"default":1,"description":"Enable the account (default). You can set this to '0' to disable the account","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"expire":{"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"firstname":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"groups":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"pve-groupid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"keys":{"description":"Keys for two factor auth (yubico).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"lastname":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"tokens":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"object"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"d63da6e568d0d44f073d758c0ffc74dc3204e6a3a9d8ef48049de3e412706986","description":"Update user configuration.","extra":{},"name":"update_user","parameters":[{"definition":{"enum":[],"extra":{"requires":"groups","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"append"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"email-opt","optional":true,"properties":{},"type":"string"},"name":"email"},{"definition":{"default":1,"description":"Enable the account (default). You can set this to '0' to disable the account","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"expire"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"firstname"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid-list","optional":true,"properties":{},"type":"string"},"name":"groups"},{"definition":{"description":"Keys for two factor auth (yubico).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"keys"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lastname"},{"definition":{"description":"User ID","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["userid-group",["User.Modify"],"groups_param",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/users/{userid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"de809231d98ef41e399403829d80fd23d42b2136067ea372fa86c93e84a2d833","description":"Get user TFA types (Personal and Realm).","extra":{},"name":"read_user_tfa_type","parameters":[{"definition":{"description":"User ID","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify","Sys.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"realm":{"description":"The type of TFA the users realm has set, if any.","enum":["oath","yubico"],"extra":{},"optional":true,"properties":{},"type":"string"},"user":{"description":"The type of TFA the user has set, if any.","enum":["oath","u2f"],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/access/users/{userid}/tfa"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d2c19c80b04dcb3ca5f7a7abea4570b14841757a248a6e071ba96191ebca7602","description":"Get user API tokens.","extra":{},"name":"token_index","parameters":[{"definition":{"description":"User ID","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["perm","/access/users/{userid}",["User.Modify"]]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{tokenid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"tokenid":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/access/users/{userid}/token"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9b4e3469333ad3685df42f8d4ec3e92e66176f0888b8a90f81c8505f2cf8f351","description":"Remove API token for a specific user.","extra":{},"name":"remove_token","parameters":[{"definition":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"tokenid"},{"definition":{"description":"User ID","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["perm","/access/users/{userid}",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"3a6cb490600c5d5c027fbde0a3124cda0c162f89b2c0fa73dd61f2134aec7742","description":"Get specific API token information.","extra":{},"name":"read_token","parameters":[{"definition":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"tokenid"},{"definition":{"description":"User ID","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["perm","/access/users/{userid}",["User.Modify"]]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"e53c0dc397b0b628fd999dfb01f87b745ca235495a87d0b75b16a4a4fa921031","description":"Generate a new API token for a specific user. NOTE: returns API token value, which needs to be stored as it cannot be retrieved afterwards!","extra":{},"name":"generate_token","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"expire"},{"definition":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"privsep"},{"definition":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"tokenid"},{"definition":{"description":"User ID","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["perm","/access/users/{userid}",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"full-tokenid":{"description":"The full token id.","enum":[],"extra":{"format_description":"!"},"properties":{},"type":"string"},"info":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"value":{"description":"API token value used for authentication.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"POST"},{"allow_token":true,"checksum":"1f6ea791558d31a189d214eadf08f6f80c2f26873531f8a3feb3a73ecae9384d","description":"Update API token for a specific user.","extra":{},"name":"update_token_info","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"expire"},{"definition":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"privsep"},{"definition":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"tokenid"},{"definition":{"description":"User ID","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["perm","/access/users/{userid}",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"description":"Updated token information.","enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"PUT"}],"path":"/access/users/{userid}/token/{tokenid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8208fe00dcce4afff6857aaaea1b384b09f47069978af63ec4017df08db2adc2","description":"Cluster index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster"},{"extra":{},"methods":[{"allow_token":true,"checksum":"454de9c8ff02ffa321a5cb4dec888a3a945bddc5bb7b099c0da6cca8fb62090b","description":"ACMEAccount index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/acme"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1effbffd5ff5a4763a2fe7769dff21fc58d70d542b250d7117b4d7aa2264e0ca","description":"ACMEAccount index.","extra":{},"name":"account_index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"8d0f6d8961219fac42537b588694882669de3f2762a283e16e7ad4b918184a8e","description":"Register a new ACME account with CA.","extra":{},"name":"register_account","parameters":[{"definition":{"description":"Contact email addresses.","enum":[],"extra":{"typetext":""},"format":"email-list","properties":{},"type":"string"},"name":"contact"},{"definition":{"default":"https://acme-v02.api.letsencrypt.org/directory","description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"optional":true,"pattern":"^https?://.*","properties":{},"type":"string"},"name":"directory"},{"definition":{"default":"default","description":"ACME account config file name.","enum":[],"extra":{"format_description":"name","typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"URL of CA TermsOfService - setting this indicates agreement.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tos_url"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/acme/account"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b454212b12e22548f4709a1c2a277a21c02818412eadbb2d14bd24d8352bddf8","description":"Deactivate existing ACME account at CA.","extra":{},"name":"deactivate_account","parameters":[{"definition":{"default":"default","description":"ACME account config file name.","enum":[],"extra":{"format_description":"name","typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"name"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"8a68ee3cda0d4d131277b3fe68cbea1ed1fb044dc7ecec47cb77afc513eef373","description":"Return existing ACME account information.","extra":{},"name":"get_account","parameters":[{"definition":{"default":"default","description":"ACME account config file name.","enum":[],"extra":{"format_description":"name","typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"name"}],"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"account":{"enum":[],"extra":{"renderer":"yaml"},"optional":true,"properties":{},"type":"object"},"directory":{"description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"optional":true,"pattern":"^https?://.*","properties":{},"type":"string"},"location":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"tos":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"d34253209420f70af9ce9636d062d86816aa0aaad6156da14616f0c62a52bf93","description":"Update existing ACME account information with CA. Note: not specifying any new account information triggers a refresh.","extra":{},"name":"update_account","parameters":[{"definition":{"description":"Contact email addresses.","enum":[],"extra":{"typetext":""},"format":"email-list","optional":true,"properties":{},"type":"string"},"name":"contact"},{"definition":{"default":"default","description":"ACME account config file name.","enum":[],"extra":{"format_description":"name","typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"name"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/cluster/acme/account/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bb3b64c0f654249ad36a0e6d6795943403662e273ec2511021fde72e27414433","description":"Get schema of ACME challenge types.","extra":{},"name":"challengeschema","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":0},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Human readable name, falls back to id","enum":[],"extra":{},"properties":{},"type":"string"},"schema":{"enum":[],"extra":{},"properties":{},"type":"object"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/acme/challenge-schema"},{"extra":{},"methods":[{"allow_token":true,"checksum":"83c926d16ce96312b6485852605650ec68d069e1004de1bf706cf88ce5230a8b","description":"Get named known ACME directory endpoints.","extra":{},"name":"get_directories","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":0},"properties":{"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"url":{"description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"pattern":"^https?://.*","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/acme/directories"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3e96f2ad7d3b068e319a6e185995cb4727138447c78db5fb64029588946ae88d","description":"ACME plugin index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list ACME plugins of a specific type","enum":["dns","standalone"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{plugin}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"plugin":{"description":"Unique identifier for ACME plugin instance.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"67ca8368d7dcdd2c706467ca927bc99fe25a3e63031e826399981d551d59180e","description":"Add ACME plugin configuration.","extra":{},"name":"add_plugin","parameters":[{"definition":{"description":"API plugin name","enum":["1984hosting","acmedns","acmeproxy","active24","ad","ali","anx","arvan","aurora","autodns","aws","azure","cf","clouddns","cloudns","cn","conoha","constellix","cx","cyon","da","ddnss","desec","df","dgon","dnsimple","do","doapi","domeneshop","dp","dpi","dreamhost","duckdns","durabledns","dyn","dynu","dynv6","easydns","edgedns","euserv","exoscale","freedns","gandi_livedns","gcloud","gd","gdnsdk","he","hetzner","hexonet","hostingde","huaweicloud","infoblox","infomaniak","internetbs","inwx","ionos","ispconfig","jd","joker","kappernet","kas","kinghost","knot","leaseweb","lexicon","linode","linode_v4","loopia","lua","maradns","me","miab","misaka","myapi","mydevil","mydnsjp","namecheap","namecom","namesilo","nederhost","neodigit","netcup","netlify","nic","njalla","nm","nsd","nsone","nsupdate","nw","one","online","openprovider","openstack","opnsense","ovh","pdns","pleskxml","pointhq","porkbun","rackcorp","rackspace","rcode0","regru","scaleway","schlundtech","selectel","servercow","simply","tele3","transip","ultra","unoeuro","variomedia","vscale","vultr","websupport","world4you","yandex","zilore","zone","zonomi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"api"},{"definition":{"description":"DNS plugin data. (base64 encoded)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"data"},{"definition":{"description":"Flag to disable the config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"ACME Plugin ID name","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"ACME challenge type.","enum":["dns","standalone"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"default":30,"description":"Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.","enum":[],"extra":{"typetext":" (0 - 172800)"},"maximum":172800,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"validation-delay"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/acme/plugins"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e31513c49230a6793d02a258e1461555d3d724ed5007c688cdf61d6047f43335","description":"Delete ACME plugin configuration.","extra":{},"name":"delete_plugin","parameters":[{"definition":{"description":"Unique identifier for ACME plugin instance.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"75aa54b197ffabed6256c4937525a341970e630aa4ea348fa6604b00f2b14e5c","description":"Get ACME plugin configuration.","extra":{},"name":"get_plugin_config","parameters":[{"definition":{"description":"Unique identifier for ACME plugin instance.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"5551534f9ad05bca5c946283560f1e9992b1a3c015369546e43e70156d2cc5d6","description":"Update ACME plugin configuration.","extra":{},"name":"update_plugin","parameters":[{"definition":{"description":"API plugin name","enum":["1984hosting","acmedns","acmeproxy","active24","ad","ali","anx","arvan","aurora","autodns","aws","azure","cf","clouddns","cloudns","cn","conoha","constellix","cx","cyon","da","ddnss","desec","df","dgon","dnsimple","do","doapi","domeneshop","dp","dpi","dreamhost","duckdns","durabledns","dyn","dynu","dynv6","easydns","edgedns","euserv","exoscale","freedns","gandi_livedns","gcloud","gd","gdnsdk","he","hetzner","hexonet","hostingde","huaweicloud","infoblox","infomaniak","internetbs","inwx","ionos","ispconfig","jd","joker","kappernet","kas","kinghost","knot","leaseweb","lexicon","linode","linode_v4","loopia","lua","maradns","me","miab","misaka","myapi","mydevil","mydnsjp","namecheap","namecom","namesilo","nederhost","neodigit","netcup","netlify","nic","njalla","nm","nsd","nsone","nsupdate","nw","one","online","openprovider","openstack","opnsense","ovh","pdns","pleskxml","pointhq","porkbun","rackcorp","rackspace","rcode0","regru","scaleway","schlundtech","selectel","servercow","simply","tele3","transip","ultra","unoeuro","variomedia","vscale","vultr","websupport","world4you","yandex","zilore","zone","zonomi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"api"},{"definition":{"description":"DNS plugin data. (base64 encoded)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"data"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Flag to disable the config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"ACME Plugin ID name","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"default":30,"description":"Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.","enum":[],"extra":{"typetext":" (0 - 172800)"},"maximum":172800,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"validation-delay"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/acme/plugins/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e778ef22db38342828980d7c53532b03f67ee66cc94de0febacf3fba7e7e2deb","description":"Retrieve ACME TermsOfService URL from CA.","extra":{},"name":"get_tos","parameters":[{"definition":{"default":"https://acme-v02.api.letsencrypt.org/directory","description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"optional":true,"pattern":"^https?://.*","properties":{},"type":"string"},"name":"directory"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"ACME TermsOfService URL.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"verb":"GET"}],"path":"/cluster/acme/tos"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b313982759943e059ca83951b1c7d999dc02e144bb6bb0aa7b540f0af19dcbcc","description":"List vzdump backup schedule.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"description":"The job ID.","enum":[],"extra":{},"max_length":50,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"50270ea4cb4db508759335d3d464e21118dca394b747d607acfb4705eb1a5585","description":"Create new vzdump backup job.","extra":{},"name":"create_job","parameters":[{"definition":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"all"},{"definition":{"default":0,"description":"Limit I/O bandwidth (KBytes per second).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"compress"},{"definition":{"default":"mon,tue,wed,thu,fri,sat,sun","description":"Day of week selection.","enum":[],"extra":{"typetext":""},"format":"pve-day-of-week-list","optional":true,"properties":{},"type":"string"},"name":"dow"},{"definition":{"description":"Store resulting files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dumpdir"},{"definition":{"default":"1","description":"Enable or disable the job.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"exclude"},{"definition":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{"typetext":""},"format":"string-alist","optional":true,"properties":{},"type":"string"},"name":"exclude-path"},{"definition":{"default":7,"description":"Set CFQ ionice priority.","enum":[],"extra":{"typetext":" (0 - 8)"},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"ionice"},{"definition":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"lockwait"},{"definition":{"default":"always","description":"Specify when to send an email","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mailnotification"},{"definition":{"description":"Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{"typetext":""},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"name":"mailto"},{"definition":{"default":1,"description":"Maximal number of backup files per guest system.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxfiles"},{"definition":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"Only run if executed on this node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"pigz"},{"definition":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"default":0,"description":"Be quiet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"quiet"},{"definition":{"default":1,"description":"Remove old backup files if there are more than 'maxfiles' backup files.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove"},{"definition":{"description":"Use specified hook script.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"script"},{"definition":{"default":1024,"description":"Unused, will be removed in a future release.","enum":[],"extra":{"typetext":" (500 - N)"},"minimum":500,"optional":true,"properties":{},"type":"integer"},"name":"size"},{"definition":{"description":"Job Start time.","enum":[],"extra":{"typetext":"HH:MM"},"pattern":"\\d{1,2}:\\d{1,2}","properties":{},"type":"string"},"name":"starttime"},{"definition":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stdexcludes"},{"definition":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stop"},{"definition":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"stopwait"},{"definition":{"description":"Store resulting file to this storage.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Store temporary files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tmpdir"},{"definition":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vmid"},{"definition":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, N>0 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"zstd"}],"permissions":{"description":"The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user.","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/backup"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b708c19c2b686aec67700af7135175d2039bd1b1fc411d259686b8f60d10262c","description":"Delete vzdump backup job definition.","extra":{},"name":"delete_job","parameters":[{"definition":{"description":"The job ID.","enum":[],"extra":{"typetext":""},"max_length":50,"properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"27b8de88f0a2f4f349cb4583bbe3633900bff8cd09d72677828f591560dde4ae","description":"Read vzdump backup job definition.","extra":{},"name":"read_job","parameters":[{"definition":{"description":"The job ID.","enum":[],"extra":{"typetext":""},"max_length":50,"properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"8aad9729be65ae99506679db9642d89dda1271aafffbeefd2793350b1f991f69","description":"Update vzdump backup job definition.","extra":{},"name":"update_job","parameters":[{"definition":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"all"},{"definition":{"default":0,"description":"Limit I/O bandwidth (KBytes per second).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"compress"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Day of week selection.","enum":[],"extra":{"typetext":""},"format":"pve-day-of-week-list","optional":true,"properties":{},"type":"string"},"name":"dow"},{"definition":{"description":"Store resulting files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dumpdir"},{"definition":{"default":"1","description":"Enable or disable the job.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"exclude"},{"definition":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{"typetext":""},"format":"string-alist","optional":true,"properties":{},"type":"string"},"name":"exclude-path"},{"definition":{"description":"The job ID.","enum":[],"extra":{"typetext":""},"max_length":50,"properties":{},"type":"string"},"name":"id"},{"definition":{"default":7,"description":"Set CFQ ionice priority.","enum":[],"extra":{"typetext":" (0 - 8)"},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"ionice"},{"definition":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"lockwait"},{"definition":{"default":"always","description":"Specify when to send an email","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mailnotification"},{"definition":{"description":"Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{"typetext":""},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"name":"mailto"},{"definition":{"default":1,"description":"Maximal number of backup files per guest system.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxfiles"},{"definition":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"Only run if executed on this node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"pigz"},{"definition":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"default":0,"description":"Be quiet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"quiet"},{"definition":{"default":1,"description":"Remove old backup files if there are more than 'maxfiles' backup files.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove"},{"definition":{"description":"Use specified hook script.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"script"},{"definition":{"default":1024,"description":"Unused, will be removed in a future release.","enum":[],"extra":{"typetext":" (500 - N)"},"minimum":500,"optional":true,"properties":{},"type":"integer"},"name":"size"},{"definition":{"description":"Job Start time.","enum":[],"extra":{"typetext":"HH:MM"},"pattern":"\\d{1,2}:\\d{1,2}","properties":{},"type":"string"},"name":"starttime"},{"definition":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stdexcludes"},{"definition":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stop"},{"definition":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"stopwait"},{"definition":{"description":"Store resulting file to this storage.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Store temporary files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tmpdir"},{"definition":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vmid"},{"definition":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, N>0 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"zstd"}],"permissions":{"description":"The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user.","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/backup/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"62c0ad7abee78ab3a2bc37808d4d965ad58c97cbc5d7ff19f953ad9f7bbb331a","description":"Returns included guests and the backup status of their disks. Optimized to be used in ExtJS tree views.","extra":{},"name":"get_volume_backup_included","parameters":[{"definition":{"description":"The job ID.","enum":[],"extra":{"typetext":""},"max_length":50,"properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"description":"Root node of the tree object. Children represent guests, grandchildren represent volumes of that guest.","enum":[],"extra":{},"properties":{"children":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"children":{"description":"The volumes of the guest with the information if they will be included in backups.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"id":{"description":"Configuration key of the volume.","enum":[],"extra":{},"properties":{},"type":"string"},"included":{"description":"Whether the volume is included in the backup or not.","enum":[],"extra":{},"properties":{},"type":"boolean"},"name":{"description":"Name of the volume.","enum":[],"extra":{},"properties":{},"type":"string"},"reason":{"description":"The reason why the volume is included (or excluded).","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"id":{"description":"VMID of the guest.","enum":[],"extra":{},"properties":{},"type":"integer"},"name":{"description":"Name of the guest","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Type of the guest, VM, CT or unknown for removed but not purged guests.","enum":["qemu","lxc","unknown"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"}],"path":"/cluster/backup/{id}/included_volumes"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ceb0a7481aa4e4b2240a3a1d593c1dab69fa4e70b195804ec3c27b61c27cc755","description":"Stub, waits for future use.","extra":{},"name":"get_backupinfo","parameters":[],"protected":true,"returns":{"description":"Shows stub message","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/cluster/backupinfo"},{"extra":{},"methods":[{"allow_token":true,"checksum":"10072ad7bf08fad7b5214622361f9bcfe52101f6e15709fc5661262557128b24","description":"Shows all guests which are not covered by any backup job.","extra":{},"name":"get_guests_not_in_backup","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"description":"Contains the guest objects.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"name":{"description":"Name of the guest","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Type of the guest.","enum":["qemu","lxc"],"extra":{},"properties":{},"type":"string"},"vmid":{"description":"VMID of the guest.","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/backupinfo/not_backed_up"},{"extra":{},"methods":[{"allow_token":true,"checksum":"eba2ffcf3c2b12528c59e5ea186dccaf2c83608b8f244536294254186e44c927","description":"Cluster ceph index.","extra":{},"name":"cephindex","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/ceph"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6ae98716f8a4244bf1efbfabc29513d0b99b62ed6c0a418d32b6a374f9b43dce","description":"get the status of all ceph flags","extra":{},"name":"get_all_flags","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"name":{"description":"Flag name.","enum":["nobackfill","nodeep-scrub","nodown","noin","noout","norebalance","norecover","noscrub","notieragent","noup","pause"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"970a0fb05e1b758fb4fdf2eb40ec7342550b919ccbc76dbfcfb001afefa4ae31","description":"Set/Unset multiple ceph flags at once.","extra":{},"name":"set_flags","parameters":[{"definition":{"description":"Backfilling of PGs is suspended.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nobackfill"},{"definition":{"description":"Deep Scrubbing is disabled.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nodeep-scrub"},{"definition":{"description":"OSD failure reports are being ignored, such that the monitors will not mark OSDs down.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nodown"},{"definition":{"description":"OSDs that were previously marked out will not be marked back in when they start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"noin"},{"definition":{"description":"OSDs will not automatically be marked out after the configured interval.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"noout"},{"definition":{"description":"Rebalancing of PGs is suspended.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"norebalance"},{"definition":{"description":"Recovery of PGs is suspended.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"norecover"},{"definition":{"description":"Scrubbing is disabled.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"noscrub"},{"definition":{"description":"Cache tiering activity is suspended.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"notieragent"},{"definition":{"description":"OSDs are not allowed to start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"noup"},{"definition":{"description":"Pauses read and writes.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pause"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/cluster/ceph/flags"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ec390749f9b3b558092a75a9d5b9a3a05a0f4d7caaba0587fbbc491a53147656","description":"Get the status of a specific ceph flag.","extra":{},"name":"get_flag","parameters":[{"definition":{"description":"The name of the flag name to get.","enum":["nobackfill","nodeep-scrub","nodown","noin","noout","norebalance","norecover","noscrub","notieragent","noup","pause"],"extra":{},"properties":{},"type":"string"},"name":"flag"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"verb":"GET"},{"allow_token":true,"checksum":"2e9c3fffaa1d7970614c7564afef27bfb7e06a951d8f2cd26e7995f90f827bf1","description":"Set or clear (unset) a specific ceph flag","extra":{},"name":"update_flag","parameters":[{"definition":{"description":"The ceph flag to update","enum":["nobackfill","nodeep-scrub","nodown","noin","noout","norebalance","norecover","noscrub","notieragent","noup","pause"],"extra":{},"properties":{},"type":"string"},"name":"flag"},{"definition":{"description":"The new value of the flag","enum":[],"extra":{"typetext":""},"properties":{},"type":"boolean"},"name":"value"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/ceph/flags/{flag}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"cf75a4c8acb76f42413fc2660be5f1a9e2e8848834ec676b2c36436a3f7a1dce","description":"Get ceph metadata.","extra":{},"name":"metadata","parameters":[{"definition":{"default":"all","enum":["all","versions"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scope"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/ceph/metadata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"409b59805f3b7f2541a2610e760ac490c3c6c53e2f4107c9149cc5870f3999ab","description":"Get ceph status.","extra":{},"name":"status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/ceph/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4e462b2d722b46bdaa5c6d40f69bc9f0fea21bf2b17f55764148409d7e6634a1","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"dc847d83f7fc30755b2764c4614fade64611f8f97ac8d872642a9b3fb1cadc5e","description":"Generate new cluster configuration. If no links given, default to local IP address as link0.","extra":{},"name":"create","parameters":[{"definition":{"description":"The name of the cluster.","enum":[],"extra":{"typetext":""},"format":"pve-node","max_length":15,"properties":{},"type":"string"},"name":"clustername"},{"definition":{"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)","enum":[],"extra":{"typetext":"[address=] [,priority=]"},"format":{"address":{"default_key":1,"description":"Hostname (or IP) of this corosync link address.","format":"address","format_description":"IP","type":"string"},"priority":{"default":0,"description":"The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.","maximum":255,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"link[n]"},{"definition":{"description":"Node id for this node.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"nodeid"},{"definition":{"description":"Number of votes for this node.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"votes"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5861b788cde0b7cc8e00ed4490c40cc476724fc3e74e8d888af4e2667f4fc440","description":"Return the version of the cluster join API available on this node.","extra":{},"name":"join_api_version","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"description":"Cluster Join API version, currently 1","enum":[],"extra":{},"minimum":0,"properties":{},"type":"integer"},"verb":"GET"}],"path":"/cluster/config/apiversion"},{"extra":{},"methods":[{"allow_token":true,"checksum":"27b190ca706bbf299b7db981785dc2470fa61c40ce5577145f166e14dfa5ab80","description":"Get information needed to join this cluster over the connected node.","extra":{},"name":"join_info","parameters":[{"definition":{"default":"current connected node","description":"The node for which the joinee gets the nodeinfo. ","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"config_digest":{"enum":[],"extra":{},"properties":{},"type":"string"},"nodelist":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"name":{"description":"The cluster node name.","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"nodeid":{"description":"Node id for this node.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"pve_addr":{"enum":[],"extra":{},"format":"ip","properties":{},"type":"string"},"pve_fp":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"quorum_votes":{"enum":[],"extra":{},"minimum":0,"properties":{},"type":"integer"},"ring0_addr":{"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)","enum":[],"extra":{},"format":{"address":{"default_key":1,"description":"Hostname (or IP) of this corosync link address.","format":"address","format_description":"IP","type":"string"},"priority":{"default":0,"description":"The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.","maximum":255,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"preferred_node":{"description":"The cluster node name.","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"totem":{"enum":[],"extra":{},"properties":{},"type":"object"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"b68eacfbf66e39c59302d333b33cc64f4ff8211a81f4b5e13e745569757d2229","description":"Joins this node into an existing cluster. If no links are given, default to IP resolved by node's hostname on single link (fallback fails for clusters with multiple links).","extra":{},"name":"join","parameters":[{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"Do not throw error if node already exists.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Hostname (or IP) of an existing cluster member.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"hostname"},{"definition":{"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)","enum":[],"extra":{"typetext":"[address=] [,priority=]"},"format":{"address":{"default_key":1,"description":"Hostname (or IP) of this corosync link address.","format":"address","format_description":"IP","type":"string"},"priority":{"default":0,"description":"The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.","maximum":255,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"link[n]"},{"definition":{"description":"Node id for this node.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"nodeid"},{"definition":{"description":"Superuser (root) password of peer node.","enum":[],"extra":{"typetext":""},"max_length":128,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Number of votes for this node","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"votes"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/config/join"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1f1fa8f6c73d69a06ca87952831af1858a31d439c8ce22d6db1dc91f7ca064ba","description":"Corosync node list.","extra":{},"name":"nodes","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{node}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"node":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/config/nodes"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4ad5a311d984ff153e9e2592b537f44cdcce104ab314eadbe47ce01a97c6f77c","description":"Removes a node from the cluster configuration.","extra":{},"name":"delnode","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"2304b23018ece442ff87923324c1fd7f3616f5b677fc4dc2af779b5c3da61fd7","description":"Adds a node to the cluster configuration. This call is for internal use.","extra":{},"name":"addnode","parameters":[{"definition":{"description":"The JOIN_API_VERSION of the new node.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"apiversion"},{"definition":{"description":"Do not throw error if node already exists.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)","enum":[],"extra":{"typetext":"[address=] [,priority=]"},"format":{"address":{"default_key":1,"description":"Hostname (or IP) of this corosync link address.","format":"address","format_description":"IP","type":"string"},"priority":{"default":0,"description":"The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.","maximum":255,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"link[n]"},{"definition":{"description":"IP Address of node to add. Used as fallback if no links are given.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"new_node_ip"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Node id for this node.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"nodeid"},{"definition":{"description":"Number of votes for this node","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"votes"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{"corosync_authkey":{"enum":[],"extra":{},"properties":{},"type":"string"},"corosync_conf":{"enum":[],"extra":{},"properties":{},"type":"string"},"warnings":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"verb":"POST"}],"path":"/cluster/config/nodes/{node}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e4dc8178545984d387d63e2c6474b1977b9eb7df966ed1d259f36c64bfcd8cbd","description":"Get QDevice status","extra":{},"name":"status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/config/qdevice"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c99926d6eacc2ee248abe8c35c3b919d67610792d6702ff22aee72db49cc4a84","description":"Get corosync totem protocol settings.","extra":{},"name":"totem","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/config/totem"},{"extra":{},"methods":[{"allow_token":true,"checksum":"74551df8a7f69c7a92251a3cae53f3fa26e51e7232e76071c74973bbbcee0c60","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f06ffe119587de3302e717bba7a4b65a1c2d80187a105c9ea6bbf37e77cd97fd","description":"List aliases","extra":{},"name":"get_aliases","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f144d7afa87a39ea6a57ac4e64d062df366af072960ccdf34d6336ac2377b7f3","description":"Create IP or Network Alias.","extra":{},"name":"create_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/aliases"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ad4257a1d4b41dd23e4430b9f983c567fea8145f05649ae95e007dae6463c90b","description":"Remove IP or Network alias.","extra":{},"name":"remove_alias","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"31f91732baef0ccfba57dfc0c349ce762ef253d020ab23770f2a16b530eb55ed","description":"Read alias.","extra":{},"name":"read_alias","parameters":[{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"5a17c347604603437b19f09ba99fe14c5e4bafb67ed183f11f1627de33ef07df","description":"Update IP or Network alias.","extra":{},"name":"update_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Rename an existing alias.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/aliases/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3445c46206838d35be8e0c694952f880add553e8132b23f4614da8e28cb8a3a4","description":"List security groups.","extra":{},"name":"list_security_groups","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{group}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"group":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"2883536c84a6a0652e559b7fd1cf8eb6e13f33c9aa8b01adba443345121a8628","description":"Create new security group.","extra":{},"name":"create_security_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Rename/update an existing security group. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing group.","enum":[],"extra":{},"max_length":18,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/groups"},{"extra":{},"methods":[{"allow_token":true,"checksum":"acdcc8bdd19b229574d5ede528b0727f932a90c3fbb9ef47222856db9f4531d9","description":"Delete security group.","extra":{},"name":"delete_security_group","parameters":[{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"5e311b86179420cbc403ca7c6e0bb22d853c4be88b8ef0b63aab2614af61e428","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"8b3fe24d4dd09dd7f8f9b5c84b14dc504b723581182e2de265a6d7ff58d58089","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/groups/{group}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7317683249582e6e573527a83e3ee1f4f29da0e5e8d527b1243f55a42bb66e7f","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"1f3be3248486446917c63efaf928e95d33b8e383145a7ac4f9a7f4abf4b7fa19","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"9394038f54d4829cd5e10d436408dcbcf18786dff5d0710df5e09a9ce0643547","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/groups/{group}/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dd7e3fad6a4b03050665f4570709b30493d1bed7cfed03fc6663fdbab459d635","description":"List IPSets","extra":{},"name":"ipset_index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"name":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"23066626f06f9d98f626a6f91170e532e1d77c32a9164acef556b7124cd71ed6","description":"Create new IPSet","extra":{},"name":"create_ipset","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/ipset"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d00ae3124da0f5b3793ee82504d51cc47fe2186bafa7bdf4ac21225d07a167d6","description":"Delete IPSet","extra":{},"name":"delete_ipset","parameters":[{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"c2d29e48c4bfd7c5b4052b880d990a132c3631ce457fd0a8ec1f9ad69df7994f","description":"List IPSet content","extra":{},"name":"get_ipset","parameters":[{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cidr}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"nomatch":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"64742b376a8e3ee9b6b16b594db4e04c4b486e54165aa69f492fb0b952ea3225","description":"Add IP or Network to IPSet.","extra":{},"name":"create_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/ipset/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"33ecae376ac07622130a4734f2b8dae40e26c659e07f734da8896f2cd104589c","description":"Remove IP or Network from IPSet.","extra":{},"name":"remove_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"63a5cefffbd4607d42d80144ed58b521edc579d7778d60043f08271ec0332405","description":"Read IP or Network settings from IPSet.","extra":{},"name":"read_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"94e10f5e55188acae83a4e96b0661e47d0d509cd12091dbf8beba054613f762a","description":"Update IP or Network settings","extra":{},"name":"update_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/ipset/{name}/{cidr}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8e98c5e0609b2624b64c801c530753f356fe8bd2682f5a27a745f43d6f986123","description":"List available macros","extra":{},"name":"get_macros","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"descr":{"description":"More verbose description (if available).","enum":[],"extra":{},"properties":{},"type":"string"},"macro":{"description":"Macro name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/firewall/macros"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0ab6fd03e17819c0c790d03086a619c7cbb5a5b16d82b4fdcb8f314269e88ef4","description":"Get Firewall options.","extra":{},"name":"get_options","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"ebtables":{"default":1,"description":"Enable ebtables rules cluster wide.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"enable":{"description":"Enable or disable the firewall cluster wide.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"log_ratelimit":{"description":"Log ratelimiting settings","enum":[],"extra":{},"format":{"burst":{"default":5,"description":"Initial burst of packages which will always get logged before the rate is applied","minimum":0,"optional":1,"type":"integer"},"enable":{"default":"1","default_key":1,"description":"Enable or disable log rate limiting","type":"boolean"},"rate":{"default":"1/second","description":"Frequency with which the burst bucket gets refilled","format_description":"rate","optional":1,"pattern":"[1-9][0-9]*\\/(second|minute|hour|day)","type":"string"}},"optional":true,"properties":{},"type":"string"},"policy_in":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"policy_out":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"aee671ef989ed185dfc5469a2df19a8dbbb3fc4988cbe5934e1e6218980988c5","description":"Set Firewall options.","extra":{},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":1,"description":"Enable ebtables rules cluster wide.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ebtables"},{"definition":{"description":"Enable or disable the firewall cluster wide.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Log ratelimiting settings","enum":[],"extra":{"typetext":"[enable=]<1|0> [,burst=] [,rate=]"},"format":{"burst":{"default":5,"description":"Initial burst of packages which will always get logged before the rate is applied","minimum":0,"optional":1,"type":"integer"},"enable":{"default":"1","default_key":1,"description":"Enable or disable log rate limiting","type":"boolean"},"rate":{"default":"1/second","description":"Frequency with which the burst bucket gets refilled","format_description":"rate","optional":1,"pattern":"[1-9][0-9]*\\/(second|minute|hour|day)","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"log_ratelimit"},{"definition":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_in"},{"definition":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_out"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"cf22699ed1dcfd76824b83c1cae7ab8e370d43a281f04efb3ddbb4445d20fa0e","description":"Lists possible IPSet/Alias reference which are allowed in source/dest properties.","extra":{},"name":"refs","parameters":[{"definition":{"description":"Only list references of specified type.","enum":["alias","ipset"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"ref":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":["alias","ipset"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/firewall/refs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9165dc3d913c799db2db301b2e535e230c212b7dbfcef2f3918b7e9c7d6408bd","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"e2d0bd9751128209fef3bc2b85d6f84905301f9e8e8b2590f21af4fb3aeede54","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"42b1d8a16029ab6833aebf089137bfdb5f2f5f1bbe4ff4676c40c4f0b5841c70","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"cbc43552b6224f680019cd55a400aab123117e58e2be663243e2ffd77259b8aa","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"d51bfce86a70518664a16456abf43ebcbfd3f9093957a8fd54116449625cedf0","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d001f6a38904cb5a8c874fb6d751e0a54ea9d1d75042d71b3c21dffb4e5c59ca","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/ha"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d0d28a184b53d0e953807ded4c6b2790bdae617fc6b96ff4fa1649238a2c8c13","description":"Get HA groups.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{group}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"group":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"21ad8fd25ef2daef3468a2f62950905e934be2c2b149fa846158df06be2891e8","description":"Create a new HA group.","extra":{},"name":"create","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"List of cluster node names with optional priority.","enum":[],"extra":{"typetext":"[:]{,[:]}*","verbose_description":"List of cluster node members, where a priority can be given to each node. A resource bound to a group will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the services will get distributed to those nodes. The priorities have a relative meaning only."},"format":"pve-ha-group-node-list","optional":false,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"default":0,"description":"The CRM tries to run services on the node with the highest priority. If a node with higher priority comes online, the CRM migrates the service to that node. Enabling nofailback prevents that behavior.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nofailback"},{"definition":{"default":0,"description":"Resources bound to restricted groups may only run on nodes defined by the group.","enum":[],"extra":{"typetext":"","verbose_description":"Resources bound to restricted groups may only run on nodes defined by the group. The resource will be placed in the stopped state if no group node member is online. Resources on unrestricted groups may run on any cluster node if all group members are offline, but they will migrate back as soon as a group member comes online. One can implement a 'preferred node' behavior using an unrestricted group with only one member."},"optional":true,"properties":{},"type":"boolean"},"name":"restricted"},{"definition":{"description":"Group type.","enum":["group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/groups"},{"extra":{},"methods":[{"allow_token":true,"checksum":"fcab72c57ac4373ef959202b673be62b63d50770dd9a16025d12a8e0f6e4a594","description":"Delete ha group configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f1dc580cb73eb7352d1f1af8768548109d5fbeee4519fb704492e9eb204c3673","description":"Read ha group configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{}},"verb":"GET"},{"allow_token":true,"checksum":"eecbd2ad7b079c07176d36049ef7e2fe4534a166c55f3b02719dff612274b284","description":"Update ha group configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"List of cluster node names with optional priority.","enum":[],"extra":{"typetext":"[:]{,[:]}*","verbose_description":"List of cluster node members, where a priority can be given to each node. A resource bound to a group will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the services will get distributed to those nodes. The priorities have a relative meaning only."},"format":"pve-ha-group-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"default":0,"description":"The CRM tries to run services on the node with the highest priority. If a node with higher priority comes online, the CRM migrates the service to that node. Enabling nofailback prevents that behavior.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nofailback"},{"definition":{"default":0,"description":"Resources bound to restricted groups may only run on nodes defined by the group.","enum":[],"extra":{"typetext":"","verbose_description":"Resources bound to restricted groups may only run on nodes defined by the group. The resource will be placed in the stopped state if no group node member is online. Resources on unrestricted groups may run on any cluster node if all group members are offline, but they will migrate back as soon as a group member comes online. One can implement a 'preferred node' behavior using an unrestricted group with only one member."},"optional":true,"properties":{},"type":"boolean"},"name":"restricted"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/ha/groups/{group}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"47984f628310d0cb88a50b127b972338f4cd63248dd3c160e5200d3e7bd0cdd1","description":"List HA resources.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list resources of specific type","enum":["ct","vm"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{sid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"sid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"70fd3e7cb628f787ba3909ce16210856bb634a2b64df6e277be007cbcee9d178","description":"Create a new HA resource.","extra":{},"name":"create","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"group"},{"definition":{"default":1,"description":"Maximal number of service relocate tries when a service failes to start.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"max_relocate"},{"definition":{"default":1,"description":"Maximal number of tries to restart the service on a node after its start failed.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"max_restart"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"},{"definition":{"default":"started","description":"Requested resource state.","enum":["started","stopped","enabled","disabled","ignored"],"extra":{"verbose_description":"Requested resource state. The CRM reads this state and acts accordingly.\nPlease note that `enabled` is just an alias for `started`.\n\n`started`;;\n\nThe CRM tries to start the resource. Service state is\nset to `started` after successful start. On node failures, or when start\nfails, it tries to recover the resource. If everything fails, service\nstate it set to `error`.\n\n`stopped`;;\n\nThe CRM tries to keep the resource in `stopped` state, but it\nstill tries to relocate the resources on node failures.\n\n`disabled`;;\n\nThe CRM tries to put the resource in `stopped` state, but does not try\nto relocate the resources on node failures. The main purpose of this\nstate is error recovery, because it is the only way to move a resource out\nof the `error` state.\n\n`ignored`;;\n\nThe resource gets removed from the manager status and so the CRM and the LRM do\nnot touch the resource anymore. All {pve} API calls affecting this resource\nwill be executed, directly bypassing the HA stack. CRM commands will be thrown\naway while there source is in this state. The resource will not get relocated\non node failures.\n\n"},"optional":true,"properties":{},"type":"string"},"name":"state"},{"definition":{"description":"Resource type.","enum":["ct","vm"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/resources"},{"extra":{},"methods":[{"allow_token":true,"checksum":"abd1828ee1c6a70f7ffa5f609831cbbc19915841154fa87ae1986c48e299a35e","description":"Delete resource configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"20b2c61081918714beedef8bf2b0263c914335b03e88f592e05a48637b5ffca1","description":"Read resource configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"comment":{"description":"Description.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Can be used to prevent concurrent modifications.","enum":[],"extra":{},"properties":{},"type":"string"},"group":{"description":"The HA group identifier.","enum":[],"extra":{},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"max_relocate":{"description":"Maximal number of service relocate tries when a service failes to start.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"max_restart":{"description":"Maximal number of tries to restart the service on a node after its start failed.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"sid":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"state":{"description":"Requested resource state.","enum":["started","stopped","enabled","disabled","ignored"],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"The type of the resources.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"9fade4d798de642c2fa6b40e68d11f6a2a782d36f6197f7d9e542464231a87a9","description":"Update resource configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"group"},{"definition":{"default":1,"description":"Maximal number of service relocate tries when a service failes to start.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"max_relocate"},{"definition":{"default":1,"description":"Maximal number of tries to restart the service on a node after its start failed.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"max_restart"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"},{"definition":{"default":"started","description":"Requested resource state.","enum":["started","stopped","enabled","disabled","ignored"],"extra":{"verbose_description":"Requested resource state. The CRM reads this state and acts accordingly.\nPlease note that `enabled` is just an alias for `started`.\n\n`started`;;\n\nThe CRM tries to start the resource. Service state is\nset to `started` after successful start. On node failures, or when start\nfails, it tries to recover the resource. If everything fails, service\nstate it set to `error`.\n\n`stopped`;;\n\nThe CRM tries to keep the resource in `stopped` state, but it\nstill tries to relocate the resources on node failures.\n\n`disabled`;;\n\nThe CRM tries to put the resource in `stopped` state, but does not try\nto relocate the resources on node failures. The main purpose of this\nstate is error recovery, because it is the only way to move a resource out\nof the `error` state.\n\n`ignored`;;\n\nThe resource gets removed from the manager status and so the CRM and the LRM do\nnot touch the resource anymore. All {pve} API calls affecting this resource\nwill be executed, directly bypassing the HA stack. CRM commands will be thrown\naway while there source is in this state. The resource will not get relocated\non node failures.\n\n"},"optional":true,"properties":{},"type":"string"},"name":"state"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/ha/resources/{sid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0899ff908a613bc0e585e0d0ff7c3689a0290c57a6ea0a132c1736f2870ef038","description":"Request resource migration (online) to another node.","extra":{},"name":"migrate","parameters":[{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/resources/{sid}/migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0fe9da71d2503a4b046199d9088d1f15a843b739258a94575aea1eaa204385f0","description":"Request resource relocatzion to another node. This stops the service on the old node, and restarts it on the target node.","extra":{},"name":"relocate","parameters":[{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/resources/{sid}/relocate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"74551df8a7f69c7a92251a3cae53f3fa26e51e7232e76071c74973bbbcee0c60","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/ha/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7aa9929c7b96c76701abdb6b90d6158bd2fe9c5b59916ca70f40e51235716eca","description":"Get HA manger status.","extra":{},"name":"status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/ha/status/current"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3a9edd6753b478f7eee2e02fa4859a8d405979a3bcff5640774bf8cd14b5d31f","description":"Get full HA manger status, including LRM status.","extra":{},"name":"manager_status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/ha/status/manager_status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"83ec57bf65a25fea7789dc000d330836a5facedb780afa50156b1634bbf5d40a","description":"Read cluster log","extra":{},"name":"log","parameters":[{"definition":{"description":"Maximum number of entries.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"32e4e0d625a43113ca32f9e4eba0fba77b683c1450a608bddb7a54be11776ea3","description":"Metrics index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/metrics"},{"extra":{},"methods":[{"allow_token":true,"checksum":"27149ea7f2dd2e6d37dc5ad79fe1835f771a7232d81bc38e686157565a692fc6","description":"List configured metric servers.","extra":{},"name":"server_index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"disable":{"description":"Flag to disable the plugin.","enum":[],"extra":{},"properties":{},"type":"boolean"},"id":{"description":"The ID of the entry.","enum":[],"extra":{},"properties":{},"type":"string"},"port":{"description":"Server network port","enum":[],"extra":{},"properties":{},"type":"integer"},"server":{"description":"Server dns name or IP address","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"Plugin type.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/metrics/server"},{"extra":{},"methods":[{"allow_token":true,"checksum":"56bc7f1733b6ce3c54389c9ceed9a20983de2c44898310930261592680aa259a","description":"Remove Metric server.","extra":{},"name":"delete","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"a53d502e8ae6ee9c25effeb04789f394e23cf119b2a13a620c971ed75e925a3f","description":"Read metric server configuration.","extra":{},"name":"read","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"e0aaacb646044cd73c3ebc280924f59275e6e5b85fc8dd0eae4a81a638e6c2aa","description":"Create a new external metric server config","extra":{},"name":"create","parameters":[{"definition":{"description":"An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"api-path-prefix"},{"definition":{"description":"The InfluxDB bucket/db. Only necessary when using the http v2 api.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"bucket"},{"definition":{"description":"Flag to disable the plugin.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"The ID of the entry.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"default":"udp","enum":["udp","http","https"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"influxdbproto"},{"definition":{"default":25000000,"description":"InfluxDB max-body-size in bytes. Requests are batched up to this size.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max-body-size"},{"definition":{"default":1500,"description":"MTU for metrics transmission over UDP","enum":[],"extra":{"typetext":" (512 - 65536)"},"maximum":65536,"minimum":512,"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"organization"},{"definition":{"description":"root graphite path (ex: proxmox.mycluster.mykey)","enum":[],"extra":{"typetext":""},"format":"graphite-path","optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"server network port","enum":[],"extra":{"typetext":" (1 - 65536)"},"maximum":65536,"minimum":1,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Protocol to send graphite data. TCP or UDP (default)","enum":["udp","tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"server dns name or IP address","enum":[],"extra":{"typetext":""},"format":"address","properties":{},"type":"string"},"name":"server"},{"definition":{"default":1,"description":"graphite TCP socket timeout (default=1)","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"},{"definition":{"description":"Plugin type.","enum":["graphite","influxdb"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"2125ca9c58eea9234a4f69c01a83b02af4a90e262c888de6594c6b3cebab6353","description":"Update metric server configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"api-path-prefix"},{"definition":{"description":"The InfluxDB bucket/db. Only necessary when using the http v2 api.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"bucket"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Flag to disable the plugin.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"The ID of the entry.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"default":"udp","enum":["udp","http","https"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"influxdbproto"},{"definition":{"default":25000000,"description":"InfluxDB max-body-size in bytes. Requests are batched up to this size.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max-body-size"},{"definition":{"default":1500,"description":"MTU for metrics transmission over UDP","enum":[],"extra":{"typetext":" (512 - 65536)"},"maximum":65536,"minimum":512,"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"organization"},{"definition":{"description":"root graphite path (ex: proxmox.mycluster.mykey)","enum":[],"extra":{"typetext":""},"format":"graphite-path","optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"server network port","enum":[],"extra":{"typetext":" (1 - 65536)"},"maximum":65536,"minimum":1,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Protocol to send graphite data. TCP or UDP (default)","enum":["udp","tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"server dns name or IP address","enum":[],"extra":{"typetext":""},"format":"address","properties":{},"type":"string"},"name":"server"},{"definition":{"default":1,"description":"graphite TCP socket timeout (default=1)","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/metrics/server/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e16f886044134ce284ae0074e1db39c64e2d901fe04a55a63a84646201a0dbf5","description":"Get next free VMID. If you pass an VMID it will raise an error if the ID is already used.","extra":{},"name":"nextid","parameters":[{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"The next free VMID.","enum":[],"extra":{},"properties":{},"type":"integer"},"verb":"GET"}],"path":"/cluster/nextid"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a16d8ffebd49cb91133b21e2c7a238bd012e2831ee430a00940963d1dbb58d37","description":"Get datacenter options.","extra":{},"name":"get_options","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"4cd97165455e9dd55e339555ce0171d7355292a5353042639b7b9082bdc429d7","description":"Set datacenter options.","extra":{},"name":"set_options","parameters":[{"definition":{"description":"Set bandwidth/io limits various operations.","enum":[],"extra":{"typetext":"[clone=] [,default=] [,migration=] [,move=] [,restore=]"},"format":{"clone":{"description":"bandwidth limit in KiB/s for cloning disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"default":{"description":"default bandwidth limit in KiB/s","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"migration":{"description":"bandwidth limit in KiB/s for migrating guests (including moving local disks)","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"move":{"description":"bandwidth limit in KiB/s for moving disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"restore":{"description":"bandwidth limit in KiB/s for restoring guests from backups","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"}},"optional":true,"properties":{},"type":"string"},"name":"bwlimit"},{"definition":{"description":"Select the default Console viewer. You can either use the builtin java applet (VNC; deprecated and maps to html5), an external virt-viewer comtatible application (SPICE), an HTML5 based vnc viewer (noVNC), or an HTML5 based console client (xtermjs). If the selected viewer is not available (e.g. SPICE not activated for the VM), the fallback is noVNC.","enum":["applet","vv","html5","xtermjs"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"console"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Specify email address to send notification from (default is root@$hostname)","enum":[],"extra":{"typetext":""},"format":"email-opt","optional":true,"properties":{},"type":"string"},"name":"email_from"},{"definition":{"default":"watchdog","description":"Set the fencing mode of the HA cluster. Hardware mode needs a valid configuration of fence devices in /etc/pve/ha/fence.cfg. With both all two modes are used.\n\nWARNING: 'hardware' and 'both' are EXPERIMENTAL & WIP","enum":["watchdog","hardware","both"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"fencing"},{"definition":{"description":"Cluster wide HA settings.","enum":[],"extra":{"typetext":"shutdown_policy="},"format":{"shutdown_policy":{"default":"conditional","description":"The policy for HA services on node shutdown. 'freeze' disables auto-recovery, 'failover' ensures recovery, 'conditional' recovers on poweroff and freezes on reboot. 'migrate' will migrate running services to other nodes, if possible. With 'freeze' or 'failover', HA Services will always get stopped first on shutdown.","enum":["freeze","failover","conditional","migrate"],"type":"string","verbose_description":"Describes the policy for handling HA services on poweroff or reboot of a node. Freeze will always freeze services which are still located on the node on shutdown, those services won't be recovered by the HA manager. Failover will not mark the services as frozen and thus the services will get recovered to other nodes, if the shutdown node does not come up again quickly (< 1min). 'conditional' chooses automatically depending on the type of shutdown, i.e., on a reboot the service will be frozen but on a poweroff the service will stay as is, and thus get recovered after about 2 minutes. Migrate will try to move all running services to another node when a reboot or shutdown was triggered. The poweroff process will only continue once no running services are located on the node anymore. If the node comes up again, the service will be moved back to the previously powered-off node, at least if no other migration, reloaction or recovery took place."}},"optional":true,"properties":{},"type":"string"},"name":"ha"},{"definition":{"description":"Specify external http proxy which is used for downloads (example: 'http://username:password@host:port/')","enum":[],"extra":{},"optional":true,"pattern":"http://.*","properties":{},"type":"string"},"name":"http_proxy"},{"definition":{"description":"Default keybord layout for vnc server.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"keyboard"},{"definition":{"description":"Default GUI language.","enum":["ca","da","de","en","es","eu","fa","fr","he","it","ja","nb","nn","pl","pt_BR","ru","sl","sv","tr","zh_CN","zh_TW"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"language"},{"definition":{"description":"Prefix for autogenerated MAC addresses.","enum":[],"extra":{"typetext":""},"format":"mac-prefix","optional":true,"properties":{},"type":"string"},"name":"mac_prefix"},{"definition":{"description":"Defines how many workers (per node) are maximal started on actions like 'stopall VMs' or task from the ha-manager.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max_workers"},{"definition":{"description":"For cluster wide migration settings.","enum":[],"extra":{"typetext":"[type=] [,network=]"},"format":{"network":{"description":"CIDR of the (sub) network that is used for migration.","format":"CIDR","format_description":"CIDR","optional":1,"type":"string"},"type":{"default":"secure","default_key":1,"description":"Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.","enum":["secure","insecure"],"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"migration"},{"definition":{"description":"Migration is secure using SSH tunnel by default. For secure private networks you can disable it to speed up migration. Deprecated, use the 'migration' property instead!","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"migration_unsecure"},{"definition":{"description":"u2f","enum":[],"extra":{"typetext":"[appid=] [,origin=]"},"format":{"appid":{"description":"U2F AppId URL override. Defaults to the origin.","format_description":"APPID","optional":1,"type":"string"},"origin":{"description":"U2F Origin override. Mostly useful for single nodes with a single URL.","format_description":"URL","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"u2f"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"836667aaea1693e9740b25ea05dfe4494a11b7bc0c6b94abf52e4c27455e17b0","description":"List replication jobs.","extra":{},"name":"index","parameters":[],"permissions":{"description":"Requires the VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"6e719bf689a19e11db1c645c80b7c865cfbd44d07efa6a1dc0fef3692b58b0a2","description":"Create a new replication job","extra":{},"name":"create","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Flag to disable/deactivate the entry.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"number"},"name":"rate"},{"definition":{"description":"Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.","enum":["local","full"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"remove_job"},{"definition":{"default":"*/15","description":"Storage replication schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"For internal use, to detect if the guest was stolen.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":false,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Section type.","enum":["local"],"extra":{},"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/replication"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a755e3fc20618d34ac577bb6749b86e277a78938aafcc74d3d1ef45aee2995da","description":"Mark replication job for removal.","extra":{},"name":"delete","parameters":[{"definition":{"default":0,"description":"Will remove the jobconfig entry, but will not cleanup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"default":0,"description":"Keep replicated data at target (do not remove).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keep"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"e7ec17056fddc5bf05f3598911533fad45ff9b2eadbc69102c3ae6404a996582","description":"Read replication job configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"}],"permissions":{"description":"Requires the VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"b2a02a200edfe9eef9130cab266cc7fc0fe6d6089aac0c7fab9430f7b8ec2b35","description":"Update replication job configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Flag to disable/deactivate the entry.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"number"},"name":"rate"},{"definition":{"description":"Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.","enum":["local","full"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"remove_job"},{"definition":{"default":"*/15","description":"Storage replication schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"For internal use, to detect if the guest was stolen.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"source"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/replication/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e18b09f4b62751be081ee5dc40695d22f8e60fbaa22080705f5c30717cf347ab","description":"Resources index (cluster wide).","extra":{},"name":"resources","parameters":[{"definition":{"enum":["vm","storage","node","sdn"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"content":{"description":"Allowed storage content types (when type == storage).","enum":[],"extra":{},"format":"pve-storage-content-list","optional":true,"properties":{},"type":"string"},"cpu":{"description":"CPU utilization (when type in node,qemu,lxc).","enum":[],"extra":{"renderer":"fraction_as_percentage"},"optional":true,"properties":{},"type":"number"},"disk":{"description":"Used disk space in bytes (when type in storage), used root image spave for VMs (type in qemu,lxc).","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"string"},"hastate":{"description":"HA service status (for HA managed VMs).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"level":{"description":"Support level (when type == node).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxcpu":{"description":"Number of available CPUs (when type in node,qemu,lxc).","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"maxdisk":{"description":"Storage size in bytes (when type in storage), root image size for VMs (type in qemu,lxc).","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Number of available memory in bytes (when type in node,qemu,lxc).","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"mem":{"description":"Used memory in bytes (when type in node,qemu,lxc).","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"string"},"node":{"description":"The cluster node name (when type in node,storage,qemu,lxc).","enum":[],"extra":{},"format":"pve-node","optional":true,"properties":{},"type":"string"},"plugintype":{"description":"More specific type, if available.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pool":{"description":"The pool name (when type in pool,qemu,lxc).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"status":{"description":"Resource type dependent status.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"storage":{"description":"The storage identifier (when type == storage).","enum":[],"extra":{},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"type":{"description":"Resource type.","enum":["node","storage","pool","qemu","lxc","openvz","sdn"],"extra":{},"properties":{},"type":"string"},"uptime":{"description":"Node uptime in seconds (when type in node,qemu,lxc).","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/resources"},{"extra":{},"methods":[{"allow_token":true,"checksum":"50dd0532cd996f30fd2ca1c578f00b7f09b5ac6a8735b377a9e74caaf9578106","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["SDN.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"e3e53e99bf397ad633261a85727564ec67c8818f3f78fba390f6a9b51f809ea2","description":"Apply sdn controller changes && reload.","extra":{},"name":"reload","parameters":[],"permissions":{"expression":{"check":["perm","/sdn",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/cluster/sdn"},{"extra":{},"methods":[{"allow_token":true,"checksum":"fffd9d5d2ede50c655273daa582c9055f5c64935bc8a916216092e618b97ed02","description":"SDN controllers index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"Only list sdn controllers of specific type","enum":["bgp","evpn","faucet"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/controllers/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{controller}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"controller":{"enum":[],"extra":{},"properties":{},"type":"string"},"pending":{"enum":[],"extra":{},"optional":true,"properties":{}},"state":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"ca7503ba7a5ad60f56175556d225dc0f76a951007b10b4e33cd20df25922df38","description":"Create a new sdn controller object.","extra":{},"name":"create","parameters":[{"definition":{"description":"autonomous system number","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"asn"},{"definition":{"description":"The SDN controller object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-controller-id","properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"Enable ebgp. (remote-as external)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ebgp"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"ebgp-multihop"},{"definition":{"description":"source loopback interface.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"loopback"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"peers address list.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"peers"},{"definition":{"description":"Plugin type.","enum":["bgp","evpn","faucet"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/sdn/controllers",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/controllers"},{"extra":{},"methods":[{"allow_token":true,"checksum":"cd5848ee8488704f054d262616cdac7dafce590f953307860febf76eb5b924d3","description":"Delete sdn controller object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN controller object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-controller-id","properties":{},"type":"string"},"name":"controller"}],"permissions":{"expression":{"check":["perm","/sdn/controllers",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"10ce0dd020d72fc27315b708c59822eda08951a6408ee5cdf9ef59e6c77b1285","description":"Read sdn controller configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The SDN controller object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-controller-id","properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"}],"permissions":{"expression":{"check":["perm","/sdn/controllers/{controller}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"9bae34cafc1ad18f1d370c287a829e41485a9e57f2a31a2c960506426d0e6892","description":"Update sdn controller object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"autonomous system number","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"asn"},{"definition":{"description":"The SDN controller object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-controller-id","properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Enable ebgp. (remote-as external)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ebgp"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"ebgp-multihop"},{"definition":{"description":"source loopback interface.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"loopback"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"peers address list.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"peers"}],"permissions":{"expression":{"check":["perm","/sdn/controllers",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/controllers/{controller}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"eb447be7b8deba4c48a26dec0552342de4afd2b7ed9b023f63bf59e8a899344a","description":"SDN dns index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list sdn dns of specific type","enum":["powerdns"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/dns/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{dns}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"dns":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"029ea423810eeebc69994f36e681a535cad885f3d584cb7ac480a9832a101d6b","description":"Create a new sdn dns object.","extra":{},"name":"create","parameters":[{"definition":{"description":"The SDN dns object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-dns-id","properties":{},"type":"string"},"name":"dns"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":false,"properties":{},"type":"string"},"name":"key"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"reversemaskv6"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"reversev6mask"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"ttl"},{"definition":{"description":"Plugin type.","enum":["powerdns"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":false,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["perm","/sdn/dns",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/dns"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5eabbb998398cee212dd2507f83c5e968a90e3413d0844b3f51a3a1e206e869e","description":"Delete sdn dns object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN dns object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-dns-id","properties":{},"type":"string"},"name":"dns"}],"permissions":{"expression":{"check":["perm","/sdn/dns",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f06c8afd05ffad3362aa90b64a2ab7239e95ed803211979c4579c145bffe8b3f","description":"Read sdn dns configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The SDN dns object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-dns-id","properties":{},"type":"string"},"name":"dns"}],"permissions":{"expression":{"check":["perm","/sdn/dns/{dns}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"75d2e9fc2b7a13fb2f70178ab6fc2a52ea2578724efe3480d361f7ab2b4fa4fc","description":"Update sdn dns object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The SDN dns object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-dns-id","properties":{},"type":"string"},"name":"dns"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"key"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"reversemaskv6"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"ttl"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["perm","/sdn/dns",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/dns/{dns}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2082f53189334ff79a0eb8a997c9e416b23b351b06e0804f95ee35b13963c6fc","description":"SDN ipams index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list sdn ipams of specific type","enum":["netbox","phpipam","pve"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/ipams/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{ipam}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"ipam":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"cacd82e3d8c942972501b03a8f9a51e0d8deb4c05b09bf5a6408565ac3235640","description":"Create a new sdn ipam object.","extra":{},"name":"create","parameters":[{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-ipam-id","properties":{},"type":"string"},"name":"ipam"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"section"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"},{"definition":{"description":"Plugin type.","enum":["netbox","phpipam","pve"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["perm","/sdn/ipams",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/ipams"},{"extra":{},"methods":[{"allow_token":true,"checksum":"02da5207be93d63cb52d2e2ffe9ddcd11d1fe46bf238811457b52efa44753926","description":"Delete sdn ipam object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-ipam-id","properties":{},"type":"string"},"name":"ipam"}],"permissions":{"expression":{"check":["perm","/sdn/ipams",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"6b0cd8f67bfc09eea4cf6d833cbf185c78ad36625225e852696671085c14793a","description":"Read sdn ipam configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-ipam-id","properties":{},"type":"string"},"name":"ipam"}],"permissions":{"expression":{"check":["perm","/sdn/ipams/{ipam}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"dc47088f2be0777370c2a4ebb16fdf883145961ab50add6cedaa41739acda7be","description":"Update sdn ipam object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-ipam-id","properties":{},"type":"string"},"name":"ipam"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"section"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["perm","/sdn/ipams",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/ipams/{ipam}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"440c93761319b6496065694cc7b444afeb1a253fdeb4d129e5c83687310fb1a2","description":"SDN vnets index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/vnets/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{vnet}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"657e09c9d00bbcb98404fd86982911804709a2adc44ec104b384a5415a73bb79","description":"Create a new sdn vnet object.","extra":{},"name":"create","parameters":[{"definition":{"description":"alias name of the vnet","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"alias"},{"definition":{"description":"vlan or vxlan id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"tag"},{"definition":{"description":"Type","enum":["vnet"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"Allow vm VLANs to pass through this vnet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"vlanaware"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"},{"definition":{"description":"zone id","enum":[],"extra":{"typetext":""},"optional":false,"properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/vnets",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/vnets"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d742d25dc41efc5c0b6f36aa04dd6b6ae07edaf8f8b3153fe81463ade004e748","description":"Delete sdn vnet object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"expression":{"check":["perm","/sdn/vnets",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"cb4269ac5f852e47e5c9b0c4066a6fb8beb6092b7fbb86eb21dedb24431d5834","description":"Read sdn vnet configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"expression":{"check":["perm","/sdn/vnets/{vnet}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"43a618ed4a8e4f3d757b2ca63c5ab5686626b5466ac6fd5277c08dd8f0084e2c","description":"Update sdn vnet object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"alias name of the vnet","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"alias"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"vlan or vxlan id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"tag"},{"definition":{"description":"Allow vm VLANs to pass through this vnet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"vlanaware"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"},{"definition":{"description":"zone id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/vnets",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/vnets/{vnet}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bf7f3930d8114570d72e14e69a562a1b6a3bbc0bfb96f02a6283c8569f53e79a","description":"SDN subnets index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/subnets/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subnet}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"70912f6334b6fb8c741681f4b84db7a6647df44a376d31ac5d3ed287876f3e49","description":"Create a new sdn subnet object.","extra":{},"name":"create","parameters":[{"definition":{"description":"dns domain zone prefix ex: 'adm' -> .adm.mydomain.com","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"dnszoneprefix"},{"definition":{"description":"Subnet Gateway: Will be assign on vnet for layer3 zones","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"gateway"},{"definition":{"description":"enable masquerade for this subnet if pve-firewall","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"snat"},{"definition":{"description":"The SDN subnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-subnet-id","properties":{},"type":"string"},"name":"subnet"},{"definition":{"enum":["subnet"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"associated vnet","enum":[],"extra":{"typetext":""},"optional":false,"properties":{},"type":"string"},"name":"vnet"}],"permissions":{"expression":{"check":["perm","/sdn/vnets/{vnet}/subnets",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/vnets/{vnet}/subnets"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2629cf52e6350fa8e61ebd0752e9eaa41f27f91368695e92ddb48ea4a62ccf21","description":"Delete sdn subnet object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN subnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-subnet-id","properties":{},"type":"string"},"name":"subnet"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"expression":{"check":["perm","/sdn/vnets/{vnet}/subnets",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"e6a1aefebb68d276b7c8e61031c8e0f1691056c37876ace9fcaf7364e5510322","description":"Read sdn subnet configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"The SDN subnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-subnet-id","properties":{},"type":"string"},"name":"subnet"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"expression":{"check":["perm","/sdn/vnets/{vnet}/subnets/{subnet}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"256a9321d58e67172d33d5395bf341062209409176cf7cec066967f828996c2d","description":"Update sdn subnet object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"dns domain zone prefix ex: 'adm' -> .adm.mydomain.com","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"dnszoneprefix"},{"definition":{"description":"Subnet Gateway: Will be assign on vnet for layer3 zones","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"gateway"},{"definition":{"description":"enable masquerade for this subnet if pve-firewall","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"snat"},{"definition":{"description":"The SDN subnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-subnet-id","properties":{},"type":"string"},"name":"subnet"},{"definition":{"description":"associated vnet","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"vnet"}],"permissions":{"expression":{"check":["perm","/sdn/vnets/{vnet}/subnets",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/vnets/{vnet}/subnets/{subnet}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"703256a54caba27a0fe1e54aadfd275f490b49dfe9071dddc1872d3c74684250","description":"SDN zones index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"Only list SDN zones of specific type","enum":["evpn","faucet","qinq","simple","vlan","vxlan"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{zone}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"dns":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dnszone":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipam":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mtu":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"nodes":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pending":{"enum":[],"extra":{},"optional":true,"properties":{}},"reversedns":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"state":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"},"zone":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"8bebff683d2e0936be3fbbe18eaae84a63cdf5f258b2d7309e30284c37064e3c","description":"Create a new sdn zone object.","extra":{},"name":"create","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"bridge"},{"definition":{"description":"Frr router name","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"dns api server","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dns"},{"definition":{"description":"dns domain zone ex: mydomain.com","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"dnszone"},{"definition":{"description":"Faucet dataplane id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"dp-id"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"exitnodes"},{"definition":{"description":"use a specific ipam","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ipam"},{"definition":{"description":"Anycast logical router mac address","enum":[],"extra":{"typetext":""},"format":"mac-addr","optional":true,"properties":{},"type":"string"},"name":"mac"},{"definition":{"description":"MTU","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"peers address list.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"peers"},{"definition":{"description":"reverse dns api server","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"reversedns"},{"definition":{"description":"Service-VLAN Tag","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"tag"},{"definition":{"description":"Plugin type.","enum":["evpn","faucet","qinq","simple","vlan","vxlan"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"},{"definition":{"default":"802.1q","enum":["802.1q","802.1ad"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"vlan-protocol"},{"definition":{"description":"l3vni.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"vrf-vxlan"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/zones"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2f5064f43ef051fe497248fbda38d7e28b717d65019a575baca823d297de25d0","description":"Delete sdn zone object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"38131dcce447712ecf268c650a95c5166219287eacc37bc414317b3c94239a9f","description":"Read sdn zone configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"1207523a35638330725118e1ea3b45a4b6f8acc6c0ca6099ec9096506eb8e3e8","description":"Update sdn zone object configuration.","extra":{},"name":"update","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"bridge"},{"definition":{"description":"Frr router name","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"dns api server","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dns"},{"definition":{"description":"dns domain zone ex: mydomain.com","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"dnszone"},{"definition":{"description":"Faucet dataplane id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"dp-id"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"exitnodes"},{"definition":{"description":"use a specific ipam","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ipam"},{"definition":{"description":"Anycast logical router mac address","enum":[],"extra":{"typetext":""},"format":"mac-addr","optional":true,"properties":{},"type":"string"},"name":"mac"},{"definition":{"description":"MTU","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"peers address list.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"peers"},{"definition":{"description":"reverse dns api server","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"reversedns"},{"definition":{"description":"Service-VLAN Tag","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"tag"},{"definition":{"default":"802.1q","enum":["802.1q","802.1ad"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"vlan-protocol"},{"definition":{"description":"l3vni.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"vrf-vxlan"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/zones/{zone}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5a589a6f8ca9ac2030fd4d33ef13a80e575465992929b29725526face0399cc5","description":"Get cluster status information.","extra":{},"name":"get_status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"ip":{"description":"[node] IP of the resolved nodename.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"level":{"description":"[node] Proxmox VE Subscription level, indicates if eligible for enterprise support as well as access to the stable Proxmox VE Enterprise Repository.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"local":{"description":"[node] Indicates if this is the responding node.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"nodeid":{"description":"[node] ID of the node from the corosync configuration.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"nodes":{"description":"[cluster] Nodes count, including offline nodes.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"online":{"description":"[node] Indicates if the node is online or offline.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"quorate":{"description":"[cluster] Indicates if there is a majority of nodes online to make decisions","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"type":{"description":"Indicates the type, either cluster or node. The type defines the object properties e.g. quorate available for type cluster.","enum":["cluster","node"],"extra":{},"properties":{},"type":"string"},"version":{"description":"[cluster] Current version of the corosync configuration file.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d04c3b849a0aa5e5920867f414fba45c484719be08796bcbeaf8832f5833fe88","description":"List recent tasks (cluster wide).","extra":{},"name":"tasks","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"upid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/tasks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"31b002c17296ec68232ef7ac7414c584f56baeeefffa7dc7edd05d8ce5e5f183","description":"Cluster node index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{node}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cpu":{"description":"CPU utilization.","enum":[],"extra":{"renderer":"fraction_as_percentage"},"optional":true,"properties":{},"type":"number"},"level":{"description":"Support level.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxcpu":{"description":"Number of available CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Number of available memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"mem":{"description":"Used memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"node":{"description":"The cluster node name.","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"ssl_fingerprint":{"description":"The SSL fingerprint for the node certificate.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"status":{"description":"Node status.","enum":["unknown","online","offline"],"extra":{},"properties":{},"type":"string"},"uptime":{"description":"Node uptime in seconds.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes"},{"extra":{},"methods":[{"allow_token":true,"checksum":"407b3d66a300b7bc4f15ce81eadffc3e3ff161e7940cd646fc925a219be029f3","description":"Node index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"35b8e469447bd0b2011a8dfbb2d764cd4c5d26a960c23bfb523d2b8c078bbaf0","description":"Get list of appliances.","extra":{"proxyto":"node"},"name":"aplinfo","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"d4aad4483b7b17e8ec114d3e2f2e0454dc69dfdda3d679e441ec953cc1bb4dd7","description":"Download appliance templates.","extra":{"proxyto":"node"},"name":"apl_download","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage where the template will be stored","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"The template which will downloaded","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"template"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.AllocateTemplate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/aplinfo"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9fba10841493cc0c3608fd5b429677bf1e44b64bc3298479603a5da713b6c7e6","description":"Directory index for apt (Advanced Package Tool).","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/apt"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a2d6c099458fd722c750e1161be41fe0d364c22884858a3a0828f0f52cb8da10","description":"Get package changelogs.","extra":{"proxyto":"node"},"name":"changelog","parameters":[{"definition":{"description":"Package name.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Package version.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"version"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/apt/changelog"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b67270ad2512c5a995135eb26fb3729c5d8711de50412275d659531302779e2a","description":"List available updates.","extra":{"proxyto":"node"},"name":"list_updates","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"4727da3cf5e9aa4553a84f63261c3561da0bce68e5a573711f49edfde5cfc249","description":"This is used to resynchronize the package index files from their sources (apt-get update).","extra":{"proxyto":"node"},"name":"update_database","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Send notification mail about new packages (to email address specified for user 'root@pam').","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"notify"},{"definition":{"default":0,"description":"Only produces output suitable for logging, omitting progress indicators.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"quiet"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/apt/update"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f99cfcd0bb0ec2bf579674fc6cfd8c56025b24f68e28984c5318e468a369fa24","description":"Get package information for important Proxmox packages.","extra":{"proxyto":"node"},"name":"versions","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/apt/versions"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8323065d812e5e1377041e57ec0822474ada502b7d6d00636fe213e047e9de68","description":"Node capabilities index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/capabilities"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e27a6b54ddd6b980e5e1d7ddede6947b8cf3f81dc2cf5a3b59b263186afae2d7","description":"QEMU capabilities index.","extra":{},"name":"qemu_caps_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/capabilities/qemu"},{"extra":{},"methods":[{"allow_token":true,"checksum":"aa82f4e315b0d3d45f24590c081570d951d49f694f60716734889b5d02e8c01f","description":"Get available QEMU/KVM machine types.","extra":{"proxyto":"node"},"name":"types","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"id":{"description":"Full name of machine type and version.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The machine type.","enum":["q35","i440fx"],"extra":{},"properties":{},"type":"string"},"version":{"description":"The machine version.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/capabilities/qemu/machines"},{"extra":{},"methods":[{"allow_token":true,"checksum":"50808c982a4bc72c9bba3f95d85803db4a5a6d9897255ac750c522b0369f4f21","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8fa6a0644359c63d1109b42daed1b8b260c8c6f1db8cb6806f71fa1ea6b758af","description":"Get Ceph configuration.","extra":{"proxyto":"node"},"name":"config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/ceph/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bb80528ce7df88b91667e5e96fa12c813a153354293f7e17ec49a614916f0615","description":"Get Ceph configuration database.","extra":{"proxyto":"node"},"name":"configdb","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"can_update_at_runtime":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"level":{"enum":[],"extra":{},"properties":{},"type":"string"},"mask":{"enum":[],"extra":{},"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"section":{"enum":[],"extra":{},"properties":{},"type":"string"},"value":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/configdb"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e0322c6f07c65f5c1619204f0c7e670156521f47e8951f35563c74787459eefd","description":"Get OSD crush map","extra":{"proxyto":"node"},"name":"crush","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/ceph/crush"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4f48ce582eaa51467f055ee3f2f41ab9da7dc9c2cf42a844a2534614b10ebdd0","description":"List local disks.","extra":{"proxyto":"node"},"name":"disks","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list specific types of disks.","enum":["unused","journal_disks"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"dev":{"enum":[],"extra":{},"properties":{},"type":"string"},"gpt":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"model":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"osdid":{"enum":[],"extra":{},"properties":{},"type":"integer"},"serial":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"size":{"enum":[],"extra":{},"properties":{},"type":"integer"},"used":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vendor":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/disks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dab7ac9da06e2382cdb27f6dbaf2b0c6742304c0cd9bfe553278f95636a27f39","description":"get all set ceph flags","extra":{"proxyto":"node"},"name":"get_flags","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/ceph/flags"},{"extra":{},"methods":[{"allow_token":true,"checksum":"27c24f9bb67c70cec33973fb057278fc1f3d6be35d70acf8478388aad33a83b5","description":"Unset a ceph flag","extra":{"proxyto":"node"},"name":"unset_flag","parameters":[{"definition":{"description":"The ceph flag to unset","enum":["nobackfill","nodeep-scrub","nodown","noin","noout","norebalance","norecover","noscrub","notieragent","noup","pause"],"extra":{},"properties":{},"type":"string"},"name":"flag"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"09a31119c3c30ad32c7f7b7bb376d3ef6c3b8f40af17488d33d80997f0ef7487","description":"Set a specific ceph flag","extra":{"proxyto":"node"},"name":"set_flag","parameters":[{"definition":{"description":"The ceph flag to set","enum":["nobackfill","nodeep-scrub","nodown","noin","noout","norebalance","norecover","noscrub","notieragent","noup","pause"],"extra":{},"properties":{},"type":"string"},"name":"flag"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/flags/{flag}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"26fe33f0ff9494d29cd6768124890f101bf0ce6aa94b0171689a06f41af1e95f","description":"Directory index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"data_pool":{"description":"The name of the data pool.","enum":[],"extra":{},"properties":{},"type":"string"},"metadata_pool":{"description":"The name of the metadata pool.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"The ceph filesystem name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/fs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dc423ab96f13144b7889e6746c2e79a238c9d36e08762a85235fec362eab0df3","description":"Create a Ceph filesystem","extra":{"proxyto":"node"},"name":"createfs","parameters":[{"definition":{"default":0,"description":"Configure the created CephFS as storage for this cluster.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add-storage"},{"definition":{"default":"cephfs","description":"The ceph filesystem name.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":128,"description":"Number of placement groups for the backing data pool. The metadata pool will use a quarter of this.","enum":[],"extra":{"typetext":" (8 - 32768)"},"maximum":32768,"minimum":8,"optional":true,"properties":{},"type":"integer"},"name":"pg_num"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/fs/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"eb5af2fb65663011d0126319b08e7596f5c1f628ce5d5281ab3946e246c38ed8","description":"Create initial ceph default configuration and setup symlinks.","extra":{"proxyto":"node"},"name":"init","parameters":[{"definition":{"description":"Declare a separate cluster network, OSDs will routeheartbeat, object replication and recovery traffic over it","enum":[],"extra":{"requires":"network","typetext":""},"format":"CIDR","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"cluster-network"},{"definition":{"default":0,"description":"Disable cephx authentication.\n\nWARNING: cephx is a security feature protecting against man-in-the-middle attacks. Only consider disabling cephx if your network is private!","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable_cephx"},{"definition":{"default":2,"description":"Minimum number of available replicas per object to allow I/O","enum":[],"extra":{"typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"min_size"},{"definition":{"description":"Use specific network for all ceph related traffic","enum":[],"extra":{"typetext":""},"format":"CIDR","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"network"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":6,"description":"Placement group bits, used to specify the default number of placement groups.\n\nNOTE: 'osd pool default pg num' does not work for default pools.","enum":[],"extra":{"typetext":" (6 - 14)"},"maximum":14,"minimum":6,"optional":true,"properties":{},"type":"integer"},"name":"pg_bits"},{"definition":{"default":3,"description":"Targeted number of replicas per object","enum":[],"extra":{"typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"size"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/init"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8a31ac771c928fe9eb6235d17a52ecaf2ae45e2169ec83ac019a01378dd9c35a","description":"Read ceph log","extra":{"proxyto":"node"},"name":"log","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"572f311d8fc0eb7f66a89e38bda2cd329ee39d8ba4a8025ce6713bf3f7d6c1be","description":"MDS directory index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"addr":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"host":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"The name (ID) for the MDS","enum":[],"extra":{},"properties":{}},"rank":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"standby_replay":{"description":"If true, the standby MDS is polling the active MDS for faster recovery (hot standby).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"state":{"description":"State of the MDS","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/mds"},{"extra":{},"methods":[{"allow_token":true,"checksum":"95bfdf6b725d610975f2cb9b78b5c858072ceb2d7fa1e721df8554522b7ff936","description":"Destroy Ceph Metadata Server","extra":{"proxyto":"node"},"name":"destroymds","parameters":[{"definition":{"description":"The name (ID) of the mds","enum":[],"extra":{},"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"9c3ec6795adb762b6e5f1367b947a261fc983bf1377a29f675353f65636f8e77","description":"Create Ceph Metadata Server (MDS)","extra":{"proxyto":"node"},"name":"createmds","parameters":[{"definition":{"default":"0","description":"Determines whether a ceph-mds daemon should poll and replay the log of an active MDS. Faster switch on MDS failure, but needs more idle resources.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"hotstandby"},{"definition":{"default":"nodename","description":"The ID for the mds, when omitted the same as the nodename","enum":[],"extra":{},"max_length":200,"optional":true,"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/mds/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"66c37a28e4da09b1f5d9ed47d7aa6d37f754c5fad2f1d951d8dfd682cc4ae54a","description":"MGR directory index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"addr":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"host":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"The name (ID) for the MGR","enum":[],"extra":{},"properties":{}},"state":{"description":"State of the MGR","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/mgr"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1b6eac6b4b1058f7d0564b86f899fc1c39d08317e8482afa20115de4fd4c5f3c","description":"Destroy Ceph Manager.","extra":{"proxyto":"node"},"name":"destroymgr","parameters":[{"definition":{"description":"The ID of the manager","enum":[],"extra":{},"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"9a9667c69cb29e5a499d6a2369ff4f46790bf4fd55e6b6364daaf2846d1e86f4","description":"Create Ceph Manager","extra":{"proxyto":"node"},"name":"createmgr","parameters":[{"definition":{"description":"The ID for the manager, when omitted the same as the nodename","enum":[],"extra":{},"max_length":200,"optional":true,"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/mgr/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0bc79b228fb22d5a39b4e5e84a51a91adc7cfd51fe7e756d83de1258c548b556","description":"Get Ceph monitor list.","extra":{"proxyto":"node"},"name":"listmon","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"addr":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"host":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/mon"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0f5ae748cffda16f98dc9978fd9e9abc28c3131e1e102f2ebe3fbf965db5b663","description":"Destroy Ceph Monitor and Manager.","extra":{"proxyto":"node"},"name":"destroymon","parameters":[{"definition":{"description":"Monitor ID","enum":[],"extra":{},"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"monid"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"d7e61644111d3058126b6175eddd5bc8761f9e023a899920efe023182669903b","description":"Create Ceph Monitor and Manager","extra":{"proxyto":"node"},"name":"createmon","parameters":[{"definition":{"description":"Overwrites autodetected monitor IP address. Must be in the public network of ceph.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"mon-address"},{"definition":{"description":"The ID for the monitor, when omitted the same as the nodename","enum":[],"extra":{},"max_length":200,"optional":true,"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"monid"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/mon/{monid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a5a555e59b960b3942bb4a45cbcaf5540ae8fa50a48f595e50eae5adc811983c","description":"Get Ceph osd list/tree.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"88c8359dedc2c8e389ff4cd833c7709b154044b46b9ade228159a069a4ed7162","description":"Create OSD","extra":{"proxyto":"node"},"name":"createosd","parameters":[{"definition":{"description":"Set the device class of the OSD in crush.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"crush-device-class"},{"definition":{"description":"Block device name for block.db.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"db_dev"},{"definition":{"default":"bluestore_block_db_size or 10% of OSD size","description":"Size in GiB for block.db.","enum":[],"extra":{"requires":"db_dev","typetext":" (1 - N)","verbose_description":"If a block.db is requested but the size is not given, will be automatically selected by: bluestore_block_db_size from the ceph database (osd or global section) or config (osd or global section)in that order. If this is not available, it will be sized 10% of the size of the OSD device. Fails if the available size is not enough."},"minimum":1,"optional":true,"properties":{},"type":"number"},"name":"db_size"},{"definition":{"description":"Block device name.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"dev"},{"definition":{"default":0,"description":"Enables encryption of the OSD.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"encrypted"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Block device name for block.wal.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"wal_dev"},{"definition":{"default":"bluestore_block_wal_size or 1% of OSD size","description":"Size in GiB for block.wal.","enum":[],"extra":{"requires":"wal_dev","typetext":" (0.5 - N)","verbose_description":"If a block.wal is requested but the size is not given, will be automatically selected by: bluestore_block_wal_size from the ceph database (osd or global section) or config (osd or global section)in that order. If this is not available, it will be sized 1% of the size of the OSD device. Fails if the available size is not enough."},"minimum":0.5,"optional":true,"properties":{},"type":"number"},"name":"wal_size"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/osd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ad8e2808277aa89b9d2fe58df7fe5a889cd128fd7b21e68ac6e2fd628f18125b","description":"Destroy OSD","extra":{"proxyto":"node"},"name":"destroyosd","parameters":[{"definition":{"default":0,"description":"If set, we remove partition table entries.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"}],"path":"/nodes/{node}/ceph/osd/{osdid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bf7b180ff0f405fde06dc5d87505bd8ab58b5d1502106abd87441f78d23f5e26","description":"ceph osd in","extra":{"proxyto":"node"},"name":"in","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/osd/{osdid}/in"},{"extra":{},"methods":[{"allow_token":true,"checksum":"23d8222b59c8aab7050f8c7415d7e3d12494cab703c1ee49bb4be15f1b666800","description":"ceph osd out","extra":{"proxyto":"node"},"name":"out","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/osd/{osdid}/out"},{"extra":{},"methods":[{"allow_token":true,"checksum":"60019df48da0442ab7a3f116bc02cc627d89cc4c978434e73175e44fa0e2107b","description":"Instruct the OSD to scrub.","extra":{"proxyto":"node"},"name":"scrub","parameters":[{"definition":{"default":0,"description":"If set, instructs a deep scrub instead of a normal one.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"deep"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/osd/{osdid}/scrub"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9cf4f40fbbf0c7af87a615ea55e892d5d119e07c0e047af04a2b7891385660d4","description":"List all pools.","extra":{"proxyto":"node"},"name":"lspools","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{pool_name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"autoscale_status":{"enum":[],"extra":{"title":"Autoscale Status"},"optional":true,"properties":{},"type":"object"},"bytes_used":{"enum":[],"extra":{"title":"Used"},"properties":{},"type":"integer"},"crush_rule":{"enum":[],"extra":{"title":"Crush Rule"},"properties":{},"type":"integer"},"crush_rule_name":{"enum":[],"extra":{"title":"Crush Rule Name"},"properties":{},"type":"string"},"min_size":{"enum":[],"extra":{"title":"Min Size"},"properties":{},"type":"integer"},"percent_used":{"enum":[],"extra":{"title":"%-Used"},"properties":{},"type":"number"},"pg_autoscale_mode":{"enum":[],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"pg_num":{"enum":[],"extra":{"title":"PG Num"},"properties":{},"type":"integer"},"pg_num_final":{"enum":[],"extra":{"title":"Optimal PG Num"},"optional":true,"properties":{},"type":"integer"},"pg_num_min":{"enum":[],"extra":{"title":"min. PG Num"},"optional":true,"properties":{},"type":"integer"},"pool":{"enum":[],"extra":{"title":"ID"},"properties":{},"type":"integer"},"pool_name":{"enum":[],"extra":{"title":"Name"},"properties":{},"type":"string"},"size":{"enum":[],"extra":{"title":"Size"},"properties":{},"type":"integer"},"target_size":{"enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"properties":{},"type":"integer"},"target_size_ratio":{"enum":[],"extra":{"title":"PG Autoscale Target Ratio"},"optional":true,"properties":{},"type":"number"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"1a0e8cf05d4cf6842f840285a6b0fb2abbd089b0d43ef2538f6b73cb5eacbf96","description":"Create POOL","extra":{"proxyto":"node"},"name":"createpool","parameters":[{"definition":{"description":"Configure VM and CT storage using the new pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storages"},{"definition":{"default":"rbd","description":"The application of the pool.","enum":["rbd","cephfs","rgw"],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"string"},"name":"application"},{"definition":{"description":"The rule to use for mapping object placement in the cluster.","enum":[],"extra":{"title":"Crush Rule Name","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"crush_rule"},{"definition":{"default":2,"description":"Minimum number of replicas per object","enum":[],"extra":{"title":"Min Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"min_size"},{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"title":"Name","typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"warn","description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"name":"pg_autoscale_mode"},{"definition":{"default":128,"description":"Number of placement groups.","enum":[],"extra":{"title":"PG Num","typetext":" (1 - 32768)"},"maximum":32768,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"pg_num"},{"definition":{"description":"Minimal number of placement groups.","enum":[],"extra":{"title":"min. PG Num","typetext":" (-N - 32768)"},"maximum":32768,"optional":true,"properties":{},"type":"integer"},"name":"pg_num_min"},{"definition":{"default":3,"description":"Number of replicas per object","enum":[],"extra":{"title":"Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"size"},{"definition":{"description":"The estimated target size of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"pattern":"^(\\d+(\\.\\d+)?)([KMGT])?$","properties":{},"type":"string"},"name":"target_size"},{"definition":{"description":"The estimated target ratio of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Ratio","typetext":""},"optional":true,"properties":{},"type":"number"},"name":"target_size_ratio"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/pools"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d4d46dd614feee056331f30376c8b62f9127905739600efa07d8fb94097a86f8","description":"Destroy pool","extra":{"proxyto":"node"},"name":"destroypool","parameters":[{"definition":{"default":0,"description":"If true, destroys pool even if in use","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Remove all pveceph-managed storages configured for this pool","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove_storages"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"cec18e0c6b9e4e69a87bdf66e272a0844a19fcf19def63da22fd538f2cb8a990","description":"List pool settings.","extra":{"proxyto":"node"},"name":"getpool","parameters":[{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"If enabled, will display additional data(eg. statistics).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verbose"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"application":{"default":"rbd","description":"The application of the pool.","enum":["rbd","cephfs","rgw"],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"string"},"application_list":{"enum":[],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"array"},"autoscale_status":{"enum":[],"extra":{"title":"Autoscale Status"},"optional":true,"properties":{},"type":"object"},"crush_rule":{"description":"The rule to use for mapping object placement in the cluster.","enum":[],"extra":{"title":"Crush Rule Name"},"optional":true,"properties":{},"type":"string"},"fast_read":{"enum":[],"extra":{"title":"Fast Read"},"properties":{},"type":"boolean"},"hashpspool":{"enum":[],"extra":{"title":"hashpspool"},"properties":{},"type":"boolean"},"id":{"enum":[],"extra":{"title":"ID"},"properties":{},"type":"integer"},"min_size":{"default":2,"description":"Minimum number of replicas per object","enum":[],"extra":{"title":"Min Size"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"title":"Name"},"properties":{},"type":"string"},"nodeep-scrub":{"enum":[],"extra":{"title":"nodeep-scrub"},"properties":{},"type":"boolean"},"nodelete":{"enum":[],"extra":{"title":"nodelete"},"properties":{},"type":"boolean"},"nopgchange":{"enum":[],"extra":{"title":"nopgchange"},"properties":{},"type":"boolean"},"noscrub":{"enum":[],"extra":{"title":"noscrub"},"properties":{},"type":"boolean"},"nosizechange":{"enum":[],"extra":{"title":"nosizechange"},"properties":{},"type":"boolean"},"pg_autoscale_mode":{"default":"warn","description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"pg_num":{"default":128,"description":"Number of placement groups.","enum":[],"extra":{"title":"PG Num"},"maximum":32768,"minimum":1,"optional":true,"properties":{},"type":"integer"},"pg_num_min":{"description":"Minimal number of placement groups.","enum":[],"extra":{"title":"min. PG Num"},"maximum":32768,"optional":true,"properties":{},"type":"integer"},"pgp_num":{"enum":[],"extra":{"title":"PGP num"},"properties":{},"type":"integer"},"size":{"default":3,"description":"Number of replicas per object","enum":[],"extra":{"title":"Size"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"statistics":{"enum":[],"extra":{"title":"Statistics"},"optional":true,"properties":{},"type":"object"},"target_size":{"description":"The estimated target size of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"pattern":"^(\\d+(\\.\\d+)?)([KMGT])?$","properties":{},"type":"string"},"target_size_ratio":{"description":"The estimated target ratio of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Ratio"},"optional":true,"properties":{},"type":"number"},"use_gmt_hitset":{"enum":[],"extra":{"title":"use_gmt_hitset"},"properties":{},"type":"boolean"},"write_fadvise_dontneed":{"enum":[],"extra":{"title":"write_fadvise_dontneed"},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"cbb73dbca627e66e481cb19a244c569135954dd33ce6307d1bb6bc08ad6ed62d","description":"Change POOL settings","extra":{"proxyto":"node"},"name":"setpool","parameters":[{"definition":{"description":"The application of the pool.","enum":["rbd","cephfs","rgw"],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"string"},"name":"application"},{"definition":{"description":"The rule to use for mapping object placement in the cluster.","enum":[],"extra":{"title":"Crush Rule Name","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"crush_rule"},{"definition":{"description":"Minimum number of replicas per object","enum":[],"extra":{"title":"Min Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"min_size"},{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"title":"Name","typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"name":"pg_autoscale_mode"},{"definition":{"description":"Number of placement groups.","enum":[],"extra":{"title":"PG Num","typetext":" (1 - 32768)"},"maximum":32768,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"pg_num"},{"definition":{"description":"Minimal number of placement groups.","enum":[],"extra":{"title":"min. PG Num","typetext":" (-N - 32768)"},"maximum":32768,"optional":true,"properties":{},"type":"integer"},"name":"pg_num_min"},{"definition":{"description":"Number of replicas per object","enum":[],"extra":{"title":"Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"size"},{"definition":{"description":"The estimated target size of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"pattern":"^(\\d+(\\.\\d+)?)([KMGT])?$","properties":{},"type":"string"},"name":"target_size"},{"definition":{"description":"The estimated target ratio of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Ratio","typetext":""},"optional":true,"properties":{},"type":"number"},"name":"target_size_ratio"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/ceph/pools/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d8f63039ca364b164a8e68d30f3a03f1ebe8c071133098c0a1781588258c7c56","description":"Restart ceph services.","extra":{"proxyto":"node"},"name":"restart","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"ceph.target","description":"Ceph service name.","enum":[],"extra":{},"optional":true,"pattern":"(mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?","properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/restart"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9721db02e516a9bc67f6d56232a60a28c9aae8b3e71f5b5dea7aba4addc7567d","description":"List ceph rules.","extra":{"proxyto":"node"},"name":"rules","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ecb354e68cb5aeaa1e4b8b63c176ff7410fa0fed35f792c2891964ab6662d962","description":"Start ceph services.","extra":{"proxyto":"node"},"name":"start","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"ceph.target","description":"Ceph service name.","enum":[],"extra":{},"optional":true,"pattern":"(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?","properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"46eb9852d690eec67eee3282fa3db6841f26e1a7ad8a7eb34f367777223906e4","description":"Get ceph status.","extra":{"proxyto":"node"},"name":"status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2844e52262806ae8703017f4b336a790d3c54cd9c0ad3ae772ed9fe138def456","description":"Stop ceph services.","extra":{"proxyto":"node"},"name":"stop","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"ceph.target","description":"Ceph service name.","enum":[],"extra":{},"optional":true,"pattern":"(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?","properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/stop"},{"extra":{},"methods":[{"allow_token":true,"checksum":"407b3d66a300b7bc4f15ce81eadffc3e3ff161e7940cd646fc925a219be029f3","description":"Node index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/certificates"},{"extra":{},"methods":[{"allow_token":true,"checksum":"93b19d6ea7cca4a3a682a7c06117351418c9725fb782f6ed86050c0ac92f4bd4","description":"ACME index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/certificates/acme"},{"extra":{},"methods":[{"allow_token":true,"checksum":"79bd82498d21a1c5d90f053e1aaec400ad82efd3983c8cf0559fe0c47b5b293c","description":"Revoke existing certificate from CA.","extra":{"proxyto":"node"},"name":"revoke_certificate","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"eb094550eb00e663dca797ef8c9dc07865542e546832f3d913080f5638f81c3a","description":"Order a new certificate from ACME-compatible CA.","extra":{"proxyto":"node"},"name":"new_certificate","parameters":[{"definition":{"default":0,"description":"Overwrite existing custom certificate.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"},{"allow_token":true,"checksum":"f8eea8445722cd9588417a2079abe85620556ba298b502dd0717e3876aa1abc5","description":"Renew existing certificate from CA.","extra":{"proxyto":"node"},"name":"renew_certificate","parameters":[{"definition":{"default":0,"description":"Force renewal even if expiry is more than 30 days away.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/certificates/acme/certificate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"929493029f5253253302d24f7a1e2c0046bf726108c3d37ed8c86801ddc3384a","description":"DELETE custom certificate chain and key.","extra":{"proxyto":"node"},"name":"remove_custom_cert","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Restart pveproxy.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restart"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"604d77053bdcded86a50810bad7ad1b20c14ff8887d4068b001db73771908654","description":"Upload or update custom certificate chain and key.","extra":{"proxyto":"node"},"name":"upload_custom_cert","parameters":[{"definition":{"description":"PEM encoded certificate (chain).","enum":[],"extra":{"typetext":""},"format":"pem-certificate-chain","properties":{},"type":"string"},"name":"certificates"},{"definition":{"default":0,"description":"Overwrite existing custom or ACME certificate files.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"PEM encoded private key.","enum":[],"extra":{"typetext":""},"format":"pem-string","optional":true,"properties":{},"type":"string"},"name":"key"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Restart pveproxy.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restart"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"fingerprint":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"issuer":{"description":"Certificate issuer name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"notafter":{"description":"Certificate's notAfter timestamp (UNIX epoch).","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"notbefore":{"description":"Certificate's notBefore timestamp (UNIX epoch).","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"pem":{"description":"Certificate in PEM format","enum":[],"extra":{},"format":"pem-certificate","optional":true,"properties":{},"type":"string"},"public-key-bits":{"description":"Certificate's public key size","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"public-key-type":{"description":"Certificate's public key algorithm","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"san":{"description":"List of Certificate's SubjectAlternativeName entries.","enum":[],"extra":{"renderer":"yaml"},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"subject":{"description":"Certificate subject name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/certificates/custom"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2a9b8f5b1a046e68e76e42747bf6de9bb776652ea56f1797a0b8f6bd32e2d21b","description":"Get information about node's certificates.","extra":{"proxyto":"node"},"name":"info","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"fingerprint":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"issuer":{"description":"Certificate issuer name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"notafter":{"description":"Certificate's notAfter timestamp (UNIX epoch).","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"notbefore":{"description":"Certificate's notBefore timestamp (UNIX epoch).","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"pem":{"description":"Certificate in PEM format","enum":[],"extra":{},"format":"pem-certificate","optional":true,"properties":{},"type":"string"},"public-key-bits":{"description":"Certificate's public key size","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"public-key-type":{"description":"Certificate's public key algorithm","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"san":{"description":"List of Certificate's SubjectAlternativeName entries.","enum":[],"extra":{"renderer":"yaml"},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"subject":{"description":"Certificate subject name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/certificates/info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ddf6b69f2f538b24b3d42a092a8851c63039e57709ebb8b670700ea18bd62241","description":"Get node configuration options.","extra":{"proxyto":"node"},"name":"get_config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"all","description":"Return only a specific property from the node configuration.","enum":["acme","acmedomain0","acmedomain1","acmedomain2","acmedomain3","acmedomain4","acmedomain5","description","startall-onboot-delay","wakeonlan"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"property"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"938967eeb74a103479871a9bf32379d89173852a3ec500ff314bc3f64b33483e","description":"Set node configuration options.","extra":{"proxyto":"node"},"name":"set_options","parameters":[{"definition":{"description":"Node specific ACME settings.","enum":[],"extra":{"typetext":"[account=] [,domains=]"},"format":{"account":{"default":"default","description":"ACME account config file name.","format":"pve-configid","format_description":"name","optional":1,"type":"string"},"domains":{"description":"List of domains for this node's ACME certificate","format":"pve-acme-domain-list","format_description":"domain[;domain;...]","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"acme"},{"definition":{"description":"ACME domain and validation plugin","enum":[],"extra":{"typetext":"[domain=] [,alias=] [,plugin=]"},"format":{"alias":{"description":"Alias for the Domain to verify ACME Challenge over DNS","format":"pve-acme-alias","format_description":"domain","optional":1,"type":"string"},"domain":{"default_key":1,"description":"domain for this node's ACME certificate","format":"pve-acme-domain","format_description":"domain","type":"string"},"plugin":{"default":"standalone","description":"The ACME plugin ID","format":"pve-configid","format_description":"name of the plugin configuration","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"acmedomain[n]"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Node description/comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.","enum":[],"extra":{"typetext":" (0 - 300)"},"maximum":300,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"startall-onboot-delay"},{"definition":{"description":"MAC address for wake on LAN","enum":[],"extra":{"typetext":""},"format":"mac-addr","optional":true,"properties":{},"type":"string"},"name":"wakeonlan"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"927d1325a9a50865ae950f9d9ec8be45d125376424b8b48420d3105b711ba85e","description":"List all custom and default CPU models.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Only returns custom models when the current user has Sys.Audit on /nodes.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"custom":{"description":"True if this is a custom CPU model.","enum":[],"extra":{},"properties":{},"type":"boolean"},"name":{"description":"Name of the CPU model. Identifies it for subsequent API calls. Prefixed with 'custom-' for custom models.","enum":[],"extra":{},"properties":{},"type":"string"},"vendor":{"description":"CPU vendor visible to the guest when this model is selected. Vendor of 'reported-model' in case of custom models.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/cpu"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c852718145641f2177102cbfc0fd436f6aeef81be29c2faedeed85f289314d9f","description":"Node index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/disks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f3537522c4031753f813beb7da086e204086ac5c89763bf227d68af05223c3f3","description":"PVE Managed Directory storages.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"device":{"description":"The mounted device.","enum":[],"extra":{},"properties":{},"type":"string"},"options":{"description":"The mount options.","enum":[],"extra":{},"properties":{},"type":"string"},"path":{"description":"The mount path.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The filesystem type.","enum":[],"extra":{},"properties":{},"type":"string"},"unitfile":{"description":"The path of the mount unit.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"122355716467fdd8f226f5aef647e6eea691d9368c73be9b8f3870a055a53b8c","description":"Create a Filesystem on an unused disk. Will be mounted under '/mnt/pve/NAME'.","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"default":0,"description":"Configure storage using the directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storage"},{"definition":{"description":"The block device you want to create the filesystem on.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"device"},{"definition":{"default":"ext4","description":"The desired filesystem.","enum":["ext4","xfs"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"filesystem"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify","Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/directory"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e07569915888aa6baceeffec53ed6c431ea006c760c7620558ca0980ba012061","description":"Initialize Disk with GPT","extra":{"proxyto":"node"},"name":"initgpt","parameters":[{"definition":{"description":"Block device name","enum":[],"extra":{},"pattern":"^/dev/[a-zA-Z0-9\\/]+$","properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"UUID for the GPT table","enum":[],"extra":{},"max_length":36,"optional":true,"pattern":"[a-fA-F0-9\\-]+","properties":{},"type":"string"},"name":"uuid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/initgpt"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e01c6ac91e3b3c73669acb1661784fe34f4c9cc6ee7053dd13c78e23b4e17d65","description":"List local disks.","extra":{"proxyto":"node"},"name":"list","parameters":[{"definition":{"default":0,"description":"Also include partitions.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"include-partitions"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Skip smart checks.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skipsmart"},{"definition":{"description":"Only list specific types of disks.","enum":["unused","journal_disks"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["or",["perm","/",["Sys.Audit","Datastore.Audit"],"any",1],["perm","/nodes/{node}",["Sys.Audit","Datastore.Audit"],"any",1]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"devpath":{"description":"The device path","enum":[],"extra":{},"properties":{},"type":"string"},"gpt":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"health":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"model":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"osdid":{"enum":[],"extra":{},"properties":{},"type":"integer"},"parent":{"description":"For partitions only. The device path of the disk the partition resides on.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"size":{"enum":[],"extra":{},"properties":{},"type":"integer"},"used":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vendor":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"wwn":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/disks/list"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d06c7ceb2c64f1f9d871a7879687c33cac78acaba470ba1a4d105be971a56e95","description":"List LVM Volume Groups","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"children":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"children":{"description":"The underlying physical volumes","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"free":{"description":"The free bytes in the physical volume","enum":[],"extra":{},"properties":{},"type":"integer"},"leaf":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"name":{"description":"The name of the physical volume","enum":[],"extra":{},"properties":{},"type":"string"},"size":{"description":"The size of the physical volume in bytes","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"free":{"description":"The free bytes in the volume group","enum":[],"extra":{},"properties":{},"type":"integer"},"leaf":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"name":{"description":"The name of the volume group","enum":[],"extra":{},"properties":{},"type":"string"},"size":{"description":"The size of the volume group in bytes","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"leaf":{"enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"412d8d6327a72b39c6a9292e0a2bcb78f97ae945d52c8b5eb1efd00c867c990f","description":"Create an LVM Volume Group","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"default":0,"description":"Configure storage using the Volume Group","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storage"},{"definition":{"description":"The block device you want to create the volume group on","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"device"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify","Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/lvm"},{"extra":{},"methods":[{"allow_token":true,"checksum":"70f7355a020c2462bb0a413048dbf5b48523ef56d721214c448ef144c8226cd7","description":"List LVM thinpools","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"lv":{"description":"The name of the thinpool.","enum":[],"extra":{},"properties":{},"type":"string"},"lv_size":{"description":"The size of the thinpool in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"metadata_size":{"description":"The size of the metadata lv in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"metadata_used":{"description":"The used bytes of the metadata lv.","enum":[],"extra":{},"properties":{},"type":"integer"},"used":{"description":"The used bytes of the thinpool.","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f3550aafa62fea1ce8de5079fbd8588d813f6c4df9975d524b8d126006c5ae1b","description":"Create an LVM thinpool","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"default":0,"description":"Configure storage using the thinpool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storage"},{"definition":{"description":"The block device you want to create the thinpool on.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"device"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify","Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/lvmthin"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6a92c85a34adf096e370bf05961141c522e5cc0aaf6f8fc7bd73251844ee6b0b","description":"Get SMART Health of a disk.","extra":{"proxyto":"node"},"name":"smart","parameters":[{"definition":{"description":"Block device name","enum":[],"extra":{},"pattern":"^/dev/[a-zA-Z0-9\\/]+$","properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"If true returns only the health status","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"healthonly"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"attributes":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"array"},"health":{"enum":[],"extra":{},"properties":{},"type":"string"},"text":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/disks/smart"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9258079c31e8352aea31f38f0b16ebd2190aa0d3bcac19ddabad2d1920847934","description":"List Zpools.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"alloc":{"description":"","enum":[],"extra":{},"properties":{},"type":"integer"},"dedup":{"description":"","enum":[],"extra":{},"properties":{},"type":"number"},"frag":{"description":"","enum":[],"extra":{},"properties":{},"type":"integer"},"free":{"description":"","enum":[],"extra":{},"properties":{},"type":"integer"},"health":{"description":"","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"","enum":[],"extra":{},"properties":{},"type":"string"},"size":{"description":"","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"39e43b01b10883c8355277a77b5eae86fd6c9aa3cfe667e4c6d0a7af2a8c8724","description":"Create a ZFS pool.","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"default":0,"description":"Configure storage using the zpool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storage"},{"definition":{"default":12,"description":"Pool sector size exponent.","enum":[],"extra":{"typetext":" (9 - 16)"},"maximum":16,"minimum":9,"optional":true,"properties":{},"type":"integer"},"name":"ashift"},{"definition":{"default":"on","description":"The compression algorithm to use.","enum":["on","off","gzip","lz4","lzjb","zle"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"compression"},{"definition":{"description":"The block devices you want to create the zpool on.","enum":[],"extra":{"typetext":""},"format":"string-list","properties":{},"type":"string"},"name":"devices"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The RAID level to use.","enum":["single","mirror","raid10","raidz","raidz2","raidz3"],"extra":{},"properties":{},"type":"string"},"name":"raidlevel"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify","Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/zfs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b2a84edcfa15d4f29cc2620ccb8d1820c12a52b3990c2bfb88bb104c4e31dc4c","description":"Get details about a zpool.","extra":{"proxyto":"node"},"name":"detail","parameters":[{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"action":{"description":"Information about the recommended action to fix the state.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"children":{"description":"The pool configuration information, including the vdevs for each section (e.g. spares, cache), may be nested.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"cksum":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"msg":{"description":"An optional message about the vdev.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"The name of the vdev or section.","enum":[],"extra":{},"properties":{},"type":"string"},"read":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"state":{"description":"The state of the vdev.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"write":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"number"}},"type":"object"},"properties":{},"type":"array"},"errors":{"description":"Information about the errors on the zpool.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"The name of the zpool.","enum":[],"extra":{},"properties":{},"type":"string"},"scan":{"description":"Information about the last/current scrub.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"state":{"description":"The state of the zpool.","enum":[],"extra":{},"properties":{},"type":"string"},"status":{"description":"Information about the state of the zpool.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/disks/zfs/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a2a9840bc5b5f6fedb64fc871e0f30293e36589bef2b2cca3b75b167641bd3ad","description":"Read DNS settings.","extra":{"proxyto":"node"},"name":"dns","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"dns1":{"description":"First name server IP address.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dns2":{"description":"Second name server IP address.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dns3":{"description":"Third name server IP address.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"search":{"description":"Search domain for host-name lookup.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"aa3976a9e9313d0108087afc577aaef882c6caa542300b9aa580823664733034","description":"Write DNS settings.","extra":{"proxyto":"node"},"name":"update_dns","parameters":[{"definition":{"description":"First name server IP address.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"dns1"},{"definition":{"description":"Second name server IP address.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"dns2"},{"definition":{"description":"Third name server IP address.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"dns3"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Search domain for host-name lookup.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"search"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/dns"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b8697b191baa7f3b82516e707bdf450b8133127460f749d708f281c074fb56bc","description":"Execute multiple commands in order.","extra":{"proxyto":"node"},"name":"execute","parameters":[{"definition":{"description":"JSON encoded array of commands.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"commands"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"array"},"verb":"POST"}],"path":"/nodes/{node}/execute"},{"extra":{},"methods":[{"allow_token":true,"checksum":"23dca6507cde2ae0cabadf81020c2e06e2c8878c3e19c7356ba7dbc49c506a9a","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3260c434b39c2122524627ed23b759c387a2afeaebbfcb0d632583aaf4aa09a0","description":"Read firewall log","extra":{"proxyto":"node"},"name":"log","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/firewall/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2111a40e43ac1ff0a534beb2d22f86af1d644f1838134c290adb88a74b8506e3","description":"Get host firewall options.","extra":{"proxyto":"node"},"name":"get_options","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"enable":{"description":"Enable host firewall rules.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"log_level_in":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_level_out":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_nf_conntrack":{"default":0,"description":"Enable logging of conntrack information.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ndp":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"nf_conntrack_allow_invalid":{"default":0,"description":"Allow invalid packets on connection tracking.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"nf_conntrack_max":{"default":262144,"description":"Maximum number of tracked connections.","enum":[],"extra":{},"minimum":32768,"optional":true,"properties":{},"type":"integer"},"nf_conntrack_tcp_timeout_established":{"default":432000,"description":"Conntrack established timeout.","enum":[],"extra":{},"minimum":7875,"optional":true,"properties":{},"type":"integer"},"nf_conntrack_tcp_timeout_syn_recv":{"default":60,"description":"Conntrack syn recv timeout.","enum":[],"extra":{},"maximum":60,"minimum":30,"optional":true,"properties":{},"type":"integer"},"nosmurfs":{"description":"Enable SMURFS filter.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"protection_synflood":{"default":0,"description":"Enable synflood protection","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"protection_synflood_burst":{"default":1000,"description":"Synflood protection rate burst by ip src.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"protection_synflood_rate":{"default":200,"description":"Synflood protection rate syn/sec by ip src.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"smurf_log_level":{"description":"Log level for SMURFS filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"tcp_flags_log_level":{"description":"Log level for illegal tcp flags filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"tcpflags":{"default":0,"description":"Filter illegal combinations of TCP flags.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"775872a487197e89bb8953d8af1c4ec773bfdd46441e60fa22134aba0c40891c","description":"Set Firewall options.","extra":{"proxyto":"node"},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Enable host firewall rules.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_in"},{"definition":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_out"},{"definition":{"default":0,"description":"Enable logging of conntrack information.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"log_nf_conntrack"},{"definition":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ndp"},{"definition":{"default":0,"description":"Allow invalid packets on connection tracking.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nf_conntrack_allow_invalid"},{"definition":{"default":262144,"description":"Maximum number of tracked connections.","enum":[],"extra":{"typetext":" (32768 - N)"},"minimum":32768,"optional":true,"properties":{},"type":"integer"},"name":"nf_conntrack_max"},{"definition":{"default":432000,"description":"Conntrack established timeout.","enum":[],"extra":{"typetext":" (7875 - N)"},"minimum":7875,"optional":true,"properties":{},"type":"integer"},"name":"nf_conntrack_tcp_timeout_established"},{"definition":{"default":60,"description":"Conntrack syn recv timeout.","enum":[],"extra":{"typetext":" (30 - 60)"},"maximum":60,"minimum":30,"optional":true,"properties":{},"type":"integer"},"name":"nf_conntrack_tcp_timeout_syn_recv"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Enable SMURFS filter.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nosmurfs"},{"definition":{"default":0,"description":"Enable synflood protection","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection_synflood"},{"definition":{"default":1000,"description":"Synflood protection rate burst by ip src.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"protection_synflood_burst"},{"definition":{"default":200,"description":"Synflood protection rate syn/sec by ip src.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"protection_synflood_rate"},{"definition":{"description":"Log level for SMURFS filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"smurf_log_level"},{"definition":{"description":"Log level for illegal tcp flags filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"tcp_flags_log_level"},{"definition":{"default":0,"description":"Filter illegal combinations of TCP flags.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tcpflags"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b60ddfff9873ec325386c9e661b00a7b59dc13a05b46d58a5a77ed0925c039ab","description":"List rules.","extra":{"proxyto":"node"},"name":"get_rules","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"39347ccf40cc2b737d16aa439637a812f274180d373d3efa4ce658665cc07e16","description":"Create new rule.","extra":{"proxyto":"node"},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"169c2557fcf5b10d3a2d121dca1e9c370648a2c511dc7983d56e10ac9e09ba80","description":"Delete rule.","extra":{"proxyto":"node"},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"334c82a7807d96fdd30b6fc1678394170a14b3aa9668f1c3231b928df2338d78","description":"Get single rule data.","extra":{"proxyto":"node"},"name":"get_rule","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"6e5ec2b58b3e43b0a3296a12a723269384983983b4c50c9da4927f70df96304e","description":"Modify rule data.","extra":{"proxyto":"node"},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a942affba5edd9876d3a47c7aaed97b5c3eeca8b6a2748dbb6cfd04b87ec4985","description":"Index of hardware types","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{type}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware"},{"extra":{},"methods":[{"allow_token":true,"checksum":"06022f2baceadadf64d27fe098b8c16ddb74a36beaeabb18f7ac45cf15c5c97d","description":"List local PCI devices.","extra":{"proxyto":"node"},"name":"pciscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"05;06;08;0b","description":"A list of blacklisted PCI classes, which will not be returned. Following are filtered by default: Memory Controller (05), Bridge (06), Generic System Peripheral (08) and Processor (0b).","enum":[],"extra":{"typetext":""},"format":"string-list","optional":true,"properties":{},"type":"string"},"name":"pci-class-blacklist"},{"definition":{"default":1,"description":"If disabled, does only print the PCI IDs. Otherwise, additional information like vendor and device will be returned.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verbose"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"class":{"description":"The PCI Class of the device.","enum":[],"extra":{},"properties":{},"type":"string"},"device":{"description":"The Device ID.","enum":[],"extra":{},"properties":{},"type":"string"},"device_name":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"description":"The PCI ID.","enum":[],"extra":{},"properties":{},"type":"string"},"iommugroup":{"description":"The IOMMU group in which the device is in. If no IOMMU group is detected, it is set to -1.","enum":[],"extra":{},"properties":{},"type":"integer"},"mdev":{"description":"If set, marks that the device is capable of creating mediated devices.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"subsystem_device":{"description":"The Subsystem Device ID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"subsystem_device_name":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"subsystem_vendor":{"description":"The Subsystem Vendor ID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"subsystem_vendor_name":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vendor":{"description":"The Vendor ID.","enum":[],"extra":{},"properties":{},"type":"string"},"vendor_name":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware/pci"},{"extra":{},"methods":[{"allow_token":true,"checksum":"00db499ff891c1ed4084f98a93db79971b16ac33db9f5294d0012ba6ded291c4","description":"Index of available pci methods","extra":{},"name":"pciindex","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{},"pattern":"(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\\.[0-9a-fA-F]","properties":{},"type":"string"},"name":"pciid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{method}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"method":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware/pci/{pciid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e6af667562583a82d014b623560f60abc930edd99993ce928424847cdd9cc693","description":"List mediated device types for given PCI device.","extra":{"proxyto":"node"},"name":"mdevscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The PCI ID to list the mdev types for.","enum":[],"extra":{},"pattern":"(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\\.[0-9a-fA-F]","properties":{},"type":"string"},"name":"pciid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"available":{"description":"The number of still available instances of this type.","enum":[],"extra":{},"properties":{},"type":"integer"},"description":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The name of the mdev type.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware/pci/{pciid}/mdev"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c34730e00f0d40259fe27fa8d10c86ca51d09c55d88e56c0a58a874dcf7bff9c","description":"List local USB devices.","extra":{"proxyto":"node"},"name":"usbscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"busnum":{"enum":[],"extra":{},"properties":{},"type":"integer"},"class":{"enum":[],"extra":{},"properties":{},"type":"integer"},"devnum":{"enum":[],"extra":{},"properties":{},"type":"integer"},"level":{"enum":[],"extra":{},"properties":{},"type":"integer"},"manufacturer":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"prodid":{"enum":[],"extra":{},"properties":{},"type":"string"},"product":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"speed":{"enum":[],"extra":{},"properties":{},"type":"string"},"usbpath":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vendid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware/usb"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e943b9c325ad6feb5fa744fd25c3496a70cffce248b736581e7f9f0ce0ad7535","description":"Get the content of /etc/hosts.","extra":{"proxyto":"node"},"name":"get_etc_hosts","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"data":{"description":"The content of /etc/hosts.","enum":[],"extra":{},"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"6e5c04602315f9bcc7d02e0c8aa2c968f3e6d7dfe2b370294162e79e765dcc82","description":"Write /etc/hosts.","extra":{"proxyto":"node"},"name":"write_etc_hosts","parameters":[{"definition":{"description":"The target content of /etc/hosts.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"data"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/hosts"},{"extra":{},"methods":[{"allow_token":true,"checksum":"04faf2d1e6766b07df402cdf939d22c00773c9ec6b520222875837f1043a7dfb","description":"Read Journal","extra":{"proxyto":"node"},"name":"journal","parameters":[{"definition":{"description":"End before the given Cursor. Conflicts with 'until'","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"endcursor"},{"definition":{"description":"Limit to the last X lines. Conflicts with a range.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"lastentries"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Display all log since this UNIX epoch. Conflicts with 'startcursor'.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"since"},{"definition":{"description":"Start after the given Cursor. Conflicts with 'since'","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"startcursor"},{"definition":{"description":"Display all log until this UNIX epoch. Conflicts with 'endcursor'.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"until"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/journal"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3a6d5650ce0097ef3a4aaada9b5c8e2331e1d13f172998ffe5a960a8d0c5d647","description":"LXC container index (per node).","extra":{"proxyto":"node"},"name":"vmlist","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Only list CTs where you have VM.Audit permissons on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{vmid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cpus":{"description":"Maximum usable CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"lock":{"description":"The current config lock, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxdisk":{"description":"Root disk size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Maximum memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxswap":{"description":"Maximum SWAP memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"name":{"description":"Container name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"status":{"description":"LXC Container status.","enum":["stopped","running"],"extra":{},"properties":{},"type":"string"},"tags":{"description":"The current configured tags, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"uptime":{"description":"Uptime.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"33d3fd289ce816a3867a4e8df49ed27e21f36aca27795efc86a7b0eaf1a0183a","description":"Create or restore a container.","extra":{"proxyto":"node"},"name":"create_vm","parameters":[{"definition":{"default":"amd64","description":"OS architecture type.","enum":["amd64","i386","arm64","armhf"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"default":"restore limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"default":"tty","description":"Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).","enum":["shell","console","tty"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmode"},{"definition":{"default":1,"description":"Attach a console device (/dev/console) to the container.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"console"},{"definition":{"description":"The number of cores assigned to the container. A container can use all available cores by default.","enum":[],"extra":{"typetext":" (1 - 8192)"},"maximum":8192,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"default":0,"description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.","enum":[],"extra":{"typetext":" (0 - 8192)"},"maximum":8192,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":1024,"description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to the weights of all the other running VMs.\n\nNOTE: You can disable fair-scheduler configuration by setting this to 0.","enum":[],"extra":{"typetext":" (0 - 500000)"},"maximum":500000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"default":0,"description":"Try to be more verbose. For now this only enables debug log-level on start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"debug"},{"definition":{"description":"Container description. Only used on the configuration web interface.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Allow containers access to advanced features.","enum":[],"extra":{"typetext":"[force_rw_sys=<1|0>] [,fuse=<1|0>] [,keyctl=<1|0>] [,mknod=<1|0>] [,mount=] [,nesting=<1|0>]"},"format":{"force_rw_sys":{"default":0,"description":"Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.","optional":1,"type":"boolean"},"fuse":{"default":0,"description":"Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.","optional":1,"type":"boolean"},"keyctl":{"default":0,"description":"For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.","optional":1,"type":"boolean"},"mknod":{"default":0,"description":"Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.","optional":1,"type":"boolean"},"mount":{"description":"Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.","format_description":"fstype;fstype;...","optional":1,"pattern":"(?^:[a-zA-Z0-9_; ]+)","type":"string"},"nesting":{"default":0,"description":"Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"features"},{"definition":{"description":"Allow to overwrite existing container.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Script that will be exectued during various steps in the containers lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Set a host name for the container.","enum":[],"extra":{"typetext":""},"format":"dns-name","max_length":255,"optional":true,"properties":{},"type":"string"},"name":"hostname"},{"definition":{"description":"Ignore errors when extracting the template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ignore-unpack-errors"},{"definition":{"description":"Lock/unlock the VM.","enum":["backup","create","destroyed","disk","fstrim","migrate","mounted","rollback","snapshot","snapshot-delete"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"default":512,"description":"Amount of RAM for the VM in MB.","enum":[],"extra":{"typetext":" (16 - N)"},"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"memory"},{"definition":{"description":"Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[volume=] ,mp= [,acl=<1|0>] [,backup=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]"},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"backup":{"description":"Whether to include the mount point in backups.","optional":1,"type":"boolean","verbose_description":"Whether to include the mount point in backups (only used for volume mount points)."},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(noatime|nodev|nosuid|noexec))(;(?^:(noatime|nodev|nosuid|noexec)))*)","type":"string"},"mp":{"description":"Path to the mount point as seen from inside the container (must not contain symlinks).","format":"pve-lxc-mp-string","format_description":"Path","type":"string","verbose_description":"Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons."},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"mp[n]"},{"definition":{"description":"Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{"typetext":""},"format":"lxc-ip-with-ll-iface-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specifies network interfaces for the container.","enum":[],"extra":{"typetext":"name= [,bridge=] [,firewall=<1|0>] [,gw=] [,gw6=] [,hwaddr=] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=<(IPv6/CIDR|auto|dhcp|manual)>] [,mtu=] [,rate=] [,tag=] [,trunks=] [,type=]"},"format":{"bridge":{"description":"Bridge to attach the network device to.","format_description":"bridge","optional":1,"pattern":"[-_.\\w\\d]+","type":"string"},"firewall":{"description":"Controls whether this interface's firewall rules should be used.","optional":1,"type":"boolean"},"gw":{"description":"Default gateway for IPv4 traffic.","format":"ipv4","format_description":"GatewayIPv4","optional":1,"type":"string"},"gw6":{"description":"Default gateway for IPv6 traffic.","format":"ipv6","format_description":"GatewayIPv6","optional":1,"type":"string"},"hwaddr":{"description":"The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"ip":{"description":"IPv4 address in CIDR format.","format":"pve-ipv4-config","format_description":"(IPv4/CIDR|dhcp|manual)","optional":1,"type":"string"},"ip6":{"description":"IPv6 address in CIDR format.","format":"pve-ipv6-config","format_description":"(IPv6/CIDR|auto|dhcp|manual)","optional":1,"type":"string"},"mtu":{"description":"Maximum transfer unit of the interface. (lxc.network.mtu)","minimum":64,"optional":1,"type":"integer"},"name":{"description":"Name of the network device as seen from inside the container. (lxc.network.name)","format_description":"string","pattern":"[-_.\\w\\d]+","type":"string"},"rate":{"description":"Apply rate limiting to the interface","format_description":"mbps","optional":1,"type":"number"},"tag":{"description":"VLAN tag for this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN ids to pass through the interface","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:;\\d+)*)","type":"string"},"type":{"description":"Network interface type.","enum":["veth"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"The OS template or backup file.","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"ostemplate"},{"definition":{"description":"OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.","enum":["debian","devuan","ubuntu","centos","fedora","opensuse","archlinux","alpine","gentoo","unmanaged"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"description":"Sets root password inside container.","enum":[],"extra":{"typetext":""},"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Add the VM to the specified pool.","enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"default":0,"description":"Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"description":"Mark this as restore task.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restore"},{"definition":{"description":"Use volume as container root.","enum":[],"extra":{"typetext":"[volume=] [,acl=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]"},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(noatime|nodev|nosuid|noexec))(;(?^:(noatime|nodev|nosuid|noexec)))*)","type":"string"},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"rootfs"},{"definition":{"description":"Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{"typetext":""},"format":"dns-name-list","optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ssh-public-keys"},{"definition":{"default":0,"description":"Start the CT after its creation finished successfully.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"start"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"default":"local","description":"Default Storage.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"default":512,"description":"Amount of SWAP for the VM in MB.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"swap"},{"definition":{"description":"Tags of the Container. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab","enum":[],"extra":{"typetext":""},"format":"pve-ct-timezone","optional":true,"properties":{},"type":"string"},"name":"timezone"},{"definition":{"default":2,"description":"Specify the number of tty available to the container","enum":[],"extra":{"typetext":" (0 - 6)"},"maximum":6,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"tty"},{"definition":{"description":"Assign a unique random ethernet address.","enum":[],"extra":{"requires":"restore","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"unique"},{"definition":{"default":0,"description":"Makes the container run as unprivileged user. (Should not be modified manually.)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"unprivileged"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[volume=]"},"format":{"volume":{"default_key":1,"description":"The volume that is not used currently.","format":"pve-volume-id","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permissions on /vms/{vmid} or on the VM pool /pool/{pool}. For restore, it is enough if the user has 'VM.Backup' permission and the VM already exists. You also need 'Datastore.AllocateSpace' permissions on the storage.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc"},{"extra":{},"methods":[{"allow_token":true,"checksum":"358b02759151ae6704197e0283558b6e0754b232b70a3c894aa3e49ec04abbe2","description":"Destroy the container (also delete all uses files).","extra":{"proxyto":"node"},"name":"destroy_vm","parameters":[{"definition":{"description":"If set, destroy additionally all disks with the VMID from all enabled storages which are not referenced in the config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"destroy-unreferenced-disks"},{"definition":{"default":0,"description":"Force destroy, even if running.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Remove container from all related configurations. For example, backup jobs, replication jobs or HA. Related ACLs and Firewall entries will *always* be removed.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"purge"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"fa055338b801bce39c739df867cff19ab708c821f45e2cd7c6ee100546aea617","description":"Directory index","extra":{"proxyto":"node"},"name":"vmdiridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"922fdc838693b8a0f7f6990ff6ab0e3cb1f4f3227b3e90953f6314bdb014742a","description":"Create a container clone/copy","extra":{"proxyto":"node"},"name":"clone_vm","parameters":[{"definition":{"default":"clone limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"description":"Description for the new CT.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Create a full copy of all disks. This is always done when you clone a normal CT. For CT templates, we try to create a linked clone by default.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"},{"definition":{"description":"Set a hostname for the new CT.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"hostname"},{"definition":{"description":"VMID for the clone.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"newid"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Add the new CT to the specified pool.","enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"Target storage for full clone.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Target node. Only allowed if the original VM is on shared storage.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions on /vms/{newid} (or on the VM pool /pool/{pool}). You also need 'Datastore.AllocateSpace' on any used storage.","expression":{"check":["and",["perm","/vms/{vmid}",["VM.Clone"]],["or",["perm","/vms/{newid}",["VM.Allocate"]],["perm","/pool/{pool}",["VM.Allocate"],"require_param","pool"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/clone"},{"extra":{},"methods":[{"allow_token":true,"checksum":"64cf3d937cdf5f1209860de041a05557ce3206b63efc37513df9bfd9ddc24ac5","description":"Get container configuration.","extra":{"proxyto":"node"},"name":"vm_config","parameters":[{"definition":{"default":0,"description":"Get current values (instead of pending values).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"current"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Fetch config values from given snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapshot"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"arch":{"default":"amd64","description":"OS architecture type.","enum":["amd64","i386","arm64","armhf"],"extra":{},"optional":true,"properties":{},"type":"string"},"cmode":{"default":"tty","description":"Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).","enum":["shell","console","tty"],"extra":{},"optional":true,"properties":{},"type":"string"},"console":{"default":1,"description":"Attach a console device (/dev/console) to the container.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"cores":{"description":"The number of cores assigned to the container. A container can use all available cores by default.","enum":[],"extra":{},"maximum":8192,"minimum":1,"optional":true,"properties":{},"type":"integer"},"cpulimit":{"default":0,"description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.","enum":[],"extra":{},"maximum":8192,"minimum":0,"optional":true,"properties":{},"type":"number"},"cpuunits":{"default":1024,"description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to the weights of all the other running VMs.\n\nNOTE: You can disable fair-scheduler configuration by setting this to 0.","enum":[],"extra":{},"maximum":500000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"debug":{"default":0,"description":"Try to be more verbose. For now this only enables debug log-level on start.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"description":{"description":"Container description. Only used on the configuration web interface.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"SHA1 digest of configuration file. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"properties":{},"type":"string"},"features":{"description":"Allow containers access to advanced features.","enum":[],"extra":{},"format":{"force_rw_sys":{"default":0,"description":"Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.","optional":1,"type":"boolean"},"fuse":{"default":0,"description":"Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.","optional":1,"type":"boolean"},"keyctl":{"default":0,"description":"For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.","optional":1,"type":"boolean"},"mknod":{"default":0,"description":"Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.","optional":1,"type":"boolean"},"mount":{"description":"Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.","format_description":"fstype;fstype;...","optional":1,"pattern":"(?^:[a-zA-Z0-9_; ]+)","type":"string"},"nesting":{"default":0,"description":"Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"hookscript":{"description":"Script that will be exectued during various steps in the containers lifetime.","enum":[],"extra":{},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"hostname":{"description":"Set a host name for the container.","enum":[],"extra":{},"format":"dns-name","max_length":255,"optional":true,"properties":{},"type":"string"},"lock":{"description":"Lock/unlock the VM.","enum":["backup","create","destroyed","disk","fstrim","migrate","mounted","rollback","snapshot","snapshot-delete"],"extra":{},"optional":true,"properties":{},"type":"string"},"lxc":{"description":"Array of lxc low-level configurations ([[key1, value1], [key2, value2] ...]).","enum":[],"extra":{},"items":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"optional":true,"properties":{},"type":"array"},"memory":{"default":512,"description":"Amount of RAM for the VM in MB.","enum":[],"extra":{},"minimum":16,"optional":true,"properties":{},"type":"integer"},"mp[n]":{"description":"Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"backup":{"description":"Whether to include the mount point in backups.","optional":1,"type":"boolean","verbose_description":"Whether to include the mount point in backups (only used for volume mount points)."},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(noatime|nodev|nosuid|noexec))(;(?^:(noatime|nodev|nosuid|noexec)))*)","type":"string"},"mp":{"description":"Path to the mount point as seen from inside the container (must not contain symlinks).","format":"pve-lxc-mp-string","format_description":"Path","type":"string","verbose_description":"Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons."},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"nameserver":{"description":"Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{},"format":"lxc-ip-with-ll-iface-list","optional":true,"properties":{},"type":"string"},"net[n]":{"description":"Specifies network interfaces for the container.","enum":[],"extra":{},"format":{"bridge":{"description":"Bridge to attach the network device to.","format_description":"bridge","optional":1,"pattern":"[-_.\\w\\d]+","type":"string"},"firewall":{"description":"Controls whether this interface's firewall rules should be used.","optional":1,"type":"boolean"},"gw":{"description":"Default gateway for IPv4 traffic.","format":"ipv4","format_description":"GatewayIPv4","optional":1,"type":"string"},"gw6":{"description":"Default gateway for IPv6 traffic.","format":"ipv6","format_description":"GatewayIPv6","optional":1,"type":"string"},"hwaddr":{"description":"The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"ip":{"description":"IPv4 address in CIDR format.","format":"pve-ipv4-config","format_description":"(IPv4/CIDR|dhcp|manual)","optional":1,"type":"string"},"ip6":{"description":"IPv6 address in CIDR format.","format":"pve-ipv6-config","format_description":"(IPv6/CIDR|auto|dhcp|manual)","optional":1,"type":"string"},"mtu":{"description":"Maximum transfer unit of the interface. (lxc.network.mtu)","minimum":64,"optional":1,"type":"integer"},"name":{"description":"Name of the network device as seen from inside the container. (lxc.network.name)","format_description":"string","pattern":"[-_.\\w\\d]+","type":"string"},"rate":{"description":"Apply rate limiting to the interface","format_description":"mbps","optional":1,"type":"number"},"tag":{"description":"VLAN tag for this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN ids to pass through the interface","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:;\\d+)*)","type":"string"},"type":{"description":"Network interface type.","enum":["veth"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"onboot":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ostype":{"description":"OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.","enum":["debian","devuan","ubuntu","centos","fedora","opensuse","archlinux","alpine","gentoo","unmanaged"],"extra":{},"optional":true,"properties":{},"type":"string"},"protection":{"default":0,"description":"Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"rootfs":{"description":"Use volume as container root.","enum":[],"extra":{},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(noatime|nodev|nosuid|noexec))(;(?^:(noatime|nodev|nosuid|noexec)))*)","type":"string"},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"searchdomain":{"description":"Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{},"format":"dns-name-list","optional":true,"properties":{},"type":"string"},"startup":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"swap":{"default":512,"description":"Amount of SWAP for the VM in MB.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"tags":{"description":"Tags of the Container. This is only meta information.","enum":[],"extra":{},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"template":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"timezone":{"description":"Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab","enum":[],"extra":{},"format":"pve-ct-timezone","optional":true,"properties":{},"type":"string"},"tty":{"default":2,"description":"Specify the number of tty available to the container","enum":[],"extra":{},"maximum":6,"minimum":0,"optional":true,"properties":{},"type":"integer"},"unprivileged":{"default":0,"description":"Makes the container run as unprivileged user. (Should not be modified manually.)","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"unused[n]":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{},"format":{"volume":{"default_key":1,"description":"The volume that is not used currently.","format":"pve-volume-id","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"08870a0bbdc128d8a6e46db8f803556b7a9671eda922c436f33cda10aae0eff7","description":"Set container options.","extra":{"proxyto":"node"},"name":"update_vm","parameters":[{"definition":{"default":"amd64","description":"OS architecture type.","enum":["amd64","i386","arm64","armhf"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"default":"tty","description":"Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).","enum":["shell","console","tty"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmode"},{"definition":{"default":1,"description":"Attach a console device (/dev/console) to the container.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"console"},{"definition":{"description":"The number of cores assigned to the container. A container can use all available cores by default.","enum":[],"extra":{"typetext":" (1 - 8192)"},"maximum":8192,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"default":0,"description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.","enum":[],"extra":{"typetext":" (0 - 8192)"},"maximum":8192,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":1024,"description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to the weights of all the other running VMs.\n\nNOTE: You can disable fair-scheduler configuration by setting this to 0.","enum":[],"extra":{"typetext":" (0 - 500000)"},"maximum":500000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"default":0,"description":"Try to be more verbose. For now this only enables debug log-level on start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"debug"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Container description. Only used on the configuration web interface.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Allow containers access to advanced features.","enum":[],"extra":{"typetext":"[force_rw_sys=<1|0>] [,fuse=<1|0>] [,keyctl=<1|0>] [,mknod=<1|0>] [,mount=] [,nesting=<1|0>]"},"format":{"force_rw_sys":{"default":0,"description":"Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.","optional":1,"type":"boolean"},"fuse":{"default":0,"description":"Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.","optional":1,"type":"boolean"},"keyctl":{"default":0,"description":"For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.","optional":1,"type":"boolean"},"mknod":{"default":0,"description":"Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.","optional":1,"type":"boolean"},"mount":{"description":"Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.","format_description":"fstype;fstype;...","optional":1,"pattern":"(?^:[a-zA-Z0-9_; ]+)","type":"string"},"nesting":{"default":0,"description":"Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"features"},{"definition":{"description":"Script that will be exectued during various steps in the containers lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Set a host name for the container.","enum":[],"extra":{"typetext":""},"format":"dns-name","max_length":255,"optional":true,"properties":{},"type":"string"},"name":"hostname"},{"definition":{"description":"Lock/unlock the VM.","enum":["backup","create","destroyed","disk","fstrim","migrate","mounted","rollback","snapshot","snapshot-delete"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"default":512,"description":"Amount of RAM for the VM in MB.","enum":[],"extra":{"typetext":" (16 - N)"},"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"memory"},{"definition":{"description":"Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[volume=] ,mp= [,acl=<1|0>] [,backup=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]"},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"backup":{"description":"Whether to include the mount point in backups.","optional":1,"type":"boolean","verbose_description":"Whether to include the mount point in backups (only used for volume mount points)."},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(noatime|nodev|nosuid|noexec))(;(?^:(noatime|nodev|nosuid|noexec)))*)","type":"string"},"mp":{"description":"Path to the mount point as seen from inside the container (must not contain symlinks).","format":"pve-lxc-mp-string","format_description":"Path","type":"string","verbose_description":"Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons."},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"mp[n]"},{"definition":{"description":"Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{"typetext":""},"format":"lxc-ip-with-ll-iface-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specifies network interfaces for the container.","enum":[],"extra":{"typetext":"name= [,bridge=] [,firewall=<1|0>] [,gw=] [,gw6=] [,hwaddr=] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=<(IPv6/CIDR|auto|dhcp|manual)>] [,mtu=] [,rate=] [,tag=] [,trunks=] [,type=]"},"format":{"bridge":{"description":"Bridge to attach the network device to.","format_description":"bridge","optional":1,"pattern":"[-_.\\w\\d]+","type":"string"},"firewall":{"description":"Controls whether this interface's firewall rules should be used.","optional":1,"type":"boolean"},"gw":{"description":"Default gateway for IPv4 traffic.","format":"ipv4","format_description":"GatewayIPv4","optional":1,"type":"string"},"gw6":{"description":"Default gateway for IPv6 traffic.","format":"ipv6","format_description":"GatewayIPv6","optional":1,"type":"string"},"hwaddr":{"description":"The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"ip":{"description":"IPv4 address in CIDR format.","format":"pve-ipv4-config","format_description":"(IPv4/CIDR|dhcp|manual)","optional":1,"type":"string"},"ip6":{"description":"IPv6 address in CIDR format.","format":"pve-ipv6-config","format_description":"(IPv6/CIDR|auto|dhcp|manual)","optional":1,"type":"string"},"mtu":{"description":"Maximum transfer unit of the interface. (lxc.network.mtu)","minimum":64,"optional":1,"type":"integer"},"name":{"description":"Name of the network device as seen from inside the container. (lxc.network.name)","format_description":"string","pattern":"[-_.\\w\\d]+","type":"string"},"rate":{"description":"Apply rate limiting to the interface","format_description":"mbps","optional":1,"type":"number"},"tag":{"description":"VLAN tag for this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN ids to pass through the interface","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:;\\d+)*)","type":"string"},"type":{"description":"Network interface type.","enum":["veth"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.","enum":["debian","devuan","ubuntu","centos","fedora","opensuse","archlinux","alpine","gentoo","unmanaged"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"default":0,"description":"Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"description":"Revert a pending change.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"revert"},{"definition":{"description":"Use volume as container root.","enum":[],"extra":{"typetext":"[volume=] [,acl=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]"},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(noatime|nodev|nosuid|noexec))(;(?^:(noatime|nodev|nosuid|noexec)))*)","type":"string"},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"rootfs"},{"definition":{"description":"Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{"typetext":""},"format":"dns-name-list","optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"default":512,"description":"Amount of SWAP for the VM in MB.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"swap"},{"definition":{"description":"Tags of the Container. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab","enum":[],"extra":{"typetext":""},"format":"pve-ct-timezone","optional":true,"properties":{},"type":"string"},"name":"timezone"},{"definition":{"default":2,"description":"Specify the number of tty available to the container","enum":[],"extra":{"typetext":" (0 - 6)"},"maximum":6,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"tty"},{"definition":{"default":0,"description":"Makes the container run as unprivileged user. (Should not be modified manually.)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"unprivileged"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[volume=]"},"format":{"volume":{"default_key":1,"description":"The volume that is not used currently.","format":"pve-volume-id","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"non-volume mount points in rootfs and mp[n] are restricted to root@pam","expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk","VM.Config.CPU","VM.Config.Memory","VM.Config.Network","VM.Config.Options"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3afc3a1f31bfc059c6274826a2899d12006ce23d5c77d09bd86b548bcc751ae3","description":"Check if feature for virtual machine is available.","extra":{"proxyto":"node"},"name":"vm_feature","parameters":[{"definition":{"description":"Feature to check.","enum":["snapshot","clone","copy"],"extra":{},"properties":{},"type":"string"},"name":"feature"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"hasFeature":{"enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/feature"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5bb143c67c66cf5b8450a21b7962a9429555249c9a169a229e7745f9d8304495","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f3ade8db07d7e168cf2c244f2327d3845c4d148a021436cde1e65f01fcc58db7","description":"List aliases","extra":{},"name":"get_aliases","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"0d804bcfd2565a8543511d9fd83e3425760031b592c1d1e50326d6725d38c139","description":"Create IP or Network Alias.","extra":{},"name":"create_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/aliases"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5920ae6968407878a5b9eb64bd68e522549bb7009cd3895d915d8adbe17e161d","description":"Remove IP or Network alias.","extra":{},"name":"remove_alias","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"1858b8e7f12863024af22797024f75a6fdf6cda0c224f6a4ce9815d3a4cb483b","description":"Read alias.","extra":{},"name":"read_alias","parameters":[{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"7e9b6195d2cd189f3b1fa52dc54fb8369c0324de89694c2614fdb3e30409670f","description":"Update IP or Network alias.","extra":{},"name":"update_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Rename an existing alias.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"72f4e0abfc4fc1fc45cf29ac6cf40bb3810b4463327824ba821b6bd63d1ebc30","description":"List IPSets","extra":{},"name":"ipset_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"name":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"ca3a7645ec2c6c377c1ae0dfb99c5feec2ef5e9bf3aa743b44670f851374983b","description":"Create new IPSet","extra":{},"name":"create_ipset","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/ipset"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3aececa9e07416c4a6077688be66d0fa6485e3d1c76d0d63a629924e7061a751","description":"Delete IPSet","extra":{},"name":"delete_ipset","parameters":[{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"c14d95b34b1dcc471da836cadc0ac6dbc2b2fc74105df7ff98f5cfc6b133644d","description":"List IPSet content","extra":{},"name":"get_ipset","parameters":[{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cidr}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"nomatch":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"e9612cc0bf355acd89e38d888ee4f89a951948c0840cb620e55d6b7bfc2cfad7","description":"Add IP or Network to IPSet.","extra":{},"name":"create_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"17a70102f27b6d30ea52149ee3614d9b300342b77b66edfeccf9f0c6662ab255","description":"Remove IP or Network from IPSet.","extra":{},"name":"remove_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"a4e0753e2fa85678d8a8d5b232c4403e3ec801c1beb4fd8f537802b987df83a4","description":"Read IP or Network settings from IPSet.","extra":{},"name":"read_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"e033d28015b80e8073780c388cbec51e67f613039684b31d4e9a10aa02c1db33","description":"Update IP or Network settings","extra":{},"name":"update_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b572db8584e8bd6519da73c5c4712e6d44b5179aa8c170b5e8ca129a7b940c39","description":"Read firewall log","extra":{"proxyto":"node"},"name":"log","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"93c4d78422db18c9d0942138c633d8f375aed0485a26da01d13c5e585127c3ab","description":"Get VM firewall options.","extra":{"proxyto":"node"},"name":"get_options","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"dhcp":{"default":0,"description":"Enable DHCP.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"enable":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ipfilter":{"description":"Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"log_level_in":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_level_out":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macfilter":{"default":0,"description":"Enable/disable MAC address filter.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ndp":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"policy_in":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"policy_out":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"radv":{"description":"Allow sending Router Advertisement.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"c6b0e7ba430ba960bf9707669825b788e0a93f6207022350b845dc321ae06a3a","description":"Set Firewall options.","extra":{"proxyto":"node"},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"default":0,"description":"Enable DHCP.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"dhcp"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ipfilter"},{"definition":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_in"},{"definition":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_out"},{"definition":{"default":0,"description":"Enable/disable MAC address filter.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"macfilter"},{"definition":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ndp"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_in"},{"definition":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_out"},{"definition":{"description":"Allow sending Router Advertisement.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"radv"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"37d9588c916a6008f684c9911b05557c57a0334b032dc6feadc90bdffbddf35a","description":"Lists possible IPSet/Alias reference which are allowed in source/dest properties.","extra":{},"name":"refs","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list references of specified type.","enum":["alias","ipset"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":["alias","ipset"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/refs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9aca6c2421abc582ee1474baf7a4e1986ba3cc546ff95ffe612bbe4a7806ac0e","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"02d16c2ee1394a58a737d72dd821f6260b5002ffa456e35ed2e801bbe4116074","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dad1a485162cfc3b459d6d3cb052c9be411bfd535ad8eec7eb1567ad899d3a47","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"74b69d51de0371ce4003eb94ff6ce4d0208d139b00d70d22cef90bc1c8693c46","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"c5e043f89f0db35e70af5e2d6587308e90b9e2157a4b8c662621b6b5a5733ecb","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c57f5c41b68dc267a495fe903a05c4a6a50fd14870bcad26331f89b4dcaa82eb","description":"Migrate the container to another node. Creates a new migration task.","extra":{"proxyto":"node"},"name":"migrate_vm","parameters":[{"definition":{"default":"migrate limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"description":"Force migration despite local bind / device mounts. NOTE: deprecated, use 'shared' property of mount point instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use online/live migration.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"online"},{"definition":{"description":"Use restart migration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restart"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"target"},{"definition":{"default":180,"description":"Timeout in seconds for shutdown for restart migration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"45a7e064fc9af860514a216baadae2a53bceab0468ebba92c704c411fe5adea6","description":"Move a rootfs-/mp-volume to a different storage","extra":{"proxyto":"node"},"name":"move_volume","parameters":[{"definition":{"default":"clone limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"default":0,"description":"Delete the original volume after successful copy. By default the original is kept as an unused volume entry.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target Storage.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Volume which will be moved.","enum":["rootfs","mp0","mp1","mp2","mp3","mp4","mp5","mp6","mp7","mp8","mp9","mp10","mp11","mp12","mp13","mp14","mp15","mp16","mp17","mp18","mp19","mp20","mp21","mp22","mp23","mp24","mp25","mp26","mp27","mp28","mp29","mp30","mp31","mp32","mp33","mp34","mp35","mp36","mp37","mp38","mp39","mp40","mp41","mp42","mp43","mp44","mp45","mp46","mp47","mp48","mp49","mp50","mp51","mp52","mp53","mp54","mp55","mp56","mp57","mp58","mp59","mp60","mp61","mp62","mp63","mp64","mp65","mp66","mp67","mp68","mp69","mp70","mp71","mp72","mp73","mp74","mp75","mp76","mp77","mp78","mp79","mp80","mp81","mp82","mp83","mp84","mp85","mp86","mp87","mp88","mp89","mp90","mp91","mp92","mp93","mp94","mp95","mp96","mp97","mp98","mp99","mp100","mp101","mp102","mp103","mp104","mp105","mp106","mp107","mp108","mp109","mp110","mp111","mp112","mp113","mp114","mp115","mp116","mp117","mp118","mp119","mp120","mp121","mp122","mp123","mp124","mp125","mp126","mp127","mp128","mp129","mp130","mp131","mp132","mp133","mp134","mp135","mp136","mp137","mp138","mp139","mp140","mp141","mp142","mp143","mp144","mp145","mp146","mp147","mp148","mp149","mp150","mp151","mp152","mp153","mp154","mp155","mp156","mp157","mp158","mp159","mp160","mp161","mp162","mp163","mp164","mp165","mp166","mp167","mp168","mp169","mp170","mp171","mp172","mp173","mp174","mp175","mp176","mp177","mp178","mp179","mp180","mp181","mp182","mp183","mp184","mp185","mp186","mp187","mp188","mp189","mp190","mp191","mp192","mp193","mp194","mp195","mp196","mp197","mp198","mp199","mp200","mp201","mp202","mp203","mp204","mp205","mp206","mp207","mp208","mp209","mp210","mp211","mp212","mp213","mp214","mp215","mp216","mp217","mp218","mp219","mp220","mp221","mp222","mp223","mp224","mp225","mp226","mp227","mp228","mp229","mp230","mp231","mp232","mp233","mp234","mp235","mp236","mp237","mp238","mp239","mp240","mp241","mp242","mp243","mp244","mp245","mp246","mp247","mp248","mp249","mp250","mp251","mp252","mp253","mp254","mp255"],"extra":{},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need 'VM.Config.Disk' permissions on /vms/{vmid}, and 'Datastore.AllocateSpace' permissions on the storage.","expression":{"check":["and",["perm","/vms/{vmid}",["VM.Config.Disk"]],["perm","/storage/{storage}",["Datastore.AllocateSpace"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/move_volume"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b8def4c87913765b840fe5700bca812ce9e40ea1b24553dbbb7789de3bc576c3","description":"Get container configuration, including pending changes.","extra":{"proxyto":"node"},"name":"vm_pending","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"delete":{"description":"Indicates a pending delete request if present and not 0.","enum":[],"extra":{},"maximum":2,"minimum":0,"optional":true,"properties":{},"type":"integer"},"key":{"description":"Configuration option name.","enum":[],"extra":{},"properties":{},"type":"string"},"pending":{"description":"Pending value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"value":{"description":"Current value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/pending"},{"extra":{},"methods":[{"allow_token":true,"checksum":"105aec7d23f0f3955a25470fc7adab20920971a64e877498886c5b45af215e71","description":"Resize a container mount point.","extra":{"proxyto":"node"},"name":"resize_vm","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The disk you want to resize.","enum":["rootfs","mp0","mp1","mp2","mp3","mp4","mp5","mp6","mp7","mp8","mp9","mp10","mp11","mp12","mp13","mp14","mp15","mp16","mp17","mp18","mp19","mp20","mp21","mp22","mp23","mp24","mp25","mp26","mp27","mp28","mp29","mp30","mp31","mp32","mp33","mp34","mp35","mp36","mp37","mp38","mp39","mp40","mp41","mp42","mp43","mp44","mp45","mp46","mp47","mp48","mp49","mp50","mp51","mp52","mp53","mp54","mp55","mp56","mp57","mp58","mp59","mp60","mp61","mp62","mp63","mp64","mp65","mp66","mp67","mp68","mp69","mp70","mp71","mp72","mp73","mp74","mp75","mp76","mp77","mp78","mp79","mp80","mp81","mp82","mp83","mp84","mp85","mp86","mp87","mp88","mp89","mp90","mp91","mp92","mp93","mp94","mp95","mp96","mp97","mp98","mp99","mp100","mp101","mp102","mp103","mp104","mp105","mp106","mp107","mp108","mp109","mp110","mp111","mp112","mp113","mp114","mp115","mp116","mp117","mp118","mp119","mp120","mp121","mp122","mp123","mp124","mp125","mp126","mp127","mp128","mp129","mp130","mp131","mp132","mp133","mp134","mp135","mp136","mp137","mp138","mp139","mp140","mp141","mp142","mp143","mp144","mp145","mp146","mp147","mp148","mp149","mp150","mp151","mp152","mp153","mp154","mp155","mp156","mp157","mp158","mp159","mp160","mp161","mp162","mp163","mp164","mp165","mp166","mp167","mp168","mp169","mp170","mp171","mp172","mp173","mp174","mp175","mp176","mp177","mp178","mp179","mp180","mp181","mp182","mp183","mp184","mp185","mp186","mp187","mp188","mp189","mp190","mp191","mp192","mp193","mp194","mp195","mp196","mp197","mp198","mp199","mp200","mp201","mp202","mp203","mp204","mp205","mp206","mp207","mp208","mp209","mp210","mp211","mp212","mp213","mp214","mp215","mp216","mp217","mp218","mp219","mp220","mp221","mp222","mp223","mp224","mp225","mp226","mp227","mp228","mp229","mp230","mp231","mp232","mp233","mp234","mp235","mp236","mp237","mp238","mp239","mp240","mp241","mp242","mp243","mp244","mp245","mp246","mp247","mp248","mp249","mp250","mp251","mp252","mp253","mp254","mp255"],"extra":{},"properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The new size. With the '+' sign the value is added to the actual size of the volume and without it, the value is taken as an absolute one. Shrinking disk size is not supported.","enum":[],"extra":{},"pattern":"\\+?\\d+(\\.\\d+)?[KMGT]?","properties":{},"type":"string"},"name":"size"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/resize"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4d311cc5db4c24ed1db63ef58b0d8f8e72b579d6828347fd89059bf258f8210e","description":"Read VM RRD statistics (returns PNG)","extra":{},"name":"rrd","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The list of datasources you want to display.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"ds"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/rrd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"53eace25a11ab03d9980fc2e58377060dd11abc1fa75a694adf1f2b2a88dcdf0","description":"Read VM RRD statistics","extra":{},"name":"rrddata","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/rrddata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3938e62f442f3c60a7df8f01428af01e4617ec9ba8fa5556d7519de159d7e483","description":"List all snapshots.","extra":{"proxyto":"node"},"name":"list","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"description":{"description":"Snapshot description.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Snapshot identifier. Value 'current' identifies the current VM.","enum":[],"extra":{},"properties":{},"type":"string"},"parent":{"description":"Parent snapshot identifier.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"snaptime":{"description":"Snapshot creation time","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"a0d4ab4772fea3e50e0d81bb7fb546db0d98690f7beadf0a9919dba46f6da8a0","description":"Snapshot a container.","extra":{"proxyto":"node"},"name":"snapshot","parameters":[{"definition":{"description":"A textual description or comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/snapshot"},{"extra":{},"methods":[{"allow_token":true,"checksum":"96f3395bd45be05f38e53134431646f83ee524e6c21b171a8b2db48c9680746d","description":"Delete a LXC snapshot.","extra":{"proxyto":"node"},"name":"delsnapshot","parameters":[{"definition":{"description":"For removal from config file, even if removing disk snapshots fails.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"3543f6f025f3e8edb235d3a81de6bc9ae888696632b72c8a0358c30d67d096cb","description":"","extra":{},"name":"snapshot_cmd_idx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cmd}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2e4c3ffc0a572cde350f82c1ed21f7483bdc0b55b3350b6c629ad4a87fce8660","description":"Get snapshot configuration","extra":{"proxyto":"node"},"name":"get_snapshot_config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback","VM.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"229bac50088cfccbb485c9371b58bfc8d8a4beddcc04c2ef4a88af7a288e62dc","description":"Update snapshot metadata.","extra":{"proxyto":"node"},"name":"update_snapshot_config","parameters":[{"definition":{"description":"A textual description or comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7af4e5f9cd7049ceafa134e087222112d92fb5bfdb401716d5f0100abf21bb5c","description":"Rollback LXC state to specified snapshot.","extra":{"proxyto":"node"},"name":"rollback","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7f47a7c211dc02e8f33814e4037ecadcbd23cc44b4053260952a901ddcd8207d","description":"Returns a SPICE configuration to connect to the CT.","extra":{"proxyto":"node"},"name":"spiceproxy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).","enum":[],"extra":{"typetext":""},"format":"address","optional":true,"properties":{},"type":"string"},"name":"proxy"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"description":"Returned values can be directly passed to the 'remote-viewer' application.","enum":[],"extra":{"additionalProperties":1},"properties":{"host":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"enum":[],"extra":{},"properties":{},"type":"string"},"proxy":{"enum":[],"extra":{},"properties":{},"type":"string"},"tls-port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/spiceproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"94a0d535add5f584338da3a56b0765094683ec9f207cd53a95a4014fc19acdf6","description":"Directory index","extra":{"proxyto":"node"},"name":"vmcmdidx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3ceca17d631c8ea13a356778f4cf9faffcf1638cca0f334e8e39212bff6770dc","description":"Get virtual machine status.","extra":{"proxyto":"node"},"name":"vm_status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"cpus":{"description":"Maximum usable CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"ha":{"description":"HA manager service status.","enum":[],"extra":{},"properties":{},"type":"object"},"lock":{"description":"The current config lock, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxdisk":{"description":"Root disk size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Maximum memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxswap":{"description":"Maximum SWAP memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"name":{"description":"Container name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"status":{"description":"LXC Container status.","enum":["stopped","running"],"extra":{},"properties":{},"type":"string"},"tags":{"description":"The current configured tags, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"uptime":{"description":"Uptime.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/status/current"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3d30165bb34e86114bf39cb3a773f1d311f4a959da2997ce8498ef72e1304c66","description":"Reboot the container by shutting it down, and starting it again. Applies pending changes.","extra":{"proxyto":"node"},"name":"vm_reboot","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Wait maximal timeout seconds for the shutdown.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/reboot"},{"extra":{},"methods":[{"allow_token":true,"checksum":"57fbd090b0d3e57bfbdb9880c010907b98b7f014167ffd8c45356ae92ee49779","description":"Resume the container.","extra":{"proxyto":"node"},"name":"vm_resume","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/resume"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8c8a8ded3ac655846cd0d5a9f6336b3c6c19de8b72bd15fb881c3a811f0b44b4","description":"Shutdown the container. This will trigger a clean shutdown of the container, see lxc-stop(1) for details.","extra":{"proxyto":"node"},"name":"vm_shutdown","parameters":[{"definition":{"default":0,"description":"Make sure the Container stops.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"forceStop"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":60,"description":"Wait maximal timeout seconds.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/shutdown"},{"extra":{},"methods":[{"allow_token":true,"checksum":"74e1347597f095190b87ed4fc37f244762885d35b6f0ae1132c1b290d50587be","description":"Start the container.","extra":{"proxyto":"node"},"name":"vm_start","parameters":[{"definition":{"default":0,"description":"If set, enables very verbose debug log-level on start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"debug"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3588eb70dcef945b2a345ff3604b01203860fc53a231a91f155b3f0d454509a5","description":"Stop the container. This will abruptly stop all processes running in the container.","extra":{"proxyto":"node"},"name":"vm_stop","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/stop"},{"extra":{},"methods":[{"allow_token":true,"checksum":"71a97fcae94618323ddbb26a1a73f3b8ff02bfd046bd6ce4efa6dbcba8318974","description":"Suspend the container.","extra":{"proxyto":"node"},"name":"vm_suspend","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/suspend"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9e6329edbc164d2926eda1f33b0d65022b8435d588b1d0132965b4d53dc9a022","description":"Create a Template.","extra":{"proxyto":"node"},"name":"template","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permissions on /vms/{vmid}","expression":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/template"},{"extra":{},"methods":[{"allow_token":true,"checksum":"83d05bc119e943385f59c7b476b453d78f4cb3511a4179f137ca3eb37ccd9f22","description":"Creates a TCP proxy connection.","extra":{},"name":"termproxy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/termproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"22e8e54db027cc564d07db10ec8bf1e60554c5fb0f7080768157783ace4e297b","description":"Creates a TCP VNC proxy connections.","extra":{},"name":"vncproxy","parameters":[{"definition":{"description":"sets the height of the console in pixels.","enum":[],"extra":{"typetext":" (16 - 2160)"},"maximum":2160,"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"height"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"use websocket instead of standard VNC.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"websocket"},{"definition":{"description":"sets the width of the console in pixels.","enum":[],"extra":{"typetext":" (16 - 4096)"},"maximum":4096,"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"width"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"cert":{"enum":[],"extra":{},"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/vncproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ee391a9db15bf946d3fcf3622e765d731bb78079d2394c583723f26e79101ac5","description":"Opens a weksocket for VNC traffic.","extra":{},"name":"vncwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Port number returned by previous vncproxy call.","enum":[],"extra":{"typetext":" (5900 - 5999)"},"maximum":5999,"minimum":5900,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Ticket from previous call to vncproxy.","enum":[],"extra":{"typetext":""},"max_length":512,"properties":{},"type":"string"},"name":"vncticket"}],"permissions":{"description":"You also need to pass a valid ticket (vncticket).","expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/vncwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5f027dd32caf07e3b210e0018d9a26a0570b6e28310be8cb2bc2808ecdf0dbce","description":"Migrate all VMs and Containers.","extra":{"proxyto":"node"},"name":"migrateall","parameters":[{"definition":{"description":"Maximal number of parallel migration job. If not set use 'max_workers' from datacenter.cfg, one of both must be set!","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxworkers"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Only consider Guests with these IDs.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"},{"definition":{"description":"Enable live storage migration for local disk","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"with-local-disks"}],"permissions":{"expression":{"check":["perm","/",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/migrateall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c2c207a7e8a4df2370ac547d2a570d636677faa99ba285adbe6298dde17efefc","description":"Read tap/vm network device interface counters","extra":{"proxyto":"node"},"name":"netstat","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/netstat"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3de07e746f474e02ab38c834d3571d70c15aa5d66e4a80d73f9f67876bcd5bfc","description":"Revert network configuration changes.","extra":{"proxyto":"node"},"name":"revert_network_changes","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"46c1567fc0f13080215d5ae833706f8b69c3a836146ddcde0bbf4e73544b199f","description":"List available networks","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list specific interface types.","enum":["bridge","bond","eth","alias","vlan","OVSBridge","OVSBond","OVSPort","OVSIntPort","any_bridge"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{iface}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"369cd63b33c3fe2031b9eaed330a1a25d9993d8890c291e86dcc811334d48f7c","description":"Create network device configuration","extra":{"proxyto":"node"},"name":"create_network","parameters":[{"definition":{"description":"IP address.","enum":[],"extra":{"requires":"netmask","typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"address"},{"definition":{"description":"IP address.","enum":[],"extra":{"requires":"netmask6","typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"address6"},{"definition":{"description":"Automatically start interface on boot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Specify the primary interface for active-backup bond.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"bond-primary"},{"definition":{"description":"Bonding mode.","enum":["balance-rr","active-backup","balance-xor","broadcast","802.3ad","balance-tlb","balance-alb","balance-slb","lacp-balance-slb","lacp-balance-tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bond_mode"},{"definition":{"description":"Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.","enum":["layer2","layer2+3","layer3+4"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bond_xmit_hash_policy"},{"definition":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"bridge_ports"},{"definition":{"description":"Enable bridge vlan support.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bridge_vlan_aware"},{"definition":{"description":"IPv4 CIDR.","enum":[],"extra":{"typetext":""},"format":"CIDRv4","optional":true,"properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IPv6 CIDR.","enum":[],"extra":{"typetext":""},"format":"CIDRv6","optional":true,"properties":{},"type":"string"},"name":"cidr6"},{"definition":{"description":"Comments","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comments"},{"definition":{"description":"Comments","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comments6"},{"definition":{"description":"Default gateway address.","enum":[],"extra":{"typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"gateway"},{"definition":{"description":"Default ipv6 gateway address.","enum":[],"extra":{"typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"gateway6"},{"definition":{"description":"Network interface name.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"MTU.","enum":[],"extra":{"typetext":" (1280 - 65520)"},"maximum":65520,"minimum":1280,"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"Network mask.","enum":[],"extra":{"requires":"address","typetext":""},"format":"ipv4mask","optional":true,"properties":{},"type":"string"},"name":"netmask"},{"definition":{"description":"Network mask.","enum":[],"extra":{"requires":"address6","typetext":" (0 - 128)"},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"netmask6"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"ovs_bonds"},{"definition":{"description":"The OVS bridge associated with a OVS port. This is required when you create an OVS port.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"ovs_bridge"},{"definition":{"description":"OVS interface options.","enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"ovs_options"},{"definition":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"ovs_ports"},{"definition":{"description":"Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)","enum":[],"extra":{"typetext":" (1 - 4094)"},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"ovs_tag"},{"definition":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"slaves"},{"definition":{"description":"Network interface type","enum":["bridge","bond","eth","alias","vlan","OVSBridge","OVSBond","OVSPort","OVSIntPort","unknown"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"vlan-id for a custom named vlan interface (ifupdown2 only).","enum":[],"extra":{"typetext":" (1 - 4094)"},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vlan-id"},{"definition":{"description":"Specify the raw interface for the vlan interface.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"vlan-raw-device"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"5c5bb8977f0eeef180ddd9a799bd358f22ac79b3f4b58c6f1f197e7659aaabb9","description":"Reload network configuration","extra":{"proxyto":"node"},"name":"reload_network_config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/network"},{"extra":{},"methods":[{"allow_token":true,"checksum":"32c344b0dfe6220c53d77420aa2694e1bc65998071ee6a33024bccd2265550f3","description":"Delete network device configuration","extra":{"proxyto":"node"},"name":"delete_network","parameters":[{"definition":{"description":"Network interface name.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"91ab56660b1db09d5d12a3a1739ea872acc81e6d3a0f84993fa51ea56b78dea3","description":"Read network device configuration","extra":{"proxyto":"node"},"name":"network_config","parameters":[{"definition":{"description":"Network interface name.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"method":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"43d6e45e69f551627fa62b7c956dc9b0cdec5cb29e90d5bc265bf7fbdf4ce8fd","description":"Update network device configuration","extra":{"proxyto":"node"},"name":"update_network","parameters":[{"definition":{"description":"IP address.","enum":[],"extra":{"requires":"netmask","typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"address"},{"definition":{"description":"IP address.","enum":[],"extra":{"requires":"netmask6","typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"address6"},{"definition":{"description":"Automatically start interface on boot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Specify the primary interface for active-backup bond.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"bond-primary"},{"definition":{"description":"Bonding mode.","enum":["balance-rr","active-backup","balance-xor","broadcast","802.3ad","balance-tlb","balance-alb","balance-slb","lacp-balance-slb","lacp-balance-tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bond_mode"},{"definition":{"description":"Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.","enum":["layer2","layer2+3","layer3+4"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bond_xmit_hash_policy"},{"definition":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"bridge_ports"},{"definition":{"description":"Enable bridge vlan support.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bridge_vlan_aware"},{"definition":{"description":"IPv4 CIDR.","enum":[],"extra":{"typetext":""},"format":"CIDRv4","optional":true,"properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IPv6 CIDR.","enum":[],"extra":{"typetext":""},"format":"CIDRv6","optional":true,"properties":{},"type":"string"},"name":"cidr6"},{"definition":{"description":"Comments","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comments"},{"definition":{"description":"Comments","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comments6"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Default gateway address.","enum":[],"extra":{"typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"gateway"},{"definition":{"description":"Default ipv6 gateway address.","enum":[],"extra":{"typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"gateway6"},{"definition":{"description":"Network interface name.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"MTU.","enum":[],"extra":{"typetext":" (1280 - 65520)"},"maximum":65520,"minimum":1280,"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"Network mask.","enum":[],"extra":{"requires":"address","typetext":""},"format":"ipv4mask","optional":true,"properties":{},"type":"string"},"name":"netmask"},{"definition":{"description":"Network mask.","enum":[],"extra":{"requires":"address6","typetext":" (0 - 128)"},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"netmask6"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"ovs_bonds"},{"definition":{"description":"The OVS bridge associated with a OVS port. This is required when you create an OVS port.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"ovs_bridge"},{"definition":{"description":"OVS interface options.","enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"ovs_options"},{"definition":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"ovs_ports"},{"definition":{"description":"Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)","enum":[],"extra":{"typetext":" (1 - 4094)"},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"ovs_tag"},{"definition":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"slaves"},{"definition":{"description":"Network interface type","enum":["bridge","bond","eth","alias","vlan","OVSBridge","OVSBond","OVSPort","OVSIntPort","unknown"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"vlan-id for a custom named vlan interface (ifupdown2 only).","enum":[],"extra":{"typetext":" (1 - 4094)"},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vlan-id"},{"definition":{"description":"Specify the raw interface for the vlan interface.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"vlan-raw-device"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/network/{iface}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"559e8ec399bd3e4df7463ab4edfa3b3baa77865c745f19f8be3821bf0ca90446","description":"Virtual machine index (per node).","extra":{"proxyto":"node"},"name":"vmlist","parameters":[{"definition":{"description":"Determine the full status of active VMs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Only list VMs where you have VM.Audit permissons on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{vmid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cpus":{"description":"Maximum usable CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"lock":{"description":"The current config lock, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxdisk":{"description":"Root disk size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Maximum memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"name":{"description":"VM name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pid":{"description":"PID of running qemu process.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"qmpstatus":{"description":"Qemu QMP agent status.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"running-machine":{"description":"The currently running machine type (if running).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"running-qemu":{"description":"The currently running QEMU version (if running).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"status":{"description":"Qemu process status.","enum":["stopped","running"],"extra":{},"properties":{},"type":"string"},"tags":{"description":"The current configured tags, if any","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"uptime":{"description":"Uptime.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"5ad2d489ab498f987cfb6da36a7e70fba07ae7193b2f6685de01ffc387f30106","description":"Create or restore a virtual machine.","extra":{"proxyto":"node"},"name":"create_vm","parameters":[{"definition":{"default":1,"description":"Enable/disable ACPI.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"acpi"},{"definition":{"description":"Enable/disable Qemu GuestAgent and its properties.","enum":[],"extra":{"typetext":"[enabled=]<1|0> [,fstrim_cloned_disks=<1|0>] [,type=]"},"format":{"enabled":{"default":0,"default_key":1,"description":"Enable/disable Qemu GuestAgent.","type":"boolean"},"fstrim_cloned_disks":{"default":0,"description":"Run fstrim after moving a disk or migrating the VM.","optional":1,"type":"boolean"},"type":{"default":"virtio","description":"Select the agent type","enum":["virtio","isa"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"agent"},{"definition":{"description":"Virtual processor architecture. Defaults to the host.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"description":"The backup archive. Either the file system path to a .tar or .vma file (use '-' to pipe data from stdin) or a proxmox storage backup volume identifier.","enum":[],"extra":{"typetext":""},"max_length":255,"optional":true,"properties":{},"type":"string"},"name":"archive"},{"definition":{"description":"Arbitrary arguments passed to kvm.","enum":[],"extra":{"typetext":"","verbose_description":"Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -no-hpet\n\nNOTE: this option is for experts only.\n"},"optional":true,"properties":{},"type":"string"},"name":"args"},{"definition":{"description":"Configure a audio device, useful in combination with QXL/Spice.","enum":[],"extra":{"typetext":"device= [,driver=]"},"format":{"device":{"description":"Configure an audio device.","enum":["ich9-intel-hda","intel-hda","AC97"],"type":"string"},"driver":{"default":"spice","description":"Driver backend for the audio device.","enum":["spice","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"audio0"},{"definition":{"default":0,"description":"Automatic restart after crash (currently ignored).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Amount of target RAM for the VM in MB. Using zero disables the ballon driver.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"balloon"},{"definition":{"default":"seabios","description":"Select BIOS implementation.","enum":["seabios","ovmf"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bios"},{"definition":{"description":"Specify guest boot order. Use with 'order=', usage with no key or 'legacy=' is deprecated.","enum":[],"extra":{"typetext":"[[legacy=]<[acdn]{1,4}>] [,order=]"},"format":"pve-qm-boot","optional":true,"properties":{},"type":"string"},"name":"boot"},{"definition":{"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","enum":[],"extra":{},"format":"pve-qm-bootdisk","optional":true,"pattern":"(ide|sata|scsi|virtio)\\d+","properties":{},"type":"string"},"name":"bootdisk"},{"definition":{"default":"restore limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"This is an alias for option -ide2","enum":[],"extra":{"typetext":""},"format":"pve-qm-ide","optional":true,"properties":{},"type":"string"},"name":"cdrom"},{"definition":{"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","enum":[],"extra":{"typetext":"[meta=] [,network=] [,user=]"},"format":"pve-qm-cicustom","optional":true,"properties":{},"type":"string"},"name":"cicustom"},{"definition":{"description":"cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cipassword"},{"definition":{"description":"Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.","enum":["configdrive2","nocloud","opennebula"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"citype"},{"definition":{"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ciuser"},{"definition":{"default":1,"description":"The number of cores per socket.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"description":"Emulated CPU type.","enum":[],"extra":{"typetext":"[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]"},"format":"pve-vm-cpu-conf","optional":true,"properties":{},"type":"string"},"name":"cpu"},{"definition":{"default":0,"description":"Limit of CPU usage.","enum":[],"extra":{"typetext":" (0 - 128)","verbose_description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit."},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":1024,"description":"CPU weight for a VM.","enum":[],"extra":{"typetext":" (2 - 262144)","verbose_description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs."},"maximum":262144,"minimum":2,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"description":"Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Configure a Disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead.","enum":[],"extra":{"typetext":"[file=] [,format=] [,size=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"efidisk0"},{"definition":{"description":"Allow to overwrite existing VM.","enum":[],"extra":{"requires":"archive","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Freeze CPU at startup (use 'c' monitor command to start execution).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"freeze"},{"definition":{"description":"Script that will be executed during various steps in the vms lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Map host PCI devices into guest.","enum":[],"extra":{"typetext":"[host=] [,legacy-igd=<1|0>] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,x-vga=<1|0>]","verbose_description":"Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"format":"pve-qm-hostpci","optional":true,"properties":{},"type":"string"},"name":"hostpci[n]"},{"definition":{"default":"network,disk,usb","description":"Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory' and 'usb'. Use '0' to disable hotplug completely. Value '1' is an alias for the default 'network,disk,usb'.","enum":[],"extra":{"typetext":""},"format":"pve-hotplug-features","optional":true,"properties":{},"type":"string"},"name":"hotplug"},{"definition":{"description":"Enable/disable hugepages memory.","enum":["any","2","1024"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"hugepages"},{"definition":{"description":"Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"model":{"description":"The drive's reported model name, url-encoded, up to 40 bytes long.","format":"urlencoded","format_description":"model","maxLength":120,"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"ide[n]"},{"definition":{"description":"cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n","enum":[],"extra":{"typetext":"[gw=] [,gw6=] [,ip=] [,ip6=]"},"format":"pve-qm-ipconfig","optional":true,"properties":{},"type":"string"},"name":"ipconfig[n]"},{"definition":{"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host.","enum":[],"extra":{"typetext":"size= [,name=]"},"format":{"name":{"description":"The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.","format_description":"string","optional":1,"pattern":"[a-zA-Z0-9\\-]+","type":"string"},"size":{"description":"The size of the file in MB.","minimum":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"ivshmem"},{"definition":{"default":0,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keephugepages"},{"definition":{"description":"Keybord layout for vnc server. Default is read from the '/etc/pve/datacenter.cfg' configuration file.It should not be necessary to set it.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"keyboard"},{"definition":{"default":1,"description":"Enable/disable KVM hardware virtualization.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"kvm"},{"definition":{"description":"Start the VM immediately from the backup and restore in background. PBS only.","enum":[],"extra":{"requires":"archive","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"live-restore"},{"definition":{"description":"Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"localtime"},{"definition":{"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"description":"Specifies the Qemu machine type.","enum":[],"extra":{},"max_length":40,"optional":true,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","properties":{},"type":"string"},"name":"machine"},{"definition":{"default":512,"description":"Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.","enum":[],"extra":{"typetext":" (16 - N)"},"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"memory"},{"definition":{"default":0.1,"description":"Set maximum tolerated downtime (in seconds) for migrations.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"migrate_downtime"},{"definition":{"default":0,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"migrate_speed"},{"definition":{"description":"Set a name for the VM. Only used on the configuration web interface.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"cloud-init: Sets DNS server IP address for a container. Create will'\n\t .' automatically use the setting from the host if neither searchdomain nor nameserver'\n\t .' are set.","enum":[],"extra":{"typetext":""},"format":"address-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specify network devices.","enum":[],"extra":{"typetext":"[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]"},"format":{"bridge":{"description":"Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n","format_description":"bridge","optional":1,"pattern":"[-_.\\w\\d]+","type":"string"},"e1000":{"alias":"macaddr","keyAlias":"model"},"e1000-82540em":{"alias":"macaddr","keyAlias":"model"},"e1000-82544gc":{"alias":"macaddr","keyAlias":"model"},"e1000-82545em":{"alias":"macaddr","keyAlias":"model"},"firewall":{"description":"Whether this interface should be protected by the firewall.","optional":1,"type":"boolean"},"i82551":{"alias":"macaddr","keyAlias":"model"},"i82557b":{"alias":"macaddr","keyAlias":"model"},"i82559er":{"alias":"macaddr","keyAlias":"model"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"macaddr":{"description":"MAC address. That address must be unique withing your network. This is automatically generated if not specified.","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"model":{"default_key":1,"description":"Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.","enum":["rtl8139","ne2k_pci","e1000","pcnet","virtio","ne2k_isa","i82551","i82557b","i82559er","vmxnet3","e1000-82540em","e1000-82544gc","e1000-82545em"],"type":"string"},"mtu":{"description":"Force MTU, for VirtIO only. Set to '1' to use the bridge MTU","maximum":65520,"minimum":1,"optional":1,"type":"integer"},"ne2k_isa":{"alias":"macaddr","keyAlias":"model"},"ne2k_pci":{"alias":"macaddr","keyAlias":"model"},"pcnet":{"alias":"macaddr","keyAlias":"model"},"queues":{"description":"Number of packet queues to be used on the device.","maximum":16,"minimum":0,"optional":1,"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":0,"optional":1,"type":"number"},"rtl8139":{"alias":"macaddr","keyAlias":"model"},"tag":{"description":"VLAN tag to apply to packets on this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN trunks to pass through this interface.","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"virtio":{"alias":"macaddr","keyAlias":"model"},"vmxnet3":{"alias":"macaddr","keyAlias":"model"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Enable/disable NUMA.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"numa"},{"definition":{"description":"NUMA topology.","enum":[],"extra":{"typetext":"cpus= [,hostnodes=] [,memory=] [,policy=]"},"format":{"cpus":{"description":"CPUs accessing this NUMA node.","format_description":"id[-id];...","pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"hostnodes":{"description":"Host NUMA nodes to use.","format_description":"id[-id];...","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"memory":{"description":"Amount of memory this NUMA node provides.","optional":1,"type":"number"},"policy":{"description":"NUMA allocation policy.","enum":["preferred","bind","interleave"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"numa[n]"},{"definition":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","l24","l26","solaris"],"extra":{"verbose_description":"Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 5.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n"},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"description":"Map host parallel devices (n is 0 to 2).","enum":[],"extra":{"verbose_description":"Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"/dev/parport\\d+|/dev/usb/lp\\d+","properties":{},"type":"string"},"name":"parallel[n]"},{"definition":{"description":"Add the VM to the specified pool.","enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"default":0,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"default":1,"description":"Allow reboot. If set to '0' the VM exit on reboot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"reboot"},{"definition":{"description":"Configure a VirtIO-based Random Number Generator.","enum":[],"extra":{"typetext":"[source=] [,max_bytes=] [,period=]"},"format":{"max_bytes":{"default":1024,"description":"Maximum bytes of entropy injected into the guest every 'period' milliseconds. Prefer a lower value when using /dev/random as source. Use 0 to disable limiting (potentially dangerous!).","optional":1,"type":"integer"},"period":{"default":1000,"description":"Every 'period' milliseconds the entropy-injection quota is reset, allowing the guest to retrieve another 'max_bytes' of entropy.","optional":1,"type":"integer"},"source":{"default_key":1,"description":"The file on the host to gather entropy from. In most cases /dev/urandom should be preferred over /dev/random to avoid entropy-starvation issues on the host. Using urandom does *not* decrease security in any meaningful way, as it's still seeded from real entropy, and the bytes provided will most likely be mixed with real entropy on the guest as well. /dev/hwrng can be used to pass through a hardware RNG from the host.","enum":["/dev/urandom","/dev/random","/dev/hwrng"],"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"rng0"},{"definition":{"description":"Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"sata[n]"},{"definition":{"description":"Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,queues=] [,replicate=<1|0>] [,rerror=] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"queues":{"description":"Number of queues.","minimum":2,"optional":1,"type":"integer"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"scsiblock":{"default":0,"description":"whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"scsi[n]"},{"definition":{"default":"lsi","description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scsihw"},{"definition":{"description":"cloud-init: Sets DNS search domains for a container. Create will'\n\t .' automatically use the setting from the host if neither searchdomain nor nameserver'\n\t .' are set.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Create a serial device inside the VM (n is 0 to 3)","enum":[],"extra":{"verbose_description":"Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"(/dev/.+|socket)","properties":{},"type":"string"},"name":"serial[n]"},{"definition":{"default":1000,"description":"Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.","enum":[],"extra":{"typetext":" (0 - 50000)"},"maximum":50000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"shares"},{"definition":{"description":"Specify SMBIOS type 1 fields.","enum":[],"extra":{"typetext":"[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]"},"format":"pve-qm-smbios1","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"smbios1"},{"definition":{"default":1,"description":"The number of CPUs. Please use option -sockets instead.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"smp"},{"definition":{"default":1,"description":"The number of CPU sockets.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"sockets"},{"definition":{"description":"Configure additional enhancements for SPICE.","enum":[],"extra":{"typetext":"[foldersharing=<1|0>] [,videostreaming=]"},"format":{"foldersharing":{"default":"0","description":"Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.","optional":1,"type":"boolean"},"videostreaming":{"default":"off","description":"Enable video streaming. Uses compression for detected video streams.","enum":["off","all","filter"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"spice_enhancements"},{"definition":{"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{"typetext":""},"format":"urlencoded","optional":true,"properties":{},"type":"string"},"name":"sshkeys"},{"definition":{"default":0,"description":"Start VM after it was created successfully.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"start"},{"definition":{"default":"now","description":"Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.","enum":[],"extra":{"typetext":"(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)"},"optional":true,"pattern":"(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)","properties":{},"type":"string"},"name":"startdate"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"description":"Default storage.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"default":1,"description":"Enable/disable the USB tablet device.","enum":[],"extra":{"typetext":"","verbose_description":"Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)."},"optional":true,"properties":{},"type":"boolean"},"name":"tablet"},{"definition":{"description":"Tags of the VM. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable time drift fix.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tdf"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Assign a unique random ethernet address.","enum":[],"extra":{"requires":"archive","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"unique"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[file=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id","format_description":"volume","type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"Configure an USB device (n is 0 to 4).","enum":[],"extra":{"typetext":"[host=] [,usb3=<1|0>]"},"format":{"host":{"default_key":1,"description":"The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadeciaml numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n","format":"pve-qm-usb-device","format_description":"HOSTUSBDEVICE|spice","type":"string"},"usb3":{"default":0,"description":"Specifies whether if given host option is a USB3 device or port.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"usb[n]"},{"definition":{"default":0,"description":"Number of hotplugged vcpus.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vcpus"},{"definition":{"description":"Configure the VGA hardware.","enum":[],"extra":{"typetext":"[[type=]] [,memory=]","verbose_description":"Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal."},"format":{"memory":{"description":"Sets the VGA memory (in MiB). Has no effect with serial display.","maximum":512,"minimum":4,"optional":1,"type":"integer"},"type":{"default":"std","default_key":1,"description":"Select the VGA type.","enum":["cirrus","qxl","qxl2","qxl3","qxl4","none","serial0","serial1","serial2","serial3","std","virtio","vmware"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"vga"},{"definition":{"description":"Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"virtio[n]"},{"definition":{"default":"1 (autogenerated)","description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","enum":[],"extra":{"format_description":"UUID","verbose_description":"The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file."},"optional":true,"pattern":"(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])","properties":{},"type":"string"},"name":"vmgenid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Default storage for VM state volumes/files.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"vmstatestorage"},{"definition":{"description":"Create a virtual hardware watchdog device.","enum":[],"extra":{"typetext":"[[model=]] [,action=]","verbose_description":"Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)"},"format":"pve-qm-watchdog","optional":true,"properties":{},"type":"string"},"name":"watchdog"}],"permissions":{"description":"You need 'VM.Allocate' permissions on /vms/{vmid} or on the VM pool /pool/{pool}. For restore (option 'archive'), it is enough if the user has 'VM.Backup' permission and the VM already exists. If you create disks you need 'Datastore.AllocateSpace' on any used storage.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d66ea62847a5792cacb5935ee3f8d27afe9f2a43aabdb68ca559278b793b94bf","description":"Destroy the VM and all used/owned volumes. Removes any VM specific permissions and firewall rules","extra":{"proxyto":"node"},"name":"destroy_vm","parameters":[{"definition":{"default":1,"description":"If set, destroy additionally all disks not referenced in the config but with a matching VMID from all enabled storages.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"destroy-unreferenced-disks"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Remove VMID from configurations, like backup & replication jobs and HA.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"purge"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"fa055338b801bce39c739df867cff19ab708c821f45e2cd7c6ee100546aea617","description":"Directory index","extra":{"proxyto":"node"},"name":"vmdiridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ffe91f66c16b13a829b7cf81c08af43854c39ea3e35a0554204da741ba42bb8b","description":"Qemu Agent command index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"Returns the list of Qemu Agent commands","enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"7c2139b8c7a7038cb63e91f1670bf564e2880075a94afe81acbd8808e5df8aab","description":"Execute Qemu Guest Agent commands.","extra":{"proxyto":"node"},"name":"agent","parameters":[{"definition":{"description":"The QGA command.","enum":["fsfreeze-freeze","fsfreeze-status","fsfreeze-thaw","fstrim","get-fsinfo","get-host-name","get-memory-block-info","get-memory-blocks","get-osinfo","get-time","get-timezone","get-users","get-vcpus","info","network-get-interfaces","ping","shutdown","suspend-disk","suspend-hybrid","suspend-ram"],"extra":{},"properties":{},"type":"string"},"name":"command"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1919fa6f3b3e4fe70c732bbdb3927d38365482e4033921906a4287113450505a","description":"Executes the given command in the vm via the guest-agent and returns an object with the pid.","extra":{"proxyto":"node"},"name":"exec","parameters":[{"definition":{"description":"The command as a list of program + arguments","enum":[],"extra":{"typetext":""},"format":"string-alist","optional":true,"properties":{},"type":"string"},"name":"command"},{"definition":{"description":"Data to pass as 'input-data' to the guest. Usually treated as STDIN to 'command'.","enum":[],"extra":{"typetext":""},"max_length":65536,"optional":true,"properties":{},"type":"string"},"name":"input-data"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"pid":{"description":"The PID of the process started by the guest-agent.","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/exec"},{"extra":{},"methods":[{"allow_token":true,"checksum":"744a2477f62419e715cd74402770a4628d821a96c211aaedf5d6074af82cbd5a","description":"Gets the status of the given pid started by the guest-agent","extra":{"proxyto":"node"},"name":"exec-status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The PID to query","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"pid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"err-data":{"description":"stderr of the process","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"err-truncated":{"description":"true if stderr was not fully captured","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"exitcode":{"description":"process exit code if it was normally terminated.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"exited":{"description":"Tells if the given command has exited yet.","enum":[],"extra":{},"properties":{},"type":"boolean"},"out-data":{"description":"stdout of the process","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"out-truncated":{"description":"true if stdout was not fully captured","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"signal":{"description":"signal number or exception code if the process was abnormally terminated.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/exec-status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6c1b6b1f964befa755c9f0c71f9ab72f3969c0ee7aed0683a4c073e0182fd98b","description":"Reads the given file via guest agent. Is limited to 16777216 bytes.","extra":{"proxyto":"node"},"name":"file-read","parameters":[{"definition":{"description":"The path to the file","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"file"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a `content` property.","enum":[],"extra":{},"properties":{"content":{"description":"The content of the file, maximum 16777216","enum":[],"extra":{},"properties":{},"type":"string"},"truncated":{"description":"If set to 1, the output is truncated and not complete","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/file-read"},{"extra":{},"methods":[{"allow_token":true,"checksum":"834ed21eb29cd93d3cf0a3358c60527bede9b37c6ac3bfb7049541f4f7a6fd8f","description":"Writes the given file via guest agent.","extra":{"proxyto":"node"},"name":"file-write","parameters":[{"definition":{"description":"The content to write into the file.","enum":[],"extra":{"typetext":""},"max_length":61440,"properties":{},"type":"string"},"name":"content"},{"definition":{"description":"The path to the file.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"file"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/file-write"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c28d21618be57ca1077632d96c9a1307a5dc56a98fb70095e197517d98382e79","description":"Execute fsfreeze-freeze.","extra":{"proxyto":"node"},"name":"fsfreeze-freeze","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze"},{"extra":{},"methods":[{"allow_token":true,"checksum":"94ea8c43248c9084afb23eb6981d541c188a770c9d45ba0c81a809f484d34e09","description":"Execute fsfreeze-status.","extra":{"proxyto":"node"},"name":"fsfreeze-status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ba7e0905312a35f9ed9b54a5d2f466764d482f20b1eb1e0c87b428cb1cc80b22","description":"Execute fsfreeze-thaw.","extra":{"proxyto":"node"},"name":"fsfreeze-thaw","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2c06bb7419c8dfeabc2a9f7ad57dccdbdb639c1e97f7076a266a72537699e4d4","description":"Execute fstrim.","extra":{"proxyto":"node"},"name":"fstrim","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/fstrim"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9925709188ca2e8228138a5f4b3f39786831a531b90ff5eb9c95939191b65ffe","description":"Execute get-fsinfo.","extra":{"proxyto":"node"},"name":"get-fsinfo","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-fsinfo"},{"extra":{},"methods":[{"allow_token":true,"checksum":"97fa3d29a33d517270e4e9f6cb42b84820b906b3d25290426da97dcd16f7ef0d","description":"Execute get-host-name.","extra":{"proxyto":"node"},"name":"get-host-name","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-host-name"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a03cce5e2343d9872b4e3d3afc1085ec3ef1975778a9fc2f1466b9a092e57e32","description":"Execute get-memory-block-info.","extra":{"proxyto":"node"},"name":"get-memory-block-info","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2ce6034fcef7cd88d4c5bc8e237aaea97ffdf7b608420d9f1567a5998c47ced2","description":"Execute get-memory-blocks.","extra":{"proxyto":"node"},"name":"get-memory-blocks","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"36d3b322e0596f046761eb102d6a4d4289e61f1a2516226e5ae55e12fa81870d","description":"Execute get-osinfo.","extra":{"proxyto":"node"},"name":"get-osinfo","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-osinfo"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5ee1af722313cc5a855977fd9886a3a605f809f44e9e7282bd0b22df6c18ecfe","description":"Execute get-time.","extra":{"proxyto":"node"},"name":"get-time","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-time"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1f45439fa6d0a5d768d276506153371ded53391eca506aef0d74cff5aee32074","description":"Execute get-timezone.","extra":{"proxyto":"node"},"name":"get-timezone","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-timezone"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e3a2e67e94d5c1108d9e604e3a87229c549243bf01e053bd2d95a1db06ea1255","description":"Execute get-users.","extra":{"proxyto":"node"},"name":"get-users","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-users"},{"extra":{},"methods":[{"allow_token":true,"checksum":"58343921431c44f8b47ddae6e015c065a705017450b82bcb02984b117e2a4cac","description":"Execute get-vcpus.","extra":{"proxyto":"node"},"name":"get-vcpus","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-vcpus"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a70d07c83af36feb6ff6c06084e36e0fc38b82cdb16d3e4d5033ebc14aa5b5ae","description":"Execute info.","extra":{"proxyto":"node"},"name":"info","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c1660e4d1ba26278dc1fc246560c4ced3189f8ca4f4db2ba5e24e90bc146f4eb","description":"Execute network-get-interfaces.","extra":{"proxyto":"node"},"name":"network-get-interfaces","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces"},{"extra":{},"methods":[{"allow_token":true,"checksum":"70759c6c57b459e7e55edd424c8529ba20c783b4aecb7aab600a57e2420da2fb","description":"Execute ping.","extra":{"proxyto":"node"},"name":"ping","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/ping"},{"extra":{},"methods":[{"allow_token":true,"checksum":"51598b3eef5745757d341759b910566de340887f06deb4d383f6d775cf8784a5","description":"Sets the password for the given user to the given password","extra":{"proxyto":"node"},"name":"set-user-password","parameters":[{"definition":{"default":0,"description":"set to 1 if the password has already been passed through crypt()","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"crypted"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The new password.","enum":[],"extra":{"typetext":""},"max_length":1024,"min_length":5,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"The user to set the password for.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"username"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/set-user-password"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b2fc0938c5e1b7ea6e10817e434fe094103366e4ebdef15354a4cbcedf112eca","description":"Execute shutdown.","extra":{"proxyto":"node"},"name":"shutdown","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/shutdown"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9e39e6d8b5266195f2f81e0414b442d1c39647c81881965e72c5805f2b6d487e","description":"Execute suspend-disk.","extra":{"proxyto":"node"},"name":"suspend-disk","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/suspend-disk"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1aeb5a294ce0ee9314e074d9c321bcaf37e7a35bcf3e239f03d70308c232ff12","description":"Execute suspend-hybrid.","extra":{"proxyto":"node"},"name":"suspend-hybrid","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e0f85b45b63334c20ddf91a6d89434b740c3a9305fa120ad6ed6c9573eb1212c","description":"Execute suspend-ram.","extra":{"proxyto":"node"},"name":"suspend-ram","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/suspend-ram"},{"extra":{},"methods":[{"allow_token":true,"checksum":"20e482b27ee16fa832fefc563fbba31b24e4c73c706a2e407cce44c0f2d55820","description":"Create a copy of virtual machine/template.","extra":{"proxyto":"node"},"name":"clone_vm","parameters":[{"definition":{"default":"clone limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"Description for the new VM.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Target format for file storage. Only valid for full clone.","enum":["raw","qcow2","vmdk"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"Create a full copy of all disks. This is always done when you clone a normal VM. For VM templates, we try to create a linked clone by default.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"},{"definition":{"description":"Set a name for the new VM.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"VMID for the clone.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"newid"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Add the new VM to the specified pool.","enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"Target storage for full clone.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Target node. Only allowed if the original VM is on shared storage.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions on /vms/{newid} (or on the VM pool /pool/{pool}). You also need 'Datastore.AllocateSpace' on any used storage.","expression":{"check":["and",["perm","/vms/{vmid}",["VM.Clone"]],["or",["perm","/vms/{newid}",["VM.Allocate"]],["perm","/pool/{pool}",["VM.Allocate"],"require_param","pool"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/clone"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2f6fd50c17e15dbe4418076618bd91a94157333bd8d9ee1763d366913d0436d5","description":"Get automatically generated cloudinit config.","extra":{"proxyto":"node"},"name":"cloudinit_generated_config_dump","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Config type.","enum":["user","network","meta"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/cloudinit/dump"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b9d3bebdc9a25b9cb016edf8c086ca84a395e3d225a993d766272202f2ce88ab","description":"Get the virtual machine configuration with pending configuration changes applied. Set the 'current' parameter to get the current configuration instead.","extra":{"proxyto":"node"},"name":"vm_config","parameters":[{"definition":{"default":0,"description":"Get current values (instead of pending values).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"current"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Fetch config values from given snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapshot"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"description":"The VM configuration.","enum":[],"extra":{},"properties":{"acpi":{"default":1,"description":"Enable/disable ACPI.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"agent":{"description":"Enable/disable Qemu GuestAgent and its properties.","enum":[],"extra":{},"format":{"enabled":{"default":0,"default_key":1,"description":"Enable/disable Qemu GuestAgent.","type":"boolean"},"fstrim_cloned_disks":{"default":0,"description":"Run fstrim after moving a disk or migrating the VM.","optional":1,"type":"boolean"},"type":{"default":"virtio","description":"Select the agent type","enum":["virtio","isa"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"arch":{"description":"Virtual processor architecture. Defaults to the host.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"args":{"description":"Arbitrary arguments passed to kvm.","enum":[],"extra":{"verbose_description":"Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -no-hpet\n\nNOTE: this option is for experts only.\n"},"optional":true,"properties":{},"type":"string"},"audio0":{"description":"Configure a audio device, useful in combination with QXL/Spice.","enum":[],"extra":{},"format":{"device":{"description":"Configure an audio device.","enum":["ich9-intel-hda","intel-hda","AC97"],"type":"string"},"driver":{"default":"spice","description":"Driver backend for the audio device.","enum":["spice","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"autostart":{"default":0,"description":"Automatic restart after crash (currently ignored).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"balloon":{"description":"Amount of target RAM for the VM in MB. Using zero disables the ballon driver.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"bios":{"default":"seabios","description":"Select BIOS implementation.","enum":["seabios","ovmf"],"extra":{},"optional":true,"properties":{},"type":"string"},"boot":{"description":"Specify guest boot order. Use with 'order=', usage with no key or 'legacy=' is deprecated.","enum":[],"extra":{},"format":"pve-qm-boot","optional":true,"properties":{},"type":"string"},"bootdisk":{"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","enum":[],"extra":{},"format":"pve-qm-bootdisk","optional":true,"pattern":"(ide|sata|scsi|virtio)\\d+","properties":{},"type":"string"},"cdrom":{"description":"This is an alias for option -ide2","enum":[],"extra":{"typetext":""},"format":"pve-qm-ide","optional":true,"properties":{},"type":"string"},"cicustom":{"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","enum":[],"extra":{},"format":"pve-qm-cicustom","optional":true,"properties":{},"type":"string"},"cipassword":{"description":"cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"citype":{"description":"Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.","enum":["configdrive2","nocloud","opennebula"],"extra":{},"optional":true,"properties":{},"type":"string"},"ciuser":{"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"cores":{"default":1,"description":"The number of cores per socket.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"cpu":{"description":"Emulated CPU type.","enum":[],"extra":{},"format":"pve-vm-cpu-conf","optional":true,"properties":{},"type":"string"},"cpulimit":{"default":0,"description":"Limit of CPU usage.","enum":[],"extra":{"verbose_description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit."},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"number"},"cpuunits":{"default":1024,"description":"CPU weight for a VM.","enum":[],"extra":{"verbose_description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs."},"maximum":262144,"minimum":2,"optional":true,"properties":{},"type":"integer"},"description":{"description":"Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"SHA1 digest of configuration file. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"properties":{},"type":"string"},"efidisk0":{"description":"Configure a Disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead.","enum":[],"extra":{},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"freeze":{"description":"Freeze CPU at startup (use 'c' monitor command to start execution).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"hookscript":{"description":"Script that will be executed during various steps in the vms lifetime.","enum":[],"extra":{},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"hostpci[n]":{"description":"Map host PCI devices into guest.","enum":[],"extra":{"verbose_description":"Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"format":"pve-qm-hostpci","optional":true,"properties":{},"type":"string"},"hotplug":{"default":"network,disk,usb","description":"Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory' and 'usb'. Use '0' to disable hotplug completely. Value '1' is an alias for the default 'network,disk,usb'.","enum":[],"extra":{},"format":"pve-hotplug-features","optional":true,"properties":{},"type":"string"},"hugepages":{"description":"Enable/disable hugepages memory.","enum":["any","2","1024"],"extra":{},"optional":true,"properties":{},"type":"string"},"ide[n]":{"description":"Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"model":{"description":"The drive's reported model name, url-encoded, up to 40 bytes long.","format":"urlencoded","format_description":"model","maxLength":120,"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"ipconfig[n]":{"description":"cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n","enum":[],"extra":{},"format":"pve-qm-ipconfig","optional":true,"properties":{},"type":"string"},"ivshmem":{"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host.","enum":[],"extra":{},"format":{"name":{"description":"The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.","format_description":"string","optional":1,"pattern":"[a-zA-Z0-9\\-]+","type":"string"},"size":{"description":"The size of the file in MB.","minimum":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"keephugepages":{"default":0,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"keyboard":{"description":"Keybord layout for vnc server. Default is read from the '/etc/pve/datacenter.cfg' configuration file.It should not be necessary to set it.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"kvm":{"default":1,"description":"Enable/disable KVM hardware virtualization.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"localtime":{"description":"Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"lock":{"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"],"extra":{},"optional":true,"properties":{},"type":"string"},"machine":{"description":"Specifies the Qemu machine type.","enum":[],"extra":{},"max_length":40,"optional":true,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","properties":{},"type":"string"},"memory":{"default":512,"description":"Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.","enum":[],"extra":{},"minimum":16,"optional":true,"properties":{},"type":"integer"},"migrate_downtime":{"default":0.1,"description":"Set maximum tolerated downtime (in seconds) for migrations.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"number"},"migrate_speed":{"default":0,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":{"description":"Set a name for the VM. Only used on the configuration web interface.","enum":[],"extra":{},"format":"dns-name","optional":true,"properties":{},"type":"string"},"nameserver":{"description":"cloud-init: Sets DNS server IP address for a container. Create will'\n\t .' automatically use the setting from the host if neither searchdomain nor nameserver'\n\t .' are set.","enum":[],"extra":{},"format":"address-list","optional":true,"properties":{},"type":"string"},"net[n]":{"description":"Specify network devices.","enum":[],"extra":{},"format":{"bridge":{"description":"Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n","format_description":"bridge","optional":1,"pattern":"[-_.\\w\\d]+","type":"string"},"e1000":{"alias":"macaddr","keyAlias":"model"},"e1000-82540em":{"alias":"macaddr","keyAlias":"model"},"e1000-82544gc":{"alias":"macaddr","keyAlias":"model"},"e1000-82545em":{"alias":"macaddr","keyAlias":"model"},"firewall":{"description":"Whether this interface should be protected by the firewall.","optional":1,"type":"boolean"},"i82551":{"alias":"macaddr","keyAlias":"model"},"i82557b":{"alias":"macaddr","keyAlias":"model"},"i82559er":{"alias":"macaddr","keyAlias":"model"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"macaddr":{"description":"MAC address. That address must be unique withing your network. This is automatically generated if not specified.","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"model":{"default_key":1,"description":"Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.","enum":["rtl8139","ne2k_pci","e1000","pcnet","virtio","ne2k_isa","i82551","i82557b","i82559er","vmxnet3","e1000-82540em","e1000-82544gc","e1000-82545em"],"type":"string"},"mtu":{"description":"Force MTU, for VirtIO only. Set to '1' to use the bridge MTU","maximum":65520,"minimum":1,"optional":1,"type":"integer"},"ne2k_isa":{"alias":"macaddr","keyAlias":"model"},"ne2k_pci":{"alias":"macaddr","keyAlias":"model"},"pcnet":{"alias":"macaddr","keyAlias":"model"},"queues":{"description":"Number of packet queues to be used on the device.","maximum":16,"minimum":0,"optional":1,"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":0,"optional":1,"type":"number"},"rtl8139":{"alias":"macaddr","keyAlias":"model"},"tag":{"description":"VLAN tag to apply to packets on this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN trunks to pass through this interface.","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"virtio":{"alias":"macaddr","keyAlias":"model"},"vmxnet3":{"alias":"macaddr","keyAlias":"model"}},"optional":true,"properties":{},"type":"string"},"numa":{"default":0,"description":"Enable/disable NUMA.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"numa[n]":{"description":"NUMA topology.","enum":[],"extra":{},"format":{"cpus":{"description":"CPUs accessing this NUMA node.","format_description":"id[-id];...","pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"hostnodes":{"description":"Host NUMA nodes to use.","format_description":"id[-id];...","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"memory":{"description":"Amount of memory this NUMA node provides.","optional":1,"type":"number"},"policy":{"description":"NUMA allocation policy.","enum":["preferred","bind","interleave"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"onboot":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ostype":{"description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","l24","l26","solaris"],"extra":{"verbose_description":"Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 5.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n"},"optional":true,"properties":{},"type":"string"},"parallel[n]":{"description":"Map host parallel devices (n is 0 to 2).","enum":[],"extra":{"verbose_description":"Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"/dev/parport\\d+|/dev/usb/lp\\d+","properties":{},"type":"string"},"protection":{"default":0,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"reboot":{"default":1,"description":"Allow reboot. If set to '0' the VM exit on reboot.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"rng0":{"description":"Configure a VirtIO-based Random Number Generator.","enum":[],"extra":{},"format":{"max_bytes":{"default":1024,"description":"Maximum bytes of entropy injected into the guest every 'period' milliseconds. Prefer a lower value when using /dev/random as source. Use 0 to disable limiting (potentially dangerous!).","optional":1,"type":"integer"},"period":{"default":1000,"description":"Every 'period' milliseconds the entropy-injection quota is reset, allowing the guest to retrieve another 'max_bytes' of entropy.","optional":1,"type":"integer"},"source":{"default_key":1,"description":"The file on the host to gather entropy from. In most cases /dev/urandom should be preferred over /dev/random to avoid entropy-starvation issues on the host. Using urandom does *not* decrease security in any meaningful way, as it's still seeded from real entropy, and the bytes provided will most likely be mixed with real entropy on the guest as well. /dev/hwrng can be used to pass through a hardware RNG from the host.","enum":["/dev/urandom","/dev/random","/dev/hwrng"],"type":"string"}},"optional":true,"properties":{},"type":"string"},"sata[n]":{"description":"Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"scsi[n]":{"description":"Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"queues":{"description":"Number of queues.","minimum":2,"optional":1,"type":"integer"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"scsiblock":{"default":0,"description":"whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"scsihw":{"default":"lsi","description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"extra":{},"optional":true,"properties":{},"type":"string"},"searchdomain":{"description":"cloud-init: Sets DNS search domains for a container. Create will'\n\t .' automatically use the setting from the host if neither searchdomain nor nameserver'\n\t .' are set.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial[n]":{"description":"Create a serial device inside the VM (n is 0 to 3)","enum":[],"extra":{"verbose_description":"Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"(/dev/.+|socket)","properties":{},"type":"string"},"shares":{"default":1000,"description":"Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.","enum":[],"extra":{},"maximum":50000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"smbios1":{"description":"Specify SMBIOS type 1 fields.","enum":[],"extra":{},"format":"pve-qm-smbios1","max_length":512,"optional":true,"properties":{},"type":"string"},"smp":{"default":1,"description":"The number of CPUs. Please use option -sockets instead.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"sockets":{"default":1,"description":"The number of CPU sockets.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"spice_enhancements":{"description":"Configure additional enhancements for SPICE.","enum":[],"extra":{},"format":{"foldersharing":{"default":"0","description":"Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.","optional":1,"type":"boolean"},"videostreaming":{"default":"off","description":"Enable video streaming. Uses compression for detected video streams.","enum":["off","all","filter"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"sshkeys":{"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{},"format":"urlencoded","optional":true,"properties":{},"type":"string"},"startdate":{"default":"now","description":"Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.","enum":[],"extra":{"typetext":"(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)"},"optional":true,"pattern":"(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)","properties":{},"type":"string"},"startup":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"tablet":{"default":1,"description":"Enable/disable the USB tablet device.","enum":[],"extra":{"verbose_description":"Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)."},"optional":true,"properties":{},"type":"boolean"},"tags":{"description":"Tags of the VM. This is only meta information.","enum":[],"extra":{},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"tdf":{"default":0,"description":"Enable/disable time drift fix.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"template":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"unused[n]":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id","format_description":"volume","type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"usb[n]":{"description":"Configure an USB device (n is 0 to 4).","enum":[],"extra":{},"format":{"host":{"default_key":1,"description":"The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadeciaml numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n","format":"pve-qm-usb-device","format_description":"HOSTUSBDEVICE|spice","type":"string"},"usb3":{"default":0,"description":"Specifies whether if given host option is a USB3 device or port.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"vcpus":{"default":0,"description":"Number of hotplugged vcpus.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"vga":{"description":"Configure the VGA hardware.","enum":[],"extra":{"verbose_description":"Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal."},"format":{"memory":{"description":"Sets the VGA memory (in MiB). Has no effect with serial display.","maximum":512,"minimum":4,"optional":1,"type":"integer"},"type":{"default":"std","default_key":1,"description":"Select the VGA type.","enum":["cirrus","qxl","qxl2","qxl3","qxl4","none","serial0","serial1","serial2","serial3","std","virtio","vmware"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"virtio[n]":{"description":"Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"vmgenid":{"default":"1 (autogenerated)","description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","enum":[],"extra":{"format_description":"UUID","verbose_description":"The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file."},"optional":true,"pattern":"(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])","properties":{},"type":"string"},"vmstatestorage":{"description":"Default storage for VM state volumes/files.","enum":[],"extra":{},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"watchdog":{"description":"Create a virtual hardware watchdog device.","enum":[],"extra":{"verbose_description":"Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)"},"format":"pve-qm-watchdog","optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"8bb5957ac6873476b730cf8bff8e190bcca53286fce6090f4b79f0c81bf82420","description":"Set virtual machine options (asynchrounous API).","extra":{"proxyto":"node"},"name":"update_vm_async","parameters":[{"definition":{"default":1,"description":"Enable/disable ACPI.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"acpi"},{"definition":{"description":"Enable/disable Qemu GuestAgent and its properties.","enum":[],"extra":{"typetext":"[enabled=]<1|0> [,fstrim_cloned_disks=<1|0>] [,type=]"},"format":{"enabled":{"default":0,"default_key":1,"description":"Enable/disable Qemu GuestAgent.","type":"boolean"},"fstrim_cloned_disks":{"default":0,"description":"Run fstrim after moving a disk or migrating the VM.","optional":1,"type":"boolean"},"type":{"default":"virtio","description":"Select the agent type","enum":["virtio","isa"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"agent"},{"definition":{"description":"Virtual processor architecture. Defaults to the host.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"description":"Arbitrary arguments passed to kvm.","enum":[],"extra":{"typetext":"","verbose_description":"Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -no-hpet\n\nNOTE: this option is for experts only.\n"},"optional":true,"properties":{},"type":"string"},"name":"args"},{"definition":{"description":"Configure a audio device, useful in combination with QXL/Spice.","enum":[],"extra":{"typetext":"device= [,driver=]"},"format":{"device":{"description":"Configure an audio device.","enum":["ich9-intel-hda","intel-hda","AC97"],"type":"string"},"driver":{"default":"spice","description":"Driver backend for the audio device.","enum":["spice","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"audio0"},{"definition":{"default":0,"description":"Automatic restart after crash (currently ignored).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Time to wait for the task to finish. We return 'null' if the task finish within that time.","enum":[],"extra":{"typetext":" (1 - 30)"},"maximum":30,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"background_delay"},{"definition":{"description":"Amount of target RAM for the VM in MB. Using zero disables the ballon driver.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"balloon"},{"definition":{"default":"seabios","description":"Select BIOS implementation.","enum":["seabios","ovmf"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bios"},{"definition":{"description":"Specify guest boot order. Use with 'order=', usage with no key or 'legacy=' is deprecated.","enum":[],"extra":{"typetext":"[[legacy=]<[acdn]{1,4}>] [,order=]"},"format":"pve-qm-boot","optional":true,"properties":{},"type":"string"},"name":"boot"},{"definition":{"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","enum":[],"extra":{},"format":"pve-qm-bootdisk","optional":true,"pattern":"(ide|sata|scsi|virtio)\\d+","properties":{},"type":"string"},"name":"bootdisk"},{"definition":{"description":"This is an alias for option -ide2","enum":[],"extra":{"typetext":""},"format":"pve-qm-ide","optional":true,"properties":{},"type":"string"},"name":"cdrom"},{"definition":{"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","enum":[],"extra":{"typetext":"[meta=] [,network=] [,user=]"},"format":"pve-qm-cicustom","optional":true,"properties":{},"type":"string"},"name":"cicustom"},{"definition":{"description":"cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cipassword"},{"definition":{"description":"Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.","enum":["configdrive2","nocloud","opennebula"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"citype"},{"definition":{"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ciuser"},{"definition":{"default":1,"description":"The number of cores per socket.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"description":"Emulated CPU type.","enum":[],"extra":{"typetext":"[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]"},"format":"pve-vm-cpu-conf","optional":true,"properties":{},"type":"string"},"name":"cpu"},{"definition":{"default":0,"description":"Limit of CPU usage.","enum":[],"extra":{"typetext":" (0 - 128)","verbose_description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit."},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":1024,"description":"CPU weight for a VM.","enum":[],"extra":{"typetext":" (2 - 262144)","verbose_description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs."},"maximum":262144,"minimum":2,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Configure a Disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead.","enum":[],"extra":{"typetext":"[file=] [,format=] [,size=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"efidisk0"},{"definition":{"description":"Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.","enum":[],"extra":{"requires":"delete","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Freeze CPU at startup (use 'c' monitor command to start execution).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"freeze"},{"definition":{"description":"Script that will be executed during various steps in the vms lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Map host PCI devices into guest.","enum":[],"extra":{"typetext":"[host=] [,legacy-igd=<1|0>] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,x-vga=<1|0>]","verbose_description":"Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"format":"pve-qm-hostpci","optional":true,"properties":{},"type":"string"},"name":"hostpci[n]"},{"definition":{"default":"network,disk,usb","description":"Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory' and 'usb'. Use '0' to disable hotplug completely. Value '1' is an alias for the default 'network,disk,usb'.","enum":[],"extra":{"typetext":""},"format":"pve-hotplug-features","optional":true,"properties":{},"type":"string"},"name":"hotplug"},{"definition":{"description":"Enable/disable hugepages memory.","enum":["any","2","1024"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"hugepages"},{"definition":{"description":"Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"model":{"description":"The drive's reported model name, url-encoded, up to 40 bytes long.","format":"urlencoded","format_description":"model","maxLength":120,"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"ide[n]"},{"definition":{"description":"cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n","enum":[],"extra":{"typetext":"[gw=] [,gw6=] [,ip=] [,ip6=]"},"format":"pve-qm-ipconfig","optional":true,"properties":{},"type":"string"},"name":"ipconfig[n]"},{"definition":{"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host.","enum":[],"extra":{"typetext":"size= [,name=]"},"format":{"name":{"description":"The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.","format_description":"string","optional":1,"pattern":"[a-zA-Z0-9\\-]+","type":"string"},"size":{"description":"The size of the file in MB.","minimum":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"ivshmem"},{"definition":{"default":0,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keephugepages"},{"definition":{"description":"Keybord layout for vnc server. Default is read from the '/etc/pve/datacenter.cfg' configuration file.It should not be necessary to set it.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"keyboard"},{"definition":{"default":1,"description":"Enable/disable KVM hardware virtualization.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"kvm"},{"definition":{"description":"Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"localtime"},{"definition":{"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"description":"Specifies the Qemu machine type.","enum":[],"extra":{},"max_length":40,"optional":true,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","properties":{},"type":"string"},"name":"machine"},{"definition":{"default":512,"description":"Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.","enum":[],"extra":{"typetext":" (16 - N)"},"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"memory"},{"definition":{"default":0.1,"description":"Set maximum tolerated downtime (in seconds) for migrations.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"migrate_downtime"},{"definition":{"default":0,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"migrate_speed"},{"definition":{"description":"Set a name for the VM. Only used on the configuration web interface.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"cloud-init: Sets DNS server IP address for a container. Create will'\n\t .' automatically use the setting from the host if neither searchdomain nor nameserver'\n\t .' are set.","enum":[],"extra":{"typetext":""},"format":"address-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specify network devices.","enum":[],"extra":{"typetext":"[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]"},"format":{"bridge":{"description":"Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n","format_description":"bridge","optional":1,"pattern":"[-_.\\w\\d]+","type":"string"},"e1000":{"alias":"macaddr","keyAlias":"model"},"e1000-82540em":{"alias":"macaddr","keyAlias":"model"},"e1000-82544gc":{"alias":"macaddr","keyAlias":"model"},"e1000-82545em":{"alias":"macaddr","keyAlias":"model"},"firewall":{"description":"Whether this interface should be protected by the firewall.","optional":1,"type":"boolean"},"i82551":{"alias":"macaddr","keyAlias":"model"},"i82557b":{"alias":"macaddr","keyAlias":"model"},"i82559er":{"alias":"macaddr","keyAlias":"model"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"macaddr":{"description":"MAC address. That address must be unique withing your network. This is automatically generated if not specified.","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"model":{"default_key":1,"description":"Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.","enum":["rtl8139","ne2k_pci","e1000","pcnet","virtio","ne2k_isa","i82551","i82557b","i82559er","vmxnet3","e1000-82540em","e1000-82544gc","e1000-82545em"],"type":"string"},"mtu":{"description":"Force MTU, for VirtIO only. Set to '1' to use the bridge MTU","maximum":65520,"minimum":1,"optional":1,"type":"integer"},"ne2k_isa":{"alias":"macaddr","keyAlias":"model"},"ne2k_pci":{"alias":"macaddr","keyAlias":"model"},"pcnet":{"alias":"macaddr","keyAlias":"model"},"queues":{"description":"Number of packet queues to be used on the device.","maximum":16,"minimum":0,"optional":1,"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":0,"optional":1,"type":"number"},"rtl8139":{"alias":"macaddr","keyAlias":"model"},"tag":{"description":"VLAN tag to apply to packets on this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN trunks to pass through this interface.","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"virtio":{"alias":"macaddr","keyAlias":"model"},"vmxnet3":{"alias":"macaddr","keyAlias":"model"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Enable/disable NUMA.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"numa"},{"definition":{"description":"NUMA topology.","enum":[],"extra":{"typetext":"cpus= [,hostnodes=] [,memory=] [,policy=]"},"format":{"cpus":{"description":"CPUs accessing this NUMA node.","format_description":"id[-id];...","pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"hostnodes":{"description":"Host NUMA nodes to use.","format_description":"id[-id];...","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"memory":{"description":"Amount of memory this NUMA node provides.","optional":1,"type":"number"},"policy":{"description":"NUMA allocation policy.","enum":["preferred","bind","interleave"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"numa[n]"},{"definition":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","l24","l26","solaris"],"extra":{"verbose_description":"Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 5.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n"},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"description":"Map host parallel devices (n is 0 to 2).","enum":[],"extra":{"verbose_description":"Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"/dev/parport\\d+|/dev/usb/lp\\d+","properties":{},"type":"string"},"name":"parallel[n]"},{"definition":{"default":0,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"default":1,"description":"Allow reboot. If set to '0' the VM exit on reboot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"reboot"},{"definition":{"description":"Revert a pending change.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"revert"},{"definition":{"description":"Configure a VirtIO-based Random Number Generator.","enum":[],"extra":{"typetext":"[source=] [,max_bytes=] [,period=]"},"format":{"max_bytes":{"default":1024,"description":"Maximum bytes of entropy injected into the guest every 'period' milliseconds. Prefer a lower value when using /dev/random as source. Use 0 to disable limiting (potentially dangerous!).","optional":1,"type":"integer"},"period":{"default":1000,"description":"Every 'period' milliseconds the entropy-injection quota is reset, allowing the guest to retrieve another 'max_bytes' of entropy.","optional":1,"type":"integer"},"source":{"default_key":1,"description":"The file on the host to gather entropy from. In most cases /dev/urandom should be preferred over /dev/random to avoid entropy-starvation issues on the host. Using urandom does *not* decrease security in any meaningful way, as it's still seeded from real entropy, and the bytes provided will most likely be mixed with real entropy on the guest as well. /dev/hwrng can be used to pass through a hardware RNG from the host.","enum":["/dev/urandom","/dev/random","/dev/hwrng"],"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"rng0"},{"definition":{"description":"Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"sata[n]"},{"definition":{"description":"Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,queues=] [,replicate=<1|0>] [,rerror=] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"queues":{"description":"Number of queues.","minimum":2,"optional":1,"type":"integer"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"scsiblock":{"default":0,"description":"whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"scsi[n]"},{"definition":{"default":"lsi","description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scsihw"},{"definition":{"description":"cloud-init: Sets DNS search domains for a container. Create will'\n\t .' automatically use the setting from the host if neither searchdomain nor nameserver'\n\t .' are set.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Create a serial device inside the VM (n is 0 to 3)","enum":[],"extra":{"verbose_description":"Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"(/dev/.+|socket)","properties":{},"type":"string"},"name":"serial[n]"},{"definition":{"default":1000,"description":"Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.","enum":[],"extra":{"typetext":" (0 - 50000)"},"maximum":50000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"shares"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Specify SMBIOS type 1 fields.","enum":[],"extra":{"typetext":"[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]"},"format":"pve-qm-smbios1","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"smbios1"},{"definition":{"default":1,"description":"The number of CPUs. Please use option -sockets instead.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"smp"},{"definition":{"default":1,"description":"The number of CPU sockets.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"sockets"},{"definition":{"description":"Configure additional enhancements for SPICE.","enum":[],"extra":{"typetext":"[foldersharing=<1|0>] [,videostreaming=]"},"format":{"foldersharing":{"default":"0","description":"Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.","optional":1,"type":"boolean"},"videostreaming":{"default":"off","description":"Enable video streaming. Uses compression for detected video streams.","enum":["off","all","filter"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"spice_enhancements"},{"definition":{"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{"typetext":""},"format":"urlencoded","optional":true,"properties":{},"type":"string"},"name":"sshkeys"},{"definition":{"default":"now","description":"Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.","enum":[],"extra":{"typetext":"(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)"},"optional":true,"pattern":"(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)","properties":{},"type":"string"},"name":"startdate"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"default":1,"description":"Enable/disable the USB tablet device.","enum":[],"extra":{"typetext":"","verbose_description":"Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)."},"optional":true,"properties":{},"type":"boolean"},"name":"tablet"},{"definition":{"description":"Tags of the VM. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable time drift fix.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tdf"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[file=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id","format_description":"volume","type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"Configure an USB device (n is 0 to 4).","enum":[],"extra":{"typetext":"[host=] [,usb3=<1|0>]"},"format":{"host":{"default_key":1,"description":"The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadeciaml numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n","format":"pve-qm-usb-device","format_description":"HOSTUSBDEVICE|spice","type":"string"},"usb3":{"default":0,"description":"Specifies whether if given host option is a USB3 device or port.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"usb[n]"},{"definition":{"default":0,"description":"Number of hotplugged vcpus.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vcpus"},{"definition":{"description":"Configure the VGA hardware.","enum":[],"extra":{"typetext":"[[type=]] [,memory=]","verbose_description":"Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal."},"format":{"memory":{"description":"Sets the VGA memory (in MiB). Has no effect with serial display.","maximum":512,"minimum":4,"optional":1,"type":"integer"},"type":{"default":"std","default_key":1,"description":"Select the VGA type.","enum":["cirrus","qxl","qxl2","qxl3","qxl4","none","serial0","serial1","serial2","serial3","std","virtio","vmware"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"vga"},{"definition":{"description":"Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"virtio[n]"},{"definition":{"default":"1 (autogenerated)","description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","enum":[],"extra":{"format_description":"UUID","verbose_description":"The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file."},"optional":true,"pattern":"(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])","properties":{},"type":"string"},"name":"vmgenid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Default storage for VM state volumes/files.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"vmstatestorage"},{"definition":{"description":"Create a virtual hardware watchdog device.","enum":[],"extra":{"typetext":"[[model=]] [,action=]","verbose_description":"Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)"},"format":"pve-qm-watchdog","optional":true,"properties":{},"type":"string"},"name":"watchdog"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk","VM.Config.CDROM","VM.Config.CPU","VM.Config.Memory","VM.Config.Network","VM.Config.HWType","VM.Config.Options","VM.Config.Cloudinit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"verb":"POST"},{"allow_token":true,"checksum":"d9e472300c14c9b8d654d91adfc41551f01ffa132ac33e51980460f83c7625bc","description":"Set virtual machine options (synchrounous API) - You should consider using the POST method instead for any actions involving hotplug or storage allocation.","extra":{"proxyto":"node"},"name":"update_vm","parameters":[{"definition":{"default":1,"description":"Enable/disable ACPI.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"acpi"},{"definition":{"description":"Enable/disable Qemu GuestAgent and its properties.","enum":[],"extra":{"typetext":"[enabled=]<1|0> [,fstrim_cloned_disks=<1|0>] [,type=]"},"format":{"enabled":{"default":0,"default_key":1,"description":"Enable/disable Qemu GuestAgent.","type":"boolean"},"fstrim_cloned_disks":{"default":0,"description":"Run fstrim after moving a disk or migrating the VM.","optional":1,"type":"boolean"},"type":{"default":"virtio","description":"Select the agent type","enum":["virtio","isa"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"agent"},{"definition":{"description":"Virtual processor architecture. Defaults to the host.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"description":"Arbitrary arguments passed to kvm.","enum":[],"extra":{"typetext":"","verbose_description":"Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -no-hpet\n\nNOTE: this option is for experts only.\n"},"optional":true,"properties":{},"type":"string"},"name":"args"},{"definition":{"description":"Configure a audio device, useful in combination with QXL/Spice.","enum":[],"extra":{"typetext":"device= [,driver=]"},"format":{"device":{"description":"Configure an audio device.","enum":["ich9-intel-hda","intel-hda","AC97"],"type":"string"},"driver":{"default":"spice","description":"Driver backend for the audio device.","enum":["spice","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"audio0"},{"definition":{"default":0,"description":"Automatic restart after crash (currently ignored).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Amount of target RAM for the VM in MB. Using zero disables the ballon driver.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"balloon"},{"definition":{"default":"seabios","description":"Select BIOS implementation.","enum":["seabios","ovmf"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bios"},{"definition":{"description":"Specify guest boot order. Use with 'order=', usage with no key or 'legacy=' is deprecated.","enum":[],"extra":{"typetext":"[[legacy=]<[acdn]{1,4}>] [,order=]"},"format":"pve-qm-boot","optional":true,"properties":{},"type":"string"},"name":"boot"},{"definition":{"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","enum":[],"extra":{},"format":"pve-qm-bootdisk","optional":true,"pattern":"(ide|sata|scsi|virtio)\\d+","properties":{},"type":"string"},"name":"bootdisk"},{"definition":{"description":"This is an alias for option -ide2","enum":[],"extra":{"typetext":""},"format":"pve-qm-ide","optional":true,"properties":{},"type":"string"},"name":"cdrom"},{"definition":{"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","enum":[],"extra":{"typetext":"[meta=] [,network=] [,user=]"},"format":"pve-qm-cicustom","optional":true,"properties":{},"type":"string"},"name":"cicustom"},{"definition":{"description":"cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cipassword"},{"definition":{"description":"Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.","enum":["configdrive2","nocloud","opennebula"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"citype"},{"definition":{"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ciuser"},{"definition":{"default":1,"description":"The number of cores per socket.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"description":"Emulated CPU type.","enum":[],"extra":{"typetext":"[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]"},"format":"pve-vm-cpu-conf","optional":true,"properties":{},"type":"string"},"name":"cpu"},{"definition":{"default":0,"description":"Limit of CPU usage.","enum":[],"extra":{"typetext":" (0 - 128)","verbose_description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit."},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":1024,"description":"CPU weight for a VM.","enum":[],"extra":{"typetext":" (2 - 262144)","verbose_description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs."},"maximum":262144,"minimum":2,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description for the VM. Only used on the configuration web interface. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Configure a Disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead.","enum":[],"extra":{"typetext":"[file=] [,format=] [,size=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"efidisk0"},{"definition":{"description":"Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.","enum":[],"extra":{"requires":"delete","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Freeze CPU at startup (use 'c' monitor command to start execution).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"freeze"},{"definition":{"description":"Script that will be executed during various steps in the vms lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Map host PCI devices into guest.","enum":[],"extra":{"typetext":"[host=] [,legacy-igd=<1|0>] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,x-vga=<1|0>]","verbose_description":"Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"format":"pve-qm-hostpci","optional":true,"properties":{},"type":"string"},"name":"hostpci[n]"},{"definition":{"default":"network,disk,usb","description":"Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory' and 'usb'. Use '0' to disable hotplug completely. Value '1' is an alias for the default 'network,disk,usb'.","enum":[],"extra":{"typetext":""},"format":"pve-hotplug-features","optional":true,"properties":{},"type":"string"},"name":"hotplug"},{"definition":{"description":"Enable/disable hugepages memory.","enum":["any","2","1024"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"hugepages"},{"definition":{"description":"Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"model":{"description":"The drive's reported model name, url-encoded, up to 40 bytes long.","format":"urlencoded","format_description":"model","maxLength":120,"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"ide[n]"},{"definition":{"description":"cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n","enum":[],"extra":{"typetext":"[gw=] [,gw6=] [,ip=] [,ip6=]"},"format":"pve-qm-ipconfig","optional":true,"properties":{},"type":"string"},"name":"ipconfig[n]"},{"definition":{"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host.","enum":[],"extra":{"typetext":"size= [,name=]"},"format":{"name":{"description":"The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.","format_description":"string","optional":1,"pattern":"[a-zA-Z0-9\\-]+","type":"string"},"size":{"description":"The size of the file in MB.","minimum":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"ivshmem"},{"definition":{"default":0,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keephugepages"},{"definition":{"description":"Keybord layout for vnc server. Default is read from the '/etc/pve/datacenter.cfg' configuration file.It should not be necessary to set it.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"keyboard"},{"definition":{"default":1,"description":"Enable/disable KVM hardware virtualization.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"kvm"},{"definition":{"description":"Set the real time clock to local time. This is enabled by default if ostype indicates a Microsoft OS.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"localtime"},{"definition":{"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"description":"Specifies the Qemu machine type.","enum":[],"extra":{},"max_length":40,"optional":true,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","properties":{},"type":"string"},"name":"machine"},{"definition":{"default":512,"description":"Amount of RAM for the VM in MB. This is the maximum available memory when you use the balloon device.","enum":[],"extra":{"typetext":" (16 - N)"},"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"memory"},{"definition":{"default":0.1,"description":"Set maximum tolerated downtime (in seconds) for migrations.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"migrate_downtime"},{"definition":{"default":0,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"migrate_speed"},{"definition":{"description":"Set a name for the VM. Only used on the configuration web interface.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"cloud-init: Sets DNS server IP address for a container. Create will'\n\t .' automatically use the setting from the host if neither searchdomain nor nameserver'\n\t .' are set.","enum":[],"extra":{"typetext":""},"format":"address-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specify network devices.","enum":[],"extra":{"typetext":"[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]"},"format":{"bridge":{"description":"Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n","format_description":"bridge","optional":1,"pattern":"[-_.\\w\\d]+","type":"string"},"e1000":{"alias":"macaddr","keyAlias":"model"},"e1000-82540em":{"alias":"macaddr","keyAlias":"model"},"e1000-82544gc":{"alias":"macaddr","keyAlias":"model"},"e1000-82545em":{"alias":"macaddr","keyAlias":"model"},"firewall":{"description":"Whether this interface should be protected by the firewall.","optional":1,"type":"boolean"},"i82551":{"alias":"macaddr","keyAlias":"model"},"i82557b":{"alias":"macaddr","keyAlias":"model"},"i82559er":{"alias":"macaddr","keyAlias":"model"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"macaddr":{"description":"MAC address. That address must be unique withing your network. This is automatically generated if not specified.","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"model":{"default_key":1,"description":"Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.","enum":["rtl8139","ne2k_pci","e1000","pcnet","virtio","ne2k_isa","i82551","i82557b","i82559er","vmxnet3","e1000-82540em","e1000-82544gc","e1000-82545em"],"type":"string"},"mtu":{"description":"Force MTU, for VirtIO only. Set to '1' to use the bridge MTU","maximum":65520,"minimum":1,"optional":1,"type":"integer"},"ne2k_isa":{"alias":"macaddr","keyAlias":"model"},"ne2k_pci":{"alias":"macaddr","keyAlias":"model"},"pcnet":{"alias":"macaddr","keyAlias":"model"},"queues":{"description":"Number of packet queues to be used on the device.","maximum":16,"minimum":0,"optional":1,"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":0,"optional":1,"type":"number"},"rtl8139":{"alias":"macaddr","keyAlias":"model"},"tag":{"description":"VLAN tag to apply to packets on this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN trunks to pass through this interface.","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"virtio":{"alias":"macaddr","keyAlias":"model"},"vmxnet3":{"alias":"macaddr","keyAlias":"model"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Enable/disable NUMA.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"numa"},{"definition":{"description":"NUMA topology.","enum":[],"extra":{"typetext":"cpus= [,hostnodes=] [,memory=] [,policy=]"},"format":{"cpus":{"description":"CPUs accessing this NUMA node.","format_description":"id[-id];...","pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"hostnodes":{"description":"Host NUMA nodes to use.","format_description":"id[-id];...","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"memory":{"description":"Amount of memory this NUMA node provides.","optional":1,"type":"number"},"policy":{"description":"NUMA allocation policy.","enum":["preferred","bind","interleave"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"numa[n]"},{"definition":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","l24","l26","solaris"],"extra":{"verbose_description":"Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 5.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n"},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"description":"Map host parallel devices (n is 0 to 2).","enum":[],"extra":{"verbose_description":"Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"/dev/parport\\d+|/dev/usb/lp\\d+","properties":{},"type":"string"},"name":"parallel[n]"},{"definition":{"default":0,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"default":1,"description":"Allow reboot. If set to '0' the VM exit on reboot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"reboot"},{"definition":{"description":"Revert a pending change.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"revert"},{"definition":{"description":"Configure a VirtIO-based Random Number Generator.","enum":[],"extra":{"typetext":"[source=] [,max_bytes=] [,period=]"},"format":{"max_bytes":{"default":1024,"description":"Maximum bytes of entropy injected into the guest every 'period' milliseconds. Prefer a lower value when using /dev/random as source. Use 0 to disable limiting (potentially dangerous!).","optional":1,"type":"integer"},"period":{"default":1000,"description":"Every 'period' milliseconds the entropy-injection quota is reset, allowing the guest to retrieve another 'max_bytes' of entropy.","optional":1,"type":"integer"},"source":{"default_key":1,"description":"The file on the host to gather entropy from. In most cases /dev/urandom should be preferred over /dev/random to avoid entropy-starvation issues on the host. Using urandom does *not* decrease security in any meaningful way, as it's still seeded from real entropy, and the bytes provided will most likely be mixed with real entropy on the guest as well. /dev/hwrng can be used to pass through a hardware RNG from the host.","enum":["/dev/urandom","/dev/random","/dev/hwrng"],"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"rng0"},{"definition":{"description":"Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"sata[n]"},{"definition":{"description":"Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,queues=] [,replicate=<1|0>] [,rerror=] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"queues":{"description":"Number of queues.","minimum":2,"optional":1,"type":"integer"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"scsiblock":{"default":0,"description":"whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"scsi[n]"},{"definition":{"default":"lsi","description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scsihw"},{"definition":{"description":"cloud-init: Sets DNS search domains for a container. Create will'\n\t .' automatically use the setting from the host if neither searchdomain nor nameserver'\n\t .' are set.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Create a serial device inside the VM (n is 0 to 3)","enum":[],"extra":{"verbose_description":"Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"(/dev/.+|socket)","properties":{},"type":"string"},"name":"serial[n]"},{"definition":{"default":1000,"description":"Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.","enum":[],"extra":{"typetext":" (0 - 50000)"},"maximum":50000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"shares"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Specify SMBIOS type 1 fields.","enum":[],"extra":{"typetext":"[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]"},"format":"pve-qm-smbios1","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"smbios1"},{"definition":{"default":1,"description":"The number of CPUs. Please use option -sockets instead.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"smp"},{"definition":{"default":1,"description":"The number of CPU sockets.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"sockets"},{"definition":{"description":"Configure additional enhancements for SPICE.","enum":[],"extra":{"typetext":"[foldersharing=<1|0>] [,videostreaming=]"},"format":{"foldersharing":{"default":"0","description":"Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.","optional":1,"type":"boolean"},"videostreaming":{"default":"off","description":"Enable video streaming. Uses compression for detected video streams.","enum":["off","all","filter"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"spice_enhancements"},{"definition":{"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{"typetext":""},"format":"urlencoded","optional":true,"properties":{},"type":"string"},"name":"sshkeys"},{"definition":{"default":"now","description":"Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.","enum":[],"extra":{"typetext":"(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)"},"optional":true,"pattern":"(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)","properties":{},"type":"string"},"name":"startdate"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"default":1,"description":"Enable/disable the USB tablet device.","enum":[],"extra":{"typetext":"","verbose_description":"Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)."},"optional":true,"properties":{},"type":"boolean"},"name":"tablet"},{"definition":{"description":"Tags of the VM. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable time drift fix.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tdf"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[file=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id","format_description":"volume","type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"Configure an USB device (n is 0 to 4).","enum":[],"extra":{"typetext":"[host=] [,usb3=<1|0>]"},"format":{"host":{"default_key":1,"description":"The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadeciaml numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n","format":"pve-qm-usb-device","format_description":"HOSTUSBDEVICE|spice","type":"string"},"usb3":{"default":0,"description":"Specifies whether if given host option is a USB3 device or port.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"usb[n]"},{"definition":{"default":0,"description":"Number of hotplugged vcpus.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vcpus"},{"definition":{"description":"Configure the VGA hardware.","enum":[],"extra":{"typetext":"[[type=]] [,memory=]","verbose_description":"Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal."},"format":{"memory":{"description":"Sets the VGA memory (in MiB). Has no effect with serial display.","maximum":512,"minimum":4,"optional":1,"type":"integer"},"type":{"default":"std","default_key":1,"description":"Select the VGA type.","enum":["cirrus","qxl","qxl2","qxl3","qxl4","none","serial0","serial1","serial2","serial3","std","virtio","vmware"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"vga"},{"definition":{"description":"Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","cow","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"virtio[n]"},{"definition":{"default":"1 (autogenerated)","description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","enum":[],"extra":{"format_description":"UUID","verbose_description":"The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file."},"optional":true,"pattern":"(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])","properties":{},"type":"string"},"name":"vmgenid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Default storage for VM state volumes/files.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"vmstatestorage"},{"definition":{"description":"Create a virtual hardware watchdog device.","enum":[],"extra":{"typetext":"[[model=]] [,action=]","verbose_description":"Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)"},"format":"pve-qm-watchdog","optional":true,"properties":{},"type":"string"},"name":"watchdog"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk","VM.Config.CDROM","VM.Config.CPU","VM.Config.Memory","VM.Config.Network","VM.Config.HWType","VM.Config.Options","VM.Config.Cloudinit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"cb23b43448aac18a116b878c559fe74daad5016f705d56baedea038aabac5c1e","description":"Check if feature for virtual machine is available.","extra":{"proxyto":"node"},"name":"vm_feature","parameters":[{"definition":{"description":"Feature to check.","enum":["snapshot","clone","copy"],"extra":{},"properties":{},"type":"string"},"name":"feature"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"hasFeature":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"nodes":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/feature"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5bb143c67c66cf5b8450a21b7962a9429555249c9a169a229e7745f9d8304495","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f3ade8db07d7e168cf2c244f2327d3845c4d148a021436cde1e65f01fcc58db7","description":"List aliases","extra":{},"name":"get_aliases","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"0d804bcfd2565a8543511d9fd83e3425760031b592c1d1e50326d6725d38c139","description":"Create IP or Network Alias.","extra":{},"name":"create_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/aliases"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5920ae6968407878a5b9eb64bd68e522549bb7009cd3895d915d8adbe17e161d","description":"Remove IP or Network alias.","extra":{},"name":"remove_alias","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"1858b8e7f12863024af22797024f75a6fdf6cda0c224f6a4ce9815d3a4cb483b","description":"Read alias.","extra":{},"name":"read_alias","parameters":[{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"7e9b6195d2cd189f3b1fa52dc54fb8369c0324de89694c2614fdb3e30409670f","description":"Update IP or Network alias.","extra":{},"name":"update_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Rename an existing alias.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"72f4e0abfc4fc1fc45cf29ac6cf40bb3810b4463327824ba821b6bd63d1ebc30","description":"List IPSets","extra":{},"name":"ipset_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"name":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"ca3a7645ec2c6c377c1ae0dfb99c5feec2ef5e9bf3aa743b44670f851374983b","description":"Create new IPSet","extra":{},"name":"create_ipset","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/ipset"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3aececa9e07416c4a6077688be66d0fa6485e3d1c76d0d63a629924e7061a751","description":"Delete IPSet","extra":{},"name":"delete_ipset","parameters":[{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"c14d95b34b1dcc471da836cadc0ac6dbc2b2fc74105df7ff98f5cfc6b133644d","description":"List IPSet content","extra":{},"name":"get_ipset","parameters":[{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cidr}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":false,"properties":{},"type":"string"},"nomatch":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"e9612cc0bf355acd89e38d888ee4f89a951948c0840cb620e55d6b7bfc2cfad7","description":"Add IP or Network to IPSet.","extra":{},"name":"create_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"17a70102f27b6d30ea52149ee3614d9b300342b77b66edfeccf9f0c6662ab255","description":"Remove IP or Network from IPSet.","extra":{},"name":"remove_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"a4e0753e2fa85678d8a8d5b232c4403e3ec801c1beb4fd8f537802b987df83a4","description":"Read IP or Network settings from IPSet.","extra":{},"name":"read_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"e033d28015b80e8073780c388cbec51e67f613039684b31d4e9a10aa02c1db33","description":"Update IP or Network settings","extra":{},"name":"update_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b572db8584e8bd6519da73c5c4712e6d44b5179aa8c170b5e8ca129a7b940c39","description":"Read firewall log","extra":{"proxyto":"node"},"name":"log","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"93c4d78422db18c9d0942138c633d8f375aed0485a26da01d13c5e585127c3ab","description":"Get VM firewall options.","extra":{"proxyto":"node"},"name":"get_options","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"dhcp":{"default":0,"description":"Enable DHCP.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"enable":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ipfilter":{"description":"Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"log_level_in":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_level_out":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macfilter":{"default":0,"description":"Enable/disable MAC address filter.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ndp":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"policy_in":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"policy_out":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"radv":{"description":"Allow sending Router Advertisement.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"c6b0e7ba430ba960bf9707669825b788e0a93f6207022350b845dc321ae06a3a","description":"Set Firewall options.","extra":{"proxyto":"node"},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"default":0,"description":"Enable DHCP.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"dhcp"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ipfilter"},{"definition":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_in"},{"definition":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_out"},{"definition":{"default":0,"description":"Enable/disable MAC address filter.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"macfilter"},{"definition":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ndp"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_in"},{"definition":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_out"},{"definition":{"description":"Allow sending Router Advertisement.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"radv"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"37d9588c916a6008f684c9911b05557c57a0334b032dc6feadc90bdffbddf35a","description":"Lists possible IPSet/Alias reference which are allowed in source/dest properties.","extra":{},"name":"refs","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list references of specified type.","enum":["alias","ipset"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":["alias","ipset"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/refs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9aca6c2421abc582ee1474baf7a4e1986ba3cc546ff95ffe612bbe4a7806ac0e","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"02d16c2ee1394a58a737d72dd821f6260b5002ffa456e35ed2e801bbe4116074","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dad1a485162cfc3b459d6d3cb052c9be411bfd535ad8eec7eb1567ad899d3a47","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"74b69d51de0371ce4003eb94ff6ce4d0208d139b00d70d22cef90bc1c8693c46","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"c5e043f89f0db35e70af5e2d6587308e90b9e2157a4b8c662621b6b5a5733ecb","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3eedd4e83d6ab27a2e0fd8190965c42356563500c3f55a2421267a3ad3ef3812","description":"Get preconditions for migration.","extra":{"proxyto":"node"},"name":"migrate_vm_precondition","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"allowed_nodes":{"description":"List nodes allowed for offline migration, only passed if VM is offline","enum":[],"extra":{},"optional":true,"properties":{},"type":"array"},"local_disks":{"description":"List local disks including CD-Rom, unsused and not referenced disks","enum":[],"extra":{},"properties":{},"type":"array"},"local_resources":{"description":"List local resources e.g. pci, usb","enum":[],"extra":{},"properties":{},"type":"array"},"not_allowed_nodes":{"description":"List not allowed nodes with additional informations, only passed if VM is offline","enum":[],"extra":{},"optional":true,"properties":{},"type":"object"},"running":{"enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"7f3c1f11919f90b5e1bbf900c4c8bf9cd327a99d269b8cf7d2ad94ed75f238ac","description":"Migrate virtual machine. Creates a new migration task.","extra":{"proxyto":"node"},"name":"migrate_vm","parameters":[{"definition":{"default":"migrate limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"Allow to migrate VMs which use local devices. Only root may use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"CIDR of the (sub) network that is used for migration.","enum":[],"extra":{"typetext":""},"format":"CIDR","optional":true,"properties":{},"type":"string"},"name":"migration_network"},{"definition":{"description":"Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.","enum":["secure","insecure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"migration_type"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use online/live migration if VM is running. Ignored if VM is stopped.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"online"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storagepair-list","optional":true,"properties":{},"type":"string"},"name":"targetstorage"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Enable live storage migration for local disk","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"with-local-disks"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b479938bad0e3f6fab4095371ec1b02905e7c9562015655112d1151273b91ce2","description":"Execute Qemu monitor commands.","extra":{"proxyto":"node"},"name":"monitor","parameters":[{"definition":{"description":"The monitor command.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"command"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"Sys.Modify is required for (sub)commands which are not read-only ('info *' and 'help')","expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/monitor"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2b211cf54b9e7ff6a63bc99689150a468fa3c49410fb3bd3ad1a47bcc8762f43","description":"Move volume to different storage.","extra":{"proxyto":"node"},"name":"move_vm_disk","parameters":[{"definition":{"default":"move limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"default":0,"description":"Delete the original disk after successful copy. By default the original disk is kept as unused disk.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The disk you want to move.","enum":["ide0","ide1","ide2","ide3","scsi0","scsi1","scsi2","scsi3","scsi4","scsi5","scsi6","scsi7","scsi8","scsi9","scsi10","scsi11","scsi12","scsi13","scsi14","scsi15","scsi16","scsi17","scsi18","scsi19","scsi20","scsi21","scsi22","scsi23","scsi24","scsi25","scsi26","scsi27","scsi28","scsi29","scsi30","virtio0","virtio1","virtio2","virtio3","virtio4","virtio5","virtio6","virtio7","virtio8","virtio9","virtio10","virtio11","virtio12","virtio13","virtio14","virtio15","sata0","sata1","sata2","sata3","sata4","sata5","efidisk0"],"extra":{},"properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"Target Format.","enum":["raw","qcow2","vmdk"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target storage.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Config.Disk' permissions on /vms/{vmid}, and 'Datastore.AllocateSpace' permissions on the storage.","expression":{"check":["and",["perm","/vms/{vmid}",["VM.Config.Disk"]],["perm","/storage/{storage}",["Datastore.AllocateSpace"]]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/move_disk"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d62ea3ba04431111f19f812d7f791c36fe1a5ac0df962735e4655f8548e0f9d5","description":"Get the virtual machine configuration with both current and pending values.","extra":{"proxyto":"node"},"name":"vm_pending","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"delete":{"description":"Indicates a pending delete request if present and not 0. The value 2 indicates a force-delete request.","enum":[],"extra":{},"maximum":2,"minimum":0,"optional":true,"properties":{},"type":"integer"},"key":{"description":"Configuration option name.","enum":[],"extra":{},"properties":{},"type":"string"},"pending":{"description":"Pending value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"value":{"description":"Current value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/pending"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a77fecb2eaae592ceb907c2382ec60cee24e143add31be198f790b7e5ae53ee4","description":"Extend volume size.","extra":{"proxyto":"node"},"name":"resize_vm","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The disk you want to resize.","enum":["ide0","ide1","ide2","ide3","scsi0","scsi1","scsi2","scsi3","scsi4","scsi5","scsi6","scsi7","scsi8","scsi9","scsi10","scsi11","scsi12","scsi13","scsi14","scsi15","scsi16","scsi17","scsi18","scsi19","scsi20","scsi21","scsi22","scsi23","scsi24","scsi25","scsi26","scsi27","scsi28","scsi29","scsi30","virtio0","virtio1","virtio2","virtio3","virtio4","virtio5","virtio6","virtio7","virtio8","virtio9","virtio10","virtio11","virtio12","virtio13","virtio14","virtio15","sata0","sata1","sata2","sata3","sata4","sata5","efidisk0"],"extra":{},"properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The new size. With the `+` sign the value is added to the actual size of the volume and without it, the value is taken as an absolute one. Shrinking disk size is not supported.","enum":[],"extra":{},"pattern":"\\+?\\d+(\\.\\d+)?[KMGT]?","properties":{},"type":"string"},"name":"size"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/resize"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4d311cc5db4c24ed1db63ef58b0d8f8e72b579d6828347fd89059bf258f8210e","description":"Read VM RRD statistics (returns PNG)","extra":{},"name":"rrd","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The list of datasources you want to display.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"ds"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/rrd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"53eace25a11ab03d9980fc2e58377060dd11abc1fa75a694adf1f2b2a88dcdf0","description":"Read VM RRD statistics","extra":{},"name":"rrddata","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/rrddata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"aa9948243349915ab716c1e9175955d01ccbc3052f0eb66f7a98986715c92219","description":"Send key event to virtual machine.","extra":{"proxyto":"node"},"name":"vm_sendkey","parameters":[{"definition":{"description":"The key (qemu monitor encoding).","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"key"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/sendkey"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0a3a5dba9c363cbb794fe03b7ec97105d6dd323226e8aa729628cebd941021c0","description":"List all snapshots.","extra":{"proxyto":"node"},"name":"snapshot_list","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"description":{"description":"Snapshot description.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Snapshot identifier. Value 'current' identifies the current VM.","enum":[],"extra":{},"properties":{},"type":"string"},"parent":{"description":"Parent snapshot identifier.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"snaptime":{"description":"Snapshot creation time","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"vmstate":{"description":"Snapshot includes RAM.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"10b32165392e243323c38c9aaf2be5fa2798cc638a05851aedc6c68941bb3c8d","description":"Snapshot a VM.","extra":{"proxyto":"node"},"name":"snapshot","parameters":[{"definition":{"description":"A textual description or comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Save the vmstate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"vmstate"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/snapshot"},{"extra":{},"methods":[{"allow_token":true,"checksum":"490232f284e83e267b2ba688eb683f392e0a66281482783c4f2c42ef54df441d","description":"Delete a VM snapshot.","extra":{"proxyto":"node"},"name":"delsnapshot","parameters":[{"definition":{"description":"For removal from config file, even if removing disk snapshots fails.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"3543f6f025f3e8edb235d3a81de6bc9ae888696632b72c8a0358c30d67d096cb","description":"","extra":{},"name":"snapshot_cmd_idx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cmd}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2e4c3ffc0a572cde350f82c1ed21f7483bdc0b55b3350b6c629ad4a87fce8660","description":"Get snapshot configuration","extra":{"proxyto":"node"},"name":"get_snapshot_config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback","VM.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"229bac50088cfccbb485c9371b58bfc8d8a4beddcc04c2ef4a88af7a288e62dc","description":"Update snapshot metadata.","extra":{"proxyto":"node"},"name":"update_snapshot_config","parameters":[{"definition":{"description":"A textual description or comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d4ca21cbb6bb36fbd210cd358bfc7b72278cab87550579170c4672db4aaeaa69","description":"Rollback VM state to specified snapshot.","extra":{"proxyto":"node"},"name":"rollback","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8f6d1ed8c139e695e0b24cc1a319e983f17e91d0a6c1ad223855a7d06f1eb5b3","description":"Returns a SPICE configuration to connect to the VM.","extra":{"proxyto":"node"},"name":"spiceproxy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).","enum":[],"extra":{"typetext":""},"format":"address","optional":true,"properties":{},"type":"string"},"name":"proxy"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"description":"Returned values can be directly passed to the 'remote-viewer' application.","enum":[],"extra":{"additionalProperties":1},"properties":{"host":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"enum":[],"extra":{},"properties":{},"type":"string"},"proxy":{"enum":[],"extra":{},"properties":{},"type":"string"},"tls-port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/spiceproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"94a0d535add5f584338da3a56b0765094683ec9f207cd53a95a4014fc19acdf6","description":"Directory index","extra":{"proxyto":"node"},"name":"vmcmdidx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c79e1451ff86428edf2f0fbd05b6c08a3b9e9cf4667e241d5f9644fa5184518e","description":"Get virtual machine status.","extra":{"proxyto":"node"},"name":"vm_status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"agent":{"description":"Qemu GuestAgent enabled in config.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"cpus":{"description":"Maximum usable CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"ha":{"description":"HA manager service status.","enum":[],"extra":{},"properties":{},"type":"object"},"lock":{"description":"The current config lock, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxdisk":{"description":"Root disk size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Maximum memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"name":{"description":"VM name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pid":{"description":"PID of running qemu process.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"qmpstatus":{"description":"Qemu QMP agent status.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"running-machine":{"description":"The currently running machine type (if running).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"running-qemu":{"description":"The currently running QEMU version (if running).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"spice":{"description":"Qemu VGA configuration supports spice.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"status":{"description":"Qemu process status.","enum":["stopped","running"],"extra":{},"properties":{},"type":"string"},"tags":{"description":"The current configured tags, if any","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"uptime":{"description":"Uptime.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/status/current"},{"extra":{},"methods":[{"allow_token":true,"checksum":"aa0c51529af4ef2fcea52ef831f1fe91057969ab05438476e1c84c4989af484a","description":"Reboot the VM by shutting it down, and starting it again. Applies pending changes.","extra":{"proxyto":"node"},"name":"vm_reboot","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Wait maximal timeout seconds for the shutdown.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/reboot"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1871f485dbc7682d42ef0ea0e30f4f03de75168335e09f05f086080e56e7b0d0","description":"Reset virtual machine.","extra":{"proxyto":"node"},"name":"vm_reset","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/reset"},{"extra":{},"methods":[{"allow_token":true,"checksum":"78c150a6c15c671cbc5a81c6f91c1c56f9372d825c25a985f3b23720934ffc03","description":"Resume virtual machine.","extra":{"proxyto":"node"},"name":"vm_resume","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nocheck"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/resume"},{"extra":{},"methods":[{"allow_token":true,"checksum":"522428bc63ba96ef2e445a1071a5d6f9bf2f6f8be1a2c0a136cba4c5522ba134","description":"Shutdown virtual machine. This is similar to pressing the power button on a physical machine.This will send an ACPI event for the guest OS, which should then proceed to a clean shutdown.","extra":{"proxyto":"node"},"name":"vm_shutdown","parameters":[{"definition":{"default":0,"description":"Make sure the VM stops.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"forceStop"},{"definition":{"default":0,"description":"Do not deactivate storage volumes.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keepActive"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Wait maximal timeout seconds.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/shutdown"},{"extra":{},"methods":[{"allow_token":true,"checksum":"84b8145f85152e1e6489183b41c79a35be0175276c0ce2e5982647934ac7af87","description":"Start virtual machine.","extra":{"proxyto":"node"},"name":"vm_start","parameters":[{"definition":{"description":"Override QEMU's -cpu argument with the given string.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"force-cpu"},{"definition":{"description":"Specifies the Qemu machine type.","enum":[],"extra":{},"max_length":40,"optional":true,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","properties":{},"type":"string"},"name":"machine"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"migratedfrom"},{"definition":{"description":"CIDR of the (sub) network that is used for migration.","enum":[],"extra":{"typetext":""},"format":"CIDR","optional":true,"properties":{},"type":"string"},"name":"migration_network"},{"definition":{"description":"Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.","enum":["secure","insecure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"migration_type"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Some command save/restore state from this location.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"stateuri"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storagepair-list","optional":true,"properties":{},"type":"string"},"name":"targetstorage"},{"definition":{"default":"max(30, vm memory in GiB)","description":"Wait maximal timeout seconds.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8b103e66ff8f578a991a9f66aad23def3df04e67eb8181fded08c4680ac024e3","description":"Stop virtual machine. The qemu process will exit immediately. Thisis akin to pulling the power plug of a running computer and may damage the VM data","extra":{"proxyto":"node"},"name":"vm_stop","parameters":[{"definition":{"default":0,"description":"Do not deactivate storage volumes.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keepActive"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"migratedfrom"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Wait maximal timeout seconds.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/stop"},{"extra":{},"methods":[{"allow_token":true,"checksum":"979226664217ce4fa592d874d27ef7cd5926ada7f510d1b4d13d9db910fa4b13","description":"Suspend virtual machine.","extra":{"proxyto":"node"},"name":"vm_suspend","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The storage for the VM state","enum":[],"extra":{"requires":"todisk","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"statestorage"},{"definition":{"default":0,"description":"If set, suspends the VM to disk. Will be resumed on next VM start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"todisk"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.PowerMgmt' on /vms/{vmid}, and if you have set 'todisk', you need also 'VM.Config.Disk' on /vms/{vmid} and 'Datastore.AllocateSpace' on the storage for the vmstate.","expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/suspend"},{"extra":{},"methods":[{"allow_token":true,"checksum":"04a218c14081590ba1cbd5b696a708ba0a6a4169bf1218d7f127a11540450fd3","description":"Create a Template.","extra":{"proxyto":"node"},"name":"template","parameters":[{"definition":{"description":"If you want to convert only 1 disk to base image.","enum":["ide0","ide1","ide2","ide3","scsi0","scsi1","scsi2","scsi3","scsi4","scsi5","scsi6","scsi7","scsi8","scsi9","scsi10","scsi11","scsi12","scsi13","scsi14","scsi15","scsi16","scsi17","scsi18","scsi19","scsi20","scsi21","scsi22","scsi23","scsi24","scsi25","scsi26","scsi27","scsi28","scsi29","scsi30","virtio0","virtio1","virtio2","virtio3","virtio4","virtio5","virtio6","virtio7","virtio8","virtio9","virtio10","virtio11","virtio12","virtio13","virtio14","virtio15","sata0","sata1","sata2","sata3","sata4","sata5","efidisk0"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permissions on /vms/{vmid}","expression":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/template"},{"extra":{},"methods":[{"allow_token":true,"checksum":"581bcc9a519fb4b422b3e0e599e45c64a0db57b56dac0ab3269915ad6c17eeca","description":"Creates a TCP proxy connections.","extra":{},"name":"termproxy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"opens a serial terminal (defaults to display)","enum":["serial0","serial1","serial2","serial3"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"serial"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/termproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4a2fb8e4da3f5127a7f9d56ae5999acd8ef738ba4f47cc0d3704787f3fcf9bf6","description":"Unlink/delete disk images.","extra":{"proxyto":"node"},"name":"unlink","parameters":[{"definition":{"description":"Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"A list of disk IDs you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"idlist"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/unlink"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9a5fcd951a70d86256acddf42be56b872795a3157a1eebbd6eebfef0a7927f13","description":"Creates a TCP VNC proxy connections.","extra":{},"name":"vncproxy","parameters":[{"definition":{"default":0,"description":"Generates a random password to be used as ticket instead of the API ticket.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"generate-password"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"starts websockify instead of vncproxy","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"websocket"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"cert":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"description":"Returned if requested with 'generate-password' param. Consists of printable ASCII characters ('!' .. '~').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/vncproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ee391a9db15bf946d3fcf3622e765d731bb78079d2394c583723f26e79101ac5","description":"Opens a weksocket for VNC traffic.","extra":{},"name":"vncwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Port number returned by previous vncproxy call.","enum":[],"extra":{"typetext":" (5900 - 5999)"},"maximum":5999,"minimum":5900,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Ticket from previous call to vncproxy.","enum":[],"extra":{"typetext":""},"max_length":512,"properties":{},"type":"string"},"name":"vncticket"}],"permissions":{"description":"You also need to pass a valid ticket (vncticket).","expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/vncwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"622b3aa84ae973517a0ec742be96c880d38bdacd2780b26fe82134224bca0d0e","description":"List status of all replication jobs on this node.","extra":{"proxyto":"node"},"name":"status","parameters":[{"definition":{"description":"Only list replication jobs for this guest.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"guest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires the VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/replication"},{"extra":{},"methods":[{"allow_token":true,"checksum":"201ac105a0b4f70bec7ac00e32a949db054741cbd2465d2f625462367edce6f7","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/replication/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6ffc6cc2602df84fe4f8eb72ae99567ce4f7fb02dec2ca8db396ff090772cd58","description":"Read replication job log.","extra":{"proxyto":"node"},"name":"read_job_log","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"}],"permissions":{"description":"Requires the VM.Audit permission on /vms/, or 'Sys.Audit' on '/nodes/'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/replication/{id}/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"77e6d9fc5931226e0ebc15d1967865306c48edb8c36e7ab4acd3c992bc22e6ef","description":"Schedule replication job to start as soon as possible.","extra":{"proxyto":"node"},"name":"schedule_now","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/replication/{id}/schedule_now"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4be58d6638ffb32fbaa33db58fac6d3964014ed3286339e84f35ca0cb6d006e1","description":"Get replication job status.","extra":{"proxyto":"node"},"name":"job_status","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires the VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/replication/{id}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0e37ddadedaa3a4ce296c24b888b12f7012e4e23b1732222e40075a4f8a9ed1f","description":"Gather various systems information about a node","extra":{"proxyto":"node"},"name":"report","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/report"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d974667aed5e89c095ef17a66fb4537d6dda82a55fa1ec5f1c05cba57f78464c","description":"Read node RRD statistics (returns PNG)","extra":{},"name":"rrd","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The list of datasources you want to display.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"ds"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/rrd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"766180222a6d70a2fd631255767fa56f8cd6a67cebf4530b038018cccd49487f","description":"Read node RRD statistics","extra":{},"name":"rrddata","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/rrddata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7cca8a7c1631d17653d463ea99f96401217997b7a680967bfc57a06b99302ff1","description":"Index of available scan methods","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{method}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"method":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2ec831a4ad191d89200069d552cc1eedbbe77316334360b9e98672a3d4cf3a94","description":"Scan remote CIFS server.","extra":{"proxyto":"node"},"name":"cifsscan","parameters":[{"definition":{"description":"SMB domain (Workgroup).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"User password.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"The server address (name or IP).","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","properties":{},"type":"string"},"name":"server"},{"definition":{"description":"User name.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"description":{"description":"Descriptive text from server.","enum":[],"extra":{},"properties":{},"type":"string"},"share":{"description":"The cifs share name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/cifs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"75c1967f47ee50cfdaf4558a4fa699bbdc9317e2fe69fd3ddccd30a2707dfe2d","description":"Scan remote GlusterFS server.","extra":{"proxyto":"node"},"name":"glusterfsscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The server address (name or IP).","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","properties":{},"type":"string"},"name":"server"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"volname":{"description":"The volume name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/glusterfs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f0b69d1299f3a287b51f9e20eddd3a6c423da92c62c5263da3308104c8f9e3d8","description":"Scan remote iSCSI server.","extra":{"proxyto":"node"},"name":"iscsiscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The iSCSI portal (IP or DNS name with optional port).","enum":[],"extra":{"typetext":""},"format":"pve-storage-portal-dns","properties":{},"type":"string"},"name":"portal"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"portal":{"description":"The iSCSI portal name.","enum":[],"extra":{},"properties":{},"type":"string"},"target":{"description":"The iSCSI target name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/iscsi"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ee58724ae9c2fbdaf09f891f8286f1c4a97862a33274213f55b64ef257c82810","description":"List local LVM volume groups.","extra":{"proxyto":"node"},"name":"lvmscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"vg":{"description":"The LVM logical volume group name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/lvm"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b85f98a17a9f58549d6a53aafbaf22bfdf0e5d1665f87e90bb69fd57fad754e8","description":"List local LVM Thin Pools.","extra":{"proxyto":"node"},"name":"lvmthinscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{},"max_length":100,"pattern":"[a-zA-Z0-9\\.\\+\\_][a-zA-Z0-9\\.\\+\\_\\-]+","properties":{},"type":"string"},"name":"vg"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"lv":{"description":"The LVM Thin Pool name (LVM logical volume).","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/lvmthin"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d9ddde30d7f532fbc6f06fbe726c2833705e8d4807f2c6cd617ee8fdae18d97d","description":"Scan remote NFS server.","extra":{"proxyto":"node"},"name":"nfsscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The server address (name or IP).","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","properties":{},"type":"string"},"name":"server"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"options":{"description":"NFS export options.","enum":[],"extra":{},"properties":{},"type":"string"},"path":{"description":"The exported path.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/nfs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3ce919d002c3d125b6b1ad3b5fd0cb889318319ec14cee96f7282ff12db0bda8","description":"Scan remote Proxmox Backup Server.","extra":{"proxyto":"node"},"name":"pbsscan","parameters":[{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"User password or API token secret.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"password"},{"definition":{"default":8007,"description":"Optional port.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The server address (name or IP).","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","properties":{},"type":"string"},"name":"server"},{"definition":{"description":"User-name or API token-ID.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"username"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"Comment from server.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"store":{"description":"The datastore name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/pbs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c34730e00f0d40259fe27fa8d10c86ca51d09c55d88e56c0a58a874dcf7bff9c","description":"List local USB devices.","extra":{"proxyto":"node"},"name":"usbscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"busnum":{"enum":[],"extra":{},"properties":{},"type":"integer"},"class":{"enum":[],"extra":{},"properties":{},"type":"integer"},"devnum":{"enum":[],"extra":{},"properties":{},"type":"integer"},"level":{"enum":[],"extra":{},"properties":{},"type":"integer"},"manufacturer":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"prodid":{"enum":[],"extra":{},"properties":{},"type":"string"},"product":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"speed":{"enum":[],"extra":{},"properties":{},"type":"string"},"usbpath":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vendid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/usb"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5742df84db0fb3e83b8a85993cee8d4667b1a311b08d135a1b751e04afd1caeb","description":"Scan zfs pool list on local node.","extra":{"proxyto":"node"},"name":"zfsscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"pool":{"description":"ZFS pool name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/zfs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ff83507bdfaa5cb101794ba2e4c40051a63c313286ecc2e102ae09a550357898","description":"SDN index.","extra":{},"name":"sdnindex","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn"},{"extra":{},"methods":[{"allow_token":true,"checksum":"12403a45a714d49c82c079929ecd505c3b507a59dc93a9d8179f4b90a7ce7318","description":"Get status for all zones.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{zone}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"status":{"description":"Status of zone","enum":["available","pending","error"],"extra":{},"properties":{},"type":"string"},"zone":{"description":"The SDN zone object identifier.","enum":[],"extra":{},"format":"pve-sdn-zone-id","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/zones"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8a85cf269cae44e965f4987f67477d55f9c0dbd96ca0ce98eeacd89f9c89084e","description":"","extra":{},"name":"diridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/zones/{zone}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"37027697e4ca9f13e96aaeed743d261261396e7f4689693272393d7d7c53e2ac","description":"List zone content.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{vnet}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"status":{"description":"Status.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"statusmsg":{"description":"Status details","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vnet":{"description":"Vnet identifier.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/zones/{zone}/content"},{"extra":{},"methods":[{"allow_token":true,"checksum":"28dfc7ff0d1244e9784ad47960d10b8e5aba10d904ddab0fc817befa32f29b9a","description":"Service list.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{service}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/services"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1732e2c9a5c8787296719768103b4871f8f0ee6371f841b7b49adfe6125ad5c1","description":"Directory index","extra":{},"name":"srvcmdidx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["pveproxy","pvedaemon","spiceproxy","pvestatd","pve-cluster","corosync","pve-firewall","pvefw-logger","pve-ha-crm","pve-ha-lrm","sshd","syslog","cron","postfix","ksmtuned","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/services/{service}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2ba7e70d9dfaa5cab965ab1af09a550e6e4dd18c6ceb5401836c84162828431b","description":"Reload service. Falls back to restart if service cannot be reloaded.","extra":{"proxyto":"node"},"name":"service_reload","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["pveproxy","pvedaemon","spiceproxy","pvestatd","pve-cluster","corosync","pve-firewall","pvefw-logger","pve-ha-crm","pve-ha-lrm","sshd","syslog","cron","postfix","ksmtuned","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/services/{service}/reload"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8c56bf469bfea2e67b6f9ab6fc784e414c40029ae56cfbfd95bd012fbd723204","description":"Hard restart service. Use reload if you want to reduce interruptions.","extra":{"proxyto":"node"},"name":"service_restart","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["pveproxy","pvedaemon","spiceproxy","pvestatd","pve-cluster","corosync","pve-firewall","pvefw-logger","pve-ha-crm","pve-ha-lrm","sshd","syslog","cron","postfix","ksmtuned","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/services/{service}/restart"},{"extra":{},"methods":[{"allow_token":true,"checksum":"286332931a30934ad4cc0f7e6de46916f4ffb36702cf2bc21a5ea32c47275e0a","description":"Start service.","extra":{"proxyto":"node"},"name":"service_start","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["pveproxy","pvedaemon","spiceproxy","pvestatd","pve-cluster","corosync","pve-firewall","pvefw-logger","pve-ha-crm","pve-ha-lrm","sshd","syslog","cron","postfix","ksmtuned","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/services/{service}/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"73a5605835d61bd543d19e9066f9bab79bad5faec02e9dafee34e77091f1fdbe","description":"Read service properties","extra":{"proxyto":"node"},"name":"service_state","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["pveproxy","pvedaemon","spiceproxy","pvestatd","pve-cluster","corosync","pve-firewall","pvefw-logger","pve-ha-crm","pve-ha-lrm","sshd","syslog","cron","postfix","ksmtuned","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/services/{service}/state"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c443d10218ab690ed87f1672525ef7c27488b5de234b769cb61d7fc729cbf1d5","description":"Stop service.","extra":{"proxyto":"node"},"name":"service_stop","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["pveproxy","pvedaemon","spiceproxy","pvestatd","pve-cluster","corosync","pve-firewall","pvefw-logger","pve-ha-crm","pve-ha-lrm","sshd","syslog","cron","postfix","ksmtuned","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/services/{service}/stop"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e805ba20124a1dc40feef3b80e3fe110d7054501e8b77ebafece0def37c17606","description":"Creates a SPICE shell.","extra":{"proxyto":"node"},"name":"spiceshell","parameters":[{"definition":{"default":"login","description":"Run specific command or default to login.","enum":["upgrade","ceph_install","login"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmd"},{"definition":{"default":"","description":"Add parameters to a command. Encoded as null terminated strings.","enum":[],"extra":{"requires":"cmd","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cmd-opts"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).","enum":[],"extra":{"typetext":""},"format":"address","optional":true,"properties":{},"type":"string"},"name":"proxy"},{"definition":{"default":0,"description":"Deprecated, use the 'cmd' property instead! Run 'apt-get dist-upgrade' instead of normal shell.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"upgrade"}],"permissions":{"description":"Restricted to users on realm 'pam'","expression":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"description":"Returned values can be directly passed to the 'remote-viewer' application.","enum":[],"extra":{"additionalProperties":1},"properties":{"host":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"enum":[],"extra":{},"properties":{},"type":"string"},"proxy":{"enum":[],"extra":{},"properties":{},"type":"string"},"tls-port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/spiceshell"},{"extra":{},"methods":[{"allow_token":true,"checksum":"34bc138d3ba461cda584b614bddf5190389f0fcf4238496bfd4bd29cef4ea101","description":"Start all VMs and containers located on this node (by default only those with onboot=1).","extra":{"proxyto":"node"},"name":"startall","parameters":[{"definition":{"default":"off","description":"Issue start command even if virtual guest have 'onboot' not set or set to off.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only consider guests from this comma separated list of VMIDs.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"}],"permissions":{"expression":{"check":["perm","/",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/startall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"659246e0644de83bea8d5511eebd10913a9fbe0d55ce182936fb7d27a50e31bb","description":"Read node status","extra":{"proxyto":"node"},"name":"status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"f11d86bf5eb63c8f7c9cd23dd0579477ea908eb3b936d39f4f8c5a20bfd0bef7","description":"Reboot or shutdown a node.","extra":{"proxyto":"node"},"name":"node_cmd","parameters":[{"definition":{"description":"Specify the command.","enum":["reboot","shutdown"],"extra":{},"properties":{},"type":"string"},"name":"command"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3da74b78f3d7661b34c069817d91884d967ebb8db647b6a24aa6aee5c01925d7","description":"Stop all VMs and Containers.","extra":{"proxyto":"node"},"name":"stopall","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only consider Guests with these IDs.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"}],"permissions":{"expression":{"check":["perm","/",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/stopall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dd0ea4f574a7d8eb6c6e6e3f5c6e2be12fd4966ad5ea3801257c47d3d28f6e43","description":"Get status for all datastores.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"Only list stores which support this content type.","enum":[],"extra":{"typetext":""},"format":"pve-storage-content-list","optional":true,"properties":{},"type":"string"},"name":"content"},{"definition":{"default":0,"description":"Only list stores which are enabled (not disabled in config).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"default":0,"description":"Include information about formats","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"format"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list status for specified storage","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"If target is different to 'node', we only lists shared storages which content is accessible on this 'node' and the specified 'target' node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"}],"permissions":{"description":"Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{storage}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"active":{"description":"Set when storage is accessible.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"avail":{"description":"Available storage space in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"content":{"description":"Allowed storage content types.","enum":[],"extra":{},"format":"pve-storage-content-list","properties":{},"type":"string"},"enabled":{"description":"Set when storage is enabled (not disabled).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"shared":{"description":"Shared flag from storage configuration.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"storage":{"description":"The storage identifier.","enum":[],"extra":{},"format":"pve-storage-id","properties":{},"type":"string"},"total":{"description":"Total storage space in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"type":{"description":"Storage type.","enum":[],"extra":{},"properties":{},"type":"string"},"used":{"description":"Used storage space in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"used_fraction":{"description":"Used fraction (used/total).","enum":[],"extra":{"renderer":"fraction_as_percentage"},"optional":true,"properties":{},"type":"number"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage"},{"extra":{},"methods":[{"allow_token":true,"checksum":"377eba426d6b0285a1543e3fc7499e4b94d9087b39aa5222e568d0258071f5f6","description":"","extra":{},"name":"diridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dd2bd3d8ec70ff736f32ab5aaece3b2a864b9e1fccc6cbef0bd33cbcbbfc0886","description":"List storage content.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"Only list content of this type.","enum":[],"extra":{"typetext":""},"format":"pve-storage-content","optional":true,"properties":{},"type":"string"},"name":"content"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Only list images for this VM","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{volid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"ctime":{"description":"Creation time (seconds since the UNIX Epoch).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"encrypted":{"description":"If whole backup is encrypted, value is the fingerprint or '1' if encrypted. Only useful for the Proxmox Backup Server storage type.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"format":{"description":"Format identifier ('raw', 'qcow2', 'subvol', 'iso', 'tgz' ...)","enum":[],"extra":{},"properties":{},"type":"string"},"notes":{"description":"Optional notes. If they contain multiple lines, only the first one is returned here.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"parent":{"description":"Volume identifier of parent (for linked cloned).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"size":{"description":"Volume size in bytes.","enum":[],"extra":{"renderer":"bytes"},"properties":{},"type":"integer"},"used":{"description":"Used space. Please note that most storage plugins do not report anything useful here.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"verification":{"description":"Last backup verification result, only useful for PBS storages.","enum":[],"extra":{},"optional":true,"properties":{"state":{"description":"Last backup verification state.","enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"description":"Last backup verification UPID.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"vmid":{"description":"Associated Owner VMID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"volid":{"description":"Volume identifier.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"0a214ab427deddf4376aa0cea9a1ad533d10456bfa2ab2b0d1bf7c95bec3c978","description":"Allocate disk images.","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"description":"The name of the file to create.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"filename"},{"definition":{"enum":["raw","qcow2","subvol"],"extra":{"requires":"size"},"optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Size in kilobyte (1024 bytes). Optional suffixes 'M' (megabyte, 1024K) and 'G' (gigabyte, 1024M)","enum":[],"extra":{},"pattern":"\\d+[MG]?","properties":{},"type":"string"},"name":"size"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Specify owner VM","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.AllocateSpace"]]},"extra":{}},"protected":true,"returns":{"description":"Volume identifier","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/storage/{storage}/content"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8c46146e5409364c21e9fabe66cda11271af6dbab1954a3bf6dfc76b5b5fb028","description":"Delete volume","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"description":"Time to wait for the task to finish. We return 'null' if the task finish within that time.","enum":[],"extra":{"typetext":" (1 - 30)"},"maximum":30,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"delay"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need 'Datastore.Allocate' privilege on the storage (or 'Datastore.AllocateSpace' for backup volumes if you have VM.Backup privilege on the VM).","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"59ff12c15ef3aa51860e470d17ec64a1ed426c618bc32286cc82f09f666dfb01","description":"Get volume attributes","extra":{"proxyto":"node"},"name":"info","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"format":{"description":"Format identifier ('raw', 'qcow2', 'subvol', 'iso', 'tgz' ...)","enum":[],"extra":{},"properties":{},"type":"string"},"notes":{"description":"Optional notes.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"path":{"description":"The Path","enum":[],"extra":{},"properties":{},"type":"string"},"size":{"description":"Volume size in bytes.","enum":[],"extra":{"renderer":"bytes"},"properties":{},"type":"integer"},"used":{"description":"Used space. Please note that most storage plugins do not report anything useful here.","enum":[],"extra":{"renderer":"bytes"},"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"1cc35ec5d8865c6efa9818c824f9593097c56ea1fe8d7e877d4e8b9127c5d27b","description":"Copy a volume. This is experimental code - do not use.","extra":{"proxyto":"node"},"name":"copy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Target volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Target node. Default is local node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target_node"},{"definition":{"description":"Source volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"},{"allow_token":true,"checksum":"1bcf674adb03c0a4623b5f2939e1b7fe04c1cf747191bee90e0de9817ce0da32","description":"Update volume attributes","extra":{"proxyto":"node"},"name":"updateattributes","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The new notes.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"notes"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/storage/{storage}/content/{volume}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a21cd4c6d6810844199101691a2a3e2395df2eb6e63f04faf9e5ff37c0ce3cc8","description":"Extract a file or directory (as zip archive) from a PBS backup.","extra":{"proxyto":"node"},"name":"download","parameters":[{"definition":{"description":"base64-path to the directory or file to download.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"filepath"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Backup volume ID or name. Currently only PBS snapshots are supported.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"any"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/file-restore/download"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ea83e757c302d00f12e115649c095a953dff5ce51794c0400f7eb7c0b64962a1","description":"List files and directories for single file restore under the given path.","extra":{"proxyto":"node"},"name":"list","parameters":[{"definition":{"description":"base64-path to the directory or file being listed, or \"/\".","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"filepath"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Backup volume ID or name. Currently only PBS snapshots are supported.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"filepath":{"description":"base64 path of the current entry","enum":[],"extra":{},"properties":{},"type":"string"},"leaf":{"description":"If this entry is a leaf in the directory graph.","enum":[],"extra":{},"properties":{},"type":"boolean"},"mtime":{"description":"Entry last-modified time (unix timestamp).","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"size":{"description":"Entry file size.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"text":{"description":"Entry display text.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"Entry type.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/file-restore/list"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c2906566c6309e1b09ec0a2b71f558d6d407831df276979d654d9100e5cd1b98","description":"Prune backups. Only those using the standard naming scheme are considered.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Either 'qemu' or 'lxc'. Only consider backups for guests of this type.","enum":["qemu","lxc"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"Only prune backups for this VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need the 'Datastore.Allocate' privilege on the storage (or if a VM ID is specified, 'Datastore.AllocateSpace' and 'VM.Backup' for the VM).","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"46f434bd46c3419ce188231f12e32464584ca762e1983c385c8547dd290db918","description":"Get prune information for backups. NOTE: this is only a preview and might not be what a subsequent prune call does if backups are removed/added in the meantime.","extra":{"proxyto":"node"},"name":"dryrun","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Either 'qemu' or 'lxc'. Only consider backups for guests of this type.","enum":["qemu","lxc"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"Only consider backups for this guest.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"ctime":{"description":"Creation time of the backup (seconds since the UNIX epoch).","enum":[],"extra":{},"properties":{},"type":"integer"},"mark":{"description":"Whether the backup would be kept or removed. For backups that don't use the standard naming scheme, it's 'protected'.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"One of 'qemu', 'lxc', 'openvz' or 'unknown'.","enum":[],"extra":{},"properties":{},"type":"string"},"vmid":{"description":"The VM the backup belongs to.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"volid":{"description":"Backup volume ID.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/prunebackups"},{"extra":{},"methods":[{"allow_token":true,"checksum":"20a583b925d3ab0aa787326c6b5e8a30b465daf2a1b9ddcff8072c987d2d1e29","description":"Read storage RRD statistics (returns PNG).","extra":{"proxyto":"node"},"name":"rrd","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The list of datasources you want to display.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"ds"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/rrd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e963d14fe33e85cd89f3e86ef8fce1f755ebd481fed7e11fe11d383f86a22990","description":"Read storage RRD statistics.","extra":{"proxyto":"node"},"name":"rrddata","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/rrddata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7c7877748327e646e17c62147e0e1f0148ea70a1237332b911aed87e646566c5","description":"Read storage status.","extra":{"proxyto":"node"},"name":"read_status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"cb34d5a318e720c9dabc769b52d63e8d8bd5a6195bb74da7e57794932007f4fc","description":"Upload templates and ISO images.","extra":{},"name":"upload","parameters":[{"definition":{"description":"Content type.","enum":[],"extra":{"typetext":""},"format":"pve-storage-content","properties":{},"type":"string"},"name":"content"},{"definition":{"description":"The name of the file to create.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"filename"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"The source file name. This parameter is usually set by the REST handler. You can only overwrite it when connecting to the trusted port on localhost.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tmpfilename"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.AllocateTemplate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/storage/{storage}/upload"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f69a09923a7e070b2be36d4ccb06e891f14a3518902eee5f7f7c27f6c58e46e7","description":"Delete subscription key of this node.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"1a55d17c6b6fcc76f2402f862dc4fc65c3995774895bbd9aab17cc2b9d769a3d","description":"Read subscription info.","extra":{"proxyto":"node"},"name":"get","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"cc5b0bf0f8d6f80ad754ad3c7f8b34593adec2e6459e66a6a5836a1158298c93","description":"Update subscription info.","extra":{"proxyto":"node"},"name":"update","parameters":[{"definition":{"default":0,"description":"Always connect to server, even if we have up to date info inside local cache.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"0ddd0a712a57d76823789e28e78bf18e08b5ffca5d79831c496a264b5ff19605","description":"Set subscription key.","extra":{"proxyto":"node"},"name":"set","parameters":[{"definition":{"description":"Proxmox VE subscription key","enum":[],"extra":{},"max_length":32,"pattern":"pve([1248])([cbsp])-[0-9a-f]{10}","properties":{},"type":"string"},"name":"key"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/subscription"},{"extra":{},"methods":[{"allow_token":true,"checksum":"627733cfb797f5cb56b37117c3cd10de855d36183e4e87b8e57c0207e6238edd","description":"Read system log","extra":{"proxyto":"node"},"name":"syslog","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"service"},{"definition":{"description":"Display all log since this date-time string.","enum":[],"extra":{},"optional":true,"pattern":"^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$","properties":{},"type":"string"},"name":"since"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"Display all log until this date-time string.","enum":[],"extra":{},"optional":true,"pattern":"^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$","properties":{},"type":"string"},"name":"until"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/syslog"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2716617b03688a8d4bfaed2bac83f7e2645a7bfd60b7ba750c4888ced436cc35","description":"Read task list for one node (finished tasks).","extra":{"proxyto":"node"},"name":"node_tasks","parameters":[{"definition":{"default":0,"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"errors"},{"definition":{"default":50,"description":"Only list this amount of tasks.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"archive","description":"List archived, active or all tasks.","enum":["archive","active","all"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"default":0,"description":"List tasks beginning from this offset.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"Only list tasks of this type (e.g., vzstart, vzdump).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"typefilter"},{"definition":{"description":"Only list tasks from this user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"userfilter"},{"definition":{"description":"Only list tasks for this VM.","enum":[],"extra":{"typetext":" (1 - N)"},"format":"pve-vmid","minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"List task associated with the current user, or all task the user has 'Sys.Audit' permissions on /nodes/ (the the task runs on).","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{upid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"endtime":{"enum":[],"extra":{"title":"Endtime"},"optional":true,"properties":{},"type":"integer"},"id":{"enum":[],"extra":{"title":"ID"},"properties":{},"type":"string"},"node":{"enum":[],"extra":{"title":"Node"},"properties":{},"type":"string"},"pid":{"enum":[],"extra":{"title":"PID"},"properties":{},"type":"integer"},"pstart":{"enum":[],"extra":{},"properties":{},"type":"integer"},"starttime":{"enum":[],"extra":{"title":"Starttime"},"properties":{},"type":"integer"},"status":{"enum":[],"extra":{"title":"Status"},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{"title":"Type"},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{"title":"UPID"},"properties":{},"type":"string"},"user":{"enum":[],"extra":{"title":"User"},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/tasks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"fcbf7bbf726ac4a85ef4b5c3096333eb0a4c293e79566a6255b54e21beb0508c","description":"Stop a task.","extra":{"proxyto":"node"},"name":"stop_task","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"upid"}],"permissions":{"description":"The user needs 'Sys.Modify' permissions on '/nodes/' if the task does not belong to him.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"88930b3a0d6654f9ead4d8adc76725935668dd88774af0a950aa627485d41dbf","description":"","extra":{},"name":"upid_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"upid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/tasks/{upid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ab302bfb4ebd6793e82ed5b035982b72a1615c36eba784cffae6ce72767bd09a","description":"Read task log.","extra":{"proxyto":"node"},"name":"read_task_log","parameters":[{"definition":{"default":50,"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"upid"}],"permissions":{"description":"The user needs 'Sys.Audit' permissions on '/nodes/' if the task does not belong to him.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/tasks/{upid}/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f6b9be8cf22de3a4013510af94841626d52a9894949bd72a1fde5c96c336dc5e","description":"Read task status.","extra":{"proxyto":"node"},"name":"read_task_status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"upid"}],"permissions":{"description":"The user needs 'Sys.Audit' permissions on '/nodes/' if the task does not belong to him.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"pid":{"enum":[],"extra":{},"properties":{},"type":"integer"},"status":{"enum":["running","stopped"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/tasks/{upid}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9ef2679c35f74968b1c2f236c71171e9814e57ff4886a2155f835fb6ccbf3f2c","description":"Creates a VNC Shell proxy.","extra":{},"name":"termproxy","parameters":[{"definition":{"default":"login","description":"Run specific command or default to login.","enum":["upgrade","ceph_install","login"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmd"},{"definition":{"default":"","description":"Add parameters to a command. Encoded as null terminated strings.","enum":[],"extra":{"requires":"cmd","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cmd-opts"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Deprecated, use the 'cmd' property instead! Run 'apt-get dist-upgrade' instead of normal shell.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"upgrade"}],"permissions":{"description":"Restricted to users on realm 'pam'","expression":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/termproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"15558dd947c7c5db6fd939f2882db13ec7cc1f3ed3889a21151f2ece44c27e19","description":"Read server time and time zone settings.","extra":{"proxyto":"node"},"name":"time","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"localtime":{"description":"Seconds since 1970-01-01 00:00:00 (local time)","enum":[],"extra":{"renderer":"timestamp_gmt"},"minimum":1297163644,"properties":{},"type":"integer"},"time":{"description":"Seconds since 1970-01-01 00:00:00 UTC.","enum":[],"extra":{"renderer":"timestamp"},"minimum":1297163644,"properties":{},"type":"integer"},"timezone":{"description":"Time zone","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"6e0e6c4e973322e4ff4de02a8f54fc9a9a9de171237797934f9056943f940639","description":"Set time zone.","extra":{"proxyto":"node"},"name":"set_timezone","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"timezone"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/time"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a2f20ffba970376ccb2903020b544f6ac94e79d7aaba8ea5df4a4cf3a2cfd266","description":"API version details","extra":{"proxyto":"node"},"name":"version","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"release":{"description":"The current installed Proxmox VE Release","enum":[],"extra":{},"properties":{},"type":"string"},"repoid":{"description":"The short git commit hash ID from which this version was build","enum":[],"extra":{},"properties":{},"type":"string"},"version":{"description":"The current installed pve-manager package version","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/version"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f099b37772ab3b845ca1d0376ebc651692bee319ffe1eaf51fa228975edc8182","description":"Creates a VNC Shell proxy.","extra":{},"name":"vncshell","parameters":[{"definition":{"default":"login","description":"Run specific command or default to login.","enum":["upgrade","ceph_install","login"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmd"},{"definition":{"default":"","description":"Add parameters to a command. Encoded as null terminated strings.","enum":[],"extra":{"requires":"cmd","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cmd-opts"},{"definition":{"description":"sets the height of the console in pixels.","enum":[],"extra":{"typetext":" (16 - 2160)"},"maximum":2160,"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"height"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Deprecated, use the 'cmd' property instead! Run 'apt-get dist-upgrade' instead of normal shell.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"upgrade"},{"definition":{"description":"use websocket instead of standard vnc.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"websocket"},{"definition":{"description":"sets the width of the console in pixels.","enum":[],"extra":{"typetext":" (16 - 4096)"},"maximum":4096,"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"width"}],"permissions":{"description":"Restricted to users on realm 'pam'","expression":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"cert":{"enum":[],"extra":{},"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/vncshell"},{"extra":{},"methods":[{"allow_token":true,"checksum":"aa197ecf243827fd112c7d26bfef6fae2cf7e5bc071caab5824f01c1ae12bdc2","description":"Opens a weksocket for VNC traffic.","extra":{},"name":"vncwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Port number returned by previous vncproxy call.","enum":[],"extra":{"typetext":" (5900 - 5999)"},"maximum":5999,"minimum":5900,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Ticket from previous call to vncproxy.","enum":[],"extra":{"typetext":""},"max_length":512,"properties":{},"type":"string"},"name":"vncticket"}],"permissions":{"description":"Restricted to users on realm 'pam'. You also need to pass a valid ticket (vncticket).","expression":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/vncwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ec130fb411843a40029c3d486f77fd221aec8b6ca97fbd2f2c856d18829bffb3","description":"Create backup.","extra":{"proxyto":"node"},"name":"vzdump","parameters":[{"definition":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"all"},{"definition":{"default":0,"description":"Limit I/O bandwidth (KBytes per second).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"compress"},{"definition":{"description":"Store resulting files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dumpdir"},{"definition":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"exclude"},{"definition":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{"typetext":""},"format":"string-alist","optional":true,"properties":{},"type":"string"},"name":"exclude-path"},{"definition":{"default":7,"description":"Set CFQ ionice priority.","enum":[],"extra":{"typetext":" (0 - 8)"},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"ionice"},{"definition":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"lockwait"},{"definition":{"default":"always","description":"Specify when to send an email","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mailnotification"},{"definition":{"description":"Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{"typetext":""},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"name":"mailto"},{"definition":{"default":1,"description":"Maximal number of backup files per guest system.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxfiles"},{"definition":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"Only run if executed on this node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"pigz"},{"definition":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"default":0,"description":"Be quiet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"quiet"},{"definition":{"default":1,"description":"Remove old backup files if there are more than 'maxfiles' backup files.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove"},{"definition":{"description":"Use specified hook script.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"script"},{"definition":{"default":1024,"description":"Unused, will be removed in a future release.","enum":[],"extra":{"typetext":" (500 - N)"},"minimum":500,"optional":true,"properties":{},"type":"integer"},"name":"size"},{"definition":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stdexcludes"},{"definition":{"description":"Write tar to stdout, not to a file.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stdout"},{"definition":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stop"},{"definition":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"stopwait"},{"definition":{"description":"Store resulting file to this storage.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Store temporary files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tmpdir"},{"definition":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vmid"},{"definition":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, N>0 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"zstd"}],"permissions":{"description":"The user needs 'VM.Backup' permissions on any VM, and 'Datastore.AllocateSpace' on the backup storage. The 'maxfiles', 'prune-backups', 'tmpdir', 'dumpdir', 'script', 'bwlimit' and 'ionice' parameters are restricted to the 'root@pam' user.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/vzdump"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f8b5be989170e3d358670d094ddea0adb2fea915f4e9dd63823c7825f787729d","description":"Get the currently configured vzdump defaults.","extra":{"proxyto":"node"},"name":"defaults","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"}],"permissions":{"description":"The user needs 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions for the specified storage (or default storage if none specified). Some properties are only returned when the user has 'Sys.Audit' permissions for the node.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"all":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bwlimit":{"default":0,"description":"Limit I/O bandwidth (KBytes per second).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"compress":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"dumpdir":{"description":"Store resulting files to specified directory.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"exclude":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"exclude-path":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{},"format":"string-alist","optional":true,"properties":{},"type":"string"},"ionice":{"default":7,"description":"Set CFQ ionice priority.","enum":[],"extra":{},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"lockwait":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"mailnotification":{"default":"always","description":"Specify when to send an email","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"mailto":{"description":"Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"maxfiles":{"default":1,"description":"Maximal number of backup files per guest system.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"mode":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"node":{"description":"Only run if executed on this node.","enum":[],"extra":{},"format":"pve-node","optional":true,"properties":{},"type":"string"},"pigz":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"pool":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"prune-backups":{"description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"quiet":{"default":0,"description":"Be quiet.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"remove":{"default":1,"description":"Remove old backup files if there are more than 'maxfiles' backup files.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"script":{"description":"Use specified hook script.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"size":{"default":1024,"description":"Unused, will be removed in a future release.","enum":[],"extra":{},"minimum":500,"optional":true,"properties":{},"type":"integer"},"stdexcludes":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"stop":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"stopwait":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"storage":{"description":"Store resulting file to this storage.","enum":[],"extra":{},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"tmpdir":{"description":"Store temporary files to specified directory.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vmid":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"zstd":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, N>0 uses N as thread count.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/vzdump/defaults"},{"extra":{},"methods":[{"allow_token":true,"checksum":"46b5389418506fa5f7d2d85017d6a32be6b0374dbb76191ec24067f39e16e8d9","description":"Extract configuration from vzdump backup archive.","extra":{"proxyto":"node"},"name":"extractconfig","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"The user needs 'VM.Backup' permissions on the backed up guest ID, and 'Datastore.AllocateSpace' on the backup storage.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/vzdump/extractconfig"},{"extra":{},"methods":[{"allow_token":true,"checksum":"08ea4b11d331163e4a96a0c898ba2d8587d9560fda14d97304383f4248499e0e","description":"Try to wake a node via 'wake on LAN' network packet.","extra":{},"name":"wakeonlan","parameters":[{"definition":{"description":"target node for wake on LAN packet","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"description":"MAC address used to assemble the WoL magic packet.","enum":[],"extra":{},"format":"mac-addr","properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/wakeonlan"},{"extra":{},"methods":[{"allow_token":true,"checksum":"028daa2afadc8a8025e960ebe0990a8296753b25ed5778dbe5bf4433859ed918","description":"Pool index.","extra":{},"name":"index","parameters":[],"permissions":{"description":"List all pools where you have Pool.Allocate or VM.Allocate permissions on /pool/.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{poolid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"poolid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"a2cb3cd45802791e51049833b8254ee8828f1f7e701c0fad2bf797ed4c4ed346","description":"Create new pool.","extra":{},"name":"create_pool","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"}],"permissions":{"expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/pools"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f4566d45dc0a2a49009509edfd1756bd72eabd7f60446d1184660ea5bc43c1f7","description":"Delete pool.","extra":{},"name":"delete_pool","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"}],"permissions":{"description":"You can only delete empty pools (no members).","expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"e81660d2d7768b9f9c103746f41938e9072aa579bfaf132876cf5e988f6c86a6","description":"Get pool configuration.","extra":{},"name":"read_pool","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"}],"permissions":{"expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"members":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"node":{"enum":[],"extra":{},"properties":{},"type":"string"},"storage":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":["qemu","lxc","openvz","storage"],"extra":{},"properties":{},"type":"string"},"vmid":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"5d1092c81fe8cc5f00d2f51bca45b5cc0354a7c74896ae61002543445f11b894","description":"Update pool data.","extra":{},"name":"update_pool","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Remove vms/storage (instead of adding it).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"},{"definition":{"description":"List of storage IDs.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id-list","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"List of virtual machines.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"}],"permissions":{"description":"You also need the right to modify permissions on any object you add/delete.","expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/pools/{poolid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4e2ef261d98cf79ebfc5c52596f91c076ec8cc8d4f15a8fe146edd33095aab31","description":"Storage index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list storage of specific type","enum":["cephfs","cifs","dir","drbd","glusterfs","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{storage}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"storage":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"25861d32024e3fbab13e3f2243ef25247bfc16b514ad6774022573973c4b8b0a","description":"Create a new storage.","extra":{},"name":"create","parameters":[{"definition":{"description":"Authsupported.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"authsupported"},{"definition":{"description":"Base volume. This volume is automatically activated.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"base"},{"definition":{"description":"block size","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"blocksize"},{"definition":{"description":"Set bandwidth/io limits various operations.","enum":[],"extra":{"typetext":"[clone=] [,default=] [,migration=] [,move=] [,restore=]"},"format":{"clone":{"description":"bandwidth limit in KiB/s for cloning disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"default":{"description":"default bandwidth limit in KiB/s","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"migration":{"description":"bandwidth limit in KiB/s for migrating guests (including moving local disks)","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"move":{"description":"bandwidth limit in KiB/s for moving disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"restore":{"description":"bandwidth limit in KiB/s for restoring guests from backups","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"}},"optional":true,"properties":{},"type":"string"},"name":"bwlimit"},{"definition":{"description":"host group for comstar views","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comstar_hg"},{"definition":{"description":"target group for comstar views","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comstar_tg"},{"definition":{"description":"Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n","enum":[],"extra":{"typetext":""},"format":"pve-storage-content-list","optional":true,"properties":{},"type":"string"},"name":"content"},{"definition":{"description":"Proxmox Backup Server datastore name.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"datastore"},{"definition":{"description":"Flag to disable the storage.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"CIFS domain.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"Encryption key. Use 'autogen' to generate one automatically without passphrase.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"encryption-key"},{"definition":{"description":"NFS export path.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"export"},{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"Default image format.","enum":[],"extra":{"typetext":""},"format":"pve-storage-format","optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"Mount CephFS through FUSE.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"fuse"},{"definition":{"default":"no","description":"Assume the given path is an externally managed mountpoint and consider the storage offline if it is not mounted. Using a boolean (yes/no) value serves as a shortcut to using the target path in this field.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"is_mountpoint"},{"definition":{"description":"iscsi provider","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"iscsiprovider"},{"definition":{"description":"Always access rbd through krbd kernel module.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"krbd"},{"definition":{"description":"target portal group for Linux LIO targets","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lio_tpg"},{"definition":{"description":"Base64-encoded, PEM-formatted public RSA key. Used tp encrypt a copy of the encryption-key which will be added to each encrypted backup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"master-pubkey"},{"definition":{"description":"Maximal number of backup files per VM. Use '0' for unlimted.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"maxfiles"},{"definition":{"default":"yes","description":"Create the directory if it doesn't exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"mkdir"},{"definition":{"description":"IP addresses of monitors (for external clusters).","enum":[],"extra":{"typetext":""},"format":"pve-storage-portal-dns-list","optional":true,"properties":{},"type":"string"},"name":"monhost"},{"definition":{"description":"mount point","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"mountpoint"},{"definition":{"description":"RBD Namespace.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"namespace"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"disable write caching on the target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nowritecache"},{"definition":{"description":"NFS mount options (see 'man nfs')","enum":[],"extra":{"typetext":""},"format":"pve-storage-options","optional":true,"properties":{},"type":"string"},"name":"options"},{"definition":{"description":"Password for accessing the share/datastore.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"File system path.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"Pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"default":8007,"description":"For non default port.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"iSCSI portal (IP or DNS name with optional port).","enum":[],"extra":{"typetext":""},"format":"pve-storage-portal-dns","optional":true,"properties":{},"type":"string"},"name":"portal"},{"definition":{"description":"The retention options with shorter intervals are processed first with --keep-last being the very first one. Each option covers a specific period of time. We say that backups within this period are covered by this option. The next option does not take care of already covered backups and only considers older backups.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"default":2,"description":"The redundancy count specifies the number of nodes to which the resource should be deployed. It must be at least 1 and at most the number of nodes in the cluster.","enum":[],"extra":{"typetext":" (1 - 16)"},"maximum":16,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"redundancy"},{"definition":{"description":"Zero-out data when removing LVs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"saferemove"},{"definition":{"description":"Wipe throughput (cstream -t parameter value).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"saferemove_throughput"},{"definition":{"description":"Server IP or DNS name.","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","optional":true,"properties":{},"type":"string"},"name":"server"},{"definition":{"description":"Backup volfile server IP or DNS name.","enum":[],"extra":{"requires":"server","typetext":""},"format":"pve-storage-server","optional":true,"properties":{},"type":"string"},"name":"server2"},{"definition":{"description":"CIFS share.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"share"},{"definition":{"description":"Mark storage as shared.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"shared"},{"definition":{"description":"SMB protocol version","enum":["2.0","2.1","3.0"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"smbversion"},{"definition":{"description":"use sparse volumes","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"sparse"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Subdir to mount.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"subdir"},{"definition":{"description":"Only use logical volumes tagged with 'pve-vm-ID'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tagged_only"},{"definition":{"description":"iSCSI target.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"LVM thin pool LV name.","enum":[],"extra":{"typetext":""},"format":"pve-storage-vgname","optional":true,"properties":{},"type":"string"},"name":"thinpool"},{"definition":{"description":"Gluster transport: tcp or rdma","enum":["tcp","rdma","unix"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"transport"},{"definition":{"description":"Storage type.","enum":["cephfs","cifs","dir","drbd","glusterfs","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"RBD Id.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username"},{"definition":{"description":"Volume group name.","enum":[],"extra":{"typetext":""},"format":"pve-storage-vgname","optional":true,"properties":{},"type":"string"},"name":"vgname"},{"definition":{"description":"Glusterfs Volume.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"volume"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"config":{"description":"Partial, possible server generated, configuration properties.","enum":[],"extra":{"additionalProperties":1},"optional":true,"properties":{"encryption-key":{"description":"The, possible auto-generated, encryption-key.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"storage":{"description":"The ID of the created storage.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The type of the created storage.","enum":["cephfs","cifs","dir","drbd","glusterfs","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"POST"}],"path":"/storage"},{"extra":{},"methods":[{"allow_token":true,"checksum":"07c09ccad12cdd559d663c2f45c8eb672506c8e764311ca5ccd2bd07698f0ce4","description":"Delete storage configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"5e124a73a6f726240a993f3e601a732af79e780bc88d085a5822c5170d7060b8","description":"Read storage configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"45fd531fe7c30a934f29b56ab03b04edb944eff708496e9644c70811743efcf0","description":"Update storage configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"block size","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"blocksize"},{"definition":{"description":"Set bandwidth/io limits various operations.","enum":[],"extra":{"typetext":"[clone=] [,default=] [,migration=] [,move=] [,restore=]"},"format":{"clone":{"description":"bandwidth limit in KiB/s for cloning disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"default":{"description":"default bandwidth limit in KiB/s","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"migration":{"description":"bandwidth limit in KiB/s for migrating guests (including moving local disks)","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"move":{"description":"bandwidth limit in KiB/s for moving disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"restore":{"description":"bandwidth limit in KiB/s for restoring guests from backups","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"}},"optional":true,"properties":{},"type":"string"},"name":"bwlimit"},{"definition":{"description":"host group for comstar views","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comstar_hg"},{"definition":{"description":"target group for comstar views","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comstar_tg"},{"definition":{"description":"Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n","enum":[],"extra":{"typetext":""},"format":"pve-storage-content-list","optional":true,"properties":{},"type":"string"},"name":"content"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Flag to disable the storage.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"CIFS domain.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"Encryption key. Use 'autogen' to generate one automatically without passphrase.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"encryption-key"},{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"Default image format.","enum":[],"extra":{"typetext":""},"format":"pve-storage-format","optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"Mount CephFS through FUSE.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"fuse"},{"definition":{"default":"no","description":"Assume the given path is an externally managed mountpoint and consider the storage offline if it is not mounted. Using a boolean (yes/no) value serves as a shortcut to using the target path in this field.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"is_mountpoint"},{"definition":{"description":"Always access rbd through krbd kernel module.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"krbd"},{"definition":{"description":"target portal group for Linux LIO targets","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lio_tpg"},{"definition":{"description":"Base64-encoded, PEM-formatted public RSA key. Used tp encrypt a copy of the encryption-key which will be added to each encrypted backup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"master-pubkey"},{"definition":{"description":"Maximal number of backup files per VM. Use '0' for unlimted.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"maxfiles"},{"definition":{"default":"yes","description":"Create the directory if it doesn't exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"mkdir"},{"definition":{"description":"IP addresses of monitors (for external clusters).","enum":[],"extra":{"typetext":""},"format":"pve-storage-portal-dns-list","optional":true,"properties":{},"type":"string"},"name":"monhost"},{"definition":{"description":"mount point","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"mountpoint"},{"definition":{"description":"RBD Namespace.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"namespace"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"disable write caching on the target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nowritecache"},{"definition":{"description":"NFS mount options (see 'man nfs')","enum":[],"extra":{"typetext":""},"format":"pve-storage-options","optional":true,"properties":{},"type":"string"},"name":"options"},{"definition":{"description":"Password for accessing the share/datastore.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"default":8007,"description":"For non default port.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The retention options with shorter intervals are processed first with --keep-last being the very first one. Each option covers a specific period of time. We say that backups within this period are covered by this option. The next option does not take care of already covered backups and only considers older backups.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"default":2,"description":"The redundancy count specifies the number of nodes to which the resource should be deployed. It must be at least 1 and at most the number of nodes in the cluster.","enum":[],"extra":{"typetext":" (1 - 16)"},"maximum":16,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"redundancy"},{"definition":{"description":"Zero-out data when removing LVs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"saferemove"},{"definition":{"description":"Wipe throughput (cstream -t parameter value).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"saferemove_throughput"},{"definition":{"description":"Server IP or DNS name.","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","optional":true,"properties":{},"type":"string"},"name":"server"},{"definition":{"description":"Backup volfile server IP or DNS name.","enum":[],"extra":{"requires":"server","typetext":""},"format":"pve-storage-server","optional":true,"properties":{},"type":"string"},"name":"server2"},{"definition":{"description":"Mark storage as shared.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"shared"},{"definition":{"description":"SMB protocol version","enum":["2.0","2.1","3.0"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"smbversion"},{"definition":{"description":"use sparse volumes","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"sparse"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Subdir to mount.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"subdir"},{"definition":{"description":"Only use logical volumes tagged with 'pve-vm-ID'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tagged_only"},{"definition":{"description":"Gluster transport: tcp or rdma","enum":["tcp","rdma","unix"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"transport"},{"definition":{"description":"RBD Id.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"config":{"description":"Partial, possible server generated, configuration properties.","enum":[],"extra":{"additionalProperties":1},"optional":true,"properties":{"encryption-key":{"description":"The, possible auto-generated, encryption-key.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"storage":{"description":"The ID of the created storage.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The type of the created storage.","enum":["cephfs","cifs","dir","drbd","glusterfs","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"PUT"}],"path":"/storage/{storage}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a6ceac5b622337356526d48b2e090a2bb5d1f78345cf43e945e6774dce465d54","description":"API version details. The result also includes the global datacenter confguration.","extra":{},"name":"version","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"release":{"enum":[],"extra":{},"properties":{},"type":"string"},"repoid":{"enum":[],"extra":{},"properties":{},"type":"string"},"version":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/version"}],"raw_sha256":"374156fc7188fb23c40982d0ff63fb7dce601f80f7319032bbb94882f47af69f","retrieved_at":"2026-07-15T10:50:30.029415Z","source_version":"6.4-15"} \ No newline at end of file diff --git a/contracts/README.md b/contracts/README.md new file mode 100644 index 0000000..6ea3a42 --- /dev/null +++ b/contracts/README.md @@ -0,0 +1,21 @@ +**Language / Язык:** [English](README.md) | [Русский](README.ru.md) + +# Contract store + +## Native vSphere stub matrices (`contracts/vsphere/`) + +Versioned `manifest.json` files for majors **6–9** (vSphere 7.0 → 8.0 U2). +They are **stub OpenAPI stand-ins** derived from +`app/vsphere/contracts/matrix.py` (handler registry + per-path floors), not +Broadcom OpenAPI dumps. + +- Catalog browse and compatibility UI read these bundles. +- `POST /ui/api/contract/apply?major=N` hot-swaps the active **catalog** major + for Web UI / evidence only; runtime still serves the full registered surface + (no HTTP 501 from version floor). +- Regenerate: `python scripts/write_vsphere_bundles.py` / `make vsphere-bundles` + +## Legacy Proxmox SHA directories + +SHA-addressed snapshot directories remain for optional `ENABLE_PVE_STUB=true` +lab mode only. They are **not** used when the native vSphere plane is default. diff --git a/contracts/README.ru.md b/contracts/README.ru.md new file mode 100644 index 0000000..6b30db3 --- /dev/null +++ b/contracts/README.ru.md @@ -0,0 +1,22 @@ +**Language / Язык:** [English](README.md) | [Русский](README.ru.md) + +# Хранилище контрактов + +## Нативные vSphere stub-матрицы (`contracts/vsphere/`) + +Версионированные файлы `manifest.json` для majors **6–9** (vSphere 7.0 → 8.0 U2). +Это **stub OpenAPI stand-in'ы**, выведенные из +`app/vsphere/contracts/matrix.py` (реестр обработчиков + per-path floors), а не +дампы Broadcom OpenAPI. + +- Browse каталога и UI совместимости читают эти bundles. +- `POST /ui/api/contract/apply?major=N` hot-swap'ает активный **catalog** major + только для Web UI / evidence; runtime по-прежнему обслуживает полную + зарегистрированную поверхность (без HTTP 501 из-за version floor). +- Перегенерация: `python scripts/write_vsphere_bundles.py` / `make vsphere-bundles` + +## Legacy-каталоги Proxmox SHA + +SHA-адресованные каталоги snapshot остаются только для опционального lab-режима +`ENABLE_PVE_STUB=true`. Они **не** используются, когда нативная плоскость +vSphere включена по умолчанию. diff --git a/contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/manifest.json b/contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/manifest.json new file mode 100644 index 0000000..f4010c0 --- /dev/null +++ b/contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/manifest.json @@ -0,0 +1 @@ +{"method_count":675,"path_count":444,"raw_sha256":"f2b77b57c71f3781a0993cc5062940ef31e0843fd9a6bcfdb4de4dd2001d6d9e","snapshot_sha256":"e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1","source_version":"9.2.3"} \ No newline at end of file diff --git a/contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/raw.js b/contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/raw.js new file mode 100644 index 0000000..1ef84ec --- /dev/null +++ b/contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/raw.js @@ -0,0 +1,71325 @@ +const apiSchema = [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Mark replication job for removal.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "Will remove the jobconfig entry, but will not cleanup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "keep" : { + "default" : 0, + "description" : "Keep replicated data at target (do not remove).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Replicate permission on /vms/.", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read replication job configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/.", + "user" : "all" + }, + "returns" : { + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "disable" : { + "description" : "Flag to disable/deactivate the entry.", + "optional" : 1, + "type" : "boolean" + }, + "guest" : { + "description" : "Guest ID.", + "type" : "integer" + }, + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "jobnum" : { + "description" : "Unique, sequential ID assigned to each job.", + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 1, + "optional" : 1, + "type" : "number" + }, + "remove_job" : { + "description" : "Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.", + "enum" : [ + "local", + "full" + ], + "optional" : 1, + "type" : "string" + }, + "schedule" : { + "default" : "*/15", + "description" : "Storage replication schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "For internal use, to detect if the guest was stolen.", + "format" : "pve-node", + "optional" : 1, + "type" : "string" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "optional" : 0, + "type" : "string" + }, + "type" : { + "description" : "Section type.", + "enum" : [ + "local" + ], + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update replication job configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable/deactivate the entry.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 1, + "optional" : 1, + "type" : "number", + "typetext" : " (1 - N)" + }, + "remove_job" : { + "description" : "Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.", + "enum" : [ + "local", + "full" + ], + "optional" : 1, + "type" : "string" + }, + "schedule" : { + "default" : "*/15", + "description" : "Storage replication schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "For internal use, to detect if the guest was stolen.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "description" : "Requires the VM.Replicate permission on /vms/.", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/replication/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List replication jobs.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "Will only return replication jobs for which the calling user has VM.Audit permission on /vms/.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string" + }, + "disable" : { + "description" : "Flag to disable/deactivate the entry.", + "optional" : 1, + "type" : "boolean" + }, + "guest" : { + "description" : "Guest ID.", + "type" : "integer" + }, + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "jobnum" : { + "description" : "Unique, sequential ID assigned to each job.", + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 1, + "optional" : 1, + "type" : "number" + }, + "remove_job" : { + "description" : "Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.", + "enum" : [ + "local", + "full" + ], + "optional" : 1, + "type" : "string" + }, + "schedule" : { + "default" : "*/15", + "description" : "Storage replication schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "For internal use, to detect if the guest was stolen.", + "format" : "pve-node", + "optional" : 1, + "type" : "string" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "optional" : 0, + "type" : "string" + }, + "type" : { + "description" : "Section type.", + "enum" : [ + "local" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new replication job", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable/deactivate the entry.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 1, + "optional" : 1, + "type" : "number", + "typetext" : " (1 - N)" + }, + "remove_job" : { + "description" : "Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.", + "enum" : [ + "local", + "full" + ], + "optional" : 1, + "type" : "string" + }, + "schedule" : { + "default" : "*/15", + "description" : "Storage replication schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "For internal use, to detect if the guest was stolen.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Section type.", + "enum" : [ + "local" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "description" : "Requires the VM.Replicate permission on /vms/.", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/replication", + "text" : "replication" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove Metric server.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read metric server configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new external metric server config", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "api-path-prefix" : { + "description" : "An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bucket" : { + "description" : "The InfluxDB bucket/db. Only necessary when using the http v2 api.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the plugin.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the entry.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "influxdbproto" : { + "default" : "udp", + "enum" : [ + "udp", + "http", + "https" + ], + "optional" : 1, + "type" : "string" + }, + "max-body-size" : { + "default" : 25000000, + "description" : "InfluxDB max-body-size in bytes. Requests are batched up to this size.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mtu" : { + "default" : 1500, + "description" : "MTU for metrics transmission over UDP", + "maximum" : 65536, + "minimum" : 512, + "optional" : 1, + "type" : "integer", + "typetext" : " (512 - 65536)" + }, + "organization" : { + "description" : "The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "otel-compression" : { + "default" : "gzip", + "description" : "Compression algorithm for requests", + "enum" : [ + "none", + "gzip" + ], + "optional" : 1, + "type" : "string" + }, + "otel-headers" : { + "description" : "Custom HTTP headers (JSON format, base64 encoded)", + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "otel-max-body-size" : { + "default" : 10000000, + "description" : "Maximum request body size in bytes", + "minimum" : 1024, + "optional" : 1, + "type" : "integer", + "typetext" : " (1024 - N)" + }, + "otel-path" : { + "default" : "/v1/metrics", + "description" : "OTLP endpoint path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "otel-protocol" : { + "default" : "https", + "description" : "HTTP protocol", + "enum" : [ + "http", + "https" + ], + "optional" : 1, + "type" : "string" + }, + "otel-resource-attributes" : { + "description" : "Additional resource attributes as JSON, base64 encoded", + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "otel-timeout" : { + "default" : 5, + "description" : "HTTP request timeout in seconds", + "maximum" : 10, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 10)" + }, + "otel-verify-ssl" : { + "default" : 1, + "description" : "Verify SSL certificates", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "path" : { + "description" : "root graphite path (ex: proxmox.mycluster.mykey)", + "format" : "graphite-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "server network port", + "maximum" : 65536, + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - 65536)" + }, + "proto" : { + "description" : "Protocol to send graphite data. TCP or UDP (default)", + "enum" : [ + "udp", + "tcp" + ], + "optional" : 1, + "type" : "string" + }, + "server" : { + "description" : "server dns name or IP address", + "format" : "address", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 1, + "description" : "graphite TCP socket timeout (default=1)", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "token" : { + "description" : "The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "graphite", + "influxdb", + "opentelemetry" + ], + "format" : "pve-configid", + "type" : "string" + }, + "verify-certificate" : { + "default" : 1, + "description" : "Set to 0 to disable certificate verification for https endpoints.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update metric server configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "api-path-prefix" : { + "description" : "An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bucket" : { + "description" : "The InfluxDB bucket/db. Only necessary when using the http v2 api.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the plugin.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the entry.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "influxdbproto" : { + "default" : "udp", + "enum" : [ + "udp", + "http", + "https" + ], + "optional" : 1, + "type" : "string" + }, + "max-body-size" : { + "default" : 25000000, + "description" : "InfluxDB max-body-size in bytes. Requests are batched up to this size.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mtu" : { + "default" : 1500, + "description" : "MTU for metrics transmission over UDP", + "maximum" : 65536, + "minimum" : 512, + "optional" : 1, + "type" : "integer", + "typetext" : " (512 - 65536)" + }, + "organization" : { + "description" : "The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "otel-compression" : { + "default" : "gzip", + "description" : "Compression algorithm for requests", + "enum" : [ + "none", + "gzip" + ], + "optional" : 1, + "type" : "string" + }, + "otel-headers" : { + "description" : "Custom HTTP headers (JSON format, base64 encoded)", + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "otel-max-body-size" : { + "default" : 10000000, + "description" : "Maximum request body size in bytes", + "minimum" : 1024, + "optional" : 1, + "type" : "integer", + "typetext" : " (1024 - N)" + }, + "otel-path" : { + "default" : "/v1/metrics", + "description" : "OTLP endpoint path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "otel-protocol" : { + "default" : "https", + "description" : "HTTP protocol", + "enum" : [ + "http", + "https" + ], + "optional" : 1, + "type" : "string" + }, + "otel-resource-attributes" : { + "description" : "Additional resource attributes as JSON, base64 encoded", + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "otel-timeout" : { + "default" : 5, + "description" : "HTTP request timeout in seconds", + "maximum" : 10, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 10)" + }, + "otel-verify-ssl" : { + "default" : 1, + "description" : "Verify SSL certificates", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "path" : { + "description" : "root graphite path (ex: proxmox.mycluster.mykey)", + "format" : "graphite-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "server network port", + "maximum" : 65536, + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - 65536)" + }, + "proto" : { + "description" : "Protocol to send graphite data. TCP or UDP (default)", + "enum" : [ + "udp", + "tcp" + ], + "optional" : 1, + "type" : "string" + }, + "server" : { + "description" : "server dns name or IP address", + "format" : "address", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 1, + "description" : "graphite TCP socket timeout (default=1)", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "token" : { + "description" : "The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "verify-certificate" : { + "default" : 1, + "description" : "Set to 0 to disable certificate verification for https endpoints.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/metrics/server/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List configured metric servers.", + "method" : "GET", + "name" : "server_index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "disable" : { + "description" : "Flag to disable the plugin.", + "type" : "boolean" + }, + "id" : { + "description" : "The ID of the entry.", + "type" : "string" + }, + "port" : { + "description" : "Server network port", + "type" : "integer" + }, + "server" : { + "description" : "Server dns name or IP address", + "type" : "string" + }, + "type" : { + "description" : "Plugin type.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/metrics/server", + "text" : "server" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Retrieve metrics of the cluster.", + "expose_credentials" : 1, + "method" : "GET", + "name" : "export", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "history" : { + "default" : 0, + "description" : "Also return historic values. Returns full available metric history unless `start-time` is also set", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "local-only" : { + "default" : 0, + "description" : "Only return metrics for the current node instead of the whole cluster", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node-list" : { + "description" : "Only return metrics from nodes passed as comma-separated list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "start-time" : { + "default" : 0, + "description" : "Only include metrics with a timestamp > start-time.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "data" : { + "description" : "Array of system metrics. Metrics are sorted by their timestamp.", + "items" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Unique identifier for this metric object, for instance 'node/' or 'qemu/'.", + "type" : "string" + }, + "metric" : { + "description" : "Name of the metric.", + "type" : "string" + }, + "timestamp" : { + "description" : "Time at which this metric was observed", + "type" : "integer" + }, + "type" : { + "description" : "Type of the metric.", + "enum" : [ + "gauge", + "counter", + "derive" + ], + "type" : "string" + }, + "value" : { + "description" : "Metric value.", + "type" : "number" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/metrics/export", + "text" : "export" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Metrics index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/metrics", + "text" : "metrics" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns known notification metadata fields", + "method" : "GET", + "name" : "get_matcher_fields", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 0, + "returns" : { + "items" : { + "properties" : { + "name" : { + "description" : "Name of the field.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/notifications/matcher-fields", + "text" : "matcher-fields" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns known notification metadata fields and their known values", + "method" : "GET", + "name" : "get_matcher_field_values", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "Additional comment for this value.", + "optional" : 1, + "type" : "string" + }, + "field" : { + "description" : "Field this value belongs to.", + "type" : "string" + }, + "value" : { + "description" : "Notification metadata value known by the system.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/notifications/matcher-field-values", + "text" : "matcher-field-values" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove sendmail endpoint", + "method" : "DELETE", + "name" : "delete_sendmail_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Return a specific sendmail endpoint", + "method" : "GET", + "name" : "get_sendmail_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "author" : { + "description" : "Author of the mail", + "optional" : 1, + "type" : "string" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean" + }, + "from-address" : { + "description" : "`From` address for the mail", + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "List of email recipients", + "items" : { + "format" : "email-or-username", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "mailto-user" : { + "description" : "List of users", + "items" : { + "format" : "pve-userid", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update existing sendmail endpoint", + "method" : "PUT", + "name" : "update_sendmail_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "author" : { + "description" : "Author of the mail", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "from-address" : { + "description" : "`From` address for the mail", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mailto" : { + "description" : "List of email recipients", + "items" : { + "format" : "email-or-username", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mailto-user" : { + "description" : "List of users", + "items" : { + "format" : "pve-userid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/notifications/endpoints/sendmail/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns a list of all sendmail endpoints", + "method" : "GET", + "name" : "get_sendmail_endpoints", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "author" : { + "description" : "Author of the mail", + "optional" : 1, + "type" : "string" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean" + }, + "from-address" : { + "description" : "`From` address for the mail", + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "List of email recipients", + "items" : { + "format" : "email-or-username", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "mailto-user" : { + "description" : "List of users", + "items" : { + "format" : "pve-userid", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string" + }, + "origin" : { + "description" : "Show if this entry was created by a user or was built-in", + "enum" : [ + "user-created", + "builtin", + "modified-builtin" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sendmail endpoint", + "method" : "POST", + "name" : "create_sendmail_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "author" : { + "description" : "Author of the mail", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "from-address" : { + "description" : "`From` address for the mail", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mailto" : { + "description" : "List of email recipients", + "items" : { + "format" : "email-or-username", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mailto-user" : { + "description" : "List of users", + "items" : { + "format" : "pve-userid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/notifications/endpoints/sendmail", + "text" : "sendmail" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove gotify endpoint", + "method" : "DELETE", + "name" : "delete_gotify_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Return a specific gotify endpoint", + "method" : "GET", + "name" : "get_gotify_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string" + }, + "server" : { + "description" : "Server URL", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update existing gotify endpoint", + "method" : "PUT", + "name" : "update_gotify_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "Server URL", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "token" : { + "description" : "Secret token", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/notifications/endpoints/gotify/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns a list of all gotify endpoints", + "method" : "GET", + "name" : "get_gotify_endpoints", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string" + }, + "origin" : { + "description" : "Show if this entry was created by a user or was built-in", + "enum" : [ + "user-created", + "builtin", + "modified-builtin" + ], + "type" : "string" + }, + "server" : { + "description" : "Server URL", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new gotify endpoint", + "method" : "POST", + "name" : "create_gotify_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "Server URL", + "type" : "string", + "typetext" : "" + }, + "token" : { + "description" : "Secret token", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/notifications/endpoints/gotify", + "text" : "gotify" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove smtp endpoint", + "method" : "DELETE", + "name" : "delete_smtp_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Return a specific smtp endpoint", + "method" : "GET", + "name" : "get_smtp_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "author" : { + "description" : "Author of the mail. Defaults to 'Proxmox VE'.", + "optional" : 1, + "type" : "string" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean" + }, + "from-address" : { + "description" : "`From` address for the mail", + "type" : "string" + }, + "mailto" : { + "description" : "List of email recipients", + "items" : { + "format" : "email-or-username", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "mailto-user" : { + "description" : "List of users", + "items" : { + "format" : "pve-userid", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "mode" : { + "default" : "tls", + "description" : "Determine which encryption method shall be used for the connection.", + "enum" : [ + "insecure", + "starttls", + "tls" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string" + }, + "port" : { + "description" : "The port to be used. Defaults to 465 for TLS based connections, 587 for STARTTLS based connections and port 25 for insecure plain-text connections.", + "optional" : 1, + "type" : "integer" + }, + "server" : { + "description" : "The address of the SMTP server.", + "type" : "string" + }, + "username" : { + "description" : "Username for SMTP authentication", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update existing smtp endpoint", + "method" : "PUT", + "name" : "update_smtp_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "author" : { + "description" : "Author of the mail. Defaults to 'Proxmox VE'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "from-address" : { + "description" : "`From` address for the mail", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mailto" : { + "description" : "List of email recipients", + "items" : { + "format" : "email-or-username", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mailto-user" : { + "description" : "List of users", + "items" : { + "format" : "pve-userid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mode" : { + "default" : "tls", + "description" : "Determine which encryption method shall be used for the connection.", + "enum" : [ + "insecure", + "starttls", + "tls" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "Password for SMTP authentication", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "The port to be used. Defaults to 465 for TLS based connections, 587 for STARTTLS based connections and port 25 for insecure plain-text connections.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "server" : { + "description" : "The address of the SMTP server.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "Username for SMTP authentication", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/notifications/endpoints/smtp/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns a list of all smtp endpoints", + "method" : "GET", + "name" : "get_smtp_endpoints", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "author" : { + "description" : "Author of the mail. Defaults to 'Proxmox VE'.", + "optional" : 1, + "type" : "string" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean" + }, + "from-address" : { + "description" : "`From` address for the mail", + "type" : "string" + }, + "mailto" : { + "description" : "List of email recipients", + "items" : { + "format" : "email-or-username", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "mailto-user" : { + "description" : "List of users", + "items" : { + "format" : "pve-userid", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "mode" : { + "default" : "tls", + "description" : "Determine which encryption method shall be used for the connection.", + "enum" : [ + "insecure", + "starttls", + "tls" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string" + }, + "origin" : { + "description" : "Show if this entry was created by a user or was built-in", + "enum" : [ + "user-created", + "builtin", + "modified-builtin" + ], + "type" : "string" + }, + "port" : { + "description" : "The port to be used. Defaults to 465 for TLS based connections, 587 for STARTTLS based connections and port 25 for insecure plain-text connections.", + "optional" : 1, + "type" : "integer" + }, + "server" : { + "description" : "The address of the SMTP server.", + "type" : "string" + }, + "username" : { + "description" : "Username for SMTP authentication", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new smtp endpoint", + "method" : "POST", + "name" : "create_smtp_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "author" : { + "description" : "Author of the mail. Defaults to 'Proxmox VE'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "from-address" : { + "description" : "`From` address for the mail", + "type" : "string", + "typetext" : "" + }, + "mailto" : { + "description" : "List of email recipients", + "items" : { + "format" : "email-or-username", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mailto-user" : { + "description" : "List of users", + "items" : { + "format" : "pve-userid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mode" : { + "default" : "tls", + "description" : "Determine which encryption method shall be used for the connection.", + "enum" : [ + "insecure", + "starttls", + "tls" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "Password for SMTP authentication", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "The port to be used. Defaults to 465 for TLS based connections, 587 for STARTTLS based connections and port 25 for insecure plain-text connections.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "server" : { + "description" : "The address of the SMTP server.", + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "Username for SMTP authentication", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/notifications/endpoints/smtp", + "text" : "smtp" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove webhook endpoint", + "method" : "DELETE", + "name" : "delete_webhook_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Return a specific webhook endpoint", + "method" : "GET", + "name" : "get_webhook_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "body" : { + "description" : "HTTP body, base64 encoded", + "optional" : 1, + "type" : "string" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean" + }, + "header" : { + "description" : "HTTP headers to set. These have to be formatted as a property string in the format name=,value=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "method" : { + "description" : "HTTP method", + "enum" : [ + "post", + "put", + "get" + ], + "type" : "string" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string" + }, + "secret" : { + "description" : "Secrets to set. These have to be formatted as a property string in the format name=,value=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "url" : { + "description" : "Server URL", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update existing webhook endpoint", + "method" : "PUT", + "name" : "update_webhook_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "body" : { + "description" : "HTTP body, base64 encoded", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "header" : { + "description" : "HTTP headers to set. These have to be formatted as a property string in the format name=,value=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "method" : { + "description" : "HTTP method", + "enum" : [ + "post", + "put", + "get" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "secret" : { + "description" : "Secrets to set. These have to be formatted as a property string in the format name=,value=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "url" : { + "description" : "Server URL", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/notifications/endpoints/webhook/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns a list of all webhook endpoints", + "method" : "GET", + "name" : "get_webhook_endpoints", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "body" : { + "description" : "HTTP body, base64 encoded", + "optional" : 1, + "type" : "string" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean" + }, + "header" : { + "description" : "HTTP headers to set. These have to be formatted as a property string in the format name=,value=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "method" : { + "description" : "HTTP method", + "enum" : [ + "post", + "put", + "get" + ], + "type" : "string" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string" + }, + "origin" : { + "description" : "Show if this entry was created by a user or was built-in", + "enum" : [ + "user-created", + "builtin", + "modified-builtin" + ], + "type" : "string" + }, + "secret" : { + "description" : "Secrets to set. These have to be formatted as a property string in the format name=,value=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "url" : { + "description" : "Server URL", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new webhook endpoint", + "method" : "POST", + "name" : "create_webhook_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "body" : { + "description" : "HTTP body, base64 encoded", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "header" : { + "description" : "HTTP headers to set. These have to be formatted as a property string in the format name=,value=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "method" : { + "description" : "HTTP method", + "enum" : [ + "post", + "put", + "get" + ], + "type" : "string" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "secret" : { + "description" : "Secrets to set. These have to be formatted as a property string in the format name=,value=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "url" : { + "description" : "Server URL", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/notifications/endpoints/webhook", + "text" : "webhook" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index for all available endpoint types.", + "method" : "GET", + "name" : "endpoints_index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/notifications/endpoints", + "text" : "endpoints" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Send a test notification to a provided target.", + "method" : "POST", + "name" : "test_target", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Name of the target.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Use" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/notifications/targets/{name}/test", + "text" : "test" + } + ], + "leaf" : 0, + "path" : "/cluster/notifications/targets/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns a list of all entities that can be used as notification targets.", + "method" : "GET", + "name" : "get_all_targets", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Use" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Show if this target is disabled", + "optional" : 1, + "type" : "boolean" + }, + "name" : { + "description" : "Name of the target.", + "format" : "pve-configid", + "type" : "string" + }, + "origin" : { + "description" : "Show if this entry was created by a user or was built-in", + "enum" : [ + "user-created", + "builtin", + "modified-builtin" + ], + "type" : "string" + }, + "type" : { + "description" : "Type of the target.", + "enum" : [ + "sendmail", + "gotify", + "smtp", + "webhook" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/notifications/targets", + "text" : "targets" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove matcher", + "method" : "DELETE", + "name" : "delete_matcher", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Return a specific matcher", + "method" : "GET", + "name" : "get_matcher", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this matcher", + "optional" : 1, + "type" : "boolean" + }, + "invert-match" : { + "description" : "Invert match of the whole matcher", + "optional" : 1, + "type" : "boolean" + }, + "match-calendar" : { + "description" : "Match notification timestamp", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "match-field" : { + "description" : "Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "match-severity" : { + "description" : "Notification severities to match", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "mode" : { + "default" : "all", + "description" : "Choose between 'all' and 'any' for when multiple properties are specified", + "enum" : [ + "all", + "any" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the matcher.", + "format" : "pve-configid", + "type" : "string" + }, + "target" : { + "description" : "Targets to notify on match", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update existing matcher", + "method" : "PUT", + "name" : "update_matcher", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this matcher", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "invert-match" : { + "description" : "Invert match of the whole matcher", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "match-calendar" : { + "description" : "Match notification timestamp", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "match-field" : { + "description" : "Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "match-severity" : { + "description" : "Notification severities to match", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mode" : { + "default" : "all", + "description" : "Choose between 'all' and 'any' for when multiple properties are specified", + "enum" : [ + "all", + "any" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the matcher.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Targets to notify on match", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/notifications/matchers/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns a list of all matchers", + "method" : "GET", + "name" : "get_matchers", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Use" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this matcher", + "optional" : 1, + "type" : "boolean" + }, + "invert-match" : { + "description" : "Invert match of the whole matcher", + "optional" : 1, + "type" : "boolean" + }, + "match-calendar" : { + "description" : "Match notification timestamp", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "match-field" : { + "description" : "Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "match-severity" : { + "description" : "Notification severities to match", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "mode" : { + "default" : "all", + "description" : "Choose between 'all' and 'any' for when multiple properties are specified", + "enum" : [ + "all", + "any" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the matcher.", + "format" : "pve-configid", + "type" : "string" + }, + "origin" : { + "description" : "Show if this entry was created by a user or was built-in", + "enum" : [ + "user-created", + "builtin", + "modified-builtin" + ], + "type" : "string" + }, + "target" : { + "description" : "Targets to notify on match", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new matcher", + "method" : "POST", + "name" : "create_matcher", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this matcher", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "invert-match" : { + "description" : "Invert match of the whole matcher", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "match-calendar" : { + "description" : "Match notification timestamp", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "match-field" : { + "description" : "Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "match-severity" : { + "description" : "Notification severities to match", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mode" : { + "default" : "all", + "description" : "Choose between 'all' and 'any' for when multiple properties are specified", + "enum" : [ + "all", + "any" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the matcher.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Targets to notify on match", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/notifications/matchers", + "text" : "matchers" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index for notification-related API endpoints.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/notifications", + "text" : "notifications" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List of available CPU flags. Currently only implemented for x86_64, returns an empty list for aarch64.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "accel" : { + "default" : "kvm", + "description" : "Acceleration type to check node compatibility for.", + "enum" : [ + "kvm", + "tcg" + ], + "optional" : 1, + "type" : "string" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host architecture.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/nodes", + [ + "Sys.Audit" + ] + ], + [ + "perm", + "/mapping/cpu", + [ + "Mapping.Audit", + "Mapping.Use", + "Mapping.Modify" + ], + "any", + 1 + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "description" : { + "description" : "Description of the CPU flag.", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the CPU flag.", + "type" : "string" + }, + "supported-on" : { + "description" : "List of nodes supporting the flag with the selected acceleration type (\"accel\").", + "items" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/qemu/cpu-flags", + "text" : "cpu-flags" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete a custom CPU model definition.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cputype" : { + "description" : "The custom model to delete. The 'custom-' prefix is optional.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Retrieve details about a specific custom CPU model.", + "method" : "GET", + "name" : "info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cputype" : { + "description" : "Name of the CPU model to query. The 'custom-' prefix is optional.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Modify" + ] + ] + ] + }, + "returns" : { + "properties" : { + "cputype" : { + "default" : "kvm64", + "default_key" : 1, + "description" : "Emulated CPU type. Can be default or custom name (custom model names must be prefixed with 'custom-').", + "format_description" : "string", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "flags" : { + "description" : "List of additional CPU flags separated by ';'. Use '+FLAG' to enable, '-FLAG' to disable a flag. There is a special 'nested-virt' shorthand which controls nested virtualization for the current CPU ('svm' for AMD and 'vmx' for Intel). Custom CPU models can specify any flag supported by QEMU/KVM, VM-specific flags must be from the following set for security reasons: aes, amd-no-ssb, amd-ssbd, hv-evmcs, hv-tlbflush, ibpb, md-clear, nested-virt, pcid, pdpe1gb, spec-ctrl, ssbd, virt-ssbd", + "format_description" : "+FLAG[;-FLAG...]", + "optional" : 1, + "pattern" : "(?^u:(?^u:([+-])([a-zA-Z0-9\\-_\\.]+))(;(?^u:([+-])([a-zA-Z0-9\\-_\\.]+)))*)", + "type" : "string" + }, + "guest-phys-bits" : { + "description" : "Number of physical address bits available to the guest.", + "maximum" : 64, + "minimum" : 32, + "optional" : 1, + "type" : "integer" + }, + "hidden" : { + "default" : 0, + "description" : "Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.", + "optional" : 1, + "type" : "boolean" + }, + "hv-vendor-id" : { + "description" : "The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID.", + "format_description" : "vendor-id", + "optional" : 1, + "pattern" : "(?^u:[a-zA-Z0-9]{1,12})", + "type" : "string" + }, + "level" : { + "description" : "Maximum input value for the basic CPUID leaves the guest can query - that is the vendor (leaf 0), family/model/stepping and feature bits (leaf 1), cache and topology info (leaves 4 and B), and so on. Higher-numbered leaves are hidden. Setting '30' is a common workaround for Hyper-V boot failures on Windows guests running on recent Intel hosts. Only applies when the vCPU architecture is x86_64.", + "maximum" : 4294967295, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "phys-bits" : { + "description" : "The physical memory address bits that are reported to the guest OS. Should be smaller or equal to the host's. Set to 'host' to use value from host CPU, but note that doing so will break live migration to CPUs with other values.", + "format" : "pve-phys-bits", + "format_description" : "8-64|host", + "optional" : 1, + "type" : "string" + }, + "reported-model" : { + "default" : "kvm64", + "description" : "CPU model and vendor to report to the guest. Must be a QEMU/KVM supported model. Only valid for custom CPU model definitions, default models will always report themselves to the guest OS.", + "enum" : [ + "486", + "a64fx", + "athlon", + "Broadwell", + "Broadwell-IBRS", + "Broadwell-noTSX", + "Broadwell-noTSX-IBRS", + "Cascadelake-Server", + "Cascadelake-Server-noTSX", + "Cascadelake-Server-v2", + "Cascadelake-Server-v4", + "Cascadelake-Server-v5", + "ClearwaterForest", + "ClearwaterForest-v2", + "ClearwaterForest-v3", + "Conroe", + "Cooperlake", + "Cooperlake-v2", + "core2duo", + "coreduo", + "cortex-a35", + "cortex-a53", + "cortex-a55", + "cortex-a57", + "cortex-a710", + "cortex-a72", + "cortex-a76", + "cortex-a78ae", + "DiamondRapids", + "EPYC", + "EPYC-Genoa", + "EPYC-Genoa-v2", + "EPYC-IBPB", + "EPYC-Milan", + "EPYC-Milan-v2", + "EPYC-Milan-v3", + "EPYC-Rome", + "EPYC-Rome-v2", + "EPYC-Rome-v3", + "EPYC-Rome-v4", + "EPYC-Rome-v5", + "EPYC-Turin", + "EPYC-v3", + "EPYC-v4", + "EPYC-v5", + "GraniteRapids", + "GraniteRapids-v2", + "GraniteRapids-v3", + "GraniteRapids-v4", + "GraniteRapids-v5", + "Haswell", + "Haswell-IBRS", + "Haswell-noTSX", + "Haswell-noTSX-IBRS", + "host", + "Icelake-Client", + "Icelake-Client-noTSX", + "Icelake-Server", + "Icelake-Server-noTSX", + "Icelake-Server-v3", + "Icelake-Server-v4", + "Icelake-Server-v5", + "Icelake-Server-v6", + "Icelake-Server-v7", + "IvyBridge", + "IvyBridge-IBRS", + "KnightsMill", + "kvm32", + "kvm64", + "max", + "Nehalem", + "Nehalem-IBRS", + "neoverse-n1", + "neoverse-n2", + "neoverse-v1", + "Opteron_G1", + "Opteron_G2", + "Opteron_G3", + "Opteron_G4", + "Opteron_G5", + "Penryn", + "pentium", + "pentium2", + "pentium3", + "phenom", + "qemu32", + "qemu64", + "SandyBridge", + "SandyBridge-IBRS", + "SapphireRapids", + "SapphireRapids-v2", + "SapphireRapids-v3", + "SapphireRapids-v4", + "SapphireRapids-v5", + "SapphireRapids-v6", + "SierraForest", + "SierraForest-v2", + "SierraForest-v3", + "SierraForest-v4", + "SierraForest-v5", + "Skylake-Client", + "Skylake-Client-IBRS", + "Skylake-Client-noTSX-IBRS", + "Skylake-Client-v4", + "Skylake-Server", + "Skylake-Server-IBRS", + "Skylake-Server-noTSX-IBRS", + "Skylake-Server-v4", + "Skylake-Server-v5", + "Westmere", + "Westmere-IBRS" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update a custom CPU model definition.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cputype" : { + "description" : "Name for the custom CPU model. The 'custom-' prefix is optional.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of properties to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "flags" : { + "description" : "List of additional CPU flags separated by ';'. Use '+FLAG' to enable, '-FLAG' to disable a flag. There is a special 'nested-virt' shorthand which controls nested virtualization for the current CPU ('svm' for AMD and 'vmx' for Intel). Custom CPU models can specify any flag supported by QEMU/KVM, VM-specific flags must be from the following set for security reasons: aes, amd-no-ssb, amd-ssbd, hv-evmcs, hv-tlbflush, ibpb, md-clear, nested-virt, pcid, pdpe1gb, spec-ctrl, ssbd, virt-ssbd", + "format_description" : "+FLAG[;-FLAG...]", + "optional" : 1, + "pattern" : "(?^u:(?^u:([+-])([a-zA-Z0-9\\-_\\.]+))(;(?^u:([+-])([a-zA-Z0-9\\-_\\.]+)))*)", + "type" : "string" + }, + "guest-phys-bits" : { + "description" : "Number of physical address bits available to the guest.", + "maximum" : 64, + "minimum" : 32, + "optional" : 1, + "type" : "integer", + "typetext" : " (32 - 64)" + }, + "hidden" : { + "default" : 0, + "description" : "Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hv-vendor-id" : { + "description" : "The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID.", + "format_description" : "vendor-id", + "optional" : 1, + "pattern" : "(?^u:[a-zA-Z0-9]{1,12})", + "type" : "string" + }, + "level" : { + "description" : "Maximum input value for the basic CPUID leaves the guest can query - that is the vendor (leaf 0), family/model/stepping and feature bits (leaf 1), cache and topology info (leaves 4 and B), and so on. Higher-numbered leaves are hidden. Setting '30' is a common workaround for Hyper-V boot failures on Windows guests running on recent Intel hosts. Only applies when the vCPU architecture is x86_64.", + "maximum" : 4294967295, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 4294967295)" + }, + "phys-bits" : { + "description" : "The physical memory address bits that are reported to the guest OS. Should be smaller or equal to the host's. Set to 'host' to use value from host CPU, but note that doing so will break live migration to CPUs with other values.", + "format" : "pve-phys-bits", + "format_description" : "8-64|host", + "optional" : 1, + "type" : "string", + "typetext" : "<8-64|host>" + }, + "reported-model" : { + "default" : "kvm64", + "description" : "CPU model and vendor to report to the guest. Must be a QEMU/KVM supported model. Only valid for custom CPU model definitions, default models will always report themselves to the guest OS.", + "enum" : [ + "486", + "a64fx", + "athlon", + "Broadwell", + "Broadwell-IBRS", + "Broadwell-noTSX", + "Broadwell-noTSX-IBRS", + "Cascadelake-Server", + "Cascadelake-Server-noTSX", + "Cascadelake-Server-v2", + "Cascadelake-Server-v4", + "Cascadelake-Server-v5", + "ClearwaterForest", + "ClearwaterForest-v2", + "ClearwaterForest-v3", + "Conroe", + "Cooperlake", + "Cooperlake-v2", + "core2duo", + "coreduo", + "cortex-a35", + "cortex-a53", + "cortex-a55", + "cortex-a57", + "cortex-a710", + "cortex-a72", + "cortex-a76", + "cortex-a78ae", + "DiamondRapids", + "EPYC", + "EPYC-Genoa", + "EPYC-Genoa-v2", + "EPYC-IBPB", + "EPYC-Milan", + "EPYC-Milan-v2", + "EPYC-Milan-v3", + "EPYC-Rome", + "EPYC-Rome-v2", + "EPYC-Rome-v3", + "EPYC-Rome-v4", + "EPYC-Rome-v5", + "EPYC-Turin", + "EPYC-v3", + "EPYC-v4", + "EPYC-v5", + "GraniteRapids", + "GraniteRapids-v2", + "GraniteRapids-v3", + "GraniteRapids-v4", + "GraniteRapids-v5", + "Haswell", + "Haswell-IBRS", + "Haswell-noTSX", + "Haswell-noTSX-IBRS", + "host", + "Icelake-Client", + "Icelake-Client-noTSX", + "Icelake-Server", + "Icelake-Server-noTSX", + "Icelake-Server-v3", + "Icelake-Server-v4", + "Icelake-Server-v5", + "Icelake-Server-v6", + "Icelake-Server-v7", + "IvyBridge", + "IvyBridge-IBRS", + "KnightsMill", + "kvm32", + "kvm64", + "max", + "Nehalem", + "Nehalem-IBRS", + "neoverse-n1", + "neoverse-n2", + "neoverse-v1", + "Opteron_G1", + "Opteron_G2", + "Opteron_G3", + "Opteron_G4", + "Opteron_G5", + "Penryn", + "pentium", + "pentium2", + "pentium3", + "phenom", + "qemu32", + "qemu64", + "SandyBridge", + "SandyBridge-IBRS", + "SapphireRapids", + "SapphireRapids-v2", + "SapphireRapids-v3", + "SapphireRapids-v4", + "SapphireRapids-v5", + "SapphireRapids-v6", + "SierraForest", + "SierraForest-v2", + "SierraForest-v3", + "SierraForest-v4", + "SierraForest-v5", + "Skylake-Client", + "Skylake-Client-IBRS", + "Skylake-Client-noTSX-IBRS", + "Skylake-Client-v4", + "Skylake-Server", + "Skylake-Server-IBRS", + "Skylake-Server-noTSX-IBRS", + "Skylake-Server-v4", + "Skylake-Server-v5", + "Westmere", + "Westmere-IBRS" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/qemu/custom-cpu-models/{cputype}", + "text" : "{cputype}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all custom CPU model definitions visible to the user.", + "method" : "GET", + "name" : "config", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "Only lists entries where the user has 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/cpu/'.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "cputype" : { + "default" : "kvm64", + "default_key" : 1, + "description" : "Emulated CPU type. Can be default or custom name (custom model names must be prefixed with 'custom-').", + "format_description" : "string", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "flags" : { + "description" : "List of additional CPU flags separated by ';'. Use '+FLAG' to enable, '-FLAG' to disable a flag. There is a special 'nested-virt' shorthand which controls nested virtualization for the current CPU ('svm' for AMD and 'vmx' for Intel). Custom CPU models can specify any flag supported by QEMU/KVM, VM-specific flags must be from the following set for security reasons: aes, amd-no-ssb, amd-ssbd, hv-evmcs, hv-tlbflush, ibpb, md-clear, nested-virt, pcid, pdpe1gb, spec-ctrl, ssbd, virt-ssbd", + "format_description" : "+FLAG[;-FLAG...]", + "optional" : 1, + "pattern" : "(?^u:(?^u:([+-])([a-zA-Z0-9\\-_\\.]+))(;(?^u:([+-])([a-zA-Z0-9\\-_\\.]+)))*)", + "type" : "string" + }, + "guest-phys-bits" : { + "description" : "Number of physical address bits available to the guest.", + "maximum" : 64, + "minimum" : 32, + "optional" : 1, + "type" : "integer" + }, + "hidden" : { + "default" : 0, + "description" : "Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.", + "optional" : 1, + "type" : "boolean" + }, + "hv-vendor-id" : { + "description" : "The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID.", + "format_description" : "vendor-id", + "optional" : 1, + "pattern" : "(?^u:[a-zA-Z0-9]{1,12})", + "type" : "string" + }, + "level" : { + "description" : "Maximum input value for the basic CPUID leaves the guest can query - that is the vendor (leaf 0), family/model/stepping and feature bits (leaf 1), cache and topology info (leaves 4 and B), and so on. Higher-numbered leaves are hidden. Setting '30' is a common workaround for Hyper-V boot failures on Windows guests running on recent Intel hosts. Only applies when the vCPU architecture is x86_64.", + "maximum" : 4294967295, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "phys-bits" : { + "description" : "The physical memory address bits that are reported to the guest OS. Should be smaller or equal to the host's. Set to 'host' to use value from host CPU, but note that doing so will break live migration to CPUs with other values.", + "format" : "pve-phys-bits", + "format_description" : "8-64|host", + "optional" : 1, + "type" : "string" + }, + "reported-model" : { + "default" : "kvm64", + "description" : "CPU model and vendor to report to the guest. Must be a QEMU/KVM supported model. Only valid for custom CPU model definitions, default models will always report themselves to the guest OS.", + "enum" : [ + "486", + "a64fx", + "athlon", + "Broadwell", + "Broadwell-IBRS", + "Broadwell-noTSX", + "Broadwell-noTSX-IBRS", + "Cascadelake-Server", + "Cascadelake-Server-noTSX", + "Cascadelake-Server-v2", + "Cascadelake-Server-v4", + "Cascadelake-Server-v5", + "ClearwaterForest", + "ClearwaterForest-v2", + "ClearwaterForest-v3", + "Conroe", + "Cooperlake", + "Cooperlake-v2", + "core2duo", + "coreduo", + "cortex-a35", + "cortex-a53", + "cortex-a55", + "cortex-a57", + "cortex-a710", + "cortex-a72", + "cortex-a76", + "cortex-a78ae", + "DiamondRapids", + "EPYC", + "EPYC-Genoa", + "EPYC-Genoa-v2", + "EPYC-IBPB", + "EPYC-Milan", + "EPYC-Milan-v2", + "EPYC-Milan-v3", + "EPYC-Rome", + "EPYC-Rome-v2", + "EPYC-Rome-v3", + "EPYC-Rome-v4", + "EPYC-Rome-v5", + "EPYC-Turin", + "EPYC-v3", + "EPYC-v4", + "EPYC-v5", + "GraniteRapids", + "GraniteRapids-v2", + "GraniteRapids-v3", + "GraniteRapids-v4", + "GraniteRapids-v5", + "Haswell", + "Haswell-IBRS", + "Haswell-noTSX", + "Haswell-noTSX-IBRS", + "host", + "Icelake-Client", + "Icelake-Client-noTSX", + "Icelake-Server", + "Icelake-Server-noTSX", + "Icelake-Server-v3", + "Icelake-Server-v4", + "Icelake-Server-v5", + "Icelake-Server-v6", + "Icelake-Server-v7", + "IvyBridge", + "IvyBridge-IBRS", + "KnightsMill", + "kvm32", + "kvm64", + "max", + "Nehalem", + "Nehalem-IBRS", + "neoverse-n1", + "neoverse-n2", + "neoverse-v1", + "Opteron_G1", + "Opteron_G2", + "Opteron_G3", + "Opteron_G4", + "Opteron_G5", + "Penryn", + "pentium", + "pentium2", + "pentium3", + "phenom", + "qemu32", + "qemu64", + "SandyBridge", + "SandyBridge-IBRS", + "SapphireRapids", + "SapphireRapids-v2", + "SapphireRapids-v3", + "SapphireRapids-v4", + "SapphireRapids-v5", + "SapphireRapids-v6", + "SierraForest", + "SierraForest-v2", + "SierraForest-v3", + "SierraForest-v4", + "SierraForest-v5", + "Skylake-Client", + "Skylake-Client-IBRS", + "Skylake-Client-noTSX-IBRS", + "Skylake-Client-v4", + "Skylake-Server", + "Skylake-Server-IBRS", + "Skylake-Server-noTSX-IBRS", + "Skylake-Server-v4", + "Skylake-Server-v5", + "Westmere", + "Westmere-IBRS" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{cputype}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add a custom CPU model definition.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cputype" : { + "description" : "Name for the custom CPU model. The 'custom-' prefix is optional.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "flags" : { + "description" : "List of additional CPU flags separated by ';'. Use '+FLAG' to enable, '-FLAG' to disable a flag. There is a special 'nested-virt' shorthand which controls nested virtualization for the current CPU ('svm' for AMD and 'vmx' for Intel). Custom CPU models can specify any flag supported by QEMU/KVM, VM-specific flags must be from the following set for security reasons: aes, amd-no-ssb, amd-ssbd, hv-evmcs, hv-tlbflush, ibpb, md-clear, nested-virt, pcid, pdpe1gb, spec-ctrl, ssbd, virt-ssbd", + "format_description" : "+FLAG[;-FLAG...]", + "optional" : 1, + "pattern" : "(?^u:(?^u:([+-])([a-zA-Z0-9\\-_\\.]+))(;(?^u:([+-])([a-zA-Z0-9\\-_\\.]+)))*)", + "type" : "string" + }, + "guest-phys-bits" : { + "description" : "Number of physical address bits available to the guest.", + "maximum" : 64, + "minimum" : 32, + "optional" : 1, + "type" : "integer", + "typetext" : " (32 - 64)" + }, + "hidden" : { + "default" : 0, + "description" : "Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hv-vendor-id" : { + "description" : "The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID.", + "format_description" : "vendor-id", + "optional" : 1, + "pattern" : "(?^u:[a-zA-Z0-9]{1,12})", + "type" : "string" + }, + "level" : { + "description" : "Maximum input value for the basic CPUID leaves the guest can query - that is the vendor (leaf 0), family/model/stepping and feature bits (leaf 1), cache and topology info (leaves 4 and B), and so on. Higher-numbered leaves are hidden. Setting '30' is a common workaround for Hyper-V boot failures on Windows guests running on recent Intel hosts. Only applies when the vCPU architecture is x86_64.", + "maximum" : 4294967295, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 4294967295)" + }, + "phys-bits" : { + "description" : "The physical memory address bits that are reported to the guest OS. Should be smaller or equal to the host's. Set to 'host' to use value from host CPU, but note that doing so will break live migration to CPUs with other values.", + "format" : "pve-phys-bits", + "format_description" : "8-64|host", + "optional" : 1, + "type" : "string", + "typetext" : "<8-64|host>" + }, + "reported-model" : { + "default" : "kvm64", + "description" : "CPU model and vendor to report to the guest. Must be a QEMU/KVM supported model. Only valid for custom CPU model definitions, default models will always report themselves to the guest OS.", + "enum" : [ + "486", + "a64fx", + "athlon", + "Broadwell", + "Broadwell-IBRS", + "Broadwell-noTSX", + "Broadwell-noTSX-IBRS", + "Cascadelake-Server", + "Cascadelake-Server-noTSX", + "Cascadelake-Server-v2", + "Cascadelake-Server-v4", + "Cascadelake-Server-v5", + "ClearwaterForest", + "ClearwaterForest-v2", + "ClearwaterForest-v3", + "Conroe", + "Cooperlake", + "Cooperlake-v2", + "core2duo", + "coreduo", + "cortex-a35", + "cortex-a53", + "cortex-a55", + "cortex-a57", + "cortex-a710", + "cortex-a72", + "cortex-a76", + "cortex-a78ae", + "DiamondRapids", + "EPYC", + "EPYC-Genoa", + "EPYC-Genoa-v2", + "EPYC-IBPB", + "EPYC-Milan", + "EPYC-Milan-v2", + "EPYC-Milan-v3", + "EPYC-Rome", + "EPYC-Rome-v2", + "EPYC-Rome-v3", + "EPYC-Rome-v4", + "EPYC-Rome-v5", + "EPYC-Turin", + "EPYC-v3", + "EPYC-v4", + "EPYC-v5", + "GraniteRapids", + "GraniteRapids-v2", + "GraniteRapids-v3", + "GraniteRapids-v4", + "GraniteRapids-v5", + "Haswell", + "Haswell-IBRS", + "Haswell-noTSX", + "Haswell-noTSX-IBRS", + "host", + "Icelake-Client", + "Icelake-Client-noTSX", + "Icelake-Server", + "Icelake-Server-noTSX", + "Icelake-Server-v3", + "Icelake-Server-v4", + "Icelake-Server-v5", + "Icelake-Server-v6", + "Icelake-Server-v7", + "IvyBridge", + "IvyBridge-IBRS", + "KnightsMill", + "kvm32", + "kvm64", + "max", + "Nehalem", + "Nehalem-IBRS", + "neoverse-n1", + "neoverse-n2", + "neoverse-v1", + "Opteron_G1", + "Opteron_G2", + "Opteron_G3", + "Opteron_G4", + "Opteron_G5", + "Penryn", + "pentium", + "pentium2", + "pentium3", + "phenom", + "qemu32", + "qemu64", + "SandyBridge", + "SandyBridge-IBRS", + "SapphireRapids", + "SapphireRapids-v2", + "SapphireRapids-v3", + "SapphireRapids-v4", + "SapphireRapids-v5", + "SapphireRapids-v6", + "SierraForest", + "SierraForest-v2", + "SierraForest-v3", + "SierraForest-v4", + "SierraForest-v5", + "Skylake-Client", + "Skylake-Client-IBRS", + "Skylake-Client-noTSX-IBRS", + "Skylake-Client-v4", + "Skylake-Server", + "Skylake-Server-IBRS", + "Skylake-Server-noTSX-IBRS", + "Skylake-Server-v4", + "Skylake-Server-v5", + "Westmere", + "Westmere-IBRS" + ], + "optional" : 0, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/cpu", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/qemu/custom-cpu-models", + "text" : "custom-cpu-models" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Cluster-wide QEMU index", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/qemu", + "text" : "qemu" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Return the version of the cluster join API available on this node.", + "method" : "GET", + "name" : "join_api_version", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "description" : "Cluster Join API version, currently 1", + "minimum" : 0, + "type" : "integer" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/apiversion", + "text" : "apiversion" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Removes a node from the cluster configuration.", + "method" : "DELETE", + "name" : "delnode", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Adds a node to the cluster configuration. This call is for internal use.", + "method" : "POST", + "name" : "addnode", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "apiversion" : { + "description" : "The JOIN_API_VERSION of the new node.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "force" : { + "description" : "Do not throw error if node already exists.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "link[n]" : { + "description" : "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)", + "format" : { + "address" : { + "default_key" : 1, + "description" : "Hostname (or IP) of this corosync link address.", + "format" : "address", + "format_description" : "IP", + "type" : "string" + }, + "priority" : { + "default" : 0, + "description" : "The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.", + "maximum" : 255, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[address=] [,priority=]" + }, + "new_node_ip" : { + "description" : "IP Address of node to add. Used as fallback if no links are given.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nodeid" : { + "description" : "Node id for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "votes" : { + "description" : "Number of votes for this node", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "protected" : 1, + "returns" : { + "properties" : { + "corosync_authkey" : { + "type" : "string" + }, + "corosync_conf" : { + "type" : "string" + }, + "warnings" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/nodes/{node}", + "text" : "{node}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Corosync node list.", + "method" : "GET", + "name" : "nodes", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "node" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{node}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/config/nodes", + "text" : "nodes" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get information needed to join this cluster over the connected node.", + "method" : "GET", + "name" : "join_info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "default" : "current connected node", + "description" : "The node for which the joinee gets the nodeinfo. ", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "config_digest" : { + "type" : "string" + }, + "nodelist" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "name" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "nodeid" : { + "description" : "Node id for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "pve_addr" : { + "format" : "ip", + "type" : "string" + }, + "pve_fp" : { + "description" : "Certificate SHA 256 fingerprint.", + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "quorum_votes" : { + "minimum" : 0, + "type" : "integer" + }, + "ring0_addr" : { + "description" : "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)", + "format" : { + "address" : { + "default_key" : 1, + "description" : "Hostname (or IP) of this corosync link address.", + "format" : "address", + "format_description" : "IP", + "type" : "string" + }, + "priority" : { + "default" : 0, + "description" : "The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.", + "maximum" : 255, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "preferred_node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "totem" : { + "type" : "object" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Joins this node into an existing cluster. If no links are given, default to IP resolved by node's hostname on single link (fallback fails for clusters with multiple links).", + "method" : "POST", + "name" : "join", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "force" : { + "description" : "Do not throw error if node already exists.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hostname" : { + "description" : "Hostname (or IP) of an existing cluster member.", + "type" : "string", + "typetext" : "" + }, + "link[n]" : { + "description" : "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)", + "format" : { + "address" : { + "default_key" : 1, + "description" : "Hostname (or IP) of this corosync link address.", + "format" : "address", + "format_description" : "IP", + "type" : "string" + }, + "priority" : { + "default" : 0, + "description" : "The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.", + "maximum" : 255, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[address=] [,priority=]" + }, + "nodeid" : { + "description" : "Node id for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "password" : { + "description" : "Superuser (root) password of peer node.", + "maxLength" : 128, + "type" : "string", + "typetext" : "" + }, + "votes" : { + "description" : "Number of votes for this node", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/join", + "text" : "join" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get corosync totem protocol settings.", + "method" : "GET", + "name" : "totem", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/totem", + "text" : "totem" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get QDevice status", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/qdevice", + "text" : "qdevice" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Generate new cluster configuration. If no links given, default to local IP address as link0.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "clustername" : { + "description" : "The name of the cluster.", + "format" : "pve-node", + "maxLength" : 15, + "type" : "string", + "typetext" : "" + }, + "link[n]" : { + "description" : "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)", + "format" : { + "address" : { + "default_key" : 1, + "description" : "Hostname (or IP) of this corosync link address.", + "format" : "address", + "format_description" : "IP", + "type" : "string" + }, + "priority" : { + "default" : 0, + "description" : "The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.", + "maximum" : 255, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[address=] [,priority=]" + }, + "nodeid" : { + "description" : "Node id for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "token-coefficient" : { + "default" : 125, + "description" : "Coefficient used to determine Corosync's token timeout. See the corosync.conf(5) manual for more details.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "votes" : { + "description" : "Number of votes for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/config", + "text" : "config" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment", + "optional" : 1, + "type" : "string" + }, + "dest" : { + "description" : "Restrict packet destination address", + "optional" : 1, + "type" : "string" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port", + "optional" : 1, + "type" : "string" + }, + "enable" : { + "description" : "Flag to enable/disable a rule", + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers", + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "description" : "IP version (4 or 6) - automatically determined from source/dest addresses", + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro", + "optional" : 1, + "type" : "string" + }, + "pos" : { + "description" : "Rule position in the ruleset", + "type" : "integer" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "Restrict packet source address", + "optional" : 1, + "type" : "string" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Rule type", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/groups/{group}/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete security group.", + "method" : "DELETE", + "name" : "delete_security_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment", + "optional" : 1, + "type" : "string" + }, + "dest" : { + "description" : "Restrict packet destination address", + "optional" : 1, + "type" : "string" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port", + "optional" : 1, + "type" : "string" + }, + "enable" : { + "description" : "Flag to enable/disable a rule", + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers", + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "description" : "IP version (4 or 6) - automatically determined from source/dest addresses", + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro", + "optional" : 1, + "type" : "string" + }, + "pos" : { + "description" : "Rule position in the ruleset", + "type" : "integer" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "Restrict packet source address", + "optional" : 1, + "type" : "string" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Rule type", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 0, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/groups/{group}", + "text" : "{group}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List security groups.", + "method" : "GET", + "name" : "list_security_groups", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{group}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new security group.", + "method" : "POST", + "name" : "create_security_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "rename" : { + "description" : "Rename/update an existing security group. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing group.", + "maxLength" : 18, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/groups", + "text" : "groups" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment", + "optional" : 1, + "type" : "string" + }, + "dest" : { + "description" : "Restrict packet destination address", + "optional" : 1, + "type" : "string" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port", + "optional" : 1, + "type" : "string" + }, + "enable" : { + "description" : "Flag to enable/disable a rule", + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers", + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "description" : "IP version (4 or 6) - automatically determined from source/dest addresses", + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro", + "optional" : 1, + "type" : "string" + }, + "pos" : { + "description" : "Rule position in the ruleset", + "type" : "integer" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "Restrict packet source address", + "optional" : 1, + "type" : "string" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Rule type", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment", + "optional" : 1, + "type" : "string" + }, + "dest" : { + "description" : "Restrict packet destination address", + "optional" : 1, + "type" : "string" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port", + "optional" : 1, + "type" : "string" + }, + "enable" : { + "description" : "Flag to enable/disable a rule", + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers", + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "description" : "IP version (4 or 6) - automatically determined from source/dest addresses", + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro", + "optional" : 1, + "type" : "string" + }, + "pos" : { + "description" : "Rule position in the ruleset", + "type" : "integer" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "Restrict packet source address", + "optional" : 1, + "type" : "string" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Rule type", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 0, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/rules", + "text" : "rules" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network from IPSet.", + "method" : "DELETE", + "name" : "remove_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read IP or Network settings from IPSet.", + "method" : "GET", + "name" : "read_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network settings", + "method" : "PUT", + "name" : "update_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/ipset/{name}/{cidr}", + "text" : "{cidr}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete IPSet", + "method" : "DELETE", + "name" : "delete_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "Delete all members of the IPSet, if there are any.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List IPSet content", + "method" : "GET", + "name" : "get_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{cidr}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add IP or Network to IPSet.", + "method" : "POST", + "name" : "create_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/ipset/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List IPSets", + "method" : "GET", + "name" : "ipset_index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new IPSet", + "method" : "POST", + "name" : "create_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "rename" : { + "description" : "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/ipset", + "text" : "ipset" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network alias.", + "method" : "DELETE", + "name" : "remove_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read alias.", + "method" : "GET", + "name" : "read_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network alias.", + "method" : "PUT", + "name" : "update_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "rename" : { + "description" : "Rename an existing alias.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/aliases/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List aliases", + "method" : "GET", + "name" : "get_aliases", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create IP or Network Alias.", + "method" : "POST", + "name" : "create_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/aliases", + "text" : "aliases" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "properties" : { + "ebtables" : { + "default" : 1, + "description" : "Enable ebtables rules cluster wide.", + "optional" : 1, + "type" : "boolean" + }, + "enable" : { + "default" : 0, + "description" : "Enable or disable the firewall cluster wide.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "log_ratelimit" : { + "description" : "Log ratelimiting settings", + "format" : { + "burst" : { + "default" : 5, + "description" : "Initial burst of packages which will always get logged before the rate is applied", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "enable" : { + "default" : "1", + "default_key" : 1, + "description" : "Enable or disable log rate limiting", + "type" : "boolean" + }, + "rate" : { + "default" : "1/second", + "description" : "Frequency with which the burst bucket gets refilled", + "format_description" : "rate", + "optional" : 1, + "pattern" : "[1-9][0-9]*\\/(second|minute|hour|day)", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "policy_forward" : { + "description" : "Forward policy.", + "enum" : [ + "ACCEPT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ebtables" : { + "default" : 1, + "description" : "Enable ebtables rules cluster wide.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "enable" : { + "default" : 0, + "description" : "Enable or disable the firewall cluster wide.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "log_ratelimit" : { + "description" : "Log ratelimiting settings", + "format" : { + "burst" : { + "default" : 5, + "description" : "Initial burst of packages which will always get logged before the rate is applied", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "enable" : { + "default" : "1", + "default_key" : 1, + "description" : "Enable or disable log rate limiting", + "type" : "boolean" + }, + "rate" : { + "default" : "1/second", + "description" : "Frequency with which the burst bucket gets refilled", + "format_description" : "rate", + "optional" : 1, + "pattern" : "[1-9][0-9]*\\/(second|minute|hour|day)", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[enable=]<1|0> [,burst=] [,rate=]" + }, + "policy_forward" : { + "description" : "Forward policy.", + "enum" : [ + "ACCEPT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List available macros", + "method" : "GET", + "name" : "get_macros", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "descr" : { + "description" : "More verbose description (if available).", + "type" : "string" + }, + "macro" : { + "description" : "Macro name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/macros", + "text" : "macros" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Lists possible IPSet/Alias reference which are allowed in source/dest properties.", + "method" : "GET", + "name" : "refs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list references of specified type.", + "enum" : [ + "alias", + "ipset" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "ref" : { + "type" : "string" + }, + "scope" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "alias", + "ipset" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/refs", + "text" : "refs" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall", + "text" : "firewall" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns included guests and the backup status of their disks. Optimized to be used in ExtJS tree views.", + "method" : "GET", + "name" : "get_volume_backup_included", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "pattern" : "\\S+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "Root node of the tree object. Children represent guests, grandchildren represent volumes of that guest.", + "properties" : { + "children" : { + "items" : { + "properties" : { + "children" : { + "description" : "The volumes of the guest with the information if they will be included in backups.", + "items" : { + "properties" : { + "id" : { + "description" : "Configuration key of the volume.", + "type" : "string" + }, + "included" : { + "description" : "Whether the volume is included in the backup or not.", + "type" : "boolean" + }, + "name" : { + "description" : "Name of the volume.", + "type" : "string" + }, + "reason" : { + "description" : "The reason why the volume is included (or excluded).", + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "id" : { + "description" : "VMID of the guest.", + "type" : "integer" + }, + "name" : { + "description" : "Name of the guest", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Type of the guest, VM, CT or unknown for removed but not purged guests.", + "enum" : [ + "qemu", + "lxc", + "unknown" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/backup/{id}/included_volumes", + "text" : "included_volumes" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete vzdump backup job definition.", + "method" : "DELETE", + "name" : "delete_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "pattern" : "\\S+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read vzdump backup job definition.", + "method" : "GET", + "name" : "read_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "pattern" : "\\S+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (in KiB/s).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "comment" : { + "description" : "Description for the Job.", + "maxLength" : 512, + "optional" : 1, + "type" : "string" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string" + }, + "enabled" : { + "default" : "1", + "description" : "Enable or disable the job.", + "optional" : 1, + "type" : "boolean" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "fleecing" : { + "description" : "Options for backup fleecing (VM only).", + "optional" : 1, + "properties" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable backup fleecing. Cache backup data from blocks where new guest writes happen on specified storage instead of copying them directly to the backup target. This can help guest IO performance and even prevent hangs, at the cost of requiring more storage space.", + "optional" : 1, + "type" : "boolean" + }, + "storage" : { + "description" : "Use this storage to storage fleecing images. For efficient space usage, it's best to use a local storage that supports discard and either thin provisioning or sparse files.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "pattern" : "\\S+", + "type" : "string" + }, + "ionice" : { + "default" : 7, + "description" : "Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "mailnotification" : { + "default" : "always", + "description" : "Deprecated: use notification targets/matchers instead. Specify when to send a notification mail", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "next-run" : { + "description" : "UNIX timestamp when this backup job will be executed next", + "optional" : 1, + "type" : "integer" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string" + }, + "notes-template" : { + "description" : "Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.", + "maxLength" : 1024, + "optional" : 1, + "requires" : "storage", + "type" : "string" + }, + "notification-mode" : { + "default" : "auto", + "description" : "Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.", + "enum" : [ + "auto", + "legacy-sendmail", + "notification-system" + ], + "optional" : 1, + "type" : "string" + }, + "pbs-change-detection-mode" : { + "description" : "PBS mode used to detect file changes and switch encoding format for container backups.", + "enum" : [ + "legacy", + "data", + "metadata" + ], + "optional" : 1, + "type" : "string" + }, + "performance" : { + "description" : "Other performance-related settings.", + "optional" : 1, + "properties" : { + "max-workers" : { + "default" : 16, + "description" : "Applies to VMs. Allow up to this many IO workers at the same time.", + "maximum" : 256, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "pbs-entries-max" : { + "default" : 1048576, + "description" : "Applies to container backups sent to PBS. Limits the number of entries allowed in memory at a given time to avoid unintended OOM situations. Increase it to enable backups of containers with a large amount of files.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string" + }, + "protected" : { + "description" : "If true, mark backup(s) as protected.", + "optional" : 1, + "requires" : "storage", + "type" : "boolean" + }, + "prune-backups" : { + "description" : "Use these retention options instead of those from the storage configuration.", + "optional" : 1, + "properties" : { + "keep-all" : { + "description" : "Keep all backups. Conflicts with the other options when true.", + "optional" : 1, + "type" : "boolean" + }, + "keep-daily" : { + "description" : "Keep backups for the last different days. If there is morethan one backup for a single day, only the latest one is kept.", + "format_description" : "N", + "minimum" : "0", + "optional" : 1, + "type" : "integer" + }, + "keep-hourly" : { + "description" : "Keep backups for the last different hours. If there is morethan one backup for a single hour, only the latest one is kept.", + "format_description" : "N", + "minimum" : "0", + "optional" : 1, + "type" : "integer" + }, + "keep-last" : { + "description" : "Keep the last backups.", + "format_description" : "N", + "minimum" : "0", + "optional" : 1, + "type" : "integer" + }, + "keep-monthly" : { + "description" : "Keep backups for the last different months. If there is morethan one backup for a single month, only the latest one is kept.", + "format_description" : "N", + "minimum" : "0", + "optional" : 1, + "type" : "integer" + }, + "keep-weekly" : { + "description" : "Keep backups for the last different weeks. If there is morethan one backup for a single week, only the latest one is kept.", + "format_description" : "N", + "minimum" : "0", + "optional" : 1, + "type" : "integer" + }, + "keep-yearly" : { + "description" : "Keep backups for the last different years. If there is morethan one backup for a single year, only the latest one is kept.", + "format_description" : "N", + "minimum" : "0", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean" + }, + "remove" : { + "default" : 1, + "description" : "Prune older backups according to 'prune-backups'.", + "optional" : 1, + "type" : "boolean" + }, + "repeat-missed" : { + "default" : 0, + "description" : "If true, the job will be run as soon as possible if it was missed while the scheduler was not running.", + "optional" : 1, + "type" : "boolean" + }, + "schedule" : { + "description" : "Backup schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update vzdump backup job definition.", + "method" : "PUT", + "name" : "update_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (in KiB/s).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "comment" : { + "description" : "Description for the Job.", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dow" : { + "description" : "Deprecated: Use 'schedule' instead. Day of week selection. 'starttime' and 'dow' will be converted into 'schedule' if used.", + "format" : "pve-day-of-week-list", + "optional" : 1, + "requires" : "starttime", + "type" : "string", + "typetext" : "" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enabled" : { + "default" : "1", + "description" : "Enable or disable the job.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "fleecing" : { + "description" : "Options for backup fleecing (VM only).", + "format" : "backup-fleecing", + "optional" : 1, + "type" : "string", + "typetext" : "[[enabled=]<1|0>] [,storage=]" + }, + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "pattern" : "\\S+", + "type" : "string" + }, + "ionice" : { + "default" : 7, + "description" : "Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 8)" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mailnotification" : { + "default" : "always", + "description" : "Deprecated: use notification targets/matchers instead. Specify when to send a notification mail", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "notes-template" : { + "description" : "Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.", + "maxLength" : 1024, + "optional" : 1, + "requires" : "storage", + "type" : "string", + "typetext" : "" + }, + "notification-mode" : { + "default" : "auto", + "description" : "Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.", + "enum" : [ + "auto", + "legacy-sendmail", + "notification-system" + ], + "optional" : 1, + "type" : "string" + }, + "pbs-change-detection-mode" : { + "description" : "PBS mode used to detect file changes and switch encoding format for container backups.", + "enum" : [ + "legacy", + "data", + "metadata" + ], + "optional" : 1, + "type" : "string" + }, + "performance" : { + "description" : "Other performance-related settings.", + "format" : "backup-performance", + "optional" : 1, + "type" : "string", + "typetext" : "[max-workers=] [,pbs-entries-max=]" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protected" : { + "description" : "If true, mark backup(s) as protected.", + "optional" : 1, + "requires" : "storage", + "type" : "boolean", + "typetext" : "" + }, + "prune-backups" : { + "default" : "keep-all=1", + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove" : { + "default" : 1, + "description" : "Prune older backups according to 'prune-backups'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "repeat-missed" : { + "default" : 0, + "description" : "If true, the job will be run as soon as possible if it was missed while the scheduler was not running.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "schedule" : { + "description" : "Backup schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "starttime" : { + "description" : "Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used.", + "optional" : 1, + "pattern" : "\\d{1,2}:\\d{1,2}", + "type" : "string", + "typetext" : "HH:MM" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/backup/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List vzdump backup schedule.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (in KiB/s).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "comment" : { + "description" : "Description for the Job.", + "maxLength" : 512, + "optional" : 1, + "type" : "string" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string" + }, + "enabled" : { + "default" : "1", + "description" : "Enable or disable the job.", + "optional" : 1, + "type" : "boolean" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "fleecing" : { + "description" : "Options for backup fleecing (VM only).", + "optional" : 1, + "properties" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable backup fleecing. Cache backup data from blocks where new guest writes happen on specified storage instead of copying them directly to the backup target. This can help guest IO performance and even prevent hangs, at the cost of requiring more storage space.", + "optional" : 1, + "type" : "boolean" + }, + "storage" : { + "description" : "Use this storage to storage fleecing images. For efficient space usage, it's best to use a local storage that supports discard and either thin provisioning or sparse files.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "pattern" : "\\S+", + "type" : "string" + }, + "ionice" : { + "default" : 7, + "description" : "Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "mailnotification" : { + "default" : "always", + "description" : "Deprecated: use notification targets/matchers instead. Specify when to send a notification mail", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "next-run" : { + "description" : "UNIX timestamp when this backup job will be executed next", + "optional" : 1, + "type" : "integer" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string" + }, + "notes-template" : { + "description" : "Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.", + "maxLength" : 1024, + "optional" : 1, + "requires" : "storage", + "type" : "string" + }, + "notification-mode" : { + "default" : "auto", + "description" : "Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.", + "enum" : [ + "auto", + "legacy-sendmail", + "notification-system" + ], + "optional" : 1, + "type" : "string" + }, + "pbs-change-detection-mode" : { + "description" : "PBS mode used to detect file changes and switch encoding format for container backups.", + "enum" : [ + "legacy", + "data", + "metadata" + ], + "optional" : 1, + "type" : "string" + }, + "performance" : { + "description" : "Other performance-related settings.", + "optional" : 1, + "properties" : { + "max-workers" : { + "default" : 16, + "description" : "Applies to VMs. Allow up to this many IO workers at the same time.", + "maximum" : 256, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "pbs-entries-max" : { + "default" : 1048576, + "description" : "Applies to container backups sent to PBS. Limits the number of entries allowed in memory at a given time to avoid unintended OOM situations. Increase it to enable backups of containers with a large amount of files.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string" + }, + "protected" : { + "description" : "If true, mark backup(s) as protected.", + "optional" : 1, + "requires" : "storage", + "type" : "boolean" + }, + "prune-backups" : { + "description" : "Use these retention options instead of those from the storage configuration.", + "optional" : 1, + "properties" : { + "keep-all" : { + "description" : "Keep all backups. Conflicts with the other options when true.", + "optional" : 1, + "type" : "boolean" + }, + "keep-daily" : { + "description" : "Keep backups for the last different days. If there is morethan one backup for a single day, only the latest one is kept.", + "format_description" : "N", + "minimum" : "0", + "optional" : 1, + "type" : "integer" + }, + "keep-hourly" : { + "description" : "Keep backups for the last different hours. If there is morethan one backup for a single hour, only the latest one is kept.", + "format_description" : "N", + "minimum" : "0", + "optional" : 1, + "type" : "integer" + }, + "keep-last" : { + "description" : "Keep the last backups.", + "format_description" : "N", + "minimum" : "0", + "optional" : 1, + "type" : "integer" + }, + "keep-monthly" : { + "description" : "Keep backups for the last different months. If there is morethan one backup for a single month, only the latest one is kept.", + "format_description" : "N", + "minimum" : "0", + "optional" : 1, + "type" : "integer" + }, + "keep-weekly" : { + "description" : "Keep backups for the last different weeks. If there is morethan one backup for a single week, only the latest one is kept.", + "format_description" : "N", + "minimum" : "0", + "optional" : 1, + "type" : "integer" + }, + "keep-yearly" : { + "description" : "Keep backups for the last different years. If there is morethan one backup for a single year, only the latest one is kept.", + "format_description" : "N", + "minimum" : "0", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean" + }, + "remove" : { + "default" : 1, + "description" : "Prune older backups according to 'prune-backups'.", + "optional" : 1, + "type" : "boolean" + }, + "repeat-missed" : { + "default" : 0, + "description" : "If true, the job will be run as soon as possible if it was missed while the scheduler was not running.", + "optional" : 1, + "type" : "boolean" + }, + "schedule" : { + "description" : "Backup schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new vzdump backup job.", + "method" : "POST", + "name" : "create_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (in KiB/s).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "comment" : { + "description" : "Description for the Job.", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "dow" : { + "default" : "mon,tue,wed,thu,fri,sat,sun", + "description" : "Deprecated: Use 'schedule' instead. Day of week selection. 'starttime' and 'dow' will be converted into 'schedule' if used.", + "format" : "pve-day-of-week-list", + "optional" : 1, + "requires" : "starttime", + "type" : "string", + "typetext" : "" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enabled" : { + "default" : "1", + "description" : "Enable or disable the job.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "fleecing" : { + "description" : "Options for backup fleecing (VM only).", + "format" : "backup-fleecing", + "optional" : 1, + "type" : "string", + "typetext" : "[[enabled=]<1|0>] [,storage=]" + }, + "id" : { + "description" : "Job ID (will be autogenerated).", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ionice" : { + "default" : 7, + "description" : "Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 8)" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mailnotification" : { + "default" : "always", + "description" : "Deprecated: use notification targets/matchers instead. Specify when to send a notification mail", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "notes-template" : { + "description" : "Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.", + "maxLength" : 1024, + "optional" : 1, + "requires" : "storage", + "type" : "string", + "typetext" : "" + }, + "notification-mode" : { + "default" : "auto", + "description" : "Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.", + "enum" : [ + "auto", + "legacy-sendmail", + "notification-system" + ], + "optional" : 1, + "type" : "string" + }, + "pbs-change-detection-mode" : { + "description" : "PBS mode used to detect file changes and switch encoding format for container backups.", + "enum" : [ + "legacy", + "data", + "metadata" + ], + "optional" : 1, + "type" : "string" + }, + "performance" : { + "description" : "Other performance-related settings.", + "format" : "backup-performance", + "optional" : 1, + "type" : "string", + "typetext" : "[max-workers=] [,pbs-entries-max=]" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protected" : { + "description" : "If true, mark backup(s) as protected.", + "optional" : 1, + "requires" : "storage", + "type" : "boolean", + "typetext" : "" + }, + "prune-backups" : { + "default" : "keep-all=1", + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove" : { + "default" : 1, + "description" : "Prune older backups according to 'prune-backups'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "repeat-missed" : { + "default" : 0, + "description" : "If true, the job will be run as soon as possible if it was missed while the scheduler was not running.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "schedule" : { + "description" : "Backup schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "starttime" : { + "description" : "Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used.", + "optional" : 1, + "pattern" : "\\d{1,2}:\\d{1,2}", + "type" : "string", + "typetext" : "HH:MM" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/backup", + "text" : "backup" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Shows all guests which are not covered by any backup job.", + "method" : "GET", + "name" : "get_guests_not_in_backup", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "Contains the guest objects.", + "items" : { + "properties" : { + "name" : { + "description" : "Name of the guest", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Type of the guest.", + "enum" : [ + "qemu", + "lxc" + ], + "type" : "string" + }, + "vmid" : { + "description" : "VMID of the guest.", + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/backup-info/not-backed-up", + "text" : "not-backed-up" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index for backup info related endpoints", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "returns" : { + "description" : "Directory index.", + "items" : { + "properties" : { + "subdir" : { + "description" : "API sub-directory endpoint", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/backup-info", + "text" : "backup-info" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Request resource migration (online) to another node.", + "method" : "POST", + "name" : "migrate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "blocking-resources" : { + "description" : "HA resources, which are blocking the given HA resource from being migrated to the requested target node.", + "items" : { + "description" : "A blocking HA resource", + "properties" : { + "cause" : { + "description" : "The reason why the HA resource is blocking the migration.", + "enum" : [ + "node-affinity", + "resource-affinity" + ], + "type" : "string" + }, + "sid" : { + "description" : "The blocking HA resource id", + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "comigrated-resources" : { + "description" : "HA resources, which are migrated to the same requested target node as the given HA resource, because these are in positive affinity with the HA resource.", + "optional" : 1, + "type" : "array" + }, + "requested-node" : { + "description" : "Node, which was requested to be migrated to.", + "optional" : 0, + "type" : "string" + }, + "sid" : { + "description" : "HA resource, which is requested to be migrated.", + "optional" : 0, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/resources/{sid}/migrate", + "text" : "migrate" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Request resource relocation to another node. This stops the service on the old node, and restarts it on the target node.", + "method" : "POST", + "name" : "relocate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "blocking-resources" : { + "description" : "HA resources, which are blocking the given HA resource from being relocated to the requested target node.", + "items" : { + "description" : "A blocking HA resource", + "properties" : { + "cause" : { + "description" : "The reason why the HA resource is blocking the relocation.", + "enum" : [ + "node-affinity", + "resource-affinity" + ], + "type" : "string" + }, + "sid" : { + "description" : "The blocking HA resource id", + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "comigrated-resources" : { + "description" : "HA resources, which are relocated to the same requested target node as the given HA resource, because these are in positive affinity with the HA resource.", + "items" : { + "description" : "A comigrated HA resource", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "requested-node" : { + "description" : "Node, which was requested to be relocated to.", + "optional" : 0, + "type" : "string" + }, + "sid" : { + "description" : "HA resource, which is requested to be relocated.", + "optional" : 0, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/resources/{sid}/relocate", + "text" : "relocate" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete resource configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "purge" : { + "default" : 1, + "description" : "Remove this resource from rules that reference it, deleting the rule if this resource is the only resource in the rule", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read resource configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "properties" : { + "auto-rebalance" : { + "default" : 1, + "description" : "HA resource may be migrated during automatic rebalancing.", + "optional" : 1, + "type" : "boolean" + }, + "comment" : { + "description" : "Description.", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Can be used to prevent concurrent modifications.", + "type" : "string" + }, + "failback" : { + "default" : 1, + "description" : "The HA resource is automatically migrated to the node with the highest priority according to their node affinity rule, if a node with a higher priority than the current node comes online.", + "optional" : 1, + "type" : "boolean" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string" + }, + "max_relocate" : { + "description" : "Maximal number of service relocate tries when a service fails to start.", + "optional" : 1, + "type" : "integer" + }, + "max_restart" : { + "description" : "Maximal number of tries to restart the service on a node after its start failed.", + "optional" : 1, + "type" : "integer" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + }, + "state" : { + "description" : "Requested resource state.", + "enum" : [ + "started", + "stopped", + "enabled", + "disabled", + "ignored" + ], + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "The type of the resources.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update resource configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "auto-rebalance" : { + "default" : 1, + "description" : "HA resource may be migrated during automatic rebalancing", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "failback" : { + "default" : 1, + "description" : "Automatically migrate HA resource to the node with the highest priority according to their node affinity rules, if a node with a higher priority than the current node comes online.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "max_relocate" : { + "default" : 1, + "description" : "Maximal number of resource relocate tries when a resource fails to start.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "max_restart" : { + "default" : 1, + "description" : "Maximal number of tries to restart the resource on a node after its start failed. When reached, the HA manager will try to relocate the resource to an eligible node.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + }, + "state" : { + "default" : "started", + "description" : "Requested resource state.", + "enum" : [ + "started", + "stopped", + "enabled", + "disabled", + "ignored" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Requested resource state. The CRM reads this state and acts accordingly.\nPlease note that `enabled` is just an alias for `started`.\n\n`started`;;\n\nThe CRM tries to start the resource. Service state is\nset to `started` after successful start. On node failures, or when start\nfails, it tries to recover the resource. If everything fails, service\nstate it set to `error`.\n\n`stopped`;;\n\nThe CRM tries to keep the resource in `stopped` state, but it\nstill tries to relocate the resources on node failures.\n\n`disabled`;;\n\nThe CRM tries to put the resource in `stopped` state, but does not try\nto relocate the resources on node failures. The main purpose of this\nstate is error recovery, because it is the only way to move a resource out\nof the `error` state.\n\n`ignored`;;\n\nThe resource gets removed from the manager status and so the CRM and the LRM do\nnot touch the resource anymore. All {pve} API calls affecting this resource\nwill be executed, directly bypassing the HA stack. CRM commands will be thrown\naway while the resource is in this state. The resource will not get relocated\non node failures.\n\n" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/resources/{sid}", + "text" : "{sid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List HA resources.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list resources of specific type", + "enum" : [ + "ct", + "vm" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "sid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{sid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new HA resource.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "auto-rebalance" : { + "default" : 1, + "description" : "HA resource may be migrated during automatic rebalancing", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "failback" : { + "default" : 1, + "description" : "Automatically migrate HA resource to the node with the highest priority according to their node affinity rules, if a node with a higher priority than the current node comes online.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "max_relocate" : { + "default" : 1, + "description" : "Maximal number of resource relocate tries when a resource fails to start.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "max_restart" : { + "default" : 1, + "description" : "Maximal number of tries to restart the resource on a node after its start failed. When reached, the HA manager will try to relocate the resource to an eligible node.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + }, + "state" : { + "default" : "started", + "description" : "Requested resource state.", + "enum" : [ + "started", + "stopped", + "enabled", + "disabled", + "ignored" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Requested resource state. The CRM reads this state and acts accordingly.\nPlease note that `enabled` is just an alias for `started`.\n\n`started`;;\n\nThe CRM tries to start the resource. Service state is\nset to `started` after successful start. On node failures, or when start\nfails, it tries to recover the resource. If everything fails, service\nstate it set to `error`.\n\n`stopped`;;\n\nThe CRM tries to keep the resource in `stopped` state, but it\nstill tries to relocate the resources on node failures.\n\n`disabled`;;\n\nThe CRM tries to put the resource in `stopped` state, but does not try\nto relocate the resources on node failures. The main purpose of this\nstate is error recovery, because it is the only way to move a resource out\nof the `error` state.\n\n`ignored`;;\n\nThe resource gets removed from the manager status and so the CRM and the LRM do\nnot touch the resource anymore. All {pve} API calls affecting this resource\nwill be executed, directly bypassing the HA stack. CRM commands will be thrown\naway while the resource is in this state. The resource will not get relocated\non node failures.\n\n" + }, + "type" : { + "description" : "Resource type.", + "enum" : [ + "ct", + "vm" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/resources", + "text" : "resources" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete ha group configuration. (deprecated in favor of HA rules)", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read ha group configuration. (deprecated in favor of HA rules)", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : {} + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update ha group configuration. (deprecated in favor of HA rules)", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names with optional priority.", + "format" : "pve-ha-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "[:]{,[:]}*", + "verbose_description" : "List of cluster node members, where a priority can be given to each node. A resource will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the resources will get distributed to those nodes. The priorities have a relative meaning only. The higher the number, the higher the priority." + }, + "nofailback" : { + "default" : 0, + "description" : "The CRM tries to run services on the node with the highest priority. If a node with higher priority comes online, the CRM migrates the service to that node. Enabling nofailback prevents that behavior.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restricted" : { + "default" : 0, + "description" : "Resources bound to restricted groups may only run on nodes defined by the group.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Resources bound to restricted groups may only run on nodes defined by the group. The resource will be placed in the stopped state if no group node member is online. Resources on unrestricted groups may run on any cluster node if all group members are offline, but they will migrate back as soon as a group member comes online. One can implement a 'preferred node' behavior using an unrestricted group with only one member." + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/groups/{group}", + "text" : "{group}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get HA groups. (deprecated in favor of HA rules)", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "group" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{group}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new HA group. (deprecated in favor of HA rules)", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names with optional priority.", + "format" : "pve-ha-node-list", + "optional" : 0, + "type" : "string", + "typetext" : "[:]{,[:]}*", + "verbose_description" : "List of cluster node members, where a priority can be given to each node. A resource will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the resources will get distributed to those nodes. The priorities have a relative meaning only. The higher the number, the higher the priority." + }, + "nofailback" : { + "default" : 0, + "description" : "The CRM tries to run services on the node with the highest priority. If a node with higher priority comes online, the CRM migrates the service to that node. Enabling nofailback prevents that behavior.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restricted" : { + "default" : 0, + "description" : "Resources bound to restricted groups may only run on nodes defined by the group.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Resources bound to restricted groups may only run on nodes defined by the group. The resource will be placed in the stopped state if no group node member is online. Resources on unrestricted groups may run on any cluster node if all group members are offline, but they will migrate back as soon as a group member comes online. One can implement a 'preferred node' behavior using an unrestricted group with only one member." + }, + "type" : { + "description" : "Group type.", + "enum" : [ + "group" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/groups", + "text" : "groups" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete HA rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "rule" : { + "description" : "HA rule identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read HA rule.", + "method" : "GET", + "name" : "read_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "rule" : { + "description" : "HA rule identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "properties" : { + "rule" : { + "description" : "HA rule identifier.", + "format" : "pve-configid", + "type" : "string" + }, + "type" : { + "description" : "HA rule type.", + "enum" : [ + "node-affinity", + "resource-affinity" + ], + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update HA rule.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "affinity" : { + "description" : "Describes whether the HA resources are supposed to be kept on the same node ('positive'), or are supposed to be kept on separate nodes ('negative').", + "enum" : [ + "positive", + "negative" + ], + "instance-types" : [ + "resource-affinity" + ], + "optional" : 1, + "type" : "string", + "type-property" : "type" + }, + "comment" : { + "description" : "HA rule description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Whether the HA rule is disabled.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names with optional priority.", + "format" : "pve-ha-node-list", + "instance-types" : [ + "node-affinity" + ], + "optional" : 1, + "type" : "string", + "type-property" : "type", + "typetext" : "[:]{,[:]}*", + "verbose_description" : "List of cluster node members, where a priority can be given to each node. A resource will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the resources will get distributed to those nodes. The priorities have a relative meaning only. The higher the number, the higher the priority." + }, + "resources" : { + "description" : "List of HA resource IDs. This consists of a list of resource types followed by a resource specific name separated with a colon (example: vm:100,ct:101).", + "format" : "pve-ha-resource-id-list", + "optional" : 1, + "type" : "string", + "typetext" : ":{,:}*" + }, + "rule" : { + "description" : "HA rule identifier.", + "format" : "pve-configid", + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "strict" : { + "default" : 0, + "description" : "Describes whether the node affinity rule is strict or non-strict.", + "instance-types" : [ + "node-affinity" + ], + "optional" : 1, + "type" : "boolean", + "type-property" : "type", + "typetext" : "", + "verbose_description" : "Describes whether the node affinity rule is strict or non-strict.\n\nA non-strict node affinity rule makes resources prefer to be on the defined nodes.\nIf none of the defined nodes are available, the resource may run on any other node.\n\nA strict node affinity rule makes resources be restricted to the defined nodes. If\nnone of the defined nodes are available, the resource will be stopped.\n" + }, + "type" : { + "description" : "HA rule type.", + "enum" : [ + "node-affinity", + "resource-affinity" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/rules/{rule}", + "text" : "{rule}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get HA rules.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "resource" : { + "description" : "Limit the returned list to rules affecting the specified resource.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Limit the returned list to the specified rule type.", + "enum" : [ + "node-affinity", + "resource-affinity" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "links" : [ + { + "href" : "{rule}", + "rel" : "child" + } + ], + "properties" : { + "rule" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create HA rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "affinity" : { + "description" : "Describes whether the HA resources are supposed to be kept on the same node ('positive'), or are supposed to be kept on separate nodes ('negative').", + "enum" : [ + "positive", + "negative" + ], + "instance-types" : [ + "resource-affinity" + ], + "optional" : 1, + "type" : "string", + "type-property" : "type" + }, + "comment" : { + "description" : "HA rule description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Whether the HA rule is disabled.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names with optional priority.", + "format" : "pve-ha-node-list", + "instance-types" : [ + "node-affinity" + ], + "optional" : 1, + "type" : "string", + "type-property" : "type", + "typetext" : "[:]{,[:]}*", + "verbose_description" : "List of cluster node members, where a priority can be given to each node. A resource will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the resources will get distributed to those nodes. The priorities have a relative meaning only. The higher the number, the higher the priority." + }, + "resources" : { + "description" : "List of HA resource IDs. This consists of a list of resource types followed by a resource specific name separated with a colon (example: vm:100,ct:101).", + "format" : "pve-ha-resource-id-list", + "optional" : 0, + "type" : "string", + "typetext" : ":{,:}*" + }, + "rule" : { + "description" : "HA rule identifier.", + "format" : "pve-configid", + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "strict" : { + "default" : 0, + "description" : "Describes whether the node affinity rule is strict or non-strict.", + "instance-types" : [ + "node-affinity" + ], + "optional" : 1, + "type" : "boolean", + "type-property" : "type", + "typetext" : "", + "verbose_description" : "Describes whether the node affinity rule is strict or non-strict.\n\nA non-strict node affinity rule makes resources prefer to be on the defined nodes.\nIf none of the defined nodes are available, the resource may run on any other node.\n\nA strict node affinity rule makes resources be restricted to the defined nodes. If\nnone of the defined nodes are available, the resource will be stopped.\n" + }, + "type" : { + "description" : "HA rule type.", + "enum" : [ + "node-affinity", + "resource-affinity" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/rules", + "text" : "rules" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get HA manager status.", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "armed-state" : { + "description" : "For type 'fencing'. Whether HA is armed, on standby, disarming or disarmed.", + "enum" : [ + "armed", + "standby", + "disarming", + "disarmed" + ], + "optional" : 1, + "type" : "string" + }, + "auto-rebalance" : { + "default" : 1, + "description" : "HA resource may be migrated during automatic rebalancing.", + "optional" : 1, + "type" : "boolean" + }, + "crm_state" : { + "description" : "For type 'service'. Service state as seen by the CRM.", + "optional" : 1, + "type" : "string" + }, + "failback" : { + "default" : 1, + "description" : "The HA resource is automatically migrated to the node with the highest priority according to their node affinity rule, if a node with a higher priority than the current node comes online.", + "optional" : 1, + "type" : "boolean" + }, + "id" : { + "description" : "Status entry ID (quorum, master, lrm:, service:).", + "type" : "string" + }, + "max_relocate" : { + "description" : "For type 'service'.", + "optional" : 1, + "type" : "integer" + }, + "max_restart" : { + "description" : "For type 'service'.", + "optional" : 1, + "type" : "integer" + }, + "node" : { + "description" : "Node associated to status entry.", + "type" : "string" + }, + "quorate" : { + "description" : "For type 'quorum'. Whether the cluster is quorate or not.", + "optional" : 1, + "type" : "boolean" + }, + "request_state" : { + "description" : "For type 'service'. Requested service state.", + "optional" : 1, + "type" : "string" + }, + "resource_mode" : { + "description" : "For type 'fencing'. How resources are handled while disarmed.", + "enum" : [ + "freeze", + "ignore" + ], + "optional" : 1, + "type" : "string" + }, + "sid" : { + "description" : "For type 'service'. Service ID.", + "optional" : 1, + "type" : "string" + }, + "state" : { + "description" : "For type 'service'. Verbose service state.", + "optional" : 1, + "type" : "string" + }, + "status" : { + "description" : "Status of the entry (value depends on type).", + "type" : "string" + }, + "timestamp" : { + "description" : "For type 'lrm','master'. Timestamp of the status information.", + "optional" : 1, + "type" : "integer" + }, + "type" : { + "description" : "Type of status entry.", + "enum" : [ + "quorum", + "master", + "lrm", + "service", + "fencing" + ] + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/status/current", + "text" : "current" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get full HA manager status, including LRM status.", + "method" : "GET", + "name" : "manager_status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/status/manager_status", + "text" : "manager_status" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Request disarming the HA stack, releasing all watchdogs cluster-wide.", + "method" : "POST", + "name" : "disarm-ha", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "resource-mode" : { + "description" : "Controls how HA managed resources are handled while disarmed. The current state of resources is not affected. 'freeze': new commands and state changes are not applied. 'ignore': resources are removed from HA tracking and can be managed as if they were not HA managed.", + "enum" : [ + "freeze", + "ignore" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/status/disarm-ha", + "text" : "disarm-ha" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Request re-arming the HA stack after it was disarmed.", + "method" : "POST", + "name" : "arm-ha", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/status/arm-ha", + "text" : "arm-ha" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/status", + "text" : "status" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha", + "text" : "ha" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete ACME plugin configuration.", + "method" : "DELETE", + "name" : "delete_plugin", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Unique identifier for ACME plugin instance.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get ACME plugin configuration.", + "method" : "GET", + "name" : "get_plugin_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Unique identifier for ACME plugin instance.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "api" : { + "description" : "API plugin name", + "enum" : [ + "1984hosting", + "acmedns", + "acmeproxy", + "active24", + "ad", + "ali", + "alviy", + "anx", + "artfiles", + "arvan", + "aurora", + "autodns", + "aws", + "azion", + "azure", + "beget", + "bookmyname", + "bunny", + "cf", + "clouddns", + "cloudns", + "cn", + "conoha", + "constellix", + "cpanel", + "curanet", + "cyon", + "da", + "ddnss", + "desec", + "df", + "dgon", + "dnsexit", + "dnshome", + "dnsimple", + "dnsservices", + "doapi", + "domeneshop", + "dp", + "dpi", + "dreamhost", + "duckdns", + "durabledns", + "dyn", + "dynu", + "dynv6", + "easydns", + "edgecenter", + "edgedns", + "euserv", + "exoscale", + "fornex", + "freedns", + "freemyip", + "gandi_livedns", + "gcloud", + "gcore", + "gd", + "geoscaling", + "googledomains", + "he", + "he_ddns", + "hetzner", + "hetznercloud", + "hexonet", + "hostingde", + "huaweicloud", + "infoblox", + "infomaniak", + "internetbs", + "inwx", + "ionos", + "ionos_cloud", + "ipv64", + "ispconfig", + "jd", + "joker", + "kappernet", + "kas", + "kinghost", + "knot", + "la", + "leaseweb", + "lexicon", + "limacity", + "linode", + "linode_v4", + "loopia", + "lua", + "maradns", + "me", + "miab", + "mijnhost", + "misaka", + "myapi", + "mydevil", + "mydnsjp", + "mythic_beasts", + "namecheap", + "namecom", + "namesilo", + "nanelo", + "nederhost", + "neodigit", + "netcup", + "netlify", + "nic", + "njalla", + "nm", + "nsd", + "nsone", + "nsupdate", + "nw", + "oci", + "omglol", + "one", + "online", + "openprovider", + "openprovider_rest", + "openstack", + "opnsense", + "ovh", + "pdns", + "pleskxml", + "pointhq", + "porkbun", + "rackcorp", + "rackspace", + "rage4", + "rcode0", + "regru", + "scaleway", + "schlundtech", + "selectel", + "selfhost", + "servercow", + "simply", + "spaceship", + "technitium", + "tele3", + "tencent", + "timeweb", + "transip", + "udr", + "ultra", + "unoeuro", + "variomedia", + "veesp", + "vercel", + "vscale", + "vultr", + "websupport", + "west_cn", + "world4you", + "yandex360", + "yc", + "zilore", + "zone", + "zoneedit", + "zonomi" + ], + "optional" : 1, + "type" : "string" + }, + "data" : { + "description" : "DNS plugin data. (base64 encoded)", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "disable" : { + "description" : "Flag to disable the config.", + "optional" : 1, + "type" : "boolean" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string" + }, + "plugin" : { + "description" : "Unique identifier for ACME plugin instance.", + "format" : "pve-configid", + "type" : "string" + }, + "type" : { + "description" : "ACME challenge type.", + "enum" : [ + "dns", + "standalone" + ], + "type" : "string" + }, + "validation-delay" : { + "default" : 30, + "description" : "Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.", + "maximum" : 172800, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update ACME plugin configuration.", + "method" : "PUT", + "name" : "update_plugin", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "api" : { + "description" : "API plugin name", + "enum" : [ + "1984hosting", + "acmedns", + "acmeproxy", + "active24", + "ad", + "ali", + "alviy", + "anx", + "artfiles", + "arvan", + "aurora", + "autodns", + "aws", + "azion", + "azure", + "beget", + "bookmyname", + "bunny", + "cf", + "clouddns", + "cloudns", + "cn", + "conoha", + "constellix", + "cpanel", + "curanet", + "cyon", + "da", + "ddnss", + "desec", + "df", + "dgon", + "dnsexit", + "dnshome", + "dnsimple", + "dnsservices", + "doapi", + "domeneshop", + "dp", + "dpi", + "dreamhost", + "duckdns", + "durabledns", + "dyn", + "dynu", + "dynv6", + "easydns", + "edgecenter", + "edgedns", + "euserv", + "exoscale", + "fornex", + "freedns", + "freemyip", + "gandi_livedns", + "gcloud", + "gcore", + "gd", + "geoscaling", + "googledomains", + "he", + "he_ddns", + "hetzner", + "hetznercloud", + "hexonet", + "hostingde", + "huaweicloud", + "infoblox", + "infomaniak", + "internetbs", + "inwx", + "ionos", + "ionos_cloud", + "ipv64", + "ispconfig", + "jd", + "joker", + "kappernet", + "kas", + "kinghost", + "knot", + "la", + "leaseweb", + "lexicon", + "limacity", + "linode", + "linode_v4", + "loopia", + "lua", + "maradns", + "me", + "miab", + "mijnhost", + "misaka", + "myapi", + "mydevil", + "mydnsjp", + "mythic_beasts", + "namecheap", + "namecom", + "namesilo", + "nanelo", + "nederhost", + "neodigit", + "netcup", + "netlify", + "nic", + "njalla", + "nm", + "nsd", + "nsone", + "nsupdate", + "nw", + "oci", + "omglol", + "one", + "online", + "openprovider", + "openprovider_rest", + "openstack", + "opnsense", + "ovh", + "pdns", + "pleskxml", + "pointhq", + "porkbun", + "rackcorp", + "rackspace", + "rage4", + "rcode0", + "regru", + "scaleway", + "schlundtech", + "selectel", + "selfhost", + "servercow", + "simply", + "spaceship", + "technitium", + "tele3", + "tencent", + "timeweb", + "transip", + "udr", + "ultra", + "unoeuro", + "variomedia", + "veesp", + "vercel", + "vscale", + "vultr", + "websupport", + "west_cn", + "world4you", + "yandex360", + "yc", + "zilore", + "zone", + "zoneedit", + "zonomi" + ], + "optional" : 1, + "type" : "string" + }, + "data" : { + "description" : "DNS plugin data. (base64 encoded)", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "ACME Plugin ID name", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "validation-delay" : { + "default" : 30, + "description" : "Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.", + "maximum" : 172800, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 172800)" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/plugins/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "ACME plugin index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list ACME plugins of a specific type", + "enum" : [ + "dns", + "standalone" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "api" : { + "description" : "API plugin name", + "enum" : [ + "1984hosting", + "acmedns", + "acmeproxy", + "active24", + "ad", + "ali", + "alviy", + "anx", + "artfiles", + "arvan", + "aurora", + "autodns", + "aws", + "azion", + "azure", + "beget", + "bookmyname", + "bunny", + "cf", + "clouddns", + "cloudns", + "cn", + "conoha", + "constellix", + "cpanel", + "curanet", + "cyon", + "da", + "ddnss", + "desec", + "df", + "dgon", + "dnsexit", + "dnshome", + "dnsimple", + "dnsservices", + "doapi", + "domeneshop", + "dp", + "dpi", + "dreamhost", + "duckdns", + "durabledns", + "dyn", + "dynu", + "dynv6", + "easydns", + "edgecenter", + "edgedns", + "euserv", + "exoscale", + "fornex", + "freedns", + "freemyip", + "gandi_livedns", + "gcloud", + "gcore", + "gd", + "geoscaling", + "googledomains", + "he", + "he_ddns", + "hetzner", + "hetznercloud", + "hexonet", + "hostingde", + "huaweicloud", + "infoblox", + "infomaniak", + "internetbs", + "inwx", + "ionos", + "ionos_cloud", + "ipv64", + "ispconfig", + "jd", + "joker", + "kappernet", + "kas", + "kinghost", + "knot", + "la", + "leaseweb", + "lexicon", + "limacity", + "linode", + "linode_v4", + "loopia", + "lua", + "maradns", + "me", + "miab", + "mijnhost", + "misaka", + "myapi", + "mydevil", + "mydnsjp", + "mythic_beasts", + "namecheap", + "namecom", + "namesilo", + "nanelo", + "nederhost", + "neodigit", + "netcup", + "netlify", + "nic", + "njalla", + "nm", + "nsd", + "nsone", + "nsupdate", + "nw", + "oci", + "omglol", + "one", + "online", + "openprovider", + "openprovider_rest", + "openstack", + "opnsense", + "ovh", + "pdns", + "pleskxml", + "pointhq", + "porkbun", + "rackcorp", + "rackspace", + "rage4", + "rcode0", + "regru", + "scaleway", + "schlundtech", + "selectel", + "selfhost", + "servercow", + "simply", + "spaceship", + "technitium", + "tele3", + "tencent", + "timeweb", + "transip", + "udr", + "ultra", + "unoeuro", + "variomedia", + "veesp", + "vercel", + "vscale", + "vultr", + "websupport", + "west_cn", + "world4you", + "yandex360", + "yc", + "zilore", + "zone", + "zoneedit", + "zonomi" + ], + "optional" : 1, + "type" : "string" + }, + "data" : { + "description" : "DNS plugin data. (base64 encoded)", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "disable" : { + "description" : "Flag to disable the config.", + "optional" : 1, + "type" : "boolean" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string" + }, + "plugin" : { + "description" : "Unique identifier for ACME plugin instance.", + "format" : "pve-configid", + "type" : "string" + }, + "type" : { + "description" : "ACME challenge type.", + "enum" : [ + "dns", + "standalone" + ], + "type" : "string" + }, + "validation-delay" : { + "default" : 30, + "description" : "Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.", + "maximum" : 172800, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{plugin}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add ACME plugin configuration.", + "method" : "POST", + "name" : "add_plugin", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "api" : { + "description" : "API plugin name", + "enum" : [ + "1984hosting", + "acmedns", + "acmeproxy", + "active24", + "ad", + "ali", + "alviy", + "anx", + "artfiles", + "arvan", + "aurora", + "autodns", + "aws", + "azion", + "azure", + "beget", + "bookmyname", + "bunny", + "cf", + "clouddns", + "cloudns", + "cn", + "conoha", + "constellix", + "cpanel", + "curanet", + "cyon", + "da", + "ddnss", + "desec", + "df", + "dgon", + "dnsexit", + "dnshome", + "dnsimple", + "dnsservices", + "doapi", + "domeneshop", + "dp", + "dpi", + "dreamhost", + "duckdns", + "durabledns", + "dyn", + "dynu", + "dynv6", + "easydns", + "edgecenter", + "edgedns", + "euserv", + "exoscale", + "fornex", + "freedns", + "freemyip", + "gandi_livedns", + "gcloud", + "gcore", + "gd", + "geoscaling", + "googledomains", + "he", + "he_ddns", + "hetzner", + "hetznercloud", + "hexonet", + "hostingde", + "huaweicloud", + "infoblox", + "infomaniak", + "internetbs", + "inwx", + "ionos", + "ionos_cloud", + "ipv64", + "ispconfig", + "jd", + "joker", + "kappernet", + "kas", + "kinghost", + "knot", + "la", + "leaseweb", + "lexicon", + "limacity", + "linode", + "linode_v4", + "loopia", + "lua", + "maradns", + "me", + "miab", + "mijnhost", + "misaka", + "myapi", + "mydevil", + "mydnsjp", + "mythic_beasts", + "namecheap", + "namecom", + "namesilo", + "nanelo", + "nederhost", + "neodigit", + "netcup", + "netlify", + "nic", + "njalla", + "nm", + "nsd", + "nsone", + "nsupdate", + "nw", + "oci", + "omglol", + "one", + "online", + "openprovider", + "openprovider_rest", + "openstack", + "opnsense", + "ovh", + "pdns", + "pleskxml", + "pointhq", + "porkbun", + "rackcorp", + "rackspace", + "rage4", + "rcode0", + "regru", + "scaleway", + "schlundtech", + "selectel", + "selfhost", + "servercow", + "simply", + "spaceship", + "technitium", + "tele3", + "tencent", + "timeweb", + "transip", + "udr", + "ultra", + "unoeuro", + "variomedia", + "veesp", + "vercel", + "vscale", + "vultr", + "websupport", + "west_cn", + "world4you", + "yandex360", + "yc", + "zilore", + "zone", + "zoneedit", + "zonomi" + ], + "optional" : 1, + "type" : "string" + }, + "data" : { + "description" : "DNS plugin data. (base64 encoded)", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "ACME Plugin ID name", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "ACME challenge type.", + "enum" : [ + "dns", + "standalone" + ], + "type" : "string" + }, + "validation-delay" : { + "default" : 30, + "description" : "Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.", + "maximum" : 172800, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 172800)" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/acme/plugins", + "text" : "plugins" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Deactivate existing ACME account at CA.", + "method" : "DELETE", + "name" : "deactivate_account", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Return existing ACME account information.", + "method" : "GET", + "name" : "get_account", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "account" : { + "optional" : 1, + "renderer" : "yaml", + "type" : "object" + }, + "directory" : { + "description" : "URL of ACME CA directory endpoint.", + "optional" : 1, + "pattern" : "^https?://.*", + "type" : "string" + }, + "location" : { + "optional" : 1, + "type" : "string" + }, + "tos" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update existing ACME account information with CA. Note: not specifying any new account information triggers a refresh.", + "method" : "PUT", + "name" : "update_account", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "contact" : { + "description" : "Contact email addresses.", + "format" : "email-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/account/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "ACMEAccount index.", + "method" : "GET", + "name" : "account_index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Register a new ACME account with CA.", + "method" : "POST", + "name" : "register_account", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "contact" : { + "description" : "Contact email addresses.", + "format" : "email-list", + "type" : "string", + "typetext" : "" + }, + "directory" : { + "default" : "https://acme-v02.api.letsencrypt.org/directory", + "description" : "URL of ACME CA directory endpoint.", + "optional" : 1, + "pattern" : "^https?://.*", + "type" : "string" + }, + "eab-hmac-key" : { + "description" : "HMAC key for External Account Binding.", + "optional" : 1, + "requires" : "eab-kid", + "type" : "string", + "typetext" : "" + }, + "eab-kid" : { + "description" : "Key Identifier for External Account Binding.", + "optional" : 1, + "requires" : "eab-hmac-key", + "type" : "string", + "typetext" : "" + }, + "name" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tos_url" : { + "description" : "URL of CA TermsOfService - setting this indicates agreement.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/acme/account", + "text" : "account" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Retrieve ACME TermsOfService URL from CA. Deprecated, please use /cluster/acme/meta.", + "method" : "GET", + "name" : "get_tos", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "directory" : { + "default" : "https://acme-v02.api.letsencrypt.org/directory", + "description" : "URL of ACME CA directory endpoint.", + "optional" : 1, + "pattern" : "^https?://.*", + "type" : "string" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "description" : "ACME TermsOfService URL.", + "optional" : 1, + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/tos", + "text" : "tos" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Retrieve ACME Directory Meta Information", + "method" : "GET", + "name" : "get_meta", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "directory" : { + "default" : "https://acme-v02.api.letsencrypt.org/directory", + "description" : "URL of ACME CA directory endpoint.", + "optional" : 1, + "pattern" : "^https?://.*", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "additionalProperties" : 1, + "properties" : { + "caaIdentities" : { + "description" : "Hostnames referring to the ACME servers.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "externalAccountRequired" : { + "description" : "EAB Required", + "optional" : 1, + "type" : "boolean" + }, + "termsOfService" : { + "description" : "ACME TermsOfService URL.", + "optional" : 1, + "type" : "string" + }, + "website" : { + "description" : "URL to more information about the ACME server.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/meta", + "text" : "meta" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get named known ACME directory endpoints.", + "method" : "GET", + "name" : "get_directories", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "type" : "string" + }, + "url" : { + "description" : "URL of ACME CA directory endpoint.", + "pattern" : "^https?://.*", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/directories", + "text" : "directories" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get schema of ACME challenge types.", + "method" : "GET", + "name" : "challengeschema", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "type" : "string" + }, + "name" : { + "description" : "Human readable name, falls back to id", + "type" : "string" + }, + "schema" : { + "type" : "object" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/challenge-schema", + "text" : "challenge-schema" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "ACMEAccount index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/acme", + "text" : "acme" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get ceph metadata.", + "method" : "GET", + "name" : "metadata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "scope" : { + "default" : "all", + "description" : "Which metadata facet to return: 'all' enriches the per-daemon metadata with the PVE-side service state (presence of unit, data directory), 'versions' collects only per-node Ceph binary version data.", + "enum" : [ + "all", + "versions" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "returns" : { + "description" : "Items for each type of service containing objects for each instance.", + "properties" : { + "mds" : { + "additionalProperties" : { + "additionalProperties" : 1, + "description" : "Useful properties are listed, but not the full list.", + "properties" : { + "addr" : { + "description" : "Bind addresses and ports.", + "optional" : 1, + "type" : "string" + }, + "ceph_release" : { + "description" : "Ceph release codename currently used.", + "type" : "string" + }, + "ceph_version" : { + "description" : "Version info currently used by the service.", + "type" : "string" + }, + "ceph_version_short" : { + "description" : "Short version (numerical) info currently used by the service.", + "type" : "string" + }, + "hostname" : { + "description" : "Hostname on which the service is running.", + "type" : "string" + }, + "mem_swap_kb" : { + "description" : "Memory of the service currently in swap.", + "type" : "integer" + }, + "mem_total_kb" : { + "description" : "Memory consumption of the service.", + "type" : "integer" + }, + "name" : { + "description" : "Name of the service instance.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "description" : "Metadata servers configured in the cluster and their properties, keyed by '@'.", + "type" : "object" + }, + "mgr" : { + "additionalProperties" : { + "additionalProperties" : 1, + "description" : "Useful properties are listed, but not the full list.", + "properties" : { + "addr" : { + "description" : "Bind address.", + "optional" : 1, + "type" : "string" + }, + "ceph_release" : { + "description" : "Ceph release codename currently used.", + "type" : "string" + }, + "ceph_version" : { + "description" : "Version info currently used by the service.", + "type" : "string" + }, + "ceph_version_short" : { + "description" : "Short version (numerical) info currently used by the service.", + "type" : "string" + }, + "hostname" : { + "description" : "Hostname on which the service is running.", + "type" : "string" + }, + "mem_swap_kb" : { + "description" : "Memory of the service currently in swap.", + "type" : "integer" + }, + "mem_total_kb" : { + "description" : "Memory consumption of the service.", + "type" : "integer" + }, + "name" : { + "description" : "Name of the service instance.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "description" : "Managers configured in the cluster and their properties, keyed by '@'.", + "type" : "object" + }, + "mon" : { + "additionalProperties" : { + "additionalProperties" : 1, + "description" : "Useful properties are listed, but not the full list.", + "properties" : { + "addrs" : { + "description" : "Bind addresses and ports.", + "optional" : 1, + "type" : "string" + }, + "ceph_release" : { + "description" : "Ceph release codename currently used.", + "type" : "string" + }, + "ceph_version" : { + "description" : "Version info currently used by the service.", + "type" : "string" + }, + "ceph_version_short" : { + "description" : "Short version (numerical) info currently used by the service.", + "type" : "string" + }, + "hostname" : { + "description" : "Hostname on which the service is running.", + "type" : "string" + }, + "mem_swap_kb" : { + "description" : "Memory of the service currently in swap.", + "type" : "integer" + }, + "mem_total_kb" : { + "description" : "Memory consumption of the service.", + "type" : "integer" + }, + "name" : { + "description" : "Name of the service instance.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "description" : "Monitors configured in the cluster and their properties, keyed by '@'.", + "type" : "object" + }, + "node" : { + "additionalProperties" : { + "additionalProperties" : 1, + "properties" : { + "buildcommit" : { + "description" : "GIT commit used for the build.", + "type" : "string" + }, + "version" : { + "description" : "Version info.", + "properties" : { + "parts" : { + "description" : "Major, minor and patch version numbers.", + "items" : { + "description" : "Version-component string.", + "type" : "string" + }, + "type" : "array" + }, + "str" : { + "description" : "Version as single string.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "type" : "object" + }, + "description" : "Ceph version installed on the nodes, keyed by node name.", + "type" : "object" + }, + "osd" : { + "description" : "OSDs configured in the cluster and their properties.", + "items" : { + "description" : "Useful properties are listed, but not the full list.", + "properties" : { + "back_addr" : { + "description" : "Bind addresses and ports for backend inter OSD traffic.", + "type" : "string" + }, + "ceph_release" : { + "description" : "Ceph release codename currently used.", + "type" : "string" + }, + "ceph_version" : { + "description" : "Version info currently used by the service.", + "type" : "string" + }, + "ceph_version_short" : { + "description" : "Short version (numerical) info currently used by the service.", + "type" : "string" + }, + "device_ids" : { + "description" : "Comma-joined list of device identifiers (e.g. 'sdb=,sdc=').", + "optional" : 1, + "type" : "string" + }, + "device_paths" : { + "description" : "Comma-joined list of /dev/disk/by-path entries for the underlying devices.", + "optional" : 1, + "type" : "string" + }, + "devices" : { + "description" : "Comma-joined list of underlying device names (e.g. 'sdb,sdc').", + "optional" : 1, + "type" : "string" + }, + "front_addr" : { + "description" : "Bind addresses and ports for frontend traffic to OSDs.", + "type" : "string" + }, + "hostname" : { + "description" : "Hostname on which the service is running.", + "type" : "string" + }, + "id" : { + "description" : "OSD ID.", + "type" : "integer" + }, + "mem_swap_kb" : { + "description" : "Memory of the service currently in swap.", + "type" : "integer" + }, + "mem_total_kb" : { + "description" : "Memory consumption of the service.", + "type" : "integer" + }, + "osd_data" : { + "description" : "Path to the OSD data directory.", + "type" : "string" + }, + "osd_objectstore" : { + "description" : "OSD objectstore type.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ceph/metadata", + "text" : "metadata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get ceph status.", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ceph/status", + "text" : "status" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the status of a specific ceph flag.", + "method" : "GET", + "name" : "get_flag", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "flag" : { + "description" : "The name of the flag name to get.", + "enum" : [ + "nobackfill", + "nodeep-scrub", + "nodown", + "noin", + "noout", + "norebalance", + "norecover", + "noscrub", + "notieragent", + "noup", + "pause" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "boolean" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set or clear (unset) a specific Ceph flag. Runs synchronously (unlike the bulk PUT /cluster/ceph/flags endpoint, which forks a worker task).", + "method" : "PUT", + "name" : "update_flag", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "flag" : { + "description" : "The ceph flag to update", + "enum" : [ + "nobackfill", + "nodeep-scrub", + "nodown", + "noin", + "noout", + "norebalance", + "norecover", + "noscrub", + "notieragent", + "noup", + "pause" + ], + "type" : "string" + }, + "value" : { + "description" : "The new value of the flag", + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ceph/flags/{flag}", + "text" : "{flag}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "get the status of all ceph flags", + "method" : "GET", + "name" : "get_all_flags", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "description" : { + "description" : "Flag description.", + "type" : "string" + }, + "name" : { + "description" : "Flag name.", + "enum" : [ + "nobackfill", + "nodeep-scrub", + "nodown", + "noin", + "noout", + "norebalance", + "norecover", + "noscrub", + "notieragent", + "noup", + "pause" + ], + "type" : "string" + }, + "value" : { + "description" : "Flag value.", + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set/Unset multiple Ceph flags at once. Each flag is a top-level optional boolean: passing true sets the flag, false unsets it, omitting it leaves the current state untouched. Runs as a worker task; returns a UPID to follow.", + "method" : "PUT", + "name" : "set_flags", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "nobackfill" : { + "description" : "Backfilling of PGs is suspended.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nodeep-scrub" : { + "description" : "Deep Scrubbing is disabled.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nodown" : { + "description" : "OSD failure reports are being ignored, such that the monitors will not mark OSDs down.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "noin" : { + "description" : "OSDs that were previously marked out will not be marked back in when they start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "noout" : { + "description" : "OSDs will not automatically be marked out after the configured interval.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "norebalance" : { + "description" : "Rebalancing of PGs is suspended.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "norecover" : { + "description" : "Recovery of PGs is suspended.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "noscrub" : { + "description" : "Scrubbing is disabled.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "notieragent" : { + "description" : "Cache tiering activity is suspended.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "noup" : { + "description" : "OSDs are not allowed to start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "pause" : { + "description" : "Pauses read and writes.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ceph/flags", + "text" : "flags" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Cluster ceph index.", + "method" : "GET", + "name" : "cephindex", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ceph", + "text" : "ceph" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete realm-sync job definition.", + "method" : "DELETE", + "name" : "delete_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read realm-sync job definition.", + "method" : "GET", + "name" : "read_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new realm-sync job.", + "method" : "POST", + "name" : "create_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description for the Job.", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable-new" : { + "default" : "1", + "description" : "Enable newly synced users immediately.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "enabled" : { + "default" : 1, + "description" : "Determines if the job is enabled.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the job.", + "format" : "pve-configid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + }, + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "remove-vanished" : { + "default" : "none", + "description" : "A semicolon-separated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).", + "optional" : 1, + "pattern" : "(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none", + "type" : "string", + "typetext" : "([acl];[properties];[entry])|none" + }, + "schedule" : { + "description" : "Backup schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "type" : "string", + "typetext" : "" + }, + "scope" : { + "description" : "Select what to sync.", + "enum" : [ + "users", + "groups", + "both" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/access/realm/{realm}", + [ + "Realm.AllocateUser" + ] + ], + [ + "perm", + "/access/groups", + [ + "User.Modify" + ] + ] + ], + "description" : "'Realm.AllocateUser' on '/access/realm/' and 'User.Modify' permissions to '/access/groups/'." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update realm-sync job definition.", + "method" : "PUT", + "name" : "update_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description for the Job.", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable-new" : { + "default" : "1", + "description" : "Enable newly synced users immediately.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "enabled" : { + "default" : 1, + "description" : "Determines if the job is enabled.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the job.", + "format" : "pve-configid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + }, + "remove-vanished" : { + "default" : "none", + "description" : "A semicolon-separated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).", + "optional" : 1, + "pattern" : "(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none", + "type" : "string", + "typetext" : "([acl];[properties];[entry])|none" + }, + "schedule" : { + "description" : "Backup schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "type" : "string", + "typetext" : "" + }, + "scope" : { + "description" : "Select what to sync.", + "enum" : [ + "users", + "groups", + "both" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/access/realm/{realm}", + [ + "Realm.AllocateUser" + ] + ], + [ + "perm", + "/access/groups", + [ + "User.Modify" + ] + ] + ], + "description" : "'Realm.AllocateUser' on '/access/realm/' and 'User.Modify' permissions to '/access/groups/'." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/jobs/realm-sync/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List configured realm-sync-jobs.", + "method" : "GET", + "name" : "syncjob_index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "A comment for the job.", + "optional" : 1, + "type" : "string" + }, + "enabled" : { + "description" : "If the job is enabled or not.", + "type" : "boolean" + }, + "id" : { + "description" : "The ID of the entry.", + "type" : "string" + }, + "last-run" : { + "description" : "Last execution time of the job in seconds since the beginning of the UNIX epoch", + "optional" : 1, + "type" : "integer" + }, + "next-run" : { + "description" : "Next planned execution time of the job in seconds since the beginning of the UNIX epoch.", + "optional" : 1, + "type" : "integer" + }, + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string" + }, + "remove-vanished" : { + "default" : "none", + "description" : "A semicolon-separated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).", + "optional" : "1", + "pattern" : "(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none", + "type" : "string", + "typetext" : "([acl];[properties];[entry])|none" + }, + "schedule" : { + "description" : "The configured sync schedule.", + "type" : "string" + }, + "scope" : { + "description" : "Select what to sync.", + "enum" : [ + "users", + "groups", + "both" + ], + "optional" : "1", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/jobs/realm-sync", + "text" : "realm-sync" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns a list of future schedule runtimes.", + "method" : "GET", + "name" : "schedule-analyze", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "iterations" : { + "default" : 10, + "description" : "Number of event-iteration to simulate and return.", + "maximum" : 100, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 100)" + }, + "schedule" : { + "description" : "Job schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "type" : "string", + "typetext" : "" + }, + "starttime" : { + "description" : "UNIX timestamp to start the calculation from. Defaults to the current time.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "description" : "An array of the next events since .", + "items" : { + "properties" : { + "timestamp" : { + "description" : "UNIX timestamp for the run.", + "type" : "integer" + }, + "utc" : { + "description" : "UTC timestamp for the run.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/jobs/schedule-analyze", + "text" : "schedule-analyze" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index for jobs related endpoints.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "description" : "Directory index.", + "items" : { + "properties" : { + "subdir" : { + "description" : "API sub-directory endpoint", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/jobs", + "text" : "jobs" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove directory mapping.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/dir", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get directory mapping.", + "method" : "GET", + "name" : "get", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update a directory mapping.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description of the directory mapping", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the directory mapping", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "map" : { + "description" : "A list of maps for the cluster nodes.", + "items" : { + "format" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "path" : { + "description" : "Absolute directory path that should be shared with the guest.", + "format" : "pve-storage-path-in-property-string", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/mapping/dir/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List directory mapping", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "check-node" : { + "description" : "If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the directory to the response.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/dir/'.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "checks" : { + "description" : "A list of checks, only present if 'check-node' is set.", + "items" : { + "properties" : { + "message" : { + "description" : "The message of the error", + "type" : "string" + }, + "severity" : { + "description" : "The severity of the error", + "enum" : [ + "warning", + "error" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "description" : { + "description" : "A description of the logical mapping.", + "type" : "string" + }, + "id" : { + "description" : "The logical ID of the mapping.", + "type" : "string" + }, + "map" : { + "description" : "The entries of the mapping.", + "items" : { + "description" : "A mapping for a node.", + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new directory mapping.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "Description of the directory mapping", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the directory mapping", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "map" : { + "description" : "A list of maps for the cluster nodes.", + "items" : { + "format" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "path" : { + "description" : "Absolute directory path that should be shared with the guest.", + "format" : "pve-storage-path-in-property-string", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 0, + "type" : "array", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/dir", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/mapping/dir", + "text" : "dir" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove Hardware Mapping.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/pci", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get PCI Mapping.", + "method" : "GET", + "name" : "get", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update a hardware mapping.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description of the logical PCI device.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the logical PCI mapping.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "live-migration-capable" : { + "default" : 0, + "description" : "Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "map" : { + "description" : "A list of maps for the cluster nodes.", + "items" : { + "format" : { + "description" : { + "description" : "Description of the node specific device.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "The vendor and device ID that is expected. Used for detecting hardware changes", + "pattern" : "(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)", + "type" : "string" + }, + "iommugroup" : { + "description" : "The IOMMU group in which the device is to be expected in. Used for detecting hardware changes.", + "optional" : 1, + "type" : "integer" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "path" : { + "description" : "The path to the device. If the function is omitted, the whole device is mapped. In that case use the attributes of the first device. You can give multiple paths as a semicolon separated list, the first available will then be chosen on guest start.", + "pattern" : "(?:[a-f0-9]{4,}:[a-f0-9]{2}:[a-f0-9]{2}(?:.[a-f0-9])?;)*[a-f0-9]{4,}:[a-f0-9]{2}:[a-f0-9]{2}(?:.[a-f0-9])?", + "type" : "string" + }, + "subsystem-id" : { + "description" : "The subsystem vendor and device ID that is expected. Used for detecting hardware changes.", + "optional" : 1, + "pattern" : "(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mdev" : { + "default" : 0, + "description" : "Marks the device(s) as being capable of providing mediated devices.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/mapping/pci/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List PCI Hardware Mapping", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "check-node" : { + "description" : "If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the devices to the response.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/pci/'.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "checks" : { + "description" : "A list of checks, only present if 'check_node' is set.", + "items" : { + "properties" : { + "message" : { + "description" : "The message of the error", + "type" : "string" + }, + "severity" : { + "description" : "The severity of the error", + "enum" : [ + "warning", + "error" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "description" : { + "description" : "A description of the logical mapping.", + "type" : "string" + }, + "id" : { + "description" : "The logical ID of the mapping.", + "type" : "string" + }, + "map" : { + "description" : "The entries of the mapping.", + "items" : { + "description" : "A mapping for a node.", + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new hardware mapping.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "Description of the logical PCI device.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the logical PCI mapping.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "live-migration-capable" : { + "default" : 0, + "description" : "Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "map" : { + "description" : "A list of maps for the cluster nodes.", + "items" : { + "format" : { + "description" : { + "description" : "Description of the node specific device.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "The vendor and device ID that is expected. Used for detecting hardware changes", + "pattern" : "(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)", + "type" : "string" + }, + "iommugroup" : { + "description" : "The IOMMU group in which the device is to be expected in. Used for detecting hardware changes.", + "optional" : 1, + "type" : "integer" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "path" : { + "description" : "The path to the device. If the function is omitted, the whole device is mapped. In that case use the attributes of the first device. You can give multiple paths as a semicolon separated list, the first available will then be chosen on guest start.", + "pattern" : "(?:[a-f0-9]{4,}:[a-f0-9]{2}:[a-f0-9]{2}(?:.[a-f0-9])?;)*[a-f0-9]{4,}:[a-f0-9]{2}:[a-f0-9]{2}(?:.[a-f0-9])?", + "type" : "string" + }, + "subsystem-id" : { + "description" : "The subsystem vendor and device ID that is expected. Used for detecting hardware changes.", + "optional" : 1, + "pattern" : "(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 0, + "type" : "array", + "typetext" : "" + }, + "mdev" : { + "default" : 0, + "description" : "Marks the device(s) as being capable of providing mediated devices.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/pci", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/mapping/pci", + "text" : "pci" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove Hardware Mapping.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/usb", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get USB Mapping.", + "method" : "GET", + "name" : "get", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update a hardware mapping.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description of the logical USB device.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the logical USB mapping.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "map" : { + "description" : "A list of maps for the cluster nodes.", + "items" : { + "format" : { + "description" : { + "description" : "Description of the node specific device.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "The vendor and device ID that is expected. If a USB path is given, it is only used for detecting hardware changes", + "pattern" : "(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "path" : { + "description" : "The path to the usb device.", + "optional" : 1, + "pattern" : "(?^:^(\\d+)\\-(\\d+(\\.\\d+)*)$)", + "type" : "string" + } + }, + "type" : "string" + }, + "type" : "array", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/mapping/usb/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List USB Hardware Mappings", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "check-node" : { + "description" : "If given, checks the configurations on the given node for correctness, and adds relevant errors to the devices.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/usb/'.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "description" : { + "description" : "A description of the logical mapping.", + "type" : "string" + }, + "error" : { + "description" : "A list of errors when 'check_node' is given.", + "items" : { + "properties" : { + "message" : { + "description" : "The message of the error", + "type" : "string" + }, + "severity" : { + "description" : "The severity of the error", + "type" : "string" + } + }, + "type" : "object" + } + }, + "id" : { + "description" : "The logical ID of the mapping.", + "type" : "string" + }, + "map" : { + "description" : "The entries of the mapping.", + "items" : { + "description" : "A mapping for a node.", + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new hardware mapping.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "Description of the logical USB device.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the logical USB mapping.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "map" : { + "description" : "A list of maps for the cluster nodes.", + "items" : { + "format" : { + "description" : { + "description" : "Description of the node specific device.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "The vendor and device ID that is expected. If a USB path is given, it is only used for detecting hardware changes", + "pattern" : "(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "path" : { + "description" : "The path to the usb device.", + "optional" : 1, + "pattern" : "(?^:^(\\d+)\\-(\\d+(\\.\\d+)*)$)", + "type" : "string" + } + }, + "type" : "string" + }, + "type" : "array", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/usb", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/mapping/usb", + "text" : "usb" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List resource types.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/mapping", + "text" : "mapping" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Bulk start or resume all guests on the cluster.", + "expose_credentials" : 1, + "method" : "POST", + "name" : "start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "max-workers" : { + "default" : 4, + "description" : "Defines the maximum number of tasks running concurrently.", + "maximum" : 64, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 64)" + }, + "maxworkers" : { + "default" : 4, + "description" : "Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.", + "maximum" : 64, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 64)" + }, + "timeout" : { + "description" : "Default start timeout in seconds. Only valid for VMs. (default depends on the guest configuration).", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "vms" : { + "description" : "Only consider guests from this list of VMIDs.", + "items" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "description" : "UPID of the worker", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/bulk-action/guest/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Bulk shutdown all guests on the cluster.", + "expose_credentials" : 1, + "method" : "POST", + "name" : "shutdown", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force-stop" : { + "default" : 1, + "description" : "Makes sure the Guest stops after the timeout.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "max-workers" : { + "default" : 4, + "description" : "Defines the maximum number of tasks running concurrently.", + "maximum" : 64, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 64)" + }, + "maxworkers" : { + "default" : 4, + "description" : "Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.", + "maximum" : 64, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 64)" + }, + "timeout" : { + "default" : 180, + "description" : "Default shutdown timeout in seconds if none is configured for the guest.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "vms" : { + "description" : "Only consider guests from this list of VMIDs.", + "items" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "description" : "UPID of the worker", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/bulk-action/guest/shutdown", + "text" : "shutdown" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Bulk suspend all guests on the cluster.", + "expose_credentials" : 1, + "method" : "POST", + "name" : "suspend", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "max-workers" : { + "default" : 4, + "description" : "Defines the maximum number of tasks running concurrently.", + "maximum" : 64, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 64)" + }, + "maxworkers" : { + "default" : 4, + "description" : "Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.", + "maximum" : 64, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 64)" + }, + "statestorage" : { + "description" : "The storage for the VM state.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "requires" : "to-disk", + "type" : "string", + "typetext" : "" + }, + "to-disk" : { + "default" : 0, + "description" : "If set, suspends the guests to disk. Will be resumed on next start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vms" : { + "description" : "Only consider guests from this list of VMIDs.", + "items" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter. Additionally, you need 'VM.Config.Disk' on the '/vms/{vmid}' path and 'Datastore.AllocateSpace' for the configured state-storage(s)", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "description" : "UPID of the worker", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/bulk-action/guest/suspend", + "text" : "suspend" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Bulk migrate all guests on the cluster.", + "expose_credentials" : 1, + "method" : "POST", + "name" : "migrate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "max-workers" : { + "default" : 1, + "description" : "Defines the maximum number of tasks running concurrently.", + "maximum" : 64, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 64)" + }, + "maxworkers" : { + "default" : 1, + "description" : "Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.", + "maximum" : 64, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 64)" + }, + "online" : { + "description" : "Enable live migration for VMs and restart migration for CTs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "Only consider guests from this list of VMIDs.", + "items" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "with-local-disks" : { + "description" : "Enable live storage migration for local disk", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The 'VM.Migrate' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "description" : "UPID of the worker", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/bulk-action/guest/migrate", + "text" : "migrate" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Bulk action index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/bulk-action/guest", + "text" : "guest" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List resource types.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/bulk-action", + "text" : "bulk-action" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'", + "user" : "all" + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment", + "optional" : 1, + "type" : "string" + }, + "dest" : { + "description" : "Restrict packet destination address", + "optional" : 1, + "type" : "string" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port", + "optional" : 1, + "type" : "string" + }, + "enable" : { + "description" : "Flag to enable/disable a rule", + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers", + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "description" : "IP version (4 or 6) - automatically determined from source/dest addresses", + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro", + "optional" : 1, + "type" : "string" + }, + "pos" : { + "description" : "Rule position in the ruleset", + "type" : "integer" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "Restrict packet source address", + "optional" : 1, + "type" : "string" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Rule type", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 1, + "type" : "string" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'", + "user" : "all" + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment", + "optional" : 1, + "type" : "string" + }, + "dest" : { + "description" : "Restrict packet destination address", + "optional" : 1, + "type" : "string" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port", + "optional" : 1, + "type" : "string" + }, + "enable" : { + "description" : "Flag to enable/disable a rule", + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers", + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "description" : "IP version (4 or 6) - automatically determined from source/dest addresses", + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro", + "optional" : 1, + "type" : "string" + }, + "pos" : { + "description" : "Rule position in the ruleset", + "type" : "integer" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "Restrict packet source address", + "optional" : 1, + "type" : "string" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Rule type", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 0, + "type" : "string" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/vnets/{vnet}/firewall/rules", + "text" : "rules" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get vnet firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'", + "user" : "all" + }, + "returns" : { + "properties" : { + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean" + }, + "log_level_forward" : { + "description" : "Log level for forwarded traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "policy_forward" : { + "description" : "Forward policy.", + "enum" : [ + "ACCEPT", + "DROP" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "log_level_forward" : { + "description" : "Log level for forwarded traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "policy_forward" : { + "description" : "Forward policy.", + "enum" : [ + "ACCEPT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/vnets/{vnet}/firewall/options", + "text" : "options" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/vnets/{vnet}/firewall", + "text" : "firewall" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn subnet object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "subnet" : { + "description" : "The SDN subnet object identifier.", + "format" : "pve-sdn-subnet-id", + "type" : "string", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn subnet configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "subnet" : { + "description" : "The SDN subnet object identifier.", + "format" : "pve-sdn-subnet-id", + "type" : "string", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user" : "all" + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn subnet object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp-dns-server" : { + "description" : "IP address for the DNS server", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp-range" : { + "description" : "A list of DHCP ranges for this subnet", + "items" : { + "format" : "pve-sdn-dhcp-range", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dnszoneprefix" : { + "description" : "dns domain zone prefix ex: 'adm' -> .adm.mydomain.com", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway" : { + "description" : "Subnet Gateway: Will be assign on vnet for layer3 zones", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "snat" : { + "description" : "enable masquerade for this subnet if pve-firewall", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "subnet" : { + "description" : "The SDN subnet object identifier.", + "format" : "pve-sdn-subnet-id", + "type" : "string", + "typetext" : "" + }, + "vnet" : { + "description" : "associated vnet", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "description" : "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "text" : "{subnet}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN subnets index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{subnet}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn subnet object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dhcp-dns-server" : { + "description" : "IP address for the DNS server", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp-range" : { + "description" : "A list of DHCP ranges for this subnet", + "items" : { + "format" : "pve-sdn-dhcp-range", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "dnszoneprefix" : { + "description" : "dns domain zone prefix ex: 'adm' -> .adm.mydomain.com", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway" : { + "description" : "Subnet Gateway: Will be assign on vnet for layer3 zones", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "snat" : { + "description" : "enable masquerade for this subnet if pve-firewall", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "subnet" : { + "description" : "The SDN subnet object identifier.", + "format" : "pve-sdn-subnet-id", + "type" : "string", + "typetext" : "" + }, + "type" : { + "enum" : [ + "subnet" + ], + "type" : "string" + }, + "vnet" : { + "description" : "associated vnet", + "optional" : 0, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "description" : "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/vnets/{vnet}/subnets", + "text" : "subnets" + }, + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete IP Mappings in a VNet", + "method" : "DELETE", + "name" : "ipdelete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ip" : { + "description" : "The IP address to delete", + "format" : "ip", + "type" : "string", + "typetext" : "" + }, + "mac" : { + "description" : "Unicast MAC address.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}/{vnet}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create IP Mapping in a VNet", + "method" : "POST", + "name" : "ipcreate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ip" : { + "description" : "The IP address to associate with the given MAC address", + "format" : "ip", + "type" : "string", + "typetext" : "" + }, + "mac" : { + "description" : "Unicast MAC address.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}/{vnet}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP Mapping in a VNet", + "method" : "PUT", + "name" : "ipupdate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ip" : { + "description" : "The IP address to associate with the given MAC address", + "format" : "ip", + "type" : "string", + "typetext" : "" + }, + "mac" : { + "description" : "Unicast MAC address.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}/{vnet}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/vnets/{vnet}/ips", + "text" : "ips" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn vnet object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn vnet configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user" : "all" + }, + "returns" : { + "properties" : { + "alias" : { + "description" : "Alias name of the VNet.", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})", + "type" : "string" + }, + "digest" : { + "description" : "Digest of the VNet section.", + "optional" : 1, + "type" : "string" + }, + "isolate-ports" : { + "description" : "If true, sets the isolated property for all interfaces on the bridge of this VNet.", + "optional" : 1, + "type" : "boolean" + }, + "pending" : { + "description" : "Changes that have not yet been applied to the running configuration.", + "optional" : 1, + "properties" : { + "alias" : { + "description" : "Alias name of the VNet.", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})", + "type" : "string" + }, + "isolate-ports" : { + "description" : "If true, sets the isolated property for all interfaces on the bridge of this VNet.", + "optional" : 1, + "type" : "boolean" + }, + "tag" : { + "description" : "VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).", + "maximum" : 16777215, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "vlanaware" : { + "description" : "Allow VLANs to pass through this VNet.", + "optional" : 1, + "type" : "boolean" + }, + "zone" : { + "description" : "Name of the zone this VNet belongs to.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "state" : { + "description" : "State of the SDN configuration object.", + "enum" : [ + "new", + "changed", + "deleted" + ], + "optional" : 1, + "type" : "string" + }, + "tag" : { + "description" : "VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).", + "maximum" : 16777215, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "description" : "Type of the VNet.", + "enum" : [ + "vnet" + ], + "optional" : 0, + "type" : "string" + }, + "vlanaware" : { + "description" : "Allow VLANs to pass through this VNet.", + "optional" : 1, + "type" : "boolean" + }, + "vnet" : { + "description" : "Name of the VNet.", + "optional" : 0, + "type" : "string" + }, + "zone" : { + "description" : "Name of the zone this VNet belongs to.", + "optional" : 1, + "type" : "string" + } + } + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn vnet object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "alias" : { + "description" : "Alias name of the VNet.", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})", + "type" : "string" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "isolate-ports" : { + "description" : "If true, sets the isolated property for all interfaces on the bridge of this VNet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tag" : { + "description" : "VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).", + "maximum" : 16777215, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 16777215)" + }, + "vlanaware" : { + "description" : "Allow VLANs to pass through this vnet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + }, + "zone" : { + "description" : "Name of the zone this VNet belongs to.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "description" : "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/vnets/{vnet}", + "text" : "{vnet}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN vnets index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "alias" : { + "description" : "Alias name of the VNet.", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})", + "type" : "string" + }, + "digest" : { + "description" : "Digest of the VNet section.", + "optional" : 1, + "type" : "string" + }, + "isolate-ports" : { + "description" : "If true, sets the isolated property for all interfaces on the bridge of this VNet.", + "optional" : 1, + "type" : "boolean" + }, + "pending" : { + "description" : "Changes that have not yet been applied to the running configuration.", + "optional" : 1, + "properties" : { + "alias" : { + "description" : "Alias name of the VNet.", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})", + "type" : "string" + }, + "isolate-ports" : { + "description" : "If true, sets the isolated property for all interfaces on the bridge of this VNet.", + "optional" : 1, + "type" : "boolean" + }, + "tag" : { + "description" : "VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).", + "maximum" : 16777215, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "vlanaware" : { + "description" : "Allow VLANs to pass through this VNet.", + "optional" : 1, + "type" : "boolean" + }, + "zone" : { + "description" : "Name of the zone this VNet belongs to.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "state" : { + "description" : "State of the SDN configuration object.", + "enum" : [ + "new", + "changed", + "deleted" + ], + "optional" : 1, + "type" : "string" + }, + "tag" : { + "description" : "VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).", + "maximum" : 16777215, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "description" : "Type of the VNet.", + "enum" : [ + "vnet" + ], + "optional" : 0, + "type" : "string" + }, + "vlanaware" : { + "description" : "Allow VLANs to pass through this VNet.", + "optional" : 1, + "type" : "boolean" + }, + "vnet" : { + "description" : "Name of the VNet.", + "optional" : 0, + "type" : "string" + }, + "zone" : { + "description" : "Name of the zone this VNet belongs to.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{vnet}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn vnet object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "alias" : { + "description" : "Alias name of the VNet.", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})", + "type" : "string" + }, + "isolate-ports" : { + "description" : "If true, sets the isolated property for all interfaces on the bridge of this VNet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tag" : { + "description" : "VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).", + "maximum" : 16777215, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 16777215)" + }, + "type" : { + "description" : "Type of the VNet.", + "enum" : [ + "vnet" + ], + "optional" : 1, + "type" : "string" + }, + "vlanaware" : { + "description" : "Allow VLANs to pass through this vnet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + }, + "zone" : { + "description" : "Name of the zone this VNet belongs to.", + "optional" : 0, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/vnets", + "text" : "vnets" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn zone object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn zone configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "properties" : { + "advertise-subnets" : { + "description" : "Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes). EVPN zone only.", + "optional" : 1, + "type" : "boolean" + }, + "bridge" : { + "description" : "the bridge for which VLANs should be managed. VLAN & QinQ zone only.", + "optional" : 1, + "type" : "string" + }, + "bridge-disable-mac-learning" : { + "description" : "Disable auto mac learning. VLAN zone only.", + "optional" : 1, + "type" : "boolean" + }, + "controller" : { + "description" : "ID of the controller for this zone. EVPN zone only.", + "optional" : 1, + "type" : "string" + }, + "dhcp" : { + "description" : "Name of DHCP server backend for this zone.", + "enum" : [ + "dnsmasq" + ], + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Digest of the controller section.", + "optional" : 1, + "type" : "string" + }, + "disable-arp-nd-suppression" : { + "description" : "Suppress IPv4 ARP && IPv6 Neighbour Discovery messages. EVPN zone only.", + "optional" : 1, + "type" : "boolean" + }, + "dns" : { + "description" : "ID of the DNS server for this zone.", + "optional" : 1, + "type" : "string" + }, + "dnszone" : { + "description" : "Domain name for this zone.", + "optional" : 1, + "type" : "string" + }, + "exitnodes" : { + "description" : "List of PVE Nodes that should act as exit node for this zone. EVPN zone only.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string" + }, + "exitnodes-local-routing" : { + "description" : "Create routes on the exit nodes, so they can connect to EVPN guests. EVPN zone only.", + "optional" : 1, + "type" : "boolean" + }, + "exitnodes-primary" : { + "description" : "Force traffic through this exitnode first. EVPN zone only.", + "format" : "pve-node", + "optional" : 1, + "type" : "string" + }, + "ipam" : { + "description" : "ID of the IPAM for this zone.", + "optional" : 1, + "type" : "string" + }, + "mac" : { + "description" : "MAC address of the anycast router for this zone.", + "optional" : 1, + "type" : "string" + }, + "mtu" : { + "description" : "MTU of the zone, will be used for the created VNet bridges.", + "optional" : 1, + "type" : "integer" + }, + "nodes" : { + "description" : "Nodes where this zone should be created.", + "optional" : 1, + "type" : "string" + }, + "peers" : { + "description" : "Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes. VXLAN zone only.", + "format" : "ip-list", + "optional" : 1, + "type" : "string" + }, + "pending" : { + "description" : "Changes that have not yet been applied to the running configuration.", + "optional" : 1, + "properties" : { + "advertise-subnets" : { + "description" : "Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes). EVPN zone only.", + "optional" : 1, + "type" : "boolean" + }, + "bridge" : { + "description" : "the bridge for which VLANs should be managed. VLAN & QinQ zone only.", + "optional" : 1, + "type" : "string" + }, + "bridge-disable-mac-learning" : { + "description" : "Disable auto mac learning. VLAN zone only.", + "optional" : 1, + "type" : "boolean" + }, + "controller" : { + "description" : "ID of the controller for this zone. EVPN zone only.", + "optional" : 1, + "type" : "string" + }, + "dhcp" : { + "description" : "Name of DHCP server backend for this zone.", + "enum" : [ + "dnsmasq" + ], + "optional" : 1, + "type" : "string" + }, + "disable-arp-nd-suppression" : { + "description" : "Suppress IPv4 ARP && IPv6 Neighbour Discovery messages. EVPN zone only.", + "optional" : 1, + "type" : "boolean" + }, + "dns" : { + "description" : "ID of the DNS server for this zone.", + "optional" : 1, + "type" : "string" + }, + "dnszone" : { + "description" : "Domain name for this zone.", + "optional" : 1, + "type" : "string" + }, + "exitnodes" : { + "description" : "List of PVE Nodes that should act as exit node for this zone. EVPN zone only.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string" + }, + "exitnodes-local-routing" : { + "description" : "Create routes on the exit nodes, so they can connect to EVPN guests. EVPN zone only.", + "optional" : 1, + "type" : "boolean" + }, + "exitnodes-primary" : { + "description" : "Force traffic through this exitnode first. EVPN zone only.", + "format" : "pve-node", + "optional" : 1, + "type" : "string" + }, + "ipam" : { + "description" : "ID of the IPAM for this zone.", + "optional" : 1, + "type" : "string" + }, + "mac" : { + "description" : "MAC address of the anycast router for this zone.", + "optional" : 1, + "type" : "string" + }, + "mtu" : { + "description" : "MTU of the zone, will be used for the created VNet bridges.", + "optional" : 1, + "type" : "integer" + }, + "nodes" : { + "description" : "Nodes where this zone should be created.", + "optional" : 1, + "type" : "string" + }, + "peers" : { + "description" : "Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes. VXLAN zone only.", + "format" : "ip-list", + "optional" : 1, + "type" : "string" + }, + "reversedns" : { + "description" : "ID of the reverse DNS server for this zone.", + "optional" : 1, + "type" : "string" + }, + "rt-import" : { + "description" : "Route-Targets that should be imported into the VRF of this zone via BGP. EVPN zone only.", + "format" : "pve-sdn-bgp-rt-list", + "optional" : 1, + "type" : "string" + }, + "secondary-controllers" : { + "description" : "Additional controllers.", + "items" : { + "description" : "Controller ID.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "tag" : { + "description" : "Service-VLAN Tag (outer VLAN). QinQ zone only", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "vlan-protocol" : { + "default" : "802.1q", + "description" : "VLAN protocol for the creation of the QinQ zone. QinQ zone only.", + "enum" : [ + "802.1q", + "802.1ad" + ], + "optional" : 1, + "type" : "string" + }, + "vrf-vxlan" : { + "description" : "VNI for the zone VRF. EVPN zone only.", + "maximum" : 16777215, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "vxlan-port" : { + "default" : 4789, + "description" : "UDP port that should be used for the VXLAN tunnel (default 4789). VXLAN zone only.", + "maximum" : 65536, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "reversedns" : { + "description" : "ID of the reverse DNS server for this zone.", + "optional" : 1, + "type" : "string" + }, + "rt-import" : { + "description" : "Route-Targets that should be imported into the VRF of this zone via BGP. EVPN zone only.", + "format" : "pve-sdn-bgp-rt-list", + "optional" : 1, + "type" : "string" + }, + "secondary-controllers" : { + "description" : "Additional controllers.", + "items" : { + "description" : "Controller ID.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "state" : { + "description" : "State of the SDN configuration object.", + "enum" : [ + "new", + "changed", + "deleted" + ], + "optional" : 1, + "type" : "string" + }, + "tag" : { + "description" : "Service-VLAN Tag (outer VLAN). QinQ zone only", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "description" : "Type of the zone.", + "enum" : [ + "evpn", + "faucet", + "qinq", + "simple", + "vlan", + "vxlan" + ], + "type" : "string" + }, + "vlan-protocol" : { + "default" : "802.1q", + "description" : "VLAN protocol for the creation of the QinQ zone. QinQ zone only.", + "enum" : [ + "802.1q", + "802.1ad" + ], + "optional" : 1, + "type" : "string" + }, + "vrf-vxlan" : { + "description" : "VNI for the zone VRF. EVPN zone only.", + "maximum" : 16777215, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "vxlan-port" : { + "default" : 4789, + "description" : "UDP port that should be used for the VXLAN tunnel (default 4789). VXLAN zone only.", + "maximum" : 65536, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "zone" : { + "description" : "Name of the zone.", + "type" : "string" + } + } + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn zone object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "advertise-subnets" : { + "description" : "Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bridge" : { + "description" : "The bridge for which VLANs should be managed.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge-disable-mac-learning" : { + "description" : "Disable auto mac learning.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "controller" : { + "description" : "Controller for this zone.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp" : { + "description" : "Type of the DHCP backend for this zone", + "enum" : [ + "dnsmasq" + ], + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable-arp-nd-suppression" : { + "description" : "Suppress IPv4 ARP && IPv6 Neighbour Discovery messages.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "dns" : { + "description" : "dns api server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dnszone" : { + "description" : "dns domain zone ex: mydomain.com", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dp-id" : { + "description" : "Faucet dataplane id", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "exitnodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exitnodes-local-routing" : { + "description" : "Allow exitnodes to connect to EVPN guests.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "exitnodes-primary" : { + "description" : "Force traffic through this exitnode first.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fabric" : { + "description" : "SDN fabric to use as underlay for this VXLAN zone.", + "format" : "pve-sdn-fabric-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ipam" : { + "description" : "use a specific ipam", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mac" : { + "description" : "Anycast logical router mac address.", + "format" : "mac-addr", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mtu" : { + "description" : "MTU of the zone, will be used for the created VNet bridges.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peers" : { + "description" : "Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "reversedns" : { + "description" : "reverse dns api server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rt-import" : { + "description" : "List of Route Targets that should be imported into the VRF of the zone.", + "format" : "pve-sdn-bgp-rt-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "secondary-controllers" : { + "description" : "Additional controllers.", + "items" : { + "description" : "Controller ID.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "tag" : { + "description" : "Service-VLAN Tag (outer VLAN)", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vlan-protocol" : { + "default" : "802.1q", + "description" : "Which VLAN protocol should be used for the creation of the QinQ zone.", + "enum" : [ + "802.1q", + "802.1ad" + ], + "optional" : 1, + "type" : "string" + }, + "vrf-vxlan" : { + "description" : "VNI for the zone VRF.", + "maximum" : 16777215, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 16777215)" + }, + "vxlan-port" : { + "default" : 4789, + "description" : "UDP port that should be used for the VXLAN tunnel (default 4789).", + "maximum" : 65536, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65536)" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/zones/{zone}", + "text" : "{zone}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN zones index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "type" : { + "description" : "Only list SDN zones of specific type", + "enum" : [ + "evpn", + "faucet", + "qinq", + "simple", + "vlan", + "vxlan" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "advertise-subnets" : { + "description" : "Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes). EVPN zone only.", + "optional" : 1, + "type" : "boolean" + }, + "bridge" : { + "description" : "the bridge for which VLANs should be managed. VLAN & QinQ zone only.", + "optional" : 1, + "type" : "string" + }, + "bridge-disable-mac-learning" : { + "description" : "Disable auto mac learning. VLAN zone only.", + "optional" : 1, + "type" : "boolean" + }, + "controller" : { + "description" : "ID of the controller for this zone. EVPN zone only.", + "optional" : 1, + "type" : "string" + }, + "dhcp" : { + "description" : "Name of DHCP server backend for this zone.", + "enum" : [ + "dnsmasq" + ], + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Digest of the controller section.", + "optional" : 1, + "type" : "string" + }, + "disable-arp-nd-suppression" : { + "description" : "Suppress IPv4 ARP && IPv6 Neighbour Discovery messages. EVPN zone only.", + "optional" : 1, + "type" : "boolean" + }, + "dns" : { + "description" : "ID of the DNS server for this zone.", + "optional" : 1, + "type" : "string" + }, + "dnszone" : { + "description" : "Domain name for this zone.", + "optional" : 1, + "type" : "string" + }, + "exitnodes" : { + "description" : "List of PVE Nodes that should act as exit node for this zone. EVPN zone only.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string" + }, + "exitnodes-local-routing" : { + "description" : "Create routes on the exit nodes, so they can connect to EVPN guests. EVPN zone only.", + "optional" : 1, + "type" : "boolean" + }, + "exitnodes-primary" : { + "description" : "Force traffic through this exitnode first. EVPN zone only.", + "format" : "pve-node", + "optional" : 1, + "type" : "string" + }, + "ipam" : { + "description" : "ID of the IPAM for this zone.", + "optional" : 1, + "type" : "string" + }, + "mac" : { + "description" : "MAC address of the anycast router for this zone.", + "optional" : 1, + "type" : "string" + }, + "mtu" : { + "description" : "MTU of the zone, will be used for the created VNet bridges.", + "optional" : 1, + "type" : "integer" + }, + "nodes" : { + "description" : "Nodes where this zone should be created.", + "optional" : 1, + "type" : "string" + }, + "peers" : { + "description" : "Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes. VXLAN zone only.", + "format" : "ip-list", + "optional" : 1, + "type" : "string" + }, + "pending" : { + "description" : "Changes that have not yet been applied to the running configuration.", + "optional" : 1, + "properties" : { + "advertise-subnets" : { + "description" : "Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes). EVPN zone only.", + "optional" : 1, + "type" : "boolean" + }, + "bridge" : { + "description" : "the bridge for which VLANs should be managed. VLAN & QinQ zone only.", + "optional" : 1, + "type" : "string" + }, + "bridge-disable-mac-learning" : { + "description" : "Disable auto mac learning. VLAN zone only.", + "optional" : 1, + "type" : "boolean" + }, + "controller" : { + "description" : "ID of the controller for this zone. EVPN zone only.", + "optional" : 1, + "type" : "string" + }, + "dhcp" : { + "description" : "Name of DHCP server backend for this zone.", + "enum" : [ + "dnsmasq" + ], + "optional" : 1, + "type" : "string" + }, + "disable-arp-nd-suppression" : { + "description" : "Suppress IPv4 ARP && IPv6 Neighbour Discovery messages. EVPN zone only.", + "optional" : 1, + "type" : "boolean" + }, + "dns" : { + "description" : "ID of the DNS server for this zone.", + "optional" : 1, + "type" : "string" + }, + "dnszone" : { + "description" : "Domain name for this zone.", + "optional" : 1, + "type" : "string" + }, + "exitnodes" : { + "description" : "List of PVE Nodes that should act as exit node for this zone. EVPN zone only.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string" + }, + "exitnodes-local-routing" : { + "description" : "Create routes on the exit nodes, so they can connect to EVPN guests. EVPN zone only.", + "optional" : 1, + "type" : "boolean" + }, + "exitnodes-primary" : { + "description" : "Force traffic through this exitnode first. EVPN zone only.", + "format" : "pve-node", + "optional" : 1, + "type" : "string" + }, + "ipam" : { + "description" : "ID of the IPAM for this zone.", + "optional" : 1, + "type" : "string" + }, + "mac" : { + "description" : "MAC address of the anycast router for this zone.", + "optional" : 1, + "type" : "string" + }, + "mtu" : { + "description" : "MTU of the zone, will be used for the created VNet bridges.", + "optional" : 1, + "type" : "integer" + }, + "nodes" : { + "description" : "Nodes where this zone should be created.", + "optional" : 1, + "type" : "string" + }, + "peers" : { + "description" : "Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes. VXLAN zone only.", + "format" : "ip-list", + "optional" : 1, + "type" : "string" + }, + "reversedns" : { + "description" : "ID of the reverse DNS server for this zone.", + "optional" : 1, + "type" : "string" + }, + "rt-import" : { + "description" : "Route-Targets that should be imported into the VRF of this zone via BGP. EVPN zone only.", + "format" : "pve-sdn-bgp-rt-list", + "optional" : 1, + "type" : "string" + }, + "secondary-controllers" : { + "description" : "Additional controllers.", + "items" : { + "description" : "Controller ID.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "tag" : { + "description" : "Service-VLAN Tag (outer VLAN). QinQ zone only", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "vlan-protocol" : { + "default" : "802.1q", + "description" : "VLAN protocol for the creation of the QinQ zone. QinQ zone only.", + "enum" : [ + "802.1q", + "802.1ad" + ], + "optional" : 1, + "type" : "string" + }, + "vrf-vxlan" : { + "description" : "VNI for the zone VRF. EVPN zone only.", + "maximum" : 16777215, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "vxlan-port" : { + "default" : 4789, + "description" : "UDP port that should be used for the VXLAN tunnel (default 4789). VXLAN zone only.", + "maximum" : 65536, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "reversedns" : { + "description" : "ID of the reverse DNS server for this zone.", + "optional" : 1, + "type" : "string" + }, + "rt-import" : { + "description" : "Route-Targets that should be imported into the VRF of this zone via BGP. EVPN zone only.", + "format" : "pve-sdn-bgp-rt-list", + "optional" : 1, + "type" : "string" + }, + "secondary-controllers" : { + "description" : "Additional controllers.", + "items" : { + "description" : "Controller ID.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "state" : { + "description" : "State of the SDN configuration object.", + "enum" : [ + "new", + "changed", + "deleted" + ], + "optional" : 1, + "type" : "string" + }, + "tag" : { + "description" : "Service-VLAN Tag (outer VLAN). QinQ zone only", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "description" : "Type of the zone.", + "enum" : [ + "evpn", + "faucet", + "qinq", + "simple", + "vlan", + "vxlan" + ], + "type" : "string" + }, + "vlan-protocol" : { + "default" : "802.1q", + "description" : "VLAN protocol for the creation of the QinQ zone. QinQ zone only.", + "enum" : [ + "802.1q", + "802.1ad" + ], + "optional" : 1, + "type" : "string" + }, + "vrf-vxlan" : { + "description" : "VNI for the zone VRF. EVPN zone only.", + "maximum" : 16777215, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "vxlan-port" : { + "default" : 4789, + "description" : "UDP port that should be used for the VXLAN tunnel (default 4789). VXLAN zone only.", + "maximum" : 65536, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "zone" : { + "description" : "Name of the zone.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{zone}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn zone object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "advertise-subnets" : { + "description" : "Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bridge" : { + "description" : "The bridge for which VLANs should be managed.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge-disable-mac-learning" : { + "description" : "Disable auto mac learning.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "controller" : { + "description" : "Controller for this zone.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp" : { + "description" : "Type of the DHCP backend for this zone", + "enum" : [ + "dnsmasq" + ], + "optional" : 1, + "type" : "string" + }, + "disable-arp-nd-suppression" : { + "description" : "Suppress IPv4 ARP && IPv6 Neighbour Discovery messages.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "dns" : { + "description" : "dns api server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dnszone" : { + "description" : "dns domain zone ex: mydomain.com", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dp-id" : { + "description" : "Faucet dataplane id", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "exitnodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exitnodes-local-routing" : { + "description" : "Allow exitnodes to connect to EVPN guests.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "exitnodes-primary" : { + "description" : "Force traffic through this exitnode first.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fabric" : { + "description" : "SDN fabric to use as underlay for this VXLAN zone.", + "format" : "pve-sdn-fabric-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ipam" : { + "description" : "use a specific ipam", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mac" : { + "description" : "Anycast logical router mac address.", + "format" : "mac-addr", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mtu" : { + "description" : "MTU of the zone, will be used for the created VNet bridges.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peers" : { + "description" : "Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "reversedns" : { + "description" : "reverse dns api server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rt-import" : { + "description" : "List of Route Targets that should be imported into the VRF of the zone.", + "format" : "pve-sdn-bgp-rt-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "secondary-controllers" : { + "description" : "Additional controllers.", + "items" : { + "description" : "Controller ID.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "tag" : { + "description" : "Service-VLAN Tag (outer VLAN)", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "evpn", + "faucet", + "qinq", + "simple", + "vlan", + "vxlan" + ], + "format" : "pve-configid", + "type" : "string" + }, + "vlan-protocol" : { + "default" : "802.1q", + "description" : "Which VLAN protocol should be used for the creation of the QinQ zone.", + "enum" : [ + "802.1q", + "802.1ad" + ], + "optional" : 1, + "type" : "string" + }, + "vrf-vxlan" : { + "description" : "VNI for the zone VRF.", + "maximum" : 16777215, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 16777215)" + }, + "vxlan-port" : { + "default" : 4789, + "description" : "UDP port that should be used for the VXLAN tunnel (default 4789).", + "maximum" : 65536, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65536)" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/zones", + "text" : "zones" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn controller object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "controller" : { + "description" : "The SDN controller object identifier.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]", + "type" : "string" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn controller configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "controller" : { + "description" : "The SDN controller object identifier.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]", + "type" : "string" + }, + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/controllers/{controller}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "properties" : { + "asn" : { + "description" : "The local ASN of the controller. BGP & EVPN only.", + "maximum" : 4294967295, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "bgp-mode" : { + "default" : "auto", + "description" : "Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP.", + "enum" : [ + "auto", + "external", + "internal" + ], + "optional" : 1, + "type" : "string" + }, + "bgp-multipath-as-relax" : { + "description" : "Consider different AS paths of equal length for multipath computation. BGP only.", + "optional" : 1, + "type" : "boolean" + }, + "controller" : { + "description" : "Name of the controller.", + "type" : "string" + }, + "digest" : { + "description" : "Digest of the controller section.", + "optional" : 1, + "type" : "string" + }, + "ebgp" : { + "description" : "Enable eBGP (remote-as external). BGP only.", + "optional" : 1, + "type" : "boolean" + }, + "ebgp-multihop" : { + "description" : "Set maximum amount of hops for eBGP peers. Needs ebgp set to 1. BGP only.", + "optional" : 1, + "type" : "integer" + }, + "isis-domain" : { + "description" : "Name of the IS-IS domain. IS-IS only.", + "optional" : 1, + "type" : "string" + }, + "isis-ifaces" : { + "description" : "Comma-separated list of interfaces where IS-IS should be active. IS-IS only.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string" + }, + "isis-net" : { + "description" : "Network Entity title for this node in the IS-IS network. IS-IS only.", + "format" : "pve-sdn-isis-net", + "optional" : 1, + "type" : "string" + }, + "loopback" : { + "description" : "Name of the loopback/dummy interface that provides the Router-IP. BGP only.", + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Node(s) where this controller is active.", + "optional" : 1, + "type" : "string" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string" + }, + "peer-group-name" : { + "description" : "Name of the peer group for this EVPN controller", + "optional" : 1, + "type" : "string" + }, + "peers" : { + "description" : "Comma-separated list of the peers IP addresses.", + "optional" : 1, + "type" : "string" + }, + "pending" : { + "description" : "Changes that have not yet been applied to the running configuration.", + "optional" : 1, + "properties" : { + "asn" : { + "description" : "The local ASN of the controller. BGP & EVPN only.", + "maximum" : 4294967295, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "bgp-mode" : { + "default" : "auto", + "description" : "Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP.", + "enum" : [ + "auto", + "external", + "internal" + ], + "optional" : 1, + "type" : "string" + }, + "bgp-multipath-as-relax" : { + "description" : "Consider different AS paths of equal length for multipath computation. BGP only.", + "optional" : 1, + "type" : "boolean" + }, + "ebgp" : { + "description" : "Enable eBGP (remote-as external). BGP only.", + "optional" : 1, + "type" : "boolean" + }, + "ebgp-multihop" : { + "description" : "Set maximum amount of hops for eBGP peers. Needs ebgp set to 1. BGP only.", + "optional" : 1, + "type" : "integer" + }, + "isis-domain" : { + "description" : "Name of the IS-IS domain. IS-IS only.", + "optional" : 1, + "type" : "string" + }, + "isis-ifaces" : { + "description" : "Comma-separated list of interfaces where IS-IS should be active. IS-IS only.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string" + }, + "isis-net" : { + "description" : "Network Entity title for this node in the IS-IS network. IS-IS only.", + "format" : "pve-sdn-isis-net", + "optional" : 1, + "type" : "string" + }, + "loopback" : { + "description" : "Name of the loopback/dummy interface that provides the Router-IP. BGP only.", + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Node(s) where this controller is active.", + "optional" : 1, + "type" : "string" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string" + }, + "peer-group-name" : { + "description" : "Name of the peer group for this EVPN controller", + "optional" : 1, + "type" : "string" + }, + "peers" : { + "description" : "Comma-separated list of the peers IP addresses.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "state" : { + "description" : "State of the SDN configuration object.", + "enum" : [ + "new", + "changed", + "deleted" + ], + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Type of the controller", + "enum" : [ + "bgp", + "evpn", + "faucet", + "isis" + ], + "type" : "string" + } + } + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn controller object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "asn" : { + "description" : "autonomous system number", + "maximum" : 4294967295, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 4294967295)" + }, + "bgp-mode" : { + "default" : "auto", + "description" : "Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP.", + "enum" : [ + "auto", + "external", + "internal" + ], + "optional" : 1, + "type" : "string" + }, + "bgp-multipath-as-path-relax" : { + "description" : "Consider different AS paths of equal length for multipath computation.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "controller" : { + "description" : "The SDN controller object identifier.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]", + "type" : "string" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ebgp" : { + "description" : "Enable eBGP (remote-as external).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ebgp-multihop" : { + "description" : "Set maximum amount of hops for eBGP peers.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "fabric" : { + "description" : "SDN fabric to use as underlay for this EVPN controller.", + "format" : "pve-sdn-fabric-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "isis-domain" : { + "description" : "Name of the IS-IS domain.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "isis-ifaces" : { + "description" : "Comma-separated list of interfaces where IS-IS should be active.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "isis-net" : { + "description" : "Network Entity title for this node in the IS-IS network.", + "format" : "pve-sdn-isis-net", + "maxLength" : 50, + "minLength" : 20, + "optional" : 1, + "pattern" : "[a-fA-F0-9]{2}(\\.[a-fA-F0-9]{4}){3,9}\\.[a-fA-F0-9]{2}", + "type" : "string" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "loopback" : { + "description" : "Name of the loopback/dummy interface that provides the Router-IP.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peer-group-name" : { + "default" : "VTEP", + "description" : "Name of the peer group for this EVPN controller", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peers" : { + "description" : "peers address list.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "route-map-in" : { + "description" : "Route Map that should be applied for incoming routes", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "route-map-out" : { + "description" : "Route Map that should be applied for outgoing routes", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/controllers/{controller}", + "text" : "{controller}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN controllers index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "type" : { + "description" : "Only list sdn controllers of specific type", + "enum" : [ + "bgp", + "evpn", + "faucet", + "isis" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/controllers/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "asn" : { + "description" : "The local ASN of the controller. BGP & EVPN only.", + "maximum" : 4294967295, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "bgp-mode" : { + "default" : "auto", + "description" : "Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP.", + "enum" : [ + "auto", + "external", + "internal" + ], + "optional" : 1, + "type" : "string" + }, + "bgp-multipath-as-relax" : { + "description" : "Consider different AS paths of equal length for multipath computation. BGP only.", + "optional" : 1, + "type" : "boolean" + }, + "controller" : { + "description" : "Name of the controller.", + "type" : "string" + }, + "digest" : { + "description" : "Digest of the controller section.", + "optional" : 1, + "type" : "string" + }, + "ebgp" : { + "description" : "Enable eBGP (remote-as external). BGP only.", + "optional" : 1, + "type" : "boolean" + }, + "ebgp-multihop" : { + "description" : "Set maximum amount of hops for eBGP peers. Needs ebgp set to 1. BGP only.", + "optional" : 1, + "type" : "integer" + }, + "isis-domain" : { + "description" : "Name of the IS-IS domain. IS-IS only.", + "optional" : 1, + "type" : "string" + }, + "isis-ifaces" : { + "description" : "Comma-separated list of interfaces where IS-IS should be active. IS-IS only.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string" + }, + "isis-net" : { + "description" : "Network Entity title for this node in the IS-IS network. IS-IS only.", + "format" : "pve-sdn-isis-net", + "optional" : 1, + "type" : "string" + }, + "loopback" : { + "description" : "Name of the loopback/dummy interface that provides the Router-IP. BGP only.", + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Node(s) where this controller is active.", + "optional" : 1, + "type" : "string" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string" + }, + "peer-group-name" : { + "description" : "Name of the peer group for this EVPN controller", + "optional" : 1, + "type" : "string" + }, + "peers" : { + "description" : "Comma-separated list of the peers IP addresses.", + "optional" : 1, + "type" : "string" + }, + "pending" : { + "description" : "Changes that have not yet been applied to the running configuration.", + "optional" : 1, + "properties" : { + "asn" : { + "description" : "The local ASN of the controller. BGP & EVPN only.", + "maximum" : 4294967295, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "bgp-mode" : { + "default" : "auto", + "description" : "Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP.", + "enum" : [ + "auto", + "external", + "internal" + ], + "optional" : 1, + "type" : "string" + }, + "bgp-multipath-as-relax" : { + "description" : "Consider different AS paths of equal length for multipath computation. BGP only.", + "optional" : 1, + "type" : "boolean" + }, + "ebgp" : { + "description" : "Enable eBGP (remote-as external). BGP only.", + "optional" : 1, + "type" : "boolean" + }, + "ebgp-multihop" : { + "description" : "Set maximum amount of hops for eBGP peers. Needs ebgp set to 1. BGP only.", + "optional" : 1, + "type" : "integer" + }, + "isis-domain" : { + "description" : "Name of the IS-IS domain. IS-IS only.", + "optional" : 1, + "type" : "string" + }, + "isis-ifaces" : { + "description" : "Comma-separated list of interfaces where IS-IS should be active. IS-IS only.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string" + }, + "isis-net" : { + "description" : "Network Entity title for this node in the IS-IS network. IS-IS only.", + "format" : "pve-sdn-isis-net", + "optional" : 1, + "type" : "string" + }, + "loopback" : { + "description" : "Name of the loopback/dummy interface that provides the Router-IP. BGP only.", + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Node(s) where this controller is active.", + "optional" : 1, + "type" : "string" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string" + }, + "peer-group-name" : { + "description" : "Name of the peer group for this EVPN controller", + "optional" : 1, + "type" : "string" + }, + "peers" : { + "description" : "Comma-separated list of the peers IP addresses.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "state" : { + "description" : "State of the SDN configuration object.", + "enum" : [ + "new", + "changed", + "deleted" + ], + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Type of the controller", + "enum" : [ + "bgp", + "evpn", + "faucet", + "isis" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{controller}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn controller object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "asn" : { + "description" : "autonomous system number", + "maximum" : 4294967295, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 4294967295)" + }, + "bgp-mode" : { + "default" : "auto", + "description" : "Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP.", + "enum" : [ + "auto", + "external", + "internal" + ], + "optional" : 1, + "type" : "string" + }, + "bgp-multipath-as-path-relax" : { + "description" : "Consider different AS paths of equal length for multipath computation.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "controller" : { + "description" : "The SDN controller object identifier.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]", + "type" : "string" + }, + "ebgp" : { + "description" : "Enable eBGP (remote-as external).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ebgp-multihop" : { + "description" : "Set maximum amount of hops for eBGP peers.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "fabric" : { + "description" : "SDN fabric to use as underlay for this EVPN controller.", + "format" : "pve-sdn-fabric-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "isis-domain" : { + "description" : "Name of the IS-IS domain.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "isis-ifaces" : { + "description" : "Comma-separated list of interfaces where IS-IS should be active.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "isis-net" : { + "description" : "Network Entity title for this node in the IS-IS network.", + "format" : "pve-sdn-isis-net", + "maxLength" : 50, + "minLength" : 20, + "optional" : 1, + "pattern" : "[a-fA-F0-9]{2}(\\.[a-fA-F0-9]{4}){3,9}\\.[a-fA-F0-9]{2}", + "type" : "string" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "loopback" : { + "description" : "Name of the loopback/dummy interface that provides the Router-IP.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peer-group-name" : { + "default" : "VTEP", + "description" : "Name of the peer group for this EVPN controller", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peers" : { + "description" : "peers address list.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "route-map-in" : { + "description" : "Route Map that should be applied for incoming routes", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "route-map-out" : { + "description" : "Route Map that should be applied for outgoing routes", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "bgp", + "evpn", + "faucet", + "isis" + ], + "format" : "pve-configid", + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/controllers", + "text" : "controllers" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List PVE IPAM Entries", + "method" : "GET", + "name" : "ipamindex", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ipam" : { + "description" : "The SDN ipam object identifier.", + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/ipams/{ipam}/status", + "text" : "status" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn ipam object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ipam" : { + "description" : "The SDN ipam object identifier.", + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn ipam configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ipam" : { + "description" : "The SDN ipam object identifier.", + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/ipams/{ipam}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn ipam object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "ipam" : { + "description" : "The SDN ipam object identifier.", + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "section" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "token" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "url" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/ipams/{ipam}", + "text" : "{ipam}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN ipams index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list sdn ipams of specific type", + "enum" : [ + "netbox", + "phpipam", + "pve" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/ipams/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "ipam" : { + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{ipam}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn ipam object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "ipam" : { + "description" : "The SDN ipam object identifier.", + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "section" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "token" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "netbox", + "phpipam", + "pve" + ], + "format" : "pve-configid", + "type" : "string" + }, + "url" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/ipams", + "text" : "ipams" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn dns object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dns" : { + "description" : "The SDN dns object identifier.", + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn dns configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dns" : { + "description" : "The SDN dns object identifier.", + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/dns/{dns}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn dns object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dns" : { + "description" : "The SDN dns object identifier.", + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "key" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "reversemaskv6" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "ttl" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "url" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/dns/{dns}", + "text" : "{dns}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN dns index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list sdn dns of specific type", + "enum" : [ + "powerdns" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/dns/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "dns" : { + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{dns}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn dns object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dns" : { + "description" : "The SDN dns object identifier.", + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "key" : { + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "reversemaskv6" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "reversev6mask" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "ttl" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "powerdns" + ], + "format" : "pve-configid", + "type" : "string" + }, + "url" : { + "optional" : 0, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/dns", + "text" : "dns" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Add a fabric", + "method" : "DELETE", + "name" : "delete_fabric", + "parameters" : { + "properties" : { + "id" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/fabrics/{id}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Update a fabric", + "method" : "GET", + "name" : "get_fabric", + "parameters" : { + "properties" : { + "id" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/fabrics/{id}", + [ + "SDN.Audit", + "SDN.Allocate" + ], + "any", + 1 + ] + }, + "returns" : { + "properties" : { + "area" : { + "description" : "OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust.", + "instance-types" : [ + "ospf" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + }, + "csnp_interval" : { + "description" : "The csnp_interval property for Openfabric", + "instance-types" : [ + "openfabric" + ], + "maximum" : 600, + "minimum" : 1, + "optional" : 1, + "type" : "number", + "type-property" : "protocol" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "hello_interval" : { + "description" : "The hello_interval property for Openfabric", + "instance-types" : [ + "openfabric" + ], + "maximum" : 600, + "minimum" : 1, + "optional" : 1, + "type" : "number", + "type-property" : "protocol" + }, + "id" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "ip6_prefix" : { + "description" : "The IP prefix for Node IPs", + "format" : "CIDR", + "optional" : 1, + "type" : "string" + }, + "ip_prefix" : { + "description" : "The IP prefix for Node IPs", + "format" : "CIDR", + "optional" : 1, + "type" : "string" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string" + }, + "persistent_keepalive" : { + "description" : "A seconds interval, between 1 and 65535 inclusive, of how often to send an authenticated empty packet to the peer for the purpose of keeping a stateful firewall or NAT mapping valid persistently. For example, if the interface very rarely sends traffic, but it might at anytime receive traffic from another node, and it is behind NAT, the interface might benefit from having a persistent keepalive interval of 25 seconds. If unset or set to 0, it is turned off", + "instance-types" : [ + "wireguard" + ], + "maximum" : 65535, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "type-property" : "protocol" + }, + "protocol" : { + "description" : "Type of configuration entry in an SDN Fabric section config", + "enum" : [ + "openfabric", + "ospf", + "wireguard", + "bgp" + ], + "type" : "string" + }, + "redistribute" : { + "oneOf" : [ + { + "instance-types" : [ + "ospf" + ], + "items" : { + "format" : { + "route-map" : { + "description" : "Route map to filter or transform redistributed routes from this source.", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "The protocol from which to redistribute routes from.", + "enum" : [ + "bgp", + "connected", + "kernel", + "static" + ], + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "instance-types" : [ + "bgp" + ], + "items" : { + "format" : { + "route-map" : { + "description" : "Route map to filter or transform redistributed routes from this source.", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "The protocol from which to redistribute routes from.", + "enum" : [ + "connected", + "kernel", + "ospf", + "static" + ], + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + ], + "type" : "array", + "type-property" : "protocol" + }, + "route_filter" : { + "description" : "A prefix list that should be used for filtering routes that are to be installed into the kernel routing table", + "format" : "pve-sdn-prefix-list-id", + "instance-types" : [ + "ospf", + "openfabric" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update a fabric", + "method" : "PUT", + "name" : "update_fabric", + "parameters" : { + "properties" : { + "area" : { + "description" : "OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust.", + "instance-types" : [ + "ospf" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol", + "typetext" : "" + }, + "csnp_interval" : { + "description" : "The csnp_interval property for Openfabric", + "instance-types" : [ + "openfabric" + ], + "maximum" : 600, + "minimum" : 1, + "optional" : 1, + "type" : "number", + "type-property" : "protocol", + "typetext" : " (1 - 600)" + }, + "delete" : { + "oneOf" : [ + { + "instance-types" : [ + "openfabric" + ], + "items" : { + "enum" : [ + "ip_prefix", + "ip6_prefix", + "hello_interval", + "csnp_interval", + "route_filter" + ], + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "instance-types" : [ + "bgp" + ], + "items" : { + "enum" : [ + "ip_prefix", + "ip6_prefix", + "redistribute", + "route_filter", + "route_map_in", + "route_map_out" + ], + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "instance-types" : [ + "ospf" + ], + "items" : { + "enum" : [ + "area", + "redistribute", + "route_filter" + ], + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "instance-types" : [ + "wireguard" + ], + "items" : { + "enum" : [ + "persistent_keepalive" + ], + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + ], + "type" : "array", + "type-property" : "protocol", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hello_interval" : { + "description" : "The hello_interval property for Openfabric", + "instance-types" : [ + "openfabric" + ], + "maximum" : 600, + "minimum" : 1, + "optional" : 1, + "type" : "number", + "type-property" : "protocol", + "typetext" : " (1 - 600)" + }, + "id" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "ip6_prefix" : { + "description" : "The IP prefix for Node IPs", + "format" : "CIDR", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ip_prefix" : { + "description" : "The IP prefix for Node IPs", + "format" : "CIDR", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "persistent_keepalive" : { + "description" : "A seconds interval, between 1 and 65535 inclusive, of how often to send an authenticated empty packet to the peer for the purpose of keeping a stateful firewall or NAT mapping valid persistently. For example, if the interface very rarely sends traffic, but it might at anytime receive traffic from another node, and it is behind NAT, the interface might benefit from having a persistent keepalive interval of 25 seconds. If unset or set to 0, it is turned off", + "instance-types" : [ + "wireguard" + ], + "maximum" : 65535, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "type-property" : "protocol", + "typetext" : " (0 - 65535)" + }, + "protocol" : { + "description" : "Type of configuration entry in an SDN Fabric section config", + "enum" : [ + "openfabric", + "ospf", + "wireguard", + "bgp" + ], + "type" : "string" + }, + "redistribute" : { + "oneOf" : [ + { + "instance-types" : [ + "ospf" + ], + "items" : { + "format" : { + "route-map" : { + "description" : "Route map to filter or transform redistributed routes from this source.", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "The protocol from which to redistribute routes from.", + "enum" : [ + "bgp", + "connected", + "kernel", + "static" + ], + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "instance-types" : [ + "bgp" + ], + "items" : { + "format" : { + "route-map" : { + "description" : "Route map to filter or transform redistributed routes from this source.", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "The protocol from which to redistribute routes from.", + "enum" : [ + "connected", + "kernel", + "ospf", + "static" + ], + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + ], + "type" : "array", + "type-property" : "protocol", + "typetext" : "" + }, + "route_filter" : { + "description" : "A prefix list that should be used for filtering routes that are to be installed into the kernel routing table", + "format" : "pve-sdn-prefix-list-id", + "instance-types" : [ + "ospf", + "openfabric" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/fabrics/{id}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/fabrics/fabric/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN Fabrics Index", + "method" : "GET", + "name" : "index", + "parameters" : { + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/fabrics/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "area" : { + "description" : "OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust.", + "instance-types" : [ + "ospf" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + }, + "csnp_interval" : { + "description" : "The csnp_interval property for Openfabric", + "instance-types" : [ + "openfabric" + ], + "maximum" : 600, + "minimum" : 1, + "optional" : 1, + "type" : "number", + "type-property" : "protocol" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "hello_interval" : { + "description" : "The hello_interval property for Openfabric", + "instance-types" : [ + "openfabric" + ], + "maximum" : 600, + "minimum" : 1, + "optional" : 1, + "type" : "number", + "type-property" : "protocol" + }, + "id" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "ip6_prefix" : { + "description" : "The IP prefix for Node IPs", + "format" : "CIDR", + "optional" : 1, + "type" : "string" + }, + "ip_prefix" : { + "description" : "The IP prefix for Node IPs", + "format" : "CIDR", + "optional" : 1, + "type" : "string" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string" + }, + "persistent_keepalive" : { + "description" : "A seconds interval, between 1 and 65535 inclusive, of how often to send an authenticated empty packet to the peer for the purpose of keeping a stateful firewall or NAT mapping valid persistently. For example, if the interface very rarely sends traffic, but it might at anytime receive traffic from another node, and it is behind NAT, the interface might benefit from having a persistent keepalive interval of 25 seconds. If unset or set to 0, it is turned off", + "instance-types" : [ + "wireguard" + ], + "maximum" : 65535, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "type-property" : "protocol" + }, + "protocol" : { + "description" : "Type of configuration entry in an SDN Fabric section config", + "enum" : [ + "openfabric", + "ospf", + "wireguard", + "bgp" + ], + "type" : "string" + }, + "redistribute" : { + "oneOf" : [ + { + "instance-types" : [ + "ospf" + ], + "items" : { + "format" : { + "route-map" : { + "description" : "Route map to filter or transform redistributed routes from this source.", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "The protocol from which to redistribute routes from.", + "enum" : [ + "bgp", + "connected", + "kernel", + "static" + ], + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "instance-types" : [ + "bgp" + ], + "items" : { + "format" : { + "route-map" : { + "description" : "Route map to filter or transform redistributed routes from this source.", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "The protocol from which to redistribute routes from.", + "enum" : [ + "connected", + "kernel", + "ospf", + "static" + ], + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + ], + "type" : "array", + "type-property" : "protocol" + }, + "route_filter" : { + "description" : "A prefix list that should be used for filtering routes that are to be installed into the kernel routing table", + "format" : "pve-sdn-prefix-list-id", + "instance-types" : [ + "ospf", + "openfabric" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add a fabric", + "method" : "POST", + "name" : "add_fabric", + "parameters" : { + "properties" : { + "area" : { + "description" : "OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust.", + "instance-types" : [ + "ospf" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol", + "typetext" : "" + }, + "csnp_interval" : { + "description" : "The csnp_interval property for Openfabric", + "instance-types" : [ + "openfabric" + ], + "maximum" : 600, + "minimum" : 1, + "optional" : 1, + "type" : "number", + "type-property" : "protocol", + "typetext" : " (1 - 600)" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hello_interval" : { + "description" : "The hello_interval property for Openfabric", + "instance-types" : [ + "openfabric" + ], + "maximum" : 600, + "minimum" : 1, + "optional" : 1, + "type" : "number", + "type-property" : "protocol", + "typetext" : " (1 - 600)" + }, + "id" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "ip6_prefix" : { + "description" : "The IP prefix for Node IPs", + "format" : "CIDR", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ip_prefix" : { + "description" : "The IP prefix for Node IPs", + "format" : "CIDR", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "persistent_keepalive" : { + "description" : "A seconds interval, between 1 and 65535 inclusive, of how often to send an authenticated empty packet to the peer for the purpose of keeping a stateful firewall or NAT mapping valid persistently. For example, if the interface very rarely sends traffic, but it might at anytime receive traffic from another node, and it is behind NAT, the interface might benefit from having a persistent keepalive interval of 25 seconds. If unset or set to 0, it is turned off", + "instance-types" : [ + "wireguard" + ], + "maximum" : 65535, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "type-property" : "protocol", + "typetext" : " (0 - 65535)" + }, + "protocol" : { + "description" : "Type of configuration entry in an SDN Fabric section config", + "enum" : [ + "openfabric", + "ospf", + "wireguard", + "bgp" + ], + "type" : "string" + }, + "redistribute" : { + "oneOf" : [ + { + "instance-types" : [ + "ospf" + ], + "items" : { + "format" : { + "route-map" : { + "description" : "Route map to filter or transform redistributed routes from this source.", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "The protocol from which to redistribute routes from.", + "enum" : [ + "bgp", + "connected", + "kernel", + "static" + ], + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "instance-types" : [ + "bgp" + ], + "items" : { + "format" : { + "route-map" : { + "description" : "Route map to filter or transform redistributed routes from this source.", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "The protocol from which to redistribute routes from.", + "enum" : [ + "connected", + "kernel", + "ospf", + "static" + ], + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + ], + "type" : "array", + "type-property" : "protocol", + "typetext" : "" + }, + "route_filter" : { + "description" : "A prefix list that should be used for filtering routes that are to be installed into the kernel routing table", + "format" : "pve-sdn-prefix-list-id", + "instance-types" : [ + "ospf", + "openfabric" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/fabrics", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/fabrics/fabric", + "text" : "fabric" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Add a node", + "method" : "DELETE", + "name" : "delete_node", + "parameters" : { + "properties" : { + "fabric_id" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "node_id" : { + "description" : "Identifier for nodes in an SDN fabric", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Allocate" + ] + ], + [ + "perm", + "/nodes/{node_id}", + [ + "Sys.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get a node", + "method" : "GET", + "name" : "get_node", + "parameters" : { + "properties" : { + "fabric_id" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "node_id" : { + "description" : "Identifier for nodes in an SDN fabric", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Audit", + "SDN.Allocate" + ], + "any", + 1 + ], + [ + "perm", + "/nodes/{node_id}", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ] + ] + }, + "returns" : { + "properties" : { + "allowed_ips" : { + "description" : "A list of IPs that are routable via this node in the WireGuard fabric.", + "instance-types" : [ + "wireguard" + ], + "items" : { + "format" : "FullRangeCIDR", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "type-property" : "protocol" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "endpoint" : { + "description" : "The endpoint used for connecting to this node.", + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + }, + "fabric_id" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "interfaces" : { + "oneOf" : [ + { + "description" : "OpenFabric network interface", + "instance-types" : [ + "openfabric" + ], + "items" : { + "format" : { + "hello_multiplier" : { + "description" : "The hello_multiplier property of the interface", + "maximum" : 100, + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "ip" : { + "description" : "IPv4 address for this node", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address for this node", + "format" : "CIDRv6", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "OSPF network interface", + "instance-types" : [ + "ospf" + ], + "items" : { + "format" : { + "ip" : { + "description" : "IPv4 address for this node", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + }, + "network_type" : { + "description" : "Network Type of the OSPF interface", + "enum" : [ + "broadcast", + "non-broadcast", + "point-to-multipoint", + "point-to-point" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "List of WireGuard network interfaces for this node.", + "instance-types" : [ + "wireguard" + ], + "items" : { + "description" : "WireGuard network interface", + "format" : "pve-sdn-fabric-wireguard-interface", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "BGP network interface", + "instance-types" : [ + "bgp" + ], + "items" : { + "format" : { + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1 + } + ], + "type" : "array", + "type-property" : "protocol" + }, + "ip" : { + "description" : "IPv4 address for this node", + "format" : "ipv4", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address for this node", + "format" : "ipv6", + "optional" : 1, + "type" : "string" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string" + }, + "node_id" : { + "description" : "Identifier for nodes in an SDN fabric", + "format" : "pve-node", + "type" : "string" + }, + "peers" : { + "instance-types" : [ + "wireguard" + ], + "items" : { + "format" : { + "endpoint" : { + "description" : "Override for the endpoint settings in the node section.", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "The interface of this node that uses this peer definition.", + "type" : "string" + }, + "node" : { + "description" : "The name of the referenced node section (the external node or the internal peer node).", + "type" : "string" + }, + "node_iface" : { + "description" : "The interface of the other node, if it is internal", + "optional" : 1, + "type" : "string" + }, + "skip_route_generation" : { + "default" : 0, + "description" : "Whether routes for the allowed IPs should be created in the kernel routing table.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "enum" : [ + "internal", + "external" + ], + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "type-property" : "protocol" + }, + "protocol" : { + "description" : "Type of configuration entry in an SDN Fabric section config", + "enum" : [ + "openfabric", + "ospf", + "wireguard", + "bgp" + ], + "type" : "string" + }, + "public_key" : { + "description" : "The public key for the external node.", + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + }, + "role" : { + "description" : "The role of this node in the WireGuard fabric.", + "enum" : [ + "internal", + "external" + ], + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + } + } + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update a node", + "method" : "PUT", + "name" : "update_node", + "parameters" : { + "properties" : { + "allowed_ips" : { + "description" : "A list of IPs that are routable via this node in the WireGuard fabric.", + "instance-types" : [ + "wireguard" + ], + "items" : { + "format" : "FullRangeCIDR", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "type-property" : "protocol", + "typetext" : "" + }, + "delete" : { + "oneOf" : [ + { + "instance-types" : [ + "bgp" + ], + "items" : { + "enum" : [ + "interfaces", + "ip", + "ip6" + ], + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "instance-types" : [ + "openfabric", + "ospf" + ], + "items" : { + "enum" : [ + "interfaces", + "ip", + "ip6" + ], + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "instance-types" : [ + "wireguard" + ], + "items" : { + "enum" : [ + "allowed_ips", + "endpoint", + "interfaces", + "ip", + "ip6", + "peers" + ], + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + ], + "type" : "array", + "type-property" : "protocol", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "endpoint" : { + "description" : "The endpoint used for connecting to this node.", + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol", + "typetext" : "" + }, + "fabric_id" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "interfaces" : { + "oneOf" : [ + { + "description" : "OpenFabric network interface", + "instance-types" : [ + "openfabric" + ], + "items" : { + "format" : { + "hello_multiplier" : { + "description" : "The hello_multiplier property of the interface", + "maximum" : 100, + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "ip" : { + "description" : "IPv4 address for this node", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address for this node", + "format" : "CIDRv6", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "OSPF network interface", + "instance-types" : [ + "ospf" + ], + "items" : { + "format" : { + "ip" : { + "description" : "IPv4 address for this node", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + }, + "network_type" : { + "description" : "Network Type of the OSPF interface", + "enum" : [ + "broadcast", + "non-broadcast", + "point-to-multipoint", + "point-to-point" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "List of WireGuard network interfaces for this node.", + "instance-types" : [ + "wireguard" + ], + "items" : { + "description" : "WireGuard network interface", + "format" : "pve-sdn-fabric-wireguard-interface", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "BGP network interface", + "instance-types" : [ + "bgp" + ], + "items" : { + "format" : { + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1 + } + ], + "type" : "array", + "type-property" : "protocol", + "typetext" : "" + }, + "ip" : { + "description" : "IPv4 address for this node", + "format" : "ipv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ip6" : { + "description" : "IPv6 address for this node", + "format" : "ipv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node_id" : { + "description" : "Identifier for nodes in an SDN fabric", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "peers" : { + "instance-types" : [ + "wireguard" + ], + "items" : { + "format" : { + "endpoint" : { + "description" : "Override for the endpoint settings in the node section.", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "The interface of this node that uses this peer definition.", + "type" : "string" + }, + "node" : { + "description" : "The name of the referenced node section (the external node or the internal peer node).", + "type" : "string" + }, + "node_iface" : { + "description" : "The interface of the other node, if it is internal", + "optional" : 1, + "type" : "string" + }, + "skip_route_generation" : { + "default" : 0, + "description" : "Whether routes for the allowed IPs should be created in the kernel routing table.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "enum" : [ + "internal", + "external" + ], + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "type-property" : "protocol", + "typetext" : "" + }, + "protocol" : { + "description" : "Type of configuration entry in an SDN Fabric section config", + "enum" : [ + "openfabric", + "ospf", + "wireguard", + "bgp" + ], + "type" : "string" + }, + "public_key" : { + "description" : "The public key for the external node.", + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol", + "typetext" : "" + }, + "role" : { + "description" : "The role of this node in the WireGuard fabric.", + "enum" : [ + "internal", + "external" + ], + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Allocate" + ] + ], + [ + "perm", + "/nodes/{node_id}", + [ + "Sys.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "text" : "{node_id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN Fabrics Index", + "method" : "GET", + "name" : "list_nodes_fabric", + "parameters" : { + "properties" : { + "fabric_id" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Audit" + ] + ], + "description" : "Only returns nodes where you have 'Sys.Audit' or 'Sys.Modify' permissions." + }, + "returns" : { + "items" : { + "properties" : { + "allowed_ips" : { + "description" : "A list of IPs that are routable via this node in the WireGuard fabric.", + "instance-types" : [ + "wireguard" + ], + "items" : { + "format" : "FullRangeCIDR", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "type-property" : "protocol" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "endpoint" : { + "description" : "The endpoint used for connecting to this node.", + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + }, + "fabric_id" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "interfaces" : { + "oneOf" : [ + { + "description" : "OpenFabric network interface", + "instance-types" : [ + "openfabric" + ], + "items" : { + "format" : { + "hello_multiplier" : { + "description" : "The hello_multiplier property of the interface", + "maximum" : 100, + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "ip" : { + "description" : "IPv4 address for this node", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address for this node", + "format" : "CIDRv6", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "OSPF network interface", + "instance-types" : [ + "ospf" + ], + "items" : { + "format" : { + "ip" : { + "description" : "IPv4 address for this node", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + }, + "network_type" : { + "description" : "Network Type of the OSPF interface", + "enum" : [ + "broadcast", + "non-broadcast", + "point-to-multipoint", + "point-to-point" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "List of WireGuard network interfaces for this node.", + "instance-types" : [ + "wireguard" + ], + "items" : { + "description" : "WireGuard network interface", + "format" : "pve-sdn-fabric-wireguard-interface", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "BGP network interface", + "instance-types" : [ + "bgp" + ], + "items" : { + "format" : { + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1 + } + ], + "type" : "array", + "type-property" : "protocol" + }, + "ip" : { + "description" : "IPv4 address for this node", + "format" : "ipv4", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address for this node", + "format" : "ipv6", + "optional" : 1, + "type" : "string" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string" + }, + "node_id" : { + "description" : "Identifier for nodes in an SDN fabric", + "format" : "pve-node", + "type" : "string" + }, + "peers" : { + "instance-types" : [ + "wireguard" + ], + "items" : { + "format" : { + "endpoint" : { + "description" : "Override for the endpoint settings in the node section.", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "The interface of this node that uses this peer definition.", + "type" : "string" + }, + "node" : { + "description" : "The name of the referenced node section (the external node or the internal peer node).", + "type" : "string" + }, + "node_iface" : { + "description" : "The interface of the other node, if it is internal", + "optional" : 1, + "type" : "string" + }, + "skip_route_generation" : { + "default" : 0, + "description" : "Whether routes for the allowed IPs should be created in the kernel routing table.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "enum" : [ + "internal", + "external" + ], + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "type-property" : "protocol" + }, + "protocol" : { + "description" : "Type of configuration entry in an SDN Fabric section config", + "enum" : [ + "openfabric", + "ospf", + "wireguard", + "bgp" + ], + "type" : "string" + }, + "public_key" : { + "description" : "The public key for the external node.", + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + }, + "role" : { + "description" : "The role of this node in the WireGuard fabric.", + "enum" : [ + "internal", + "external" + ], + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{node_id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add a node", + "method" : "POST", + "name" : "add_node", + "parameters" : { + "properties" : { + "allowed_ips" : { + "description" : "A list of IPs that are routable via this node in the WireGuard fabric.", + "instance-types" : [ + "wireguard" + ], + "items" : { + "format" : "FullRangeCIDR", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "type-property" : "protocol", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "endpoint" : { + "description" : "The endpoint used for connecting to this node.", + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol", + "typetext" : "" + }, + "fabric_id" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "interfaces" : { + "oneOf" : [ + { + "description" : "OpenFabric network interface", + "instance-types" : [ + "openfabric" + ], + "items" : { + "format" : { + "hello_multiplier" : { + "description" : "The hello_multiplier property of the interface", + "maximum" : 100, + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "ip" : { + "description" : "IPv4 address for this node", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address for this node", + "format" : "CIDRv6", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "OSPF network interface", + "instance-types" : [ + "ospf" + ], + "items" : { + "format" : { + "ip" : { + "description" : "IPv4 address for this node", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + }, + "network_type" : { + "description" : "Network Type of the OSPF interface", + "enum" : [ + "broadcast", + "non-broadcast", + "point-to-multipoint", + "point-to-point" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "List of WireGuard network interfaces for this node.", + "instance-types" : [ + "wireguard" + ], + "items" : { + "description" : "WireGuard network interface", + "format" : "pve-sdn-fabric-wireguard-interface", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "BGP network interface", + "instance-types" : [ + "bgp" + ], + "items" : { + "format" : { + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1 + } + ], + "type" : "array", + "type-property" : "protocol", + "typetext" : "" + }, + "ip" : { + "description" : "IPv4 address for this node", + "format" : "ipv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ip6" : { + "description" : "IPv6 address for this node", + "format" : "ipv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node_id" : { + "description" : "Identifier for nodes in an SDN fabric", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "peers" : { + "instance-types" : [ + "wireguard" + ], + "items" : { + "format" : { + "endpoint" : { + "description" : "Override for the endpoint settings in the node section.", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "The interface of this node that uses this peer definition.", + "type" : "string" + }, + "node" : { + "description" : "The name of the referenced node section (the external node or the internal peer node).", + "type" : "string" + }, + "node_iface" : { + "description" : "The interface of the other node, if it is internal", + "optional" : 1, + "type" : "string" + }, + "skip_route_generation" : { + "default" : 0, + "description" : "Whether routes for the allowed IPs should be created in the kernel routing table.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "enum" : [ + "internal", + "external" + ], + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "type-property" : "protocol", + "typetext" : "" + }, + "protocol" : { + "description" : "Type of configuration entry in an SDN Fabric section config", + "enum" : [ + "openfabric", + "ospf", + "wireguard", + "bgp" + ], + "type" : "string" + }, + "public_key" : { + "description" : "The public key for the external node.", + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol", + "typetext" : "" + }, + "role" : { + "description" : "The role of this node in the WireGuard fabric.", + "enum" : [ + "internal", + "external" + ], + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Allocate" + ] + ], + [ + "perm", + "/nodes/{node_id}", + [ + "Sys.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/fabrics/node/{fabric_id}", + "text" : "{fabric_id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN Fabrics Index", + "method" : "GET", + "name" : "list_nodes", + "parameters" : { + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list nodes where you have 'SDN.Audit' or 'SDN.Allocate' permissions on\n'/sdn/fabrics/' and 'Sys.Audit' or 'Sys.Modify' on /nodes/", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "allowed_ips" : { + "description" : "A list of IPs that are routable via this node in the WireGuard fabric.", + "instance-types" : [ + "wireguard" + ], + "items" : { + "format" : "FullRangeCIDR", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "type-property" : "protocol" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "endpoint" : { + "description" : "The endpoint used for connecting to this node.", + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + }, + "fabric_id" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "interfaces" : { + "oneOf" : [ + { + "description" : "OpenFabric network interface", + "instance-types" : [ + "openfabric" + ], + "items" : { + "format" : { + "hello_multiplier" : { + "description" : "The hello_multiplier property of the interface", + "maximum" : 100, + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "ip" : { + "description" : "IPv4 address for this node", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address for this node", + "format" : "CIDRv6", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "OSPF network interface", + "instance-types" : [ + "ospf" + ], + "items" : { + "format" : { + "ip" : { + "description" : "IPv4 address for this node", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + }, + "network_type" : { + "description" : "Network Type of the OSPF interface", + "enum" : [ + "broadcast", + "non-broadcast", + "point-to-multipoint", + "point-to-point" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "List of WireGuard network interfaces for this node.", + "instance-types" : [ + "wireguard" + ], + "items" : { + "description" : "WireGuard network interface", + "format" : "pve-sdn-fabric-wireguard-interface", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "BGP network interface", + "instance-types" : [ + "bgp" + ], + "items" : { + "format" : { + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1 + } + ], + "type" : "array", + "type-property" : "protocol" + }, + "ip" : { + "description" : "IPv4 address for this node", + "format" : "ipv4", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address for this node", + "format" : "ipv6", + "optional" : 1, + "type" : "string" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string" + }, + "node_id" : { + "description" : "Identifier for nodes in an SDN fabric", + "format" : "pve-node", + "type" : "string" + }, + "peers" : { + "instance-types" : [ + "wireguard" + ], + "items" : { + "format" : { + "endpoint" : { + "description" : "Override for the endpoint settings in the node section.", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "The interface of this node that uses this peer definition.", + "type" : "string" + }, + "node" : { + "description" : "The name of the referenced node section (the external node or the internal peer node).", + "type" : "string" + }, + "node_iface" : { + "description" : "The interface of the other node, if it is internal", + "optional" : 1, + "type" : "string" + }, + "skip_route_generation" : { + "default" : 0, + "description" : "Whether routes for the allowed IPs should be created in the kernel routing table.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "enum" : [ + "internal", + "external" + ], + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "type-property" : "protocol" + }, + "protocol" : { + "description" : "Type of configuration entry in an SDN Fabric section config", + "enum" : [ + "openfabric", + "ospf", + "wireguard", + "bgp" + ], + "type" : "string" + }, + "public_key" : { + "description" : "The public key for the external node.", + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + }, + "role" : { + "description" : "The role of this node in the WireGuard fabric.", + "enum" : [ + "internal", + "external" + ], + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{fabric_id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/fabrics/node", + "text" : "node" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN Fabrics Index", + "method" : "GET", + "name" : "list_all", + "parameters" : { + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list fabrics where you have 'SDN.Audit' or 'SDN.Allocate' permissions on\n'/sdn/fabrics/', only list nodes where you have 'Sys.Audit' or 'Sys.Modify' on /nodes/", + "user" : "all" + }, + "returns" : { + "properties" : { + "fabrics" : { + "items" : { + "properties" : { + "area" : { + "description" : "OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust.", + "instance-types" : [ + "ospf" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + }, + "csnp_interval" : { + "description" : "The csnp_interval property for Openfabric", + "instance-types" : [ + "openfabric" + ], + "maximum" : 600, + "minimum" : 1, + "optional" : 1, + "type" : "number", + "type-property" : "protocol" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "hello_interval" : { + "description" : "The hello_interval property for Openfabric", + "instance-types" : [ + "openfabric" + ], + "maximum" : 600, + "minimum" : 1, + "optional" : 1, + "type" : "number", + "type-property" : "protocol" + }, + "id" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "ip6_prefix" : { + "description" : "The IP prefix for Node IPs", + "format" : "CIDR", + "optional" : 1, + "type" : "string" + }, + "ip_prefix" : { + "description" : "The IP prefix for Node IPs", + "format" : "CIDR", + "optional" : 1, + "type" : "string" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string" + }, + "persistent_keepalive" : { + "description" : "A seconds interval, between 1 and 65535 inclusive, of how often to send an authenticated empty packet to the peer for the purpose of keeping a stateful firewall or NAT mapping valid persistently. For example, if the interface very rarely sends traffic, but it might at anytime receive traffic from another node, and it is behind NAT, the interface might benefit from having a persistent keepalive interval of 25 seconds. If unset or set to 0, it is turned off", + "instance-types" : [ + "wireguard" + ], + "maximum" : 65535, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "type-property" : "protocol" + }, + "protocol" : { + "description" : "Type of configuration entry in an SDN Fabric section config", + "enum" : [ + "openfabric", + "ospf", + "wireguard", + "bgp" + ], + "type" : "string" + }, + "redistribute" : { + "oneOf" : [ + { + "instance-types" : [ + "ospf" + ], + "items" : { + "format" : { + "route-map" : { + "description" : "Route map to filter or transform redistributed routes from this source.", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "The protocol from which to redistribute routes from.", + "enum" : [ + "bgp", + "connected", + "kernel", + "static" + ], + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "instance-types" : [ + "bgp" + ], + "items" : { + "format" : { + "route-map" : { + "description" : "Route map to filter or transform redistributed routes from this source.", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "The protocol from which to redistribute routes from.", + "enum" : [ + "connected", + "kernel", + "ospf", + "static" + ], + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + ], + "type" : "array", + "type-property" : "protocol" + }, + "route_filter" : { + "description" : "A prefix list that should be used for filtering routes that are to be installed into the kernel routing table", + "format" : "pve-sdn-prefix-list-id", + "instance-types" : [ + "ospf", + "openfabric" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "nodes" : { + "items" : { + "properties" : { + "allowed_ips" : { + "description" : "A list of IPs that are routable via this node in the WireGuard fabric.", + "instance-types" : [ + "wireguard" + ], + "items" : { + "format" : "FullRangeCIDR", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "type-property" : "protocol" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "endpoint" : { + "description" : "The endpoint used for connecting to this node.", + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + }, + "fabric_id" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "interfaces" : { + "oneOf" : [ + { + "description" : "OpenFabric network interface", + "instance-types" : [ + "openfabric" + ], + "items" : { + "format" : { + "hello_multiplier" : { + "description" : "The hello_multiplier property of the interface", + "maximum" : 100, + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "ip" : { + "description" : "IPv4 address for this node", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address for this node", + "format" : "CIDRv6", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "OSPF network interface", + "instance-types" : [ + "ospf" + ], + "items" : { + "format" : { + "ip" : { + "description" : "IPv4 address for this node", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + }, + "network_type" : { + "description" : "Network Type of the OSPF interface", + "enum" : [ + "broadcast", + "non-broadcast", + "point-to-multipoint", + "point-to-point" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "List of WireGuard network interfaces for this node.", + "instance-types" : [ + "wireguard" + ], + "items" : { + "description" : "WireGuard network interface", + "format" : "pve-sdn-fabric-wireguard-interface", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + { + "description" : "BGP network interface", + "instance-types" : [ + "bgp" + ], + "items" : { + "format" : { + "name" : { + "description" : "Name of the network interface", + "format" : "pve-iface", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1 + } + ], + "type" : "array", + "type-property" : "protocol" + }, + "ip" : { + "description" : "IPv4 address for this node", + "format" : "ipv4", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address for this node", + "format" : "ipv6", + "optional" : 1, + "type" : "string" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string" + }, + "node_id" : { + "description" : "Identifier for nodes in an SDN fabric", + "format" : "pve-node", + "type" : "string" + }, + "peers" : { + "instance-types" : [ + "wireguard" + ], + "items" : { + "format" : { + "endpoint" : { + "description" : "Override for the endpoint settings in the node section.", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "The interface of this node that uses this peer definition.", + "type" : "string" + }, + "node" : { + "description" : "The name of the referenced node section (the external node or the internal peer node).", + "type" : "string" + }, + "node_iface" : { + "description" : "The interface of the other node, if it is internal", + "optional" : 1, + "type" : "string" + }, + "skip_route_generation" : { + "default" : 0, + "description" : "Whether routes for the allowed IPs should be created in the kernel routing table.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "enum" : [ + "internal", + "external" + ], + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "type-property" : "protocol" + }, + "protocol" : { + "description" : "Type of configuration entry in an SDN Fabric section config", + "enum" : [ + "openfabric", + "ospf", + "wireguard", + "bgp" + ], + "type" : "string" + }, + "public_key" : { + "description" : "The public key for the external node.", + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + }, + "role" : { + "description" : "The role of this node in the WireGuard fabric.", + "enum" : [ + "internal", + "external" + ], + "instance-types" : [ + "wireguard" + ], + "optional" : 1, + "type" : "string", + "type-property" : "protocol" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/fabrics/all", + "text" : "all" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN Fabrics Index", + "method" : "GET", + "name" : "index", + "parameters" : {}, + "permissions" : { + "check" : [ + "perm", + "/sdn/fabrics", + [ + "SDN.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/fabrics", + "text" : "fabrics" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete Prefix List Entry", + "method" : "DELETE", + "name" : "delete_prefix_list_entry", + "parameters" : { + "properties" : { + "id" : { + "description" : "The SDN prefix list identifier", + "format" : "pve-sdn-prefix-list-id", + "type" : "string", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get Prefix List Entry", + "method" : "GET", + "name" : "get_prefix_list_entry", + "parameters" : { + "properties" : { + "id" : { + "description" : "The SDN prefix list identifier", + "format" : "pve-sdn-prefix-list-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update Prefix List Entry", + "method" : "PUT", + "name" : "update_prefix_list_entry", + "parameters" : { + "properties" : { + "action" : { + "enum" : [ + "permit", + "deny" + ], + "optional" : 1, + "type" : "string" + }, + "delete" : { + "items" : { + "enum" : [ + "le", + "ge", + "seq" + ], + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ge" : { + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 128)" + }, + "le" : { + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 128)" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "prefix" : { + "format" : "FullRangeCIDR", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "seq" : { + "maximum" : 4294967295, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4294967295)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "text" : "{url_seq}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List Prefix List Entries", + "method" : "GET", + "name" : "get_prefix_list_entries", + "parameters" : { + "properties" : { + "id" : { + "description" : "The SDN prefix list identifier", + "format" : "pve-sdn-prefix-list-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{seq}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Prefix List Entry", + "method" : "POST", + "name" : "create_prefix_list_entry", + "parameters" : { + "properties" : { + "action" : { + "enum" : [ + "permit", + "deny" + ], + "optional" : 0, + "type" : "string" + }, + "ge" : { + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 128)" + }, + "id" : { + "description" : "The SDN prefix list identifier", + "format" : "pve-sdn-prefix-list-id", + "type" : "string", + "typetext" : "" + }, + "le" : { + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 128)" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "prefix" : { + "format" : "FullRangeCIDR", + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "seq" : { + "maximum" : 4294967295, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4294967295)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/prefix-lists/{id}/entries", + "text" : "entries" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete Prefix List", + "method" : "DELETE", + "name" : "delete_prefix_list", + "parameters" : { + "properties" : { + "id" : { + "description" : "The SDN prefix list identifier", + "format" : "pve-sdn-prefix-list-id", + "type" : "string", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get Prefix List", + "method" : "GET", + "name" : "get_prefix_list", + "parameters" : { + "properties" : { + "id" : { + "description" : "The SDN prefix list identifier", + "format" : "pve-sdn-prefix-list-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update Prefix List", + "method" : "PUT", + "name" : "update_prefix_list", + "parameters" : { + "properties" : { + "delete" : { + "items" : { + "enum" : [ + "entries" + ], + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "entries" : { + "items" : { + "format" : { + "action" : { + "enum" : [ + "permit", + "deny" + ], + "optional" : 1, + "type" : "string" + }, + "ge" : { + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "le" : { + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "prefix" : { + "format" : "FullRangeCIDR", + "optional" : 1, + "type" : "string" + }, + "seq" : { + "maximum" : 4294967295, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "id" : { + "description" : "The SDN prefix list identifier", + "format" : "pve-sdn-prefix-list-id", + "type" : "string", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/prefix-lists/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List Prefix Lists", + "method" : "GET", + "name" : "list_prefix_lists", + "parameters" : { + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "verbose" : { + "description" : "If 0, only returns id - otherwise returns all properties.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only returns prefix list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Prefix List", + "method" : "POST", + "name" : "create_prefix_list_entry", + "parameters" : { + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "entries" : { + "items" : { + "format" : { + "action" : { + "enum" : [ + "permit", + "deny" + ], + "optional" : 0, + "type" : "string" + }, + "ge" : { + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "le" : { + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "prefix" : { + "format" : "FullRangeCIDR", + "optional" : 0, + "type" : "string" + }, + "seq" : { + "maximum" : 4294967295, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "id" : { + "description" : "The SDN prefix list identifier", + "format" : "pve-sdn-prefix-list-id", + "type" : "string", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/prefix-lists", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/prefix-lists", + "text" : "prefix-lists" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete Route Map Entry", + "method" : "DELETE", + "name" : "delete_route_map_entry", + "parameters" : { + "properties" : { + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "order" : { + "description" : "The index of this route map entry", + "maximum" : 65535, + "minimum" : 0, + "type" : "integer", + "typetext" : " (0 - 65535)" + }, + "route-map-id" : { + "description" : "The SDN route map identifier", + "format" : "pve-sdn-route-map-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/route-maps/{route-map-id}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get Route Map Entry", + "method" : "GET", + "name" : "get_route_map_entry", + "parameters" : { + "properties" : { + "order" : { + "description" : "The index of this route map entry", + "maximum" : 65535, + "minimum" : 0, + "type" : "integer", + "typetext" : " (0 - 65535)" + }, + "route-map-id" : { + "description" : "The SDN route map identifier", + "format" : "pve-sdn-route-map-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/route-maps/{route-map-id}", + [ + "SDN.Audit", + "SDN.Allocate" + ], + "any", + 1 + ] + }, + "returns" : { + "properties" : { + "action" : { + "description" : "Matching policy of a route map entry.", + "enum" : [ + "permit", + "deny" + ], + "optional" : 0, + "type" : "string" + }, + "call" : { + "description" : "The SDN route map identifier", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "exit-action" : { + "format" : { + "key" : { + "enum" : [ + "on-match-goto", + "on-match-next", + "continue" + ], + "type" : "string" + }, + "value" : { + "description" : "The index of this route map entry", + "maximum" : 65535, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string" + }, + "match" : { + "items" : { + "format" : { + "key" : { + "enum" : [ + "route-type", + "vni", + "ip-address-prefix-list", + "ip6-address-prefix-list", + "ip-next-hop-prefix-list", + "ip6-next-hop-prefix-list", + "ip-next-hop-address", + "ip6-next-hop-address", + "metric", + "local-preference", + "peer", + "tag" + ], + "type" : "string" + }, + "value" : { + "description" : "Value that the field should be matched on.", + "format_description" : "", + "optional" : 1, + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "order" : { + "description" : "The index of this route map entry", + "maximum" : 65535, + "minimum" : 0, + "type" : "integer" + }, + "route-map-id" : { + "description" : "The SDN route map identifier", + "format" : "pve-sdn-route-map-id", + "type" : "string" + }, + "set" : { + "items" : { + "format" : { + "key" : { + "enum" : [ + "ip-next-hop-peer-address", + "ip-next-hop", + "ip-next-hop-unchanged", + "ip6-next-hop-peer-address", + "ip6-next-hop-prefer-global", + "ip6-next-hop", + "local-preference", + "tag", + "weight", + "metric", + "src" + ], + "type" : "string" + }, + "value" : { + "description" : "Value that the field should be set to.", + "format_description" : "", + "optional" : 1, + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update Route Map Entry", + "method" : "PUT", + "name" : "update_route_map_entry", + "parameters" : { + "properties" : { + "action" : { + "description" : "Matching policy of a route map entry.", + "enum" : [ + "permit", + "deny" + ], + "optional" : 1, + "type" : "string" + }, + "call" : { + "description" : "The SDN route map identifier", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "items" : { + "enum" : [ + "set", + "match", + "call", + "exit-action" + ], + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exit-action" : { + "format" : { + "key" : { + "enum" : [ + "on-match-goto", + "on-match-next", + "continue" + ], + "type" : "string" + }, + "value" : { + "description" : "The index of this route map entry", + "maximum" : 65535, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "key= [,value=]" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "match" : { + "items" : { + "format" : { + "key" : { + "enum" : [ + "route-type", + "vni", + "ip-address-prefix-list", + "ip6-address-prefix-list", + "ip-next-hop-prefix-list", + "ip6-next-hop-prefix-list", + "ip-next-hop-address", + "ip6-next-hop-address", + "metric", + "local-preference", + "peer", + "tag" + ], + "type" : "string" + }, + "value" : { + "description" : "Value that the field should be matched on.", + "format_description" : "", + "optional" : 1, + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "order" : { + "description" : "The index of this route map entry", + "maximum" : 65535, + "minimum" : 0, + "type" : "integer", + "typetext" : " (0 - 65535)" + }, + "route-map-id" : { + "description" : "The SDN route map identifier", + "format" : "pve-sdn-route-map-id", + "type" : "string", + "typetext" : "" + }, + "set" : { + "items" : { + "format" : { + "key" : { + "enum" : [ + "ip-next-hop-peer-address", + "ip-next-hop", + "ip-next-hop-unchanged", + "ip6-next-hop-peer-address", + "ip6-next-hop-prefer-global", + "ip6-next-hop", + "local-preference", + "tag", + "weight", + "metric", + "src" + ], + "type" : "string" + }, + "value" : { + "description" : "Value that the field should be set to.", + "format_description" : "", + "optional" : 1, + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/route-maps/{route-map-id}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "text" : "{order}" + } + ], + "leaf" : 0, + "path" : "/cluster/sdn/route-maps/entries/{route-map-id}/entry", + "text" : "entry" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all entries for a given Route Map", + "method" : "GET", + "name" : "list_route_map_entries_for_route_map", + "parameters" : { + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "route-map-id" : { + "description" : "The SDN route map identifier", + "format" : "pve-sdn-route-map-id", + "type" : "string", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/route-maps/{route-map-id}", + [ + "SDN.Audit", + "SDN.Allocate" + ], + "any", + 1 + ] + }, + "returns" : { + "items" : { + "properties" : { + "action" : { + "description" : "Matching policy of a route map entry.", + "enum" : [ + "permit", + "deny" + ], + "optional" : 0, + "type" : "string" + }, + "call" : { + "description" : "The SDN route map identifier", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "exit-action" : { + "format" : { + "key" : { + "enum" : [ + "on-match-goto", + "on-match-next", + "continue" + ], + "type" : "string" + }, + "value" : { + "description" : "The index of this route map entry", + "maximum" : 65535, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string" + }, + "match" : { + "items" : { + "format" : { + "key" : { + "enum" : [ + "route-type", + "vni", + "ip-address-prefix-list", + "ip6-address-prefix-list", + "ip-next-hop-prefix-list", + "ip6-next-hop-prefix-list", + "ip-next-hop-address", + "ip6-next-hop-address", + "metric", + "local-preference", + "peer", + "tag" + ], + "type" : "string" + }, + "value" : { + "description" : "Value that the field should be matched on.", + "format_description" : "", + "optional" : 1, + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "order" : { + "description" : "The index of this route map entry", + "maximum" : 65535, + "minimum" : 0, + "type" : "integer" + }, + "route-map-id" : { + "description" : "The SDN route map identifier", + "format" : "pve-sdn-route-map-id", + "type" : "string" + }, + "set" : { + "items" : { + "format" : { + "key" : { + "enum" : [ + "ip-next-hop-peer-address", + "ip-next-hop", + "ip-next-hop-unchanged", + "ip6-next-hop-peer-address", + "ip6-next-hop-prefer-global", + "ip6-next-hop", + "local-preference", + "tag", + "weight", + "metric", + "src" + ], + "type" : "string" + }, + "value" : { + "description" : "Value that the field should be set to.", + "format_description" : "", + "optional" : 1, + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "entry/{order}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/route-maps/entries/{route-map-id}", + "text" : "{route-map-id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Lists all route map entries.", + "method" : "GET", + "name" : "list_route_map_entries", + "parameters" : { + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only returns route map entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "action" : { + "description" : "Matching policy of a route map entry.", + "enum" : [ + "permit", + "deny" + ], + "optional" : 0, + "type" : "string" + }, + "call" : { + "description" : "The SDN route map identifier", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "exit-action" : { + "format" : { + "key" : { + "enum" : [ + "on-match-goto", + "on-match-next", + "continue" + ], + "type" : "string" + }, + "value" : { + "description" : "The index of this route map entry", + "maximum" : 65535, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string" + }, + "match" : { + "items" : { + "format" : { + "key" : { + "enum" : [ + "route-type", + "vni", + "ip-address-prefix-list", + "ip6-address-prefix-list", + "ip-next-hop-prefix-list", + "ip6-next-hop-prefix-list", + "ip-next-hop-address", + "ip6-next-hop-address", + "metric", + "local-preference", + "peer", + "tag" + ], + "type" : "string" + }, + "value" : { + "description" : "Value that the field should be matched on.", + "format_description" : "", + "optional" : 1, + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "order" : { + "description" : "The index of this route map entry", + "maximum" : 65535, + "minimum" : 0, + "type" : "integer" + }, + "route-map-id" : { + "description" : "The SDN route map identifier", + "format" : "pve-sdn-route-map-id", + "type" : "string" + }, + "set" : { + "items" : { + "format" : { + "key" : { + "enum" : [ + "ip-next-hop-peer-address", + "ip-next-hop", + "ip-next-hop-unchanged", + "ip6-next-hop-peer-address", + "ip6-next-hop-prefer-global", + "ip6-next-hop", + "local-preference", + "tag", + "weight", + "metric", + "src" + ], + "type" : "string" + }, + "value" : { + "description" : "Value that the field should be set to.", + "format_description" : "", + "optional" : 1, + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{route-map-id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Route Map entry", + "method" : "POST", + "name" : "create_route_map_entry", + "parameters" : { + "properties" : { + "action" : { + "description" : "Matching policy of a route map entry.", + "enum" : [ + "permit", + "deny" + ], + "optional" : 0, + "type" : "string" + }, + "call" : { + "description" : "The SDN route map identifier", + "format" : "pve-sdn-route-map-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exit-action" : { + "format" : { + "key" : { + "enum" : [ + "on-match-goto", + "on-match-next", + "continue" + ], + "type" : "string" + }, + "value" : { + "description" : "The index of this route map entry", + "maximum" : 65535, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "key= [,value=]" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "match" : { + "items" : { + "format" : { + "key" : { + "enum" : [ + "route-type", + "vni", + "ip-address-prefix-list", + "ip6-address-prefix-list", + "ip-next-hop-prefix-list", + "ip6-next-hop-prefix-list", + "ip-next-hop-address", + "ip6-next-hop-address", + "metric", + "local-preference", + "peer", + "tag" + ], + "type" : "string" + }, + "value" : { + "description" : "Value that the field should be matched on.", + "format_description" : "", + "optional" : 1, + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "order" : { + "description" : "The index of this route map entry", + "maximum" : 65535, + "minimum" : 0, + "type" : "integer", + "typetext" : " (0 - 65535)" + }, + "route-map-id" : { + "description" : "The SDN route map identifier", + "format" : "pve-sdn-route-map-id", + "type" : "string", + "typetext" : "" + }, + "set" : { + "items" : { + "format" : { + "key" : { + "enum" : [ + "ip-next-hop-peer-address", + "ip-next-hop", + "ip-next-hop-unchanged", + "ip6-next-hop-peer-address", + "ip6-next-hop-prefer-global", + "ip6-next-hop", + "local-preference", + "tag", + "weight", + "metric", + "src" + ], + "type" : "string" + }, + "value" : { + "description" : "Value that the field should be set to.", + "format_description" : "", + "optional" : 1, + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/route-maps", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/route-maps/entries", + "text" : "entries" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List Route Maps", + "method" : "GET", + "name" : "list_route_maps", + "parameters" : { + "properties" : { + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only returns route maps where you have 'SDN.Audit' or 'SDN.Allocate' permissions.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "id" : { + "description" : "The SDN route map identifier", + "format" : "pve-sdn-route-map-id", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "entries/{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/route-maps", + "text" : "route-maps" + }, + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Release global lock for SDN configuration", + "method" : "DELETE", + "name" : "release_lock", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "if true, allow releasing lock without providing the token", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Acquire global lock for SDN configuration", + "method" : "POST", + "name" : "lock", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "allow-pending" : { + "default" : 0, + "description" : "if true, allow acquiring lock even though there are pending changes", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/lock", + "text" : "lock" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Rollback pending changes to SDN configuration", + "method" : "POST", + "name" : "rollback", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "release-lock" : { + "default" : 1, + "description" : "When lock-token has been provided and configuration successfully rollbacked, release the lock automatically afterwards", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/rollback", + "text" : "rollback" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Dry-run the SDN apply action and return the difference between the current configuration and the pending configuration", + "method" : "GET", + "name" : "dry-run", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "frr-diff" : { + "description" : "The difference between the current and pending FRR configuration.", + "optional" : 1, + "type" : "string" + }, + "interfaces-diff" : { + "description" : "The difference between the current and pending /etc/network/interfaces.d/sdn configuration.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/dry-run", + "text" : "dry-run" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/sdn", + [ + "SDN.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Apply sdn controller changes && reload.", + "method" : "PUT", + "name" : "reload", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "lock-token" : { + "description" : "the token for unlocking the global SDN configuration", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "release-lock" : { + "default" : 1, + "description" : "When lock-token has been provided and configuration successfully committed, release the lock automatically afterwards", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn", + "text" : "sdn" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read cluster log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "max" : { + "description" : "Maximum number of entries.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "description" : "The user needs 'Sys.Syslog' on '/' in order to get all logs.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Resources index (cluster wide).", + "method" : "GET", + "name" : "resources", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Resource type.", + "enum" : [ + "vm", + "storage", + "node", + "sdn" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "cgroup-mode" : { + "description" : "The cgroup mode the node operates under (for type 'node').", + "optional" : 1, + "type" : "integer" + }, + "content" : { + "description" : "Allowed storage content types (for type 'storage').", + "format" : "pve-storage-content-list", + "optional" : 1, + "type" : "string" + }, + "cpu" : { + "description" : "CPU utilization (for types 'node', 'qemu' and 'lxc').", + "minimum" : 0, + "optional" : 1, + "renderer" : "fraction_as_percentage", + "type" : "number" + }, + "disk" : { + "description" : "Used disk space in bytes (for type 'storage'), used root image space for VMs (for types 'qemu' and 'lxc').", + "minimum" : 0, + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "diskread" : { + "description" : "The number of bytes the guest read from its block devices since the guest was started. This info is not available for all storage types. (for types 'qemu' and 'lxc')", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "diskwrite" : { + "description" : "The number of bytes the guest wrote to its block devices since the guest was started. This info is not available for all storage types. (for types 'qemu' and 'lxc')", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "hastate" : { + "description" : "HA service status (for HA managed VMs).", + "optional" : 1, + "type" : "string" + }, + "host-arch" : { + "default" : "x86_64", + "description" : "The node's CPU architecture. (for type 'node').", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "Resource id.", + "type" : "string" + }, + "level" : { + "description" : "Support level (for type 'node').", + "optional" : 1, + "type" : "string" + }, + "lock" : { + "description" : "The guest's current config lock (for types 'qemu' and 'lxc')", + "optional" : 1, + "type" : "string" + }, + "maxcpu" : { + "description" : "Number of available CPUs (for types 'node', 'qemu' and 'lxc').", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "maxdisk" : { + "description" : "Storage size in bytes (for type 'storage'), root image size for VMs (for types 'qemu' and 'lxc').", + "minimum" : 0, + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Number of available memory in bytes (for types 'node', 'qemu' and 'lxc').", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "mem" : { + "description" : "Used memory in bytes (for types 'node', 'qemu' and 'lxc').", + "minimum" : 0, + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "memhost" : { + "description" : "Used memory in bytes from the point of view of the host (for types 'qemu').", + "minimum" : 0, + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "Name of the resource.", + "optional" : 1, + "type" : "string" + }, + "netin" : { + "description" : "The amount of traffic in bytes that was sent to the guest over the network since it was started. (for types 'qemu' and 'lxc')", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "netout" : { + "description" : "The amount of traffic in bytes that was sent from the guest over the network since it was started. (for types 'qemu' and 'lxc')", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "network" : { + "description" : "The name of a Network entity (for type 'network').", + "optional" : 1, + "type" : "string" + }, + "network-type" : { + "description" : "The type of network resource (for type 'network').", + "enum" : [ + "fabric", + "zone" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name (for types 'node', 'storage', 'qemu', and 'lxc').", + "format" : "pve-node", + "optional" : 1, + "type" : "string" + }, + "plugintype" : { + "description" : "More specific type, if available.", + "optional" : 1, + "type" : "string" + }, + "pool" : { + "description" : "The pool name (for types 'pool', 'qemu' and 'lxc').", + "optional" : 1, + "type" : "string" + }, + "protocol" : { + "description" : "The protocol of a fabric (for type 'network', network-type 'fabric').", + "optional" : 1, + "type" : "string" + }, + "sdn" : { + "description" : "The name of an SDN entity (for type 'sdn')", + "optional" : 1, + "type" : "string" + }, + "shared" : { + "description" : "Determines whether the storage is shared", + "optional" : 1, + "type" : "boolean" + }, + "status" : { + "description" : "Resource type dependent status.", + "optional" : 1, + "type" : "string" + }, + "storage" : { + "description" : "The storage identifier (for type 'storage').", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string" + }, + "tags" : { + "description" : "The guest's tags (for types 'qemu' and 'lxc')", + "optional" : 1, + "type" : "string" + }, + "template" : { + "default" : 0, + "description" : "Determines if the guest is a template. (for types 'qemu' and 'lxc')", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "description" : "Resource type.", + "enum" : [ + "node", + "storage", + "pool", + "qemu", + "lxc", + "openvz", + "sdn", + "network" + ], + "type" : "string" + }, + "uptime" : { + "description" : "Uptime of node or virtual guest in seconds (for types 'node', 'qemu' and 'lxc').", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The numerical vmid (for types 'qemu' and 'lxc').", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer" + }, + "zone-type" : { + "description" : "The type of an SDN zone (for type 'sdn').", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/resources", + "text" : "resources" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List recent tasks (cluster wide).", + "method" : "GET", + "name" : "tasks", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "upid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/tasks", + "text" : "tasks" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get datacenter options. Without 'Sys.Audit' on '/' not all options are returned.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ], + "user" : "all" + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set datacenter options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "description" : "Set I/O bandwidth limit for various operations (in KiB/s).", + "format" : { + "clone" : { + "description" : "bandwidth limit in KiB/s for cloning disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "default" : { + "description" : "default bandwidth limit in KiB/s", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "migration" : { + "description" : "bandwidth limit in KiB/s for migrating guests (including moving local disks)", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "move" : { + "description" : "bandwidth limit in KiB/s for moving disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "restore" : { + "description" : "bandwidth limit in KiB/s for restoring guests from backups", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[clone=] [,default=] [,migration=] [,move=] [,restore=]" + }, + "consent-text" : { + "description" : "Consent text that is displayed before logging in.", + "maxLength" : 65536, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "console" : { + "description" : "Select the default Console viewer. You can either use the builtin java applet (VNC; deprecated and maps to html5), an external virt-viewer comtatible application (SPICE), an HTML5 based vnc viewer (noVNC), or an HTML5 based console client (xtermjs). If the selected viewer is not available (e.g. SPICE not activated for the VM), the fallback is noVNC.", + "enum" : [ + "applet", + "vv", + "html5", + "xtermjs" + ], + "optional" : 1, + "type" : "string" + }, + "crs" : { + "description" : "Cluster resource scheduling settings.", + "format" : { + "ha" : { + "default" : "basic", + "description" : "Use this resource scheduler mode for HA.", + "enum" : [ + "basic", + "static", + "dynamic" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Configures how the HA Manager should select nodes to start or recover services:\n\n- with 'basic', only the number of services is used,\n- with 'static', static CPU and memory configuration of services are considered,\n- with 'dynamic', static and dynamic CPU and memory usage of services are considered.\n" + }, + "ha-auto-rebalance" : { + "default" : 0, + "description" : "Whether to use CRS for balancing HA resources automatically depending on the current node imbalance.", + "optional" : 1, + "type" : "boolean" + }, + "ha-auto-rebalance-hold-duration" : { + "default" : 3, + "description" : "The number of HA rounds for which the cluster node imbalance threshold must be exceeded before triggering an automatic resource balancing migration.", + "minimum" : 0, + "optional" : 1, + "requires" : "ha-auto-rebalance", + "type" : "number" + }, + "ha-auto-rebalance-margin" : { + "default" : 10, + "description" : "The minimum relative improvement in cluster node imbalance, in percent, to commit to a resource balancing migration.", + "maximum" : 100, + "minimum" : 0, + "optional" : 1, + "requires" : "ha-auto-rebalance", + "type" : "number" + }, + "ha-auto-rebalance-method" : { + "default" : "bruteforce", + "description" : "The method to use for the scoring of balancing migrations.", + "enum" : [ + "bruteforce", + "topsis" + ], + "optional" : 1, + "requires" : "ha-auto-rebalance", + "type" : "string" + }, + "ha-auto-rebalance-threshold" : { + "default" : 30, + "description" : "The cluster node imbalance, in percent, which will trigger the automatic resource balancing system if exceeded.", + "maximum" : 100, + "minimum" : 0, + "optional" : 1, + "requires" : "ha-auto-rebalance", + "type" : "number" + }, + "ha-rebalance-on-start" : { + "default" : 0, + "description" : "Set to use CRS for selecting a suited node when a HA services request-state changes from stop to start.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[ha=] [,ha-auto-rebalance=<1|0>] [,ha-auto-rebalance-hold-duration=] [,ha-auto-rebalance-margin=] [,ha-auto-rebalance-method=] [,ha-auto-rebalance-threshold=] [,ha-rebalance-on-start=<1|0>]" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Datacenter description. Shown in the web-interface datacenter notes panel. This is saved as comment inside the configuration file.", + "maxLength" : 65536, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "email_from" : { + "description" : "Specify email address to send notification from (default is root@$hostname)", + "format" : "email-opt", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fencing" : { + "default" : "watchdog", + "description" : "Set the fencing mode of the HA cluster. Hardware mode needs a valid configuration of fence devices in /etc/pve/ha/fence.cfg. With both all two modes are used.\n\nWARNING: 'hardware' and 'both' are EXPERIMENTAL & WIP", + "enum" : [ + "watchdog", + "hardware", + "both" + ], + "optional" : 1, + "type" : "string" + }, + "ha" : { + "description" : "Cluster wide HA settings.", + "format" : { + "shutdown_policy" : { + "default" : "conditional", + "description" : "The policy for HA services on node shutdown. 'freeze' disables auto-recovery, 'failover' ensures recovery, 'conditional' recovers on poweroff and freezes on reboot. 'migrate' will migrate running services to other nodes, if possible. With 'freeze' or 'failover', HA Services will always get stopped first on shutdown.", + "enum" : [ + "freeze", + "failover", + "conditional", + "migrate" + ], + "type" : "string", + "verbose_description" : "Describes the policy for handling HA services on poweroff or reboot of a node. Freeze will always freeze services which are still located on the node on shutdown, those services won't be recovered by the HA manager. Failover will not mark the services as frozen and thus the services will get recovered to other nodes, if the shutdown node does not come up again quickly (< 1min). 'conditional' chooses automatically depending on the type of shutdown, i.e., on a reboot the service will be frozen but on a poweroff the service will stay as is, and thus get recovered after about 2 minutes. Migrate will try to move all running services to another node when a reboot or shutdown was triggered. The poweroff process will only continue once no running services are located on the node anymore. If the node comes up again, the service will be moved back to the previously powered-off node, at least if no other migration, reloaction or recovery took place." + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "shutdown_policy=" + }, + "http_proxy" : { + "description" : "Specify external http proxy which is used for downloads (example: 'http://username:password@host:port/')", + "optional" : 1, + "pattern" : "http://.*", + "type" : "string" + }, + "keyboard" : { + "description" : "Default keybord layout for vnc server.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "language" : { + "description" : "Default GUI language.", + "enum" : [ + "ar", + "ca", + "da", + "de", + "en", + "es", + "eu", + "fa", + "fr", + "hr", + "he", + "it", + "ja", + "ka", + "kr", + "nb", + "nl", + "nn", + "pl", + "pt_BR", + "ru", + "sl", + "sv", + "tr", + "ukr", + "zh_CN", + "zh_TW" + ], + "optional" : 1, + "type" : "string" + }, + "location" : { + "description" : "The location of the cluster.", + "format" : { + "latitude" : { + "description" : "The latitude of the nodes location in degrees.", + "maximum" : 90, + "minimum" : -90, + "type" : "number" + }, + "longitude" : { + "description" : "The longitude of the nodes location in degrees.", + "maximum" : 180, + "minimum" : -180, + "type" : "number" + }, + "name" : { + "description" : "The name of the location of this node", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "latitude= ,longitude= [,name=]" + }, + "mac_prefix" : { + "default" : "BC:24:11", + "description" : "Prefix for the auto-generated MAC addresses of virtual guests. The default 'BC:24:11' is the OUI assigned by the IEEE to Proxmox Server Solutions GmbH for a 24-bit large MAC block. You're allowed to use this in local networks, i.e., those not directly reachable by the public (e.g., in a LAN or behind NAT).", + "format" : "mac-prefix", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "Prefix for the auto-generated MAC addresses of virtual guests. The default `BC:24:11` is the Organizationally Unique Identifier (OUI) assigned by the IEEE to Proxmox Server Solutions GmbH for a MAC Address Block Large (MA-L). You're allowed to use this in local networks, i.e., those not directly reachable by the public (e.g., in a LAN or NAT/Masquerading).\n \nNote that when you run multiple cluster that (partially) share the networks of their virtual guests, it's highly recommended that you extend the default MAC prefix, or generate a custom (valid) one, to reduce the chance of MAC collisions. For example, add a separate extra hexadecimal to the Proxmox OUI for each cluster, like `BC:24:11:0` for the first, `BC:24:11:1` for the second, and so on.\n Alternatively, you can also separate the networks of the guests logically, e.g., by using VLANs.\n\nFor publicly accessible guests it's recommended that you get your own https://standards.ieee.org/products-programs/regauth/[OUI from the IEEE] registered or coordinate with your, or your hosting providers, network admins." + }, + "max_workers" : { + "description" : "Defines how many workers (per node) are maximal started on actions like 'stopall VMs' or task from the ha-manager.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "migration" : { + "description" : "For cluster wide migration settings.", + "format" : { + "network" : { + "description" : "CIDR of the (sub) network that is used for migration. Used as a fallback for replications jobs if the replication network setting is not set", + "format" : "CIDR", + "format_description" : "CIDR", + "optional" : 1, + "type" : "string" + }, + "type" : { + "default" : "secure", + "default_key" : 1, + "description" : "Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.", + "enum" : [ + "secure", + "insecure" + ], + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[type=] [,network=]" + }, + "migration_unsecure" : { + "description" : "Migration is secure using SSH tunnel by default. For secure private networks you can disable it to speed up migration. Deprecated, use the 'migration' property instead!", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "next-id" : { + "description" : "Control the range for the free VMID auto-selection pool.", + "format" : { + "lower" : { + "default" : 100, + "description" : "Lower, inclusive boundary for free next-id API range.", + "max" : 999999999, + "min" : 100, + "optional" : 1, + "type" : "integer" + }, + "upper" : { + "default" : 1000000, + "description" : "Upper, exclusive boundary for free next-id API range.", + "max" : 1000000000, + "min" : 100, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[lower=] [,upper=]" + }, + "notify" : { + "description" : "Cluster-wide notification settings.", + "format" : { + "fencing" : { + "description" : "UNUSED - Use datacenter notification settings instead.", + "enum" : [ + "always", + "never" + ], + "optional" : 1, + "type" : "string" + }, + "package-updates" : { + "default" : "auto", + "description" : "DEPRECATED: Use datacenter notification settings instead. Control when the daily update job should send out notifications.", + "enum" : [ + "auto", + "always", + "never" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "DEPRECATED: Use datacenter notification settings instead.\nControl how often the daily update job should send out notifications:\n* 'auto' daily for systems with a valid subscription, as those are assumed to be production-ready and thus should know about pending updates.\n* 'always' every update, if there are new pending updates.\n* 'never' never send a notification for new pending updates.\n" + }, + "replication" : { + "description" : "UNUSED - Use datacenter notification settings instead.", + "enum" : [ + "always", + "never" + ], + "optional" : 1, + "type" : "string" + }, + "target-fencing" : { + "description" : "UNUSED - Use datacenter notification settings instead.", + "format_description" : "TARGET", + "optional" : 1, + "type" : "string" + }, + "target-package-updates" : { + "description" : "UNUSED - Use datacenter notification settings instead.", + "format_description" : "TARGET", + "optional" : 1, + "type" : "string" + }, + "target-replication" : { + "description" : "UNUSED - Use datacenter notification settings instead.", + "format_description" : "TARGET", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[fencing=] [,package-updates=] [,replication=] [,target-fencing=] [,target-package-updates=] [,target-replication=]" + }, + "registered-tags" : { + "description" : "A list of tags that require a `Sys.Modify` on '/' to set and delete. Tags set here that are also in 'user-tag-access' also require `Sys.Modify`.", + "optional" : 1, + "pattern" : "(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*);)*(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*)", + "type" : "string", + "typetext" : "[;...]" + }, + "replication" : { + "description" : "For cluster wide replication settings.", + "format" : { + "network" : { + "description" : "CIDR of the (sub) network that is used for replication jobs.", + "format" : "CIDR", + "format_description" : "CIDR", + "optional" : 1, + "type" : "string" + }, + "type" : { + "default" : "secure", + "default_key" : 1, + "description" : "Replication traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.", + "enum" : [ + "secure", + "insecure" + ], + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[type=] [,network=]" + }, + "tag-style" : { + "description" : "Tag style options.", + "format" : { + "case-sensitive" : { + "default" : 0, + "description" : "Controls if filtering for unique tags on update should check case-sensitive.", + "optional" : 1, + "type" : "boolean" + }, + "color-map" : { + "description" : "Manual color mapping for tags (semicolon separated).", + "optional" : 1, + "pattern" : "(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*):[0-9a-fA-F]{6}(?::[0-9a-fA-F]{6})?)(?:;(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*):[0-9a-fA-F]{6}(?::[0-9a-fA-F]{6})?))*", + "type" : "string", + "typetext" : ":[:][;=...]" + }, + "ordering" : { + "default" : "alphabetical", + "description" : "Controls the sorting of the tags in the web-interface and the API update.", + "enum" : [ + "config", + "alphabetical" + ], + "optional" : 1, + "type" : "string" + }, + "shape" : { + "default" : "circle", + "description" : "Tag shape for the web ui tree. 'full' draws the full tag. 'circle' draws only a circle with the background color. 'dense' only draws a small rectancle (useful when many tags are assigned to each guest).'none' disables showing the tags.", + "enum" : [ + "full", + "circle", + "dense", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[case-sensitive=<1|0>] [,color-map=:[:][;=...]] [,ordering=] [,shape=]" + }, + "u2f" : { + "description" : "u2f", + "format" : { + "appid" : { + "description" : "U2F AppId URL override. Defaults to the origin.", + "format_description" : "APPID", + "optional" : 1, + "type" : "string" + }, + "origin" : { + "description" : "U2F Origin override. Mostly useful for single nodes with a single URL.", + "format_description" : "URL", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[appid=] [,origin=]" + }, + "user-tag-access" : { + "description" : "Privilege options for user-settable tags", + "format" : { + "user-allow" : { + "default" : "free", + "description" : "Controls tag usage for users without `Sys.Modify` on `/` by either allowing `none`, a `list`, already `existing` or anything (`free`).", + "enum" : [ + "none", + "list", + "existing", + "free" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Controls which tags can be set or deleted on resources a user controls (such as guests). Users with the `Sys.Modify` privilege on `/` are alwaysunrestricted.\n* 'none' no tags are usable.\n* 'list' tags from 'user-allow-list' are usable.\n* 'existing' like list, but already existing tags of resources are also usable.\n* 'free' no tag restrictions.\n" + }, + "user-allow-list" : { + "description" : "List of tags users are allowed to set and delete (semicolon separated) for 'user-allow' values 'list' and 'existing'.", + "optional" : 1, + "pattern" : "(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*)(?:;(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*))*", + "type" : "string", + "typetext" : "[;...]" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[user-allow=] [,user-allow-list=[;...]]" + }, + "webauthn" : { + "description" : "webauthn configuration", + "format" : { + "allow-subdomains" : { + "default" : 1, + "description" : "Whether to allow the origin to be a subdomain, rather than the exact URL.", + "optional" : 1, + "type" : "boolean" + }, + "id" : { + "description" : "Relying party ID. Must be the domain name without protocol, port or location. Changing this *will* break existing credentials.", + "format_description" : "DOMAINNAME", + "optional" : 1, + "type" : "string" + }, + "origin" : { + "description" : "Site origin. Must be a `https://` URL (or `http://localhost`). Should contain the address users type in their browsers to access the web interface. Changing this *may* break existing credentials.", + "format_description" : "URL", + "optional" : 1, + "type" : "string" + }, + "rp" : { + "description" : "Relying party name. Any text identifier. Changing this *may* break existing credentials.", + "format_description" : "RELYING_PARTY", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[allow-subdomains=<1|0>] [,id=] [,origin=] [,rp=]" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get cluster status information.", + "method" : "GET", + "name" : "get_status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + }, + "ip" : { + "description" : "[node] IP of the resolved nodename.", + "optional" : 1, + "type" : "string" + }, + "level" : { + "description" : "[node] Proxmox VE Subscription level, indicates if eligible for enterprise support as well as access to the stable Proxmox VE Enterprise Repository.", + "optional" : 1, + "type" : "string" + }, + "local" : { + "description" : "[node] Indicates if this is the responding node.", + "optional" : 1, + "type" : "boolean" + }, + "name" : { + "type" : "string" + }, + "nodeid" : { + "description" : "[node] ID of the node from the corosync configuration.", + "optional" : 1, + "type" : "integer" + }, + "nodes" : { + "description" : "[cluster] Nodes count, including offline nodes.", + "optional" : 1, + "type" : "integer" + }, + "online" : { + "description" : "[node] Indicates if the node is online or offline.", + "optional" : 1, + "type" : "boolean" + }, + "quorate" : { + "description" : "[cluster] Indicates if there is a majority of nodes online to make decisions", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "description" : "Indicates the type, either cluster or node. The type defines the object properties e.g. quorate available for type cluster.", + "enum" : [ + "cluster", + "node" + ], + "type" : "string" + }, + "version" : { + "description" : "[cluster] Current version of the corosync configuration file.", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get next free VMID. Pass a VMID to assert that its free (at time of check).", + "method" : "GET", + "name" : "nextid", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "description" : "The next free VMID.", + "type" : "integer" + } + } + }, + "leaf" : 1, + "path" : "/cluster/nextid", + "text" : "nextid" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Cluster index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster", + "text" : "cluster" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment", + "optional" : 1, + "type" : "string" + }, + "dest" : { + "description" : "Restrict packet destination address", + "optional" : 1, + "type" : "string" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port", + "optional" : 1, + "type" : "string" + }, + "enable" : { + "description" : "Flag to enable/disable a rule", + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers", + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "description" : "IP version (4 or 6) - automatically determined from source/dest addresses", + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro", + "optional" : 1, + "type" : "string" + }, + "pos" : { + "description" : "Rule position in the ruleset", + "type" : "integer" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "Restrict packet source address", + "optional" : 1, + "type" : "string" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Rule type", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment", + "optional" : 1, + "type" : "string" + }, + "dest" : { + "description" : "Restrict packet destination address", + "optional" : 1, + "type" : "string" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port", + "optional" : 1, + "type" : "string" + }, + "enable" : { + "description" : "Flag to enable/disable a rule", + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers", + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "description" : "IP version (4 or 6) - automatically determined from source/dest addresses", + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro", + "optional" : 1, + "type" : "string" + }, + "pos" : { + "description" : "Rule position in the ruleset", + "type" : "integer" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "Restrict packet source address", + "optional" : 1, + "type" : "string" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Rule type", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 0, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/rules", + "text" : "rules" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network alias.", + "method" : "DELETE", + "name" : "remove_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read alias.", + "method" : "GET", + "name" : "read_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network alias.", + "method" : "PUT", + "name" : "update_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "rename" : { + "description" : "Rename an existing alias.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List aliases", + "method" : "GET", + "name" : "get_aliases", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create IP or Network Alias.", + "method" : "POST", + "name" : "create_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/aliases", + "text" : "aliases" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network from IPSet.", + "method" : "DELETE", + "name" : "remove_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read IP or Network settings from IPSet.", + "method" : "GET", + "name" : "read_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network settings", + "method" : "PUT", + "name" : "update_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "text" : "{cidr}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete IPSet", + "method" : "DELETE", + "name" : "delete_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "Delete all members of the IPSet, if there are any.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List IPSet content", + "method" : "GET", + "name" : "get_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{cidr}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add IP or Network to IPSet.", + "method" : "POST", + "name" : "create_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List IPSets", + "method" : "GET", + "name" : "ipset_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new IPSet", + "method" : "POST", + "name" : "create_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "rename" : { + "description" : "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/ipset", + "text" : "ipset" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get VM firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "dhcp" : { + "default" : 0, + "description" : "Enable DHCP.", + "optional" : 1, + "type" : "boolean" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean" + }, + "ipfilter" : { + "description" : "Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.", + "optional" : 1, + "type" : "boolean" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macfilter" : { + "default" : 1, + "description" : "Enable/disable MAC address filter.", + "optional" : 1, + "type" : "boolean" + }, + "ndp" : { + "default" : 1, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "radv" : { + "description" : "Allow sending Router Advertisement.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp" : { + "default" : 0, + "description" : "Enable DHCP.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ipfilter" : { + "description" : "Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macfilter" : { + "default" : 1, + "description" : "Enable/disable MAC address filter.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ndp" : { + "default" : 1, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "radv" : { + "description" : "Allow sending Router Advertisement.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read firewall log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display log since this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "until" : { + "description" : "Display log until this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Lists possible IPSet/Alias reference which are allowed in source/dest properties.", + "method" : "GET", + "name" : "refs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Only list references of specified type.", + "enum" : [ + "alias", + "ipset" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "ref" : { + "type" : "string" + }, + "scope" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "alias", + "ipset" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/refs", + "text" : "refs" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall", + "text" : "firewall" + }, + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute fsfreeze-freeze.", + "method" : "POST", + "name" : "fsfreeze-freeze", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileSystemMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze", + "text" : "fsfreeze-freeze" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute fsfreeze-status.", + "method" : "POST", + "name" : "fsfreeze-status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.FileSystemMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status", + "text" : "fsfreeze-status" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute fsfreeze-thaw.", + "method" : "POST", + "name" : "fsfreeze-thaw", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileSystemMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw", + "text" : "fsfreeze-thaw" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute fstrim.", + "method" : "POST", + "name" : "fstrim", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileSystemMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/fstrim", + "text" : "fstrim" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-fsinfo.", + "method" : "GET", + "name" : "get-fsinfo", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-fsinfo", + "text" : "get-fsinfo" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-host-name.", + "method" : "GET", + "name" : "get-host-name", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-host-name", + "text" : "get-host-name" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-memory-block-info.", + "method" : "GET", + "name" : "get-memory-block-info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info", + "text" : "get-memory-block-info" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-memory-blocks.", + "method" : "GET", + "name" : "get-memory-blocks", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks", + "text" : "get-memory-blocks" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-osinfo.", + "method" : "GET", + "name" : "get-osinfo", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-osinfo", + "text" : "get-osinfo" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-time.", + "method" : "GET", + "name" : "get-time", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-time", + "text" : "get-time" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-timezone.", + "method" : "GET", + "name" : "get-timezone", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-timezone", + "text" : "get-timezone" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-users.", + "method" : "GET", + "name" : "get-users", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-users", + "text" : "get-users" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-vcpus.", + "method" : "GET", + "name" : "get-vcpus", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-vcpus", + "text" : "get-vcpus" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute info.", + "method" : "GET", + "name" : "info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/info", + "text" : "info" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute network-get-interfaces.", + "method" : "GET", + "name" : "network-get-interfaces", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces", + "text" : "network-get-interfaces" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute ping.", + "method" : "POST", + "name" : "ping", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/ping", + "text" : "ping" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute shutdown.", + "method" : "POST", + "name" : "shutdown", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/shutdown", + "text" : "shutdown" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute suspend-disk.", + "method" : "POST", + "name" : "suspend-disk", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/suspend-disk", + "text" : "suspend-disk" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute suspend-hybrid.", + "method" : "POST", + "name" : "suspend-hybrid", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid", + "text" : "suspend-hybrid" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute suspend-ram.", + "method" : "POST", + "name" : "suspend-ram", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/suspend-ram", + "text" : "suspend-ram" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Sets the password for the given user to the given password", + "method" : "POST", + "name" : "set-user-password", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "crypted" : { + "default" : 0, + "description" : "set to 1 if the password has already been passed through crypt()", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The new password.", + "maxLength" : 1024, + "minLength" : 5, + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "The user to set the password for.", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Unrestricted" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/set-user-password", + "text" : "set-user-password" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Executes the given command in the vm via the guest-agent and returns an object with the pid.", + "method" : "POST", + "name" : "exec", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "command" : { + "description" : "The command as a list of program + arguments.", + "items" : { + "description" : "A single part of the program + arguments.", + "type" : "string" + }, + "type" : "array", + "typetext" : "" + }, + "input-data" : { + "description" : "Data to pass as 'input-data' to the guest. Usually treated as STDIN to 'command'.", + "maxLength" : 65536, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Unrestricted" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "pid" : { + "description" : "The PID of the process started by the guest-agent.", + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/exec", + "text" : "exec" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Gets the status of the given pid started by the guest-agent", + "method" : "GET", + "name" : "exec-status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pid" : { + "description" : "The PID to query", + "type" : "integer", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Unrestricted" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "err-data" : { + "description" : "stderr of the process", + "optional" : 1, + "type" : "string" + }, + "err-truncated" : { + "description" : "true if stderr was not fully captured", + "optional" : 1, + "type" : "boolean" + }, + "exitcode" : { + "description" : "process exit code if it was normally terminated.", + "optional" : 1, + "type" : "integer" + }, + "exited" : { + "description" : "Tells if the given command has exited yet.", + "type" : "boolean" + }, + "out-data" : { + "description" : "stdout of the process", + "optional" : 1, + "type" : "string" + }, + "out-truncated" : { + "description" : "true if stdout was not fully captured", + "optional" : 1, + "type" : "boolean" + }, + "signal" : { + "description" : "signal number or exception code if the process was abnormally terminated.", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/exec-status", + "text" : "exec-status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Reads the given file via guest agent. Is limited to 16777216 bytes.", + "method" : "GET", + "name" : "file-read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "count" : { + "default" : "16777216", + "description" : "Number of bytes to read.", + "maximum" : "16777216", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 16777216)" + }, + "decode" : { + "default" : 1, + "description" : "Data received from the QEMU Guest-Agent is base64 encoded. If this is set to true, the data is decoded. Otherwise the content is forwarded with base64 encoding. Defaults to true.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "file" : { + "description" : "The path to the file", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "offset" : { + "default" : 0, + "description" : "Offset to start reading at", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileRead", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a `content` property.", + "properties" : { + "content" : { + "description" : "The content of the file, maximum 16777216", + "type" : "string" + }, + "truncated" : { + "description" : "If set to 1, the read did not reach the end of the file.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/file-read", + "text" : "file-read" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Writes the given file via guest agent.", + "method" : "POST", + "name" : "file-write", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "content" : { + "description" : "The content to write into the file.", + "maxLength" : 61440, + "type" : "string", + "typetext" : "" + }, + "encode" : { + "default" : 1, + "description" : "If set, the content will be encoded as base64 (required by QEMU).Otherwise the content needs to be encoded beforehand - defaults to true.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "file" : { + "description" : "The path to the file.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileWrite", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/file-write", + "text" : "file-write" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "QEMU Guest Agent command index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 1, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "description" : "Returns the list of QEMU Guest Agent commands", + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Execute QEMU Guest Agent commands.", + "method" : "POST", + "name" : "agent", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "command" : { + "description" : "The QGA command.", + "enum" : [ + "fsfreeze-freeze", + "fsfreeze-status", + "fsfreeze-thaw", + "fstrim", + "get-fsinfo", + "get-host-name", + "get-memory-block-info", + "get-memory-blocks", + "get-osinfo", + "get-time", + "get-timezone", + "get-users", + "get-vcpus", + "info", + "network-get-interfaces", + "ping", + "shutdown", + "suspend-disk", + "suspend-hybrid", + "suspend-ram" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Unrestricted", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/agent", + "text" : "agent" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read VM RRD statistics (returns PNG)", + "method" : "GET", + "name" : "rrd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "ds" : { + "description" : "The list of datasources you want to display.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "filename" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/rrd", + "text" : "rrd" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read VM RRD statistics", + "method" : "GET", + "name" : "rrddata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/rrddata", + "text" : "rrddata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the virtual machine configuration with pending configuration changes applied. Set the 'current' parameter to get the current configuration instead.", + "method" : "GET", + "name" : "vm_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "current" : { + "default" : 0, + "description" : "Get current values (instead of pending values).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapshot" : { + "description" : "Fetch config values from given snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "description" : "The VM configuration.", + "properties" : { + "acpi" : { + "default" : 1, + "description" : "Enable/disable ACPI.", + "optional" : 1, + "type" : "boolean" + }, + "affinity" : { + "description" : "List of host cores used to execute guest processes, for example: 0,5,8-11", + "format" : "pve-cpuset", + "optional" : 1, + "type" : "string" + }, + "agent" : { + "description" : "Enable/disable communication with the QEMU Guest Agent and its properties.", + "format" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.", + "type" : "boolean" + }, + "freeze-fs" : { + "default" : 1, + "description" : "Freeze guest filesystems through QGA for consistent disk state on operations such as snapshots, backups, replications and clones.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Whether to issue the guest-fsfreeze-freeze and guest-fsfreeze-thaw QEMU guest agent commands. Backups in snapshot mode, clones, snapshots without RAM, importing disks from a running guest, and replications normally issue a guest-fsfreeze-freeze and a respective thaw command when the QEMU Guest agent option is enabled in the guest's configuration and the agent is running inside of the guest.\n\nThe deprecated 'freeze-fs-on-backup' setting is treated as an alias for this setting." + }, + "freeze-fs-on-backup" : { + "alias" : "freeze-fs" + }, + "fstrim_cloned_disks" : { + "default" : 0, + "description" : "Run fstrim after moving a disk or migrating the VM.", + "optional" : 1, + "type" : "boolean" + }, + "guest-fsfreeze" : { + "alias" : "freeze-fs" + }, + "type" : { + "default" : "virtio", + "description" : "Select the agent type", + "enum" : [ + "virtio", + "isa" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "allow-ksm" : { + "default" : 1, + "description" : "Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).", + "optional" : 1, + "type" : "boolean" + }, + "amd-sev" : { + "description" : "Secure Encrypted Virtualization (SEV) features by AMD CPUs", + "format" : "pve-qemu-sev-fmt", + "optional" : 1, + "type" : "string" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host architecture.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "args" : { + "description" : "Arbitrary arguments passed to kvm.", + "optional" : 1, + "type" : "string", + "verbose_description" : "Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -smbios 'type=0,vendor=FOO'\n\nNOTE: this option is for experts only.\n" + }, + "audio0" : { + "description" : "Configure a audio device, useful in combination with QXL/Spice.", + "format" : { + "device" : { + "description" : "Configure an audio device.", + "enum" : [ + "ich9-intel-hda", + "intel-hda", + "AC97" + ], + "type" : "string" + }, + "driver" : { + "default" : "spice", + "description" : "Driver backend for the audio device.", + "enum" : [ + "spice", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "autostart" : { + "default" : 0, + "description" : "Automatic restart after crash (currently ignored).", + "optional" : 1, + "type" : "boolean" + }, + "balloon" : { + "description" : "Amount of target RAM for the VM in MiB. The balloon driver is enabled by default, unless it is explicitly disabled by setting the value to zero.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "bios" : { + "default" : "seabios", + "description" : "Select BIOS implementation.", + "enum" : [ + "seabios", + "ovmf" + ], + "optional" : 1, + "type" : "string" + }, + "boot" : { + "description" : "Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.", + "format" : "pve-qm-boot", + "optional" : 1, + "type" : "string" + }, + "bootdisk" : { + "description" : "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format" : "pve-qm-bootdisk", + "optional" : 1, + "pattern" : "(ide|sata|scsi|virtio)\\d+", + "type" : "string" + }, + "cdrom" : { + "description" : "This is an alias for option -ide2", + "format" : "pve-qm-ide", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cicustom" : { + "description" : "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format" : "pve-qm-cicustom", + "optional" : 1, + "type" : "string" + }, + "cipassword" : { + "description" : "cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.", + "optional" : 1, + "type" : "string" + }, + "citype" : { + "description" : "Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.", + "enum" : [ + "configdrive2", + "nocloud", + "opennebula" + ], + "optional" : 1, + "type" : "string" + }, + "ciupgrade" : { + "default" : 1, + "description" : "cloud-init: do an automatic package upgrade after the first boot.", + "optional" : 1, + "type" : "boolean" + }, + "ciuser" : { + "description" : "cloud-init: User name to change ssh keys and password for instead of the image's configured default user.", + "optional" : 1, + "type" : "string" + }, + "cores" : { + "default" : 1, + "description" : "The number of cores per socket.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cpu" : { + "description" : "Emulated CPU type.", + "format" : "pve-vm-cpu-conf", + "optional" : 1, + "type" : "string" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "verbose_description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit." + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 262144, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "verbose_description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs." + }, + "description" : { + "description" : "Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "SHA1 digest of configuration file. This can be used to prevent concurrent modifications.", + "type" : "string" + }, + "efidisk0" : { + "description" : "Configure a disk for storing EFI vars.", + "format" : { + "efitype" : { + "default" : "2m", + "description" : "Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarch64 (ARM).", + "enum" : [ + "2m", + "4m" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "ms-cert" : { + "default" : "2011", + "description" : "Informational marker indicating the version of the latest Microsoft UEFI certificates that have been enrolled by Proxmox VE. The value '2023k' means that the 'Microsoft UEFI CA 2023', the 'Windows UEFI CA 2023' and the 'Microsoft Corporation KEK 2K CA 2023' certificates are included. The values '2023' and '2023w' are deprecated and for compatibility only.", + "enum" : [ + "2011", + "2023", + "2023w", + "2023k" + ], + "optional" : 1, + "type" : "string" + }, + "pre-enrolled-keys" : { + "default" : 0, + "description" : "Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string" + }, + "freeze" : { + "description" : "Freeze CPU at startup (use 'c' monitor command to start execution).", + "optional" : 1, + "type" : "boolean" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the vms lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string" + }, + "hostpci[n]" : { + "description" : "Map host PCI devices into guest.", + "format" : "pve-qm-hostpci", + "optional" : 1, + "type" : "string", + "verbose_description" : "Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "hotplug" : { + "default" : "network,disk,usb", + "description" : "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.", + "format" : "pve-hotplug-features", + "optional" : 1, + "type" : "string" + }, + "hugepages" : { + "description" : "Enables hugepages memory.\n\nSets the size of hugepages in MiB. If the value is set to 'any' then 1 GiB hugepages will be used if possible, otherwise the size will fall back to 2 MiB.", + "enum" : [ + "any", + "2", + "1024" + ], + "optional" : 1, + "type" : "string" + }, + "ide[n]" : { + "description" : "Use volume as IDE hard disk or CD-ROM (n is 0 to 3).", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "model" : { + "description" : "The drive's reported model name, url-encoded, up to 40 bytes long.", + "format" : "urlencoded", + "format_description" : "model", + "maxLength" : 120, + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "intel-tdx" : { + "description" : "Trusted Domain Extension (TDX) features by Intel CPUs", + "format" : "pve-qemu-tdx-fmt", + "optional" : 1, + "type" : "string" + }, + "ipconfig[n]" : { + "description" : "cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n", + "format" : "pve-qm-ipconfig", + "optional" : 1, + "type" : "string" + }, + "ivshmem" : { + "description" : "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + "format" : { + "name" : { + "description" : "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + "format_description" : "string", + "optional" : 1, + "pattern" : "[a-zA-Z0-9\\-]+", + "type" : "string" + }, + "size" : { + "description" : "The size of the file in MB.", + "minimum" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string" + }, + "keephugepages" : { + "default" : 0, + "description" : "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "optional" : 1, + "type" : "boolean" + }, + "keyboard" : { + "default" : null, + "description" : "Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "kvm" : { + "default" : 1, + "description" : "Enable/disable KVM hardware virtualization.", + "optional" : 1, + "type" : "boolean" + }, + "localtime" : { + "description" : "Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.", + "optional" : 1, + "type" : "boolean" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ], + "optional" : 1, + "type" : "string" + }, + "machine" : { + "description" : "Specify the QEMU machine.", + "format" : { + "aw-bits" : { + "description" : "Specifies the vIOMMU address space bit width.", + "maximum" : 64, + "minimum" : 32, + "optional" : 1, + "type" : "number", + "verbose_description" : "Specifies the vIOMMU address space bit width.\n\nIntel vIOMMU supports a bit width of either 39 or 48 bits and VirtIO vIOMMU supports any bit width between 32 and 64 bits." + }, + "enable-s3" : { + "description" : "Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "enable-s4" : { + "description" : "Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default_key" : 1, + "description" : "Specifies the QEMU machine type.", + "format_description" : "machine type", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "viommu" : { + "description" : "Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).", + "enum" : [ + "intel", + "virtio" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "memory" : { + "description" : "Memory properties.", + "format" : { + "current" : { + "default" : 512, + "default_key" : 1, + "description" : "Current amount of online RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.", + "minimum" : 16, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string" + }, + "meta" : { + "description" : "Some (read-only) meta-information about this guest.", + "format" : { + "creation-qemu" : { + "description" : "The QEMU (machine) version from the time this VM was created.", + "optional" : 1, + "pattern" : "\\d+(\\.\\d+)+", + "type" : "string" + }, + "ctime" : { + "description" : "The guest creation timestamp as UNIX epoch time", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string" + }, + "migrate_downtime" : { + "default" : 0.1, + "description" : "Set maximum tolerated downtime (in seconds) for migrations. Should the migration not be able to converge in the very end, because too much newly dirtied RAM needs to be transferred, the limit will be increased automatically step-by-step until migration can converge. Will be capped to 2000 seconds (maximum in QEMU).", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "migrate_speed" : { + "default" : 0, + "description" : "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "Set a name for the VM. Only used on the configuration web interface.", + "format" : "dns-name", + "optional" : 1, + "type" : "string" + }, + "nameserver" : { + "description" : "cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "format" : "address-list", + "optional" : 1, + "type" : "string" + }, + "net[n]" : { + "description" : "Specify network devices.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n", + "format" : "pve-bridge-id", + "format_description" : "bridge", + "optional" : 1, + "type" : "string" + }, + "e1000" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82540em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82544gc" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82545em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000e" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "firewall" : { + "description" : "Whether this interface should be protected by the firewall.", + "optional" : 1, + "type" : "boolean" + }, + "i82551" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82557b" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82559er" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "macaddr" : { + "description" : "MAC address. That address must be unique within your network. This is automatically generated if not specified.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "model" : { + "default_key" : 1, + "description" : "Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.", + "enum" : [ + "e1000", + "e1000-82540em", + "e1000-82544gc", + "e1000-82545em", + "e1000e", + "i82551", + "i82557b", + "i82559er", + "ne2k_isa", + "ne2k_pci", + "pcnet", + "rtl8139", + "virtio", + "vmxnet3" + ], + "type" : "string" + }, + "mtu" : { + "description" : "Force MTU of network device (VirtIO only). Setting to '1' or empty will use the bridge MTU", + "maximum" : 65520, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "ne2k_isa" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "ne2k_pci" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "pcnet" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "queues" : { + "description" : "Number of packet queues to be used on the device.", + "maximum" : 64, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "rtl8139" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "tag" : { + "description" : "VLAN tag to apply to packets on this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN trunks to pass through this interface.", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "virtio" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "vmxnet3" : { + "alias" : "macaddr", + "keyAlias" : "model" + } + }, + "optional" : 1, + "type" : "string" + }, + "numa" : { + "default" : 0, + "description" : "Enable/disable NUMA.", + "optional" : 1, + "type" : "boolean" + }, + "numa[n]" : { + "description" : "NUMA topology.", + "format" : { + "cpus" : { + "description" : "CPUs accessing this NUMA node.", + "format_description" : "id[-id];...", + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "hostnodes" : { + "description" : "Host NUMA nodes to use.", + "format_description" : "id[-id];...", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "memory" : { + "description" : "Amount of memory this NUMA node provides.", + "optional" : 1, + "type" : "number" + }, + "policy" : { + "description" : "NUMA allocation policy.", + "enum" : [ + "preferred", + "bind", + "interleave" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean" + }, + "ostype" : { + "default" : "other", + "description" : "Specify guest operating system.", + "enum" : [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "win11", + "l24", + "l26", + "solaris" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022/2025\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 7.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n" + }, + "parallel[n]" : { + "description" : "Map host parallel devices (n is 0 to 2).", + "optional" : 1, + "pattern" : "/dev/parport\\d+|/dev/usb/lp\\d+", + "type" : "string", + "verbose_description" : "Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "parent" : { + "description" : "Parent snapshot name. This is used internally, and should not be modified.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "optional" : 1, + "type" : "boolean" + }, + "reboot" : { + "default" : 1, + "description" : "Allow reboot. If set to '0' the VM exit on reboot.", + "optional" : 1, + "type" : "boolean" + }, + "rng0" : { + "description" : "Configure a VirtIO-based Random Number Generator.", + "format" : "pve-qm-rng", + "optional" : 1, + "type" : "string" + }, + "running-nets-host-mtu" : { + "description" : "List of VirtIO network devices and their effective host_mtu setting. A value of 0 means that the host_mtu parameter is to be avoided for the corresponding device. This is used internally for snapshots.", + "optional" : 1, + "pattern" : "net\\d+=\\d+(,net\\d+=\\d+)*", + "type" : "string" + }, + "runningcpu" : { + "description" : "Specifies the QEMU '-cpu' parameter of the running vm. This is used internally for snapshots.", + "format_description" : "QEMU -cpu parameter", + "optional" : 1, + "pattern" : "(?^u:^((?>[+-]?[\\w\\-\\._=]+,?)+)$)", + "type" : "string" + }, + "runningmachine" : { + "description" : "Specifies the QEMU machine type of the running vm. This is used internally for snapshots.", + "format" : { + "aw-bits" : { + "description" : "Specifies the vIOMMU address space bit width.", + "maximum" : 64, + "minimum" : 32, + "optional" : 1, + "type" : "number", + "verbose_description" : "Specifies the vIOMMU address space bit width.\n\nIntel vIOMMU supports a bit width of either 39 or 48 bits and VirtIO vIOMMU supports any bit width between 32 and 64 bits." + }, + "enable-s3" : { + "description" : "Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "enable-s4" : { + "description" : "Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default_key" : 1, + "description" : "Specifies the QEMU machine type.", + "format_description" : "machine type", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "viommu" : { + "description" : "Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).", + "enum" : [ + "intel", + "virtio" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "sata[n]" : { + "description" : "Use volume as SATA hard disk or CD-ROM (n is 0 to 5).", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "scsi[n]" : { + "description" : "Use volume as SCSI hard disk or CD-ROM (n is 0 to 30).", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "product" : { + "description" : "The drive's product name, up to 16 bytes long.", + "format_description" : "product", + "optional" : 1, + "pattern" : "[A-Za-z0-9\\-_\\s]{,16}", + "type" : "string" + }, + "queues" : { + "description" : "Number of queues.", + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "scsiblock" : { + "default" : 0, + "description" : "whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host", + "optional" : 1, + "type" : "boolean" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "vendor" : { + "description" : "The drive's vendor name, up to 8 bytes long.", + "format_description" : "vendor", + "optional" : 1, + "pattern" : "[A-Za-z0-9\\-_\\s]{,8}", + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "scsihw" : { + "default" : "lsi", + "description" : "SCSI controller model", + "enum" : [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "optional" : 1, + "type" : "string" + }, + "serial[n]" : { + "description" : "Create a serial device inside the VM (n is 0 to 3)", + "optional" : 1, + "pattern" : "(/dev/[^,]+|socket)", + "type" : "string", + "verbose_description" : "Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "shares" : { + "default" : 1000, + "description" : "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.", + "maximum" : 50000, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "smbios1" : { + "description" : "Specify SMBIOS type 1 fields.", + "format" : "pve-qm-smbios1", + "maxLength" : 512, + "optional" : 1, + "type" : "string" + }, + "smp" : { + "default" : 1, + "description" : "The number of CPUs. Please use option -sockets instead.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "snaptime" : { + "description" : "Timestamp for snapshots.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "sockets" : { + "default" : 1, + "description" : "The number of CPU sockets.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "spice_enhancements" : { + "description" : "Configure additional enhancements for SPICE.", + "format" : { + "foldersharing" : { + "default" : "0", + "description" : "Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.", + "optional" : 1, + "type" : "boolean" + }, + "videostreaming" : { + "default" : "off", + "description" : "Enable video streaming. Uses compression for detected video streams.", + "enum" : [ + "off", + "all", + "filter" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "sshkeys" : { + "description" : "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format" : "urlencoded", + "optional" : 1, + "type" : "string" + }, + "startdate" : { + "default" : "now", + "description" : "Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.", + "optional" : 1, + "pattern" : "(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)", + "type" : "string", + "typetext" : "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "tablet" : { + "default" : 1, + "description" : "Enable/disable the USB tablet device.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)." + }, + "tags" : { + "description" : "Tags of the VM. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string" + }, + "tdf" : { + "default" : 0, + "description" : "Enable/disable time drift fix.", + "optional" : 1, + "type" : "boolean" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean" + }, + "tpmstate0" : { + "description" : "Configure a Disk for storing TPM state. The format is fixed to 'raw'.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "Format of the image.", + "enum" : [ + "raw", + "qcow2", + "vmdk" + ], + "optional" : 1, + "type" : "string" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "version" : { + "default" : "v1.2", + "description" : "The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.", + "enum" : [ + "v1.2", + "v2.0" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string" + }, + "usb[n]" : { + "description" : "Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).", + "format" : { + "host" : { + "default_key" : 1, + "description" : "The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadecimal numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n\nEither this or the 'mapping' key must be set.\n", + "format_description" : "HOSTUSBDEVICE|spice", + "optional" : 1, + "pattern" : "(?^:(?:(?:(?^:(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})))|(?:(?^:(\\d+)\\-(\\d+(\\.\\d+)*)))|[Ss][Pp][Ii][Cc][Ee]))", + "type" : "string" + }, + "mapping" : { + "description" : "The ID of a cluster wide mapping. Either this or the default-key 'host' must be set.", + "format" : "pve-configid", + "format_description" : "mapping-id", + "optional" : 1, + "type" : "string" + }, + "usb3" : { + "default" : 0, + "description" : "Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string" + }, + "vcpus" : { + "default" : 0, + "description" : "Number of hotplugged vcpus.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "vga" : { + "description" : "Configure the VGA hardware.", + "format" : { + "clipboard" : { + "description" : "Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Live migration with a VNC clipboard is not possible with QEMU machine version < 10.1.", + "enum" : [ + "vnc" + ], + "optional" : 1, + "type" : "string" + }, + "memory" : { + "description" : "Sets the VGA memory (in MiB). Has no effect with serial display.", + "maximum" : 512, + "minimum" : 4, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "default" : "std", + "default_key" : 1, + "description" : "Select the VGA type. Using type 'cirrus' is not recommended.", + "enum" : [ + "cirrus", + "qxl", + "qxl2", + "qxl3", + "qxl4", + "none", + "serial0", + "serial1", + "serial2", + "serial3", + "std", + "virtio", + "virtio-gl", + "vmware" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "verbose_description" : "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal." + }, + "virtio[n]" : { + "description" : "Use volume as VIRTIO hard disk (n is 0 to 15).", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "virtiofs[n]" : { + "description" : "Configuration for sharing a directory between host and guest using Virtio-fs.", + "format" : { + "cache" : { + "default" : "auto", + "description" : "The caching policy the file system should use (auto, always, metadata, never).", + "enum" : [ + "auto", + "always", + "metadata", + "never" + ], + "optional" : 1, + "type" : "string" + }, + "direct-io" : { + "default" : 0, + "description" : "Honor the O_DIRECT flag passed down by guest applications.", + "optional" : 1, + "type" : "boolean" + }, + "dirid" : { + "default_key" : 1, + "description" : "Mapping identifier of the directory mapping to be shared with the guest. Also used as a mount tag inside the VM.", + "format" : "pve-configid", + "format_description" : "mapping-id", + "type" : "string" + }, + "expose-acl" : { + "default" : 0, + "description" : "Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.", + "optional" : 1, + "type" : "boolean" + }, + "expose-xattr" : { + "default" : 0, + "description" : "Enable support for extended attributes for this mount.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string" + }, + "vmgenid" : { + "default" : "1 (autogenerated)", + "description" : "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "format_description" : "UUID", + "optional" : 1, + "pattern" : "(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])", + "type" : "string", + "verbose_description" : "The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file." + }, + "vmstate" : { + "description" : "Reference to a volume which stores the VM state. This is used internally for snapshots.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string" + }, + "vmstatestorage" : { + "description" : "Default storage for VM state volumes/files.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string" + }, + "watchdog" : { + "description" : "Create a virtual hardware watchdog device.", + "format" : "pve-qm-watchdog", + "optional" : 1, + "type" : "string", + "verbose_description" : "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Set virtual machine options (asynchronous API).", + "method" : "POST", + "name" : "update_vm_async", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acpi" : { + "default" : 1, + "description" : "Enable/disable ACPI.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "affinity" : { + "description" : "List of host cores used to execute guest processes, for example: 0,5,8-11", + "format" : "pve-cpuset", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "agent" : { + "description" : "Enable/disable communication with the QEMU Guest Agent and its properties.", + "format" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.", + "type" : "boolean" + }, + "freeze-fs" : { + "default" : 1, + "description" : "Freeze guest filesystems through QGA for consistent disk state on operations such as snapshots, backups, replications and clones.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Whether to issue the guest-fsfreeze-freeze and guest-fsfreeze-thaw QEMU guest agent commands. Backups in snapshot mode, clones, snapshots without RAM, importing disks from a running guest, and replications normally issue a guest-fsfreeze-freeze and a respective thaw command when the QEMU Guest agent option is enabled in the guest's configuration and the agent is running inside of the guest.\n\nThe deprecated 'freeze-fs-on-backup' setting is treated as an alias for this setting." + }, + "freeze-fs-on-backup" : { + "alias" : "freeze-fs" + }, + "fstrim_cloned_disks" : { + "default" : 0, + "description" : "Run fstrim after moving a disk or migrating the VM.", + "optional" : 1, + "type" : "boolean" + }, + "guest-fsfreeze" : { + "alias" : "freeze-fs" + }, + "type" : { + "default" : "virtio", + "description" : "Select the agent type", + "enum" : [ + "virtio", + "isa" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[enabled=]<1|0> [,freeze-fs=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]" + }, + "allow-ksm" : { + "default" : 1, + "description" : "Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "amd-sev" : { + "description" : "Secure Encrypted Virtualization (SEV) features by AMD CPUs", + "format" : "pve-qemu-sev-fmt", + "optional" : 1, + "type" : "string", + "typetext" : "[type=] [,allow-smt=<1|0>] [,kernel-hashes=<1|0>] [,no-debug=<1|0>] [,no-key-sharing=<1|0>]" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host architecture.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "args" : { + "description" : "Arbitrary arguments passed to kvm.", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -smbios 'type=0,vendor=FOO'\n\nNOTE: this option is for experts only.\n" + }, + "audio0" : { + "description" : "Configure a audio device, useful in combination with QXL/Spice.", + "format" : { + "device" : { + "description" : "Configure an audio device.", + "enum" : [ + "ich9-intel-hda", + "intel-hda", + "AC97" + ], + "type" : "string" + }, + "driver" : { + "default" : "spice", + "description" : "Driver backend for the audio device.", + "enum" : [ + "spice", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "device= [,driver=]" + }, + "autostart" : { + "default" : 0, + "description" : "Automatic restart after crash (currently ignored).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "background_delay" : { + "description" : "Time to wait for the task to finish. We return 'null' if the task finish within that time.", + "maximum" : 30, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 30)" + }, + "balloon" : { + "description" : "Amount of target RAM for the VM in MiB. The balloon driver is enabled by default, unless it is explicitly disabled by setting the value to zero.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "bios" : { + "default" : "seabios", + "description" : "Select BIOS implementation.", + "enum" : [ + "seabios", + "ovmf" + ], + "optional" : 1, + "type" : "string" + }, + "boot" : { + "description" : "Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.", + "format" : "pve-qm-boot", + "optional" : 1, + "type" : "string", + "typetext" : "[[legacy=]<[acdn]{1,4}>] [,order=]" + }, + "bootdisk" : { + "description" : "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format" : "pve-qm-bootdisk", + "optional" : 1, + "pattern" : "(ide|sata|scsi|virtio)\\d+", + "type" : "string" + }, + "cdrom" : { + "description" : "This is an alias for option -ide2", + "format" : "pve-qm-ide", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cicustom" : { + "description" : "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format" : "pve-qm-cicustom", + "optional" : 1, + "type" : "string", + "typetext" : "[meta=] [,network=] [,user=] [,vendor=]" + }, + "cipassword" : { + "description" : "cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "citype" : { + "description" : "Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.", + "enum" : [ + "configdrive2", + "nocloud", + "opennebula" + ], + "optional" : 1, + "type" : "string" + }, + "ciupgrade" : { + "default" : 1, + "description" : "cloud-init: do an automatic package upgrade after the first boot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ciuser" : { + "description" : "cloud-init: User name to change ssh keys and password for instead of the image's configured default user.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cores" : { + "default" : 1, + "description" : "The number of cores per socket.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "cpu" : { + "description" : "Emulated CPU type.", + "format" : "pve-vm-cpu-conf", + "optional" : 1, + "type" : "string", + "typetext" : "[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,guest-phys-bits=] [,hidden=<1|0>] [,hv-vendor-id=] [,level=] [,phys-bits=<8-64|host>] [,reported-model=]" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 128)", + "verbose_description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit." + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 262144, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 262144)", + "verbose_description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs." + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "efidisk0" : { + "description" : "Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "efitype" : { + "default" : "2m", + "description" : "Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarch64 (ARM).", + "enum" : [ + "2m", + "4m" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "ms-cert" : { + "default" : "2011", + "description" : "Informational marker indicating the version of the latest Microsoft UEFI certificates that have been enrolled by Proxmox VE. The value '2023k' means that the 'Microsoft UEFI CA 2023', the 'Windows UEFI CA 2023' and the 'Microsoft Corporation KEK 2K CA 2023' certificates are included. The values '2023' and '2023w' are deprecated and for compatibility only.", + "enum" : [ + "2011", + "2023", + "2023w", + "2023k" + ], + "optional" : 1, + "type" : "string" + }, + "pre-enrolled-keys" : { + "default" : 0, + "description" : "Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,ms-cert=] [,pre-enrolled-keys=<1|0>] [,size=]" + }, + "force" : { + "description" : "Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.", + "optional" : 1, + "requires" : "delete", + "type" : "boolean", + "typetext" : "" + }, + "freeze" : { + "description" : "Freeze CPU at startup (use 'c' monitor command to start execution).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the vms lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostpci[n]" : { + "description" : "Map host PCI devices into guest.", + "format" : "pve-qm-hostpci", + "optional" : 1, + "type" : "string", + "typetext" : "[[host=]] [,device-id=] [,driver=] [,legacy-igd=<1|0>] [,mapping=] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]", + "verbose_description" : "Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "hotplug" : { + "default" : "network,disk,usb", + "description" : "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.", + "format" : "pve-hotplug-features", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hugepages" : { + "description" : "Enables hugepages memory.\n\nSets the size of hugepages in MiB. If the value is set to 'any' then 1 GiB hugepages will be used if possible, otherwise the size will fall back to 2 MiB.", + "enum" : [ + "any", + "2", + "1024" + ], + "optional" : 1, + "type" : "string" + }, + "ide[n]" : { + "description" : "Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "model" : { + "description" : "The drive's reported model name, url-encoded, up to 40 bytes long.", + "format" : "urlencoded", + "format_description" : "model", + "maxLength" : 120, + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,werror=] [,wwn=]" + }, + "import-working-storage" : { + "description" : "A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "intel-tdx" : { + "description" : "Trusted Domain Extension (TDX) features by Intel CPUs", + "format" : "pve-qemu-tdx-fmt", + "optional" : 1, + "type" : "string", + "typetext" : "[type=] ,attestation=<1|0> [,vsock-cid=] [,vsock-port=]" + }, + "ipconfig[n]" : { + "description" : "cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n", + "format" : "pve-qm-ipconfig", + "optional" : 1, + "type" : "string", + "typetext" : "[gw=] [,gw6=] [,ip=] [,ip6=]" + }, + "ivshmem" : { + "description" : "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + "format" : { + "name" : { + "description" : "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + "format_description" : "string", + "optional" : 1, + "pattern" : "[a-zA-Z0-9\\-]+", + "type" : "string" + }, + "size" : { + "description" : "The size of the file in MB.", + "minimum" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "size= [,name=]" + }, + "keephugepages" : { + "default" : 0, + "description" : "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "keyboard" : { + "default" : null, + "description" : "Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "kvm" : { + "default" : 1, + "description" : "Enable/disable KVM hardware virtualization.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "localtime" : { + "description" : "Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ], + "optional" : 1, + "type" : "string" + }, + "machine" : { + "description" : "Specify the QEMU machine.", + "format" : { + "aw-bits" : { + "description" : "Specifies the vIOMMU address space bit width.", + "maximum" : 64, + "minimum" : 32, + "optional" : 1, + "type" : "number", + "verbose_description" : "Specifies the vIOMMU address space bit width.\n\nIntel vIOMMU supports a bit width of either 39 or 48 bits and VirtIO vIOMMU supports any bit width between 32 and 64 bits." + }, + "enable-s3" : { + "description" : "Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "enable-s4" : { + "description" : "Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default_key" : 1, + "description" : "Specifies the QEMU machine type.", + "format_description" : "machine type", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "viommu" : { + "description" : "Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).", + "enum" : [ + "intel", + "virtio" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,aw-bits=] [,enable-s3=<1|0>] [,enable-s4=<1|0>] [,viommu=]" + }, + "memory" : { + "description" : "Memory properties.", + "format" : { + "current" : { + "default" : 512, + "default_key" : 1, + "description" : "Current amount of online RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.", + "minimum" : 16, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[current=]" + }, + "migrate_downtime" : { + "default" : 0.1, + "description" : "Set maximum tolerated downtime (in seconds) for migrations. Should the migration not be able to converge in the very end, because too much newly dirtied RAM needs to be transferred, the limit will be increased automatically step-by-step until migration can converge. Will be capped to 2000 seconds (maximum in QEMU).", + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "migrate_speed" : { + "default" : 0, + "description" : "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "name" : { + "description" : "Set a name for the VM. Only used on the configuration web interface.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nameserver" : { + "description" : "cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "format" : "address-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specify network devices.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n", + "format" : "pve-bridge-id", + "format_description" : "bridge", + "optional" : 1, + "type" : "string" + }, + "e1000" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82540em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82544gc" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82545em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000e" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "firewall" : { + "description" : "Whether this interface should be protected by the firewall.", + "optional" : 1, + "type" : "boolean" + }, + "i82551" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82557b" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82559er" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "macaddr" : { + "description" : "MAC address. That address must be unique within your network. This is automatically generated if not specified.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "model" : { + "default_key" : 1, + "description" : "Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.", + "enum" : [ + "e1000", + "e1000-82540em", + "e1000-82544gc", + "e1000-82545em", + "e1000e", + "i82551", + "i82557b", + "i82559er", + "ne2k_isa", + "ne2k_pci", + "pcnet", + "rtl8139", + "virtio", + "vmxnet3" + ], + "type" : "string" + }, + "mtu" : { + "description" : "Force MTU of network device (VirtIO only). Setting to '1' or empty will use the bridge MTU", + "maximum" : 65520, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "ne2k_isa" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "ne2k_pci" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "pcnet" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "queues" : { + "description" : "Number of packet queues to be used on the device.", + "maximum" : 64, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "rtl8139" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "tag" : { + "description" : "VLAN tag to apply to packets on this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN trunks to pass through this interface.", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "virtio" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "vmxnet3" : { + "alias" : "macaddr", + "keyAlias" : "model" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "numa" : { + "default" : 0, + "description" : "Enable/disable NUMA.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "numa[n]" : { + "description" : "NUMA topology.", + "format" : { + "cpus" : { + "description" : "CPUs accessing this NUMA node.", + "format_description" : "id[-id];...", + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "hostnodes" : { + "description" : "Host NUMA nodes to use.", + "format_description" : "id[-id];...", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "memory" : { + "description" : "Amount of memory this NUMA node provides.", + "optional" : 1, + "type" : "number" + }, + "policy" : { + "description" : "NUMA allocation policy.", + "enum" : [ + "preferred", + "bind", + "interleave" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "cpus= [,hostnodes=] [,memory=] [,policy=]" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostype" : { + "default" : "other", + "description" : "Specify guest operating system.", + "enum" : [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "win11", + "l24", + "l26", + "solaris" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022/2025\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 7.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n" + }, + "parallel[n]" : { + "description" : "Map host parallel devices (n is 0 to 2).", + "optional" : 1, + "pattern" : "/dev/parport\\d+|/dev/usb/lp\\d+", + "type" : "string", + "verbose_description" : "Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "reboot" : { + "default" : 1, + "description" : "Allow reboot. If set to '0' the VM exit on reboot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "revert" : { + "description" : "Revert a pending change.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rng0" : { + "description" : "Configure a VirtIO-based Random Number Generator.", + "format" : "pve-qm-rng", + "optional" : 1, + "type" : "string", + "typetext" : "[source=] [,max_bytes=] [,period=]" + }, + "sata[n]" : { + "description" : "Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,werror=] [,wwn=]" + }, + "scsi[n]" : { + "description" : "Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "product" : { + "description" : "The drive's product name, up to 16 bytes long.", + "format_description" : "product", + "optional" : 1, + "pattern" : "[A-Za-z0-9\\-_\\s]{,16}", + "type" : "string" + }, + "queues" : { + "description" : "Number of queues.", + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "scsiblock" : { + "default" : 0, + "description" : "whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host", + "optional" : 1, + "type" : "boolean" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "vendor" : { + "description" : "The drive's vendor name, up to 8 bytes long.", + "format_description" : "vendor", + "optional" : 1, + "pattern" : "[A-Za-z0-9\\-_\\s]{,8}", + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,product=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,vendor=] [,werror=] [,wwn=]" + }, + "scsihw" : { + "default" : "lsi", + "description" : "SCSI controller model", + "enum" : [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "serial[n]" : { + "description" : "Create a serial device inside the VM (n is 0 to 3)", + "optional" : 1, + "pattern" : "(/dev/[^,]+|socket)", + "type" : "string", + "verbose_description" : "Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "shares" : { + "default" : 1000, + "description" : "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.", + "maximum" : 50000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 50000)" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "smbios1" : { + "description" : "Specify SMBIOS type 1 fields.", + "format" : "pve-qm-smbios1", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]" + }, + "smp" : { + "default" : 1, + "description" : "The number of CPUs. Please use option -sockets instead.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "sockets" : { + "default" : 1, + "description" : "The number of CPU sockets.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "spice_enhancements" : { + "description" : "Configure additional enhancements for SPICE.", + "format" : { + "foldersharing" : { + "default" : "0", + "description" : "Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.", + "optional" : 1, + "type" : "boolean" + }, + "videostreaming" : { + "default" : "off", + "description" : "Enable video streaming. Uses compression for detected video streams.", + "enum" : [ + "off", + "all", + "filter" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[foldersharing=<1|0>] [,videostreaming=]" + }, + "sshkeys" : { + "description" : "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format" : "urlencoded", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "startdate" : { + "default" : "now", + "description" : "Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.", + "optional" : 1, + "pattern" : "(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)", + "type" : "string", + "typetext" : "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "tablet" : { + "default" : 1, + "description" : "Enable/disable the USB tablet device.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)." + }, + "tags" : { + "description" : "Tags of the VM. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tdf" : { + "default" : 0, + "description" : "Enable/disable time drift fix.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tpmstate0" : { + "description" : "Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "Format of the image.", + "enum" : [ + "raw", + "qcow2", + "vmdk" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "version" : { + "default" : "v1.2", + "description" : "The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.", + "enum" : [ + "v1.2", + "v2.0" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,format=] [,import-from=] [,size=] [,version=]" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=]" + }, + "usb[n]" : { + "description" : "Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).", + "format" : { + "host" : { + "default_key" : 1, + "description" : "The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadecimal numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n\nEither this or the 'mapping' key must be set.\n", + "format_description" : "HOSTUSBDEVICE|spice", + "optional" : 1, + "pattern" : "(?^:(?:(?:(?^:(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})))|(?:(?^:(\\d+)\\-(\\d+(\\.\\d+)*)))|[Ss][Pp][Ii][Cc][Ee]))", + "type" : "string" + }, + "mapping" : { + "description" : "The ID of a cluster wide mapping. Either this or the default-key 'host' must be set.", + "format" : "pve-configid", + "format_description" : "mapping-id", + "optional" : 1, + "type" : "string" + }, + "usb3" : { + "default" : 0, + "description" : "Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[host=]] [,mapping=] [,usb3=<1|0>]" + }, + "vcpus" : { + "default" : 0, + "description" : "Number of hotplugged vcpus.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vga" : { + "description" : "Configure the VGA hardware.", + "format" : { + "clipboard" : { + "description" : "Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Live migration with a VNC clipboard is not possible with QEMU machine version < 10.1.", + "enum" : [ + "vnc" + ], + "optional" : 1, + "type" : "string" + }, + "memory" : { + "description" : "Sets the VGA memory (in MiB). Has no effect with serial display.", + "maximum" : 512, + "minimum" : 4, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "default" : "std", + "default_key" : 1, + "description" : "Select the VGA type. Using type 'cirrus' is not recommended.", + "enum" : [ + "cirrus", + "qxl", + "qxl2", + "qxl3", + "qxl4", + "none", + "serial0", + "serial1", + "serial2", + "serial3", + "std", + "virtio", + "virtio-gl", + "vmware" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,clipboard=] [,memory=]", + "verbose_description" : "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal." + }, + "virtio[n]" : { + "description" : "Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,werror=]" + }, + "virtiofs[n]" : { + "description" : "Configuration for sharing a directory between host and guest using Virtio-fs.", + "format" : { + "cache" : { + "default" : "auto", + "description" : "The caching policy the file system should use (auto, always, metadata, never).", + "enum" : [ + "auto", + "always", + "metadata", + "never" + ], + "optional" : 1, + "type" : "string" + }, + "direct-io" : { + "default" : 0, + "description" : "Honor the O_DIRECT flag passed down by guest applications.", + "optional" : 1, + "type" : "boolean" + }, + "dirid" : { + "default_key" : 1, + "description" : "Mapping identifier of the directory mapping to be shared with the guest. Also used as a mount tag inside the VM.", + "format" : "pve-configid", + "format_description" : "mapping-id", + "type" : "string" + }, + "expose-acl" : { + "default" : 0, + "description" : "Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.", + "optional" : 1, + "type" : "boolean" + }, + "expose-xattr" : { + "default" : 0, + "description" : "Enable support for extended attributes for this mount.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[dirid=] [,cache=] [,direct-io=<1|0>] [,expose-acl=<1|0>] [,expose-xattr=<1|0>]" + }, + "vmgenid" : { + "default" : "1 (autogenerated)", + "description" : "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "format_description" : "UUID", + "optional" : 1, + "pattern" : "(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])", + "type" : "string", + "verbose_description" : "The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file." + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vmstatestorage" : { + "description" : "Default storage for VM state volumes/files.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "watchdog" : { + "description" : "Create a virtual hardware watchdog device.", + "format" : "pve-qm-watchdog", + "optional" : 1, + "type" : "string", + "typetext" : "[[model=]] [,action=]", + "verbose_description" : "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk", + "VM.Config.CDROM", + "VM.Config.CPU", + "VM.Config.Memory", + "VM.Config.Network", + "VM.Config.HWType", + "VM.Config.Options", + "VM.Config.Cloudinit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "optional" : 1, + "type" : "string" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set virtual machine options (synchronous API) - You should consider using the POST method instead for any actions involving hotplug or storage allocation.", + "method" : "PUT", + "name" : "update_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acpi" : { + "default" : 1, + "description" : "Enable/disable ACPI.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "affinity" : { + "description" : "List of host cores used to execute guest processes, for example: 0,5,8-11", + "format" : "pve-cpuset", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "agent" : { + "description" : "Enable/disable communication with the QEMU Guest Agent and its properties.", + "format" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.", + "type" : "boolean" + }, + "freeze-fs" : { + "default" : 1, + "description" : "Freeze guest filesystems through QGA for consistent disk state on operations such as snapshots, backups, replications and clones.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Whether to issue the guest-fsfreeze-freeze and guest-fsfreeze-thaw QEMU guest agent commands. Backups in snapshot mode, clones, snapshots without RAM, importing disks from a running guest, and replications normally issue a guest-fsfreeze-freeze and a respective thaw command when the QEMU Guest agent option is enabled in the guest's configuration and the agent is running inside of the guest.\n\nThe deprecated 'freeze-fs-on-backup' setting is treated as an alias for this setting." + }, + "freeze-fs-on-backup" : { + "alias" : "freeze-fs" + }, + "fstrim_cloned_disks" : { + "default" : 0, + "description" : "Run fstrim after moving a disk or migrating the VM.", + "optional" : 1, + "type" : "boolean" + }, + "guest-fsfreeze" : { + "alias" : "freeze-fs" + }, + "type" : { + "default" : "virtio", + "description" : "Select the agent type", + "enum" : [ + "virtio", + "isa" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[enabled=]<1|0> [,freeze-fs=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]" + }, + "allow-ksm" : { + "default" : 1, + "description" : "Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "amd-sev" : { + "description" : "Secure Encrypted Virtualization (SEV) features by AMD CPUs", + "format" : "pve-qemu-sev-fmt", + "optional" : 1, + "type" : "string", + "typetext" : "[type=] [,allow-smt=<1|0>] [,kernel-hashes=<1|0>] [,no-debug=<1|0>] [,no-key-sharing=<1|0>]" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host architecture.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "args" : { + "description" : "Arbitrary arguments passed to kvm.", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -smbios 'type=0,vendor=FOO'\n\nNOTE: this option is for experts only.\n" + }, + "audio0" : { + "description" : "Configure a audio device, useful in combination with QXL/Spice.", + "format" : { + "device" : { + "description" : "Configure an audio device.", + "enum" : [ + "ich9-intel-hda", + "intel-hda", + "AC97" + ], + "type" : "string" + }, + "driver" : { + "default" : "spice", + "description" : "Driver backend for the audio device.", + "enum" : [ + "spice", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "device= [,driver=]" + }, + "autostart" : { + "default" : 0, + "description" : "Automatic restart after crash (currently ignored).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "balloon" : { + "description" : "Amount of target RAM for the VM in MiB. The balloon driver is enabled by default, unless it is explicitly disabled by setting the value to zero.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "bios" : { + "default" : "seabios", + "description" : "Select BIOS implementation.", + "enum" : [ + "seabios", + "ovmf" + ], + "optional" : 1, + "type" : "string" + }, + "boot" : { + "description" : "Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.", + "format" : "pve-qm-boot", + "optional" : 1, + "type" : "string", + "typetext" : "[[legacy=]<[acdn]{1,4}>] [,order=]" + }, + "bootdisk" : { + "description" : "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format" : "pve-qm-bootdisk", + "optional" : 1, + "pattern" : "(ide|sata|scsi|virtio)\\d+", + "type" : "string" + }, + "cdrom" : { + "description" : "This is an alias for option -ide2", + "format" : "pve-qm-ide", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cicustom" : { + "description" : "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format" : "pve-qm-cicustom", + "optional" : 1, + "type" : "string", + "typetext" : "[meta=] [,network=] [,user=] [,vendor=]" + }, + "cipassword" : { + "description" : "cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "citype" : { + "description" : "Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.", + "enum" : [ + "configdrive2", + "nocloud", + "opennebula" + ], + "optional" : 1, + "type" : "string" + }, + "ciupgrade" : { + "default" : 1, + "description" : "cloud-init: do an automatic package upgrade after the first boot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ciuser" : { + "description" : "cloud-init: User name to change ssh keys and password for instead of the image's configured default user.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cores" : { + "default" : 1, + "description" : "The number of cores per socket.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "cpu" : { + "description" : "Emulated CPU type.", + "format" : "pve-vm-cpu-conf", + "optional" : 1, + "type" : "string", + "typetext" : "[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,guest-phys-bits=] [,hidden=<1|0>] [,hv-vendor-id=] [,level=] [,phys-bits=<8-64|host>] [,reported-model=]" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 128)", + "verbose_description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit." + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 262144, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 262144)", + "verbose_description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs." + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "efidisk0" : { + "description" : "Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "efitype" : { + "default" : "2m", + "description" : "Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarch64 (ARM).", + "enum" : [ + "2m", + "4m" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "ms-cert" : { + "default" : "2011", + "description" : "Informational marker indicating the version of the latest Microsoft UEFI certificates that have been enrolled by Proxmox VE. The value '2023k' means that the 'Microsoft UEFI CA 2023', the 'Windows UEFI CA 2023' and the 'Microsoft Corporation KEK 2K CA 2023' certificates are included. The values '2023' and '2023w' are deprecated and for compatibility only.", + "enum" : [ + "2011", + "2023", + "2023w", + "2023k" + ], + "optional" : 1, + "type" : "string" + }, + "pre-enrolled-keys" : { + "default" : 0, + "description" : "Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,ms-cert=] [,pre-enrolled-keys=<1|0>] [,size=]" + }, + "force" : { + "description" : "Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.", + "optional" : 1, + "requires" : "delete", + "type" : "boolean", + "typetext" : "" + }, + "freeze" : { + "description" : "Freeze CPU at startup (use 'c' monitor command to start execution).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the vms lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostpci[n]" : { + "description" : "Map host PCI devices into guest.", + "format" : "pve-qm-hostpci", + "optional" : 1, + "type" : "string", + "typetext" : "[[host=]] [,device-id=] [,driver=] [,legacy-igd=<1|0>] [,mapping=] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]", + "verbose_description" : "Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "hotplug" : { + "default" : "network,disk,usb", + "description" : "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.", + "format" : "pve-hotplug-features", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hugepages" : { + "description" : "Enables hugepages memory.\n\nSets the size of hugepages in MiB. If the value is set to 'any' then 1 GiB hugepages will be used if possible, otherwise the size will fall back to 2 MiB.", + "enum" : [ + "any", + "2", + "1024" + ], + "optional" : 1, + "type" : "string" + }, + "ide[n]" : { + "description" : "Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "model" : { + "description" : "The drive's reported model name, url-encoded, up to 40 bytes long.", + "format" : "urlencoded", + "format_description" : "model", + "maxLength" : 120, + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,werror=] [,wwn=]" + }, + "intel-tdx" : { + "description" : "Trusted Domain Extension (TDX) features by Intel CPUs", + "format" : "pve-qemu-tdx-fmt", + "optional" : 1, + "type" : "string", + "typetext" : "[type=] ,attestation=<1|0> [,vsock-cid=] [,vsock-port=]" + }, + "ipconfig[n]" : { + "description" : "cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n", + "format" : "pve-qm-ipconfig", + "optional" : 1, + "type" : "string", + "typetext" : "[gw=] [,gw6=] [,ip=] [,ip6=]" + }, + "ivshmem" : { + "description" : "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + "format" : { + "name" : { + "description" : "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + "format_description" : "string", + "optional" : 1, + "pattern" : "[a-zA-Z0-9\\-]+", + "type" : "string" + }, + "size" : { + "description" : "The size of the file in MB.", + "minimum" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "size= [,name=]" + }, + "keephugepages" : { + "default" : 0, + "description" : "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "keyboard" : { + "default" : null, + "description" : "Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "kvm" : { + "default" : 1, + "description" : "Enable/disable KVM hardware virtualization.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "localtime" : { + "description" : "Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ], + "optional" : 1, + "type" : "string" + }, + "machine" : { + "description" : "Specify the QEMU machine.", + "format" : { + "aw-bits" : { + "description" : "Specifies the vIOMMU address space bit width.", + "maximum" : 64, + "minimum" : 32, + "optional" : 1, + "type" : "number", + "verbose_description" : "Specifies the vIOMMU address space bit width.\n\nIntel vIOMMU supports a bit width of either 39 or 48 bits and VirtIO vIOMMU supports any bit width between 32 and 64 bits." + }, + "enable-s3" : { + "description" : "Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "enable-s4" : { + "description" : "Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default_key" : 1, + "description" : "Specifies the QEMU machine type.", + "format_description" : "machine type", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "viommu" : { + "description" : "Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).", + "enum" : [ + "intel", + "virtio" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,aw-bits=] [,enable-s3=<1|0>] [,enable-s4=<1|0>] [,viommu=]" + }, + "memory" : { + "description" : "Memory properties.", + "format" : { + "current" : { + "default" : 512, + "default_key" : 1, + "description" : "Current amount of online RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.", + "minimum" : 16, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[current=]" + }, + "migrate_downtime" : { + "default" : 0.1, + "description" : "Set maximum tolerated downtime (in seconds) for migrations. Should the migration not be able to converge in the very end, because too much newly dirtied RAM needs to be transferred, the limit will be increased automatically step-by-step until migration can converge. Will be capped to 2000 seconds (maximum in QEMU).", + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "migrate_speed" : { + "default" : 0, + "description" : "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "name" : { + "description" : "Set a name for the VM. Only used on the configuration web interface.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nameserver" : { + "description" : "cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "format" : "address-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specify network devices.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n", + "format" : "pve-bridge-id", + "format_description" : "bridge", + "optional" : 1, + "type" : "string" + }, + "e1000" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82540em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82544gc" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82545em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000e" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "firewall" : { + "description" : "Whether this interface should be protected by the firewall.", + "optional" : 1, + "type" : "boolean" + }, + "i82551" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82557b" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82559er" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "macaddr" : { + "description" : "MAC address. That address must be unique within your network. This is automatically generated if not specified.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "model" : { + "default_key" : 1, + "description" : "Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.", + "enum" : [ + "e1000", + "e1000-82540em", + "e1000-82544gc", + "e1000-82545em", + "e1000e", + "i82551", + "i82557b", + "i82559er", + "ne2k_isa", + "ne2k_pci", + "pcnet", + "rtl8139", + "virtio", + "vmxnet3" + ], + "type" : "string" + }, + "mtu" : { + "description" : "Force MTU of network device (VirtIO only). Setting to '1' or empty will use the bridge MTU", + "maximum" : 65520, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "ne2k_isa" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "ne2k_pci" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "pcnet" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "queues" : { + "description" : "Number of packet queues to be used on the device.", + "maximum" : 64, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "rtl8139" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "tag" : { + "description" : "VLAN tag to apply to packets on this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN trunks to pass through this interface.", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "virtio" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "vmxnet3" : { + "alias" : "macaddr", + "keyAlias" : "model" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "numa" : { + "default" : 0, + "description" : "Enable/disable NUMA.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "numa[n]" : { + "description" : "NUMA topology.", + "format" : { + "cpus" : { + "description" : "CPUs accessing this NUMA node.", + "format_description" : "id[-id];...", + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "hostnodes" : { + "description" : "Host NUMA nodes to use.", + "format_description" : "id[-id];...", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "memory" : { + "description" : "Amount of memory this NUMA node provides.", + "optional" : 1, + "type" : "number" + }, + "policy" : { + "description" : "NUMA allocation policy.", + "enum" : [ + "preferred", + "bind", + "interleave" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "cpus= [,hostnodes=] [,memory=] [,policy=]" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostype" : { + "default" : "other", + "description" : "Specify guest operating system.", + "enum" : [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "win11", + "l24", + "l26", + "solaris" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022/2025\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 7.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n" + }, + "parallel[n]" : { + "description" : "Map host parallel devices (n is 0 to 2).", + "optional" : 1, + "pattern" : "/dev/parport\\d+|/dev/usb/lp\\d+", + "type" : "string", + "verbose_description" : "Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "reboot" : { + "default" : 1, + "description" : "Allow reboot. If set to '0' the VM exit on reboot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "revert" : { + "description" : "Revert a pending change.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rng0" : { + "description" : "Configure a VirtIO-based Random Number Generator.", + "format" : "pve-qm-rng", + "optional" : 1, + "type" : "string", + "typetext" : "[source=] [,max_bytes=] [,period=]" + }, + "sata[n]" : { + "description" : "Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,werror=] [,wwn=]" + }, + "scsi[n]" : { + "description" : "Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "product" : { + "description" : "The drive's product name, up to 16 bytes long.", + "format_description" : "product", + "optional" : 1, + "pattern" : "[A-Za-z0-9\\-_\\s]{,16}", + "type" : "string" + }, + "queues" : { + "description" : "Number of queues.", + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "scsiblock" : { + "default" : 0, + "description" : "whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host", + "optional" : 1, + "type" : "boolean" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "vendor" : { + "description" : "The drive's vendor name, up to 8 bytes long.", + "format_description" : "vendor", + "optional" : 1, + "pattern" : "[A-Za-z0-9\\-_\\s]{,8}", + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,product=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,vendor=] [,werror=] [,wwn=]" + }, + "scsihw" : { + "default" : "lsi", + "description" : "SCSI controller model", + "enum" : [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "serial[n]" : { + "description" : "Create a serial device inside the VM (n is 0 to 3)", + "optional" : 1, + "pattern" : "(/dev/[^,]+|socket)", + "type" : "string", + "verbose_description" : "Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "shares" : { + "default" : 1000, + "description" : "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.", + "maximum" : 50000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 50000)" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "smbios1" : { + "description" : "Specify SMBIOS type 1 fields.", + "format" : "pve-qm-smbios1", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]" + }, + "smp" : { + "default" : 1, + "description" : "The number of CPUs. Please use option -sockets instead.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "sockets" : { + "default" : 1, + "description" : "The number of CPU sockets.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "spice_enhancements" : { + "description" : "Configure additional enhancements for SPICE.", + "format" : { + "foldersharing" : { + "default" : "0", + "description" : "Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.", + "optional" : 1, + "type" : "boolean" + }, + "videostreaming" : { + "default" : "off", + "description" : "Enable video streaming. Uses compression for detected video streams.", + "enum" : [ + "off", + "all", + "filter" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[foldersharing=<1|0>] [,videostreaming=]" + }, + "sshkeys" : { + "description" : "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format" : "urlencoded", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "startdate" : { + "default" : "now", + "description" : "Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.", + "optional" : 1, + "pattern" : "(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)", + "type" : "string", + "typetext" : "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "tablet" : { + "default" : 1, + "description" : "Enable/disable the USB tablet device.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)." + }, + "tags" : { + "description" : "Tags of the VM. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tdf" : { + "default" : 0, + "description" : "Enable/disable time drift fix.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tpmstate0" : { + "description" : "Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "Format of the image.", + "enum" : [ + "raw", + "qcow2", + "vmdk" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "version" : { + "default" : "v1.2", + "description" : "The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.", + "enum" : [ + "v1.2", + "v2.0" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,format=] [,import-from=] [,size=] [,version=]" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=]" + }, + "usb[n]" : { + "description" : "Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).", + "format" : { + "host" : { + "default_key" : 1, + "description" : "The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadecimal numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n\nEither this or the 'mapping' key must be set.\n", + "format_description" : "HOSTUSBDEVICE|spice", + "optional" : 1, + "pattern" : "(?^:(?:(?:(?^:(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})))|(?:(?^:(\\d+)\\-(\\d+(\\.\\d+)*)))|[Ss][Pp][Ii][Cc][Ee]))", + "type" : "string" + }, + "mapping" : { + "description" : "The ID of a cluster wide mapping. Either this or the default-key 'host' must be set.", + "format" : "pve-configid", + "format_description" : "mapping-id", + "optional" : 1, + "type" : "string" + }, + "usb3" : { + "default" : 0, + "description" : "Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[host=]] [,mapping=] [,usb3=<1|0>]" + }, + "vcpus" : { + "default" : 0, + "description" : "Number of hotplugged vcpus.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vga" : { + "description" : "Configure the VGA hardware.", + "format" : { + "clipboard" : { + "description" : "Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Live migration with a VNC clipboard is not possible with QEMU machine version < 10.1.", + "enum" : [ + "vnc" + ], + "optional" : 1, + "type" : "string" + }, + "memory" : { + "description" : "Sets the VGA memory (in MiB). Has no effect with serial display.", + "maximum" : 512, + "minimum" : 4, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "default" : "std", + "default_key" : 1, + "description" : "Select the VGA type. Using type 'cirrus' is not recommended.", + "enum" : [ + "cirrus", + "qxl", + "qxl2", + "qxl3", + "qxl4", + "none", + "serial0", + "serial1", + "serial2", + "serial3", + "std", + "virtio", + "virtio-gl", + "vmware" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,clipboard=] [,memory=]", + "verbose_description" : "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal." + }, + "virtio[n]" : { + "description" : "Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,werror=]" + }, + "virtiofs[n]" : { + "description" : "Configuration for sharing a directory between host and guest using Virtio-fs.", + "format" : { + "cache" : { + "default" : "auto", + "description" : "The caching policy the file system should use (auto, always, metadata, never).", + "enum" : [ + "auto", + "always", + "metadata", + "never" + ], + "optional" : 1, + "type" : "string" + }, + "direct-io" : { + "default" : 0, + "description" : "Honor the O_DIRECT flag passed down by guest applications.", + "optional" : 1, + "type" : "boolean" + }, + "dirid" : { + "default_key" : 1, + "description" : "Mapping identifier of the directory mapping to be shared with the guest. Also used as a mount tag inside the VM.", + "format" : "pve-configid", + "format_description" : "mapping-id", + "type" : "string" + }, + "expose-acl" : { + "default" : 0, + "description" : "Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.", + "optional" : 1, + "type" : "boolean" + }, + "expose-xattr" : { + "default" : 0, + "description" : "Enable support for extended attributes for this mount.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[dirid=] [,cache=] [,direct-io=<1|0>] [,expose-acl=<1|0>] [,expose-xattr=<1|0>]" + }, + "vmgenid" : { + "default" : "1 (autogenerated)", + "description" : "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "format_description" : "UUID", + "optional" : 1, + "pattern" : "(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])", + "type" : "string", + "verbose_description" : "The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file." + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vmstatestorage" : { + "description" : "Default storage for VM state volumes/files.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "watchdog" : { + "description" : "Create a virtual hardware watchdog device.", + "format" : "pve-qm-watchdog", + "optional" : 1, + "type" : "string", + "typetext" : "[[model=]] [,action=]", + "verbose_description" : "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk", + "VM.Config.CDROM", + "VM.Config.CPU", + "VM.Config.Memory", + "VM.Config.Network", + "VM.Config.HWType", + "VM.Config.Options", + "VM.Config.Cloudinit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/config", + "text" : "config" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the virtual machine configuration with both current and pending values.", + "method" : "GET", + "name" : "vm_pending", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "delete" : { + "description" : "Indicates a pending delete request if present and not 0. The value 2 indicates a force-delete request.", + "maximum" : 2, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "key" : { + "description" : "Configuration option name.", + "type" : "string" + }, + "pending" : { + "description" : "Pending value.", + "optional" : 1, + "type" : "string" + }, + "value" : { + "description" : "Current value.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/pending", + "text" : "pending" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get automatically generated cloudinit config.", + "method" : "GET", + "name" : "cloudinit_generated_config_dump", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Config type.", + "enum" : [ + "user", + "network", + "meta" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/cloudinit/dump", + "text" : "dump" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the cloudinit configuration with both current and pending values.", + "method" : "GET", + "name" : "cloudinit_pending", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "delete" : { + "description" : "Indicates a pending delete request if present and not 0. ", + "maximum" : 1, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "key" : { + "description" : "Configuration option name.", + "type" : "string" + }, + "pending" : { + "description" : "The new pending value.", + "optional" : 1, + "type" : "string" + }, + "value" : { + "description" : "Value as it was used to generate the current cloudinit image.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Regenerate and change cloudinit config drive.", + "method" : "PUT", + "name" : "cloudinit_update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Cloudinit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/cloudinit", + "text" : "cloudinit" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Unlink/delete disk images.", + "method" : "PUT", + "name" : "unlink", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "idlist" : { + "description" : "A list of disk IDs you want to delete.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/unlink", + "text" : "unlink" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a TCP VNC proxy connections.", + "method" : "POST", + "name" : "vncproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "generate-password" : { + "default" : 0, + "description" : "Deprecated, do not use. Password is generated when required.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "websocket" : { + "description" : "Prepare for websocket upgrade (only required when using serial terminal, otherwise upgrade is always possible).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "cert" : { + "type" : "string" + }, + "password" : { + "description" : "Password used for authentication within the VNC protocol. Consists of printable ASCII characters ('!' .. '~').", + "optional" : 1, + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/vncproxy", + "text" : "vncproxy" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a TCP proxy connections.", + "method" : "POST", + "name" : "termproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "serial" : { + "description" : "opens a serial terminal (defaults to display)", + "enum" : [ + "serial0", + "serial1", + "serial2", + "serial3" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/termproxy", + "text" : "termproxy" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Opens a websocket for VNC traffic.", + "method" : "GET", + "name" : "vncwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Port number returned by previous vncproxy call.", + "maximum" : 5999, + "minimum" : 5900, + "type" : "integer", + "typetext" : " (5900 - 5999)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vncticket" : { + "description" : "Ticket from previous call to vncproxy.", + "maxLength" : 512, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ], + "description" : "You also need to pass a valid ticket (vncticket)." + }, + "returns" : { + "properties" : { + "port" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/vncwebsocket", + "text" : "vncwebsocket" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Returns a SPICE configuration to connect to the VM.", + "method" : "POST", + "name" : "spiceproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "proxy" : { + "description" : "SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).", + "format" : "address", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 1, + "description" : "Returned values can be directly passed to the 'remote-viewer' application.", + "properties" : { + "host" : { + "type" : "string" + }, + "password" : { + "type" : "string" + }, + "proxy" : { + "type" : "string" + }, + "tls-port" : { + "type" : "integer" + }, + "type" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/spiceproxy", + "text" : "spiceproxy" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get virtual machine status.", + "method" : "GET", + "name" : "vm_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "agent" : { + "description" : "QEMU Guest Agent is enabled in config.", + "optional" : 1, + "type" : "boolean" + }, + "clipboard" : { + "description" : "Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added.", + "enum" : [ + "vnc" + ], + "optional" : 1, + "type" : "string" + }, + "cpu" : { + "description" : "Current CPU usage.", + "optional" : 1, + "type" : "number" + }, + "cpus" : { + "description" : "Maximum usable CPUs.", + "optional" : 1, + "type" : "number" + }, + "diskread" : { + "description" : "The amount of bytes the guest read from it's block devices since the guest was started. (Note: This info is not available for all storage types.)", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "diskwrite" : { + "description" : "The amount of bytes the guest wrote from it's block devices since the guest was started. (Note: This info is not available for all storage types.)", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "ha" : { + "description" : "HA manager service status.", + "type" : "object" + }, + "lock" : { + "description" : "The current config lock, if any.", + "optional" : 1, + "type" : "string" + }, + "maxdisk" : { + "description" : "Root disk size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Maximum memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "mem" : { + "description" : "Currently used memory in bytes. Does not take into account kernel same-page merging (KSM). Uses information from ballooning when available.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "memhost" : { + "description" : "Current memory usage on the host. Does not take into account kernel same-page merging (KSM).", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "VM (host)name.", + "optional" : 1, + "type" : "string" + }, + "netin" : { + "description" : "The amount of traffic in bytes that was sent to the guest over the network since it was started.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "netout" : { + "description" : "The amount of traffic in bytes that was sent from the guest over the network since it was started.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "pid" : { + "description" : "PID of the QEMU process, if the VM is running.", + "optional" : 1, + "type" : "integer" + }, + "pressurecpufull" : { + "description" : "CPU Full pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressurecpusome" : { + "description" : "CPU Some pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressureiofull" : { + "description" : "IO Full pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressureiosome" : { + "description" : "IO Some pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressurememoryfull" : { + "description" : "Memory Full pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressurememorysome" : { + "description" : "Memory Some pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "qmpstatus" : { + "description" : "VM run state from the 'query-status' QMP monitor command.", + "optional" : 1, + "type" : "string" + }, + "running-machine" : { + "description" : "The currently running machine type (if running).", + "optional" : 1, + "type" : "string" + }, + "running-qemu" : { + "description" : "The QEMU version the VM is currently using (if running).", + "optional" : 1, + "type" : "string" + }, + "serial" : { + "description" : "Guest has serial device configured.", + "optional" : 1, + "type" : "boolean" + }, + "spice" : { + "description" : "QEMU VGA configuration supports spice.", + "optional" : 1, + "type" : "boolean" + }, + "status" : { + "description" : "QEMU process status.", + "enum" : [ + "stopped", + "running" + ], + "type" : "string" + }, + "tags" : { + "description" : "The current configured tags, if any", + "optional" : 1, + "type" : "string" + }, + "template" : { + "default" : 0, + "description" : "Determines if the guest is a template.", + "optional" : 1, + "type" : "boolean" + }, + "uptime" : { + "description" : "Uptime in seconds.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/current", + "text" : "current" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start virtual machine.", + "method" : "POST", + "name" : "vm_start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force-cpu" : { + "description" : "Override QEMU's -cpu argument with the given string.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "machine" : { + "description" : "Specify the QEMU machine.", + "format" : { + "aw-bits" : { + "description" : "Specifies the vIOMMU address space bit width.", + "maximum" : 64, + "minimum" : 32, + "optional" : 1, + "type" : "number", + "verbose_description" : "Specifies the vIOMMU address space bit width.\n\nIntel vIOMMU supports a bit width of either 39 or 48 bits and VirtIO vIOMMU supports any bit width between 32 and 64 bits." + }, + "enable-s3" : { + "description" : "Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "enable-s4" : { + "description" : "Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default_key" : 1, + "description" : "Specifies the QEMU machine type.", + "format_description" : "machine type", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "viommu" : { + "description" : "Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).", + "enum" : [ + "intel", + "virtio" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,aw-bits=] [,enable-s3=<1|0>] [,enable-s4=<1|0>] [,viommu=]" + }, + "migratedfrom" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "migration_network" : { + "description" : "CIDR of the (sub) network that is used for migration.", + "format" : "CIDR", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "migration_type" : { + "description" : "Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.", + "enum" : [ + "secure", + "insecure" + ], + "optional" : 1, + "type" : "string" + }, + "nets-host-mtu" : { + "description" : "Used for migration compat. List of VirtIO network devices and their effective host_mtu setting according to the QEMU object model on the source side of the migration. A value of 0 means that the host_mtu parameter is to be avoided for the corresponding device.", + "optional" : 1, + "pattern" : "net\\d+=\\d+(,net\\d+=\\d+)*", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stateuri" : { + "description" : "Some command save/restore state from this location.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "targetstorage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storage-pair-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : "max(30, vm memory in GiB)", + "description" : "Wait maximal timeout seconds.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "with-conntrack-state" : { + "default" : 0, + "description" : "Whether to migrate conntrack entries for running VMs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop virtual machine. The qemu process will exit immediately. This is akin to pulling the power plug of a running computer and may damage the VM data.", + "method" : "POST", + "name" : "vm_stop", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "keepActive" : { + "default" : 0, + "description" : "Do not deactivate storage volumes.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "migratedfrom" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "overrule-shutdown" : { + "default" : 0, + "description" : "Try to abort active 'qmshutdown' tasks before stopping.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "timeout" : { + "description" : "Wait maximal timeout seconds.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/stop", + "text" : "stop" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Reset virtual machine.", + "method" : "POST", + "name" : "vm_reset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/reset", + "text" : "reset" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Shutdown virtual machine. This is similar to pressing the power button on a physical machine. This will send an ACPI event for the guest OS, which should then proceed to a clean shutdown.", + "method" : "POST", + "name" : "vm_shutdown", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "forceStop" : { + "default" : 0, + "description" : "Make sure the VM stops.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "keepActive" : { + "default" : 0, + "description" : "Do not deactivate storage volumes.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "timeout" : { + "description" : "Wait maximal timeout seconds.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/shutdown", + "text" : "shutdown" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Reboot the VM by shutting it down, and starting it again. Applies pending changes.", + "method" : "POST", + "name" : "vm_reboot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "description" : "Wait maximal timeout seconds for the shutdown.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/reboot", + "text" : "reboot" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Suspend virtual machine.", + "method" : "POST", + "name" : "vm_suspend", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "statestorage" : { + "description" : "The storage for the VM state", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "requires" : "todisk", + "type" : "string", + "typetext" : "" + }, + "todisk" : { + "default" : 0, + "description" : "If set, suspends the VM to disk. Will be resumed on next VM start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ], + "description" : "You need 'VM.PowerMgmt' on /vms/{vmid}, and if you have set 'todisk', you need also 'VM.Config.Disk' on /vms/{vmid} and 'Datastore.AllocateSpace' on the storage for the vmstate." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/suspend", + "text" : "suspend" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Resume virtual machine.", + "method" : "POST", + "name" : "vm_resume", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "nocheck" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/resume", + "text" : "resume" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "vmcmdidx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/status", + "text" : "status" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Send key event to virtual machine.", + "method" : "PUT", + "name" : "vm_sendkey", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "key" : { + "description" : "The key (qemu monitor encoding).", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/sendkey", + "text" : "sendkey" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Check if feature for virtual machine is available.", + "method" : "GET", + "name" : "vm_feature", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "feature" : { + "description" : "Feature to check.", + "enum" : [ + "snapshot", + "clone", + "copy" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "hasFeature" : { + "type" : "boolean" + }, + "nodes" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/feature", + "text" : "feature" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a copy of virtual machine/template.", + "method" : "POST", + "name" : "clone_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "clone limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "description" : { + "description" : "Description for the new VM.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "format" : { + "description" : "Target format for file storage. Only valid for full clone.", + "enum" : [ + "raw", + "qcow2", + "vmdk" + ], + "optional" : 1, + "type" : "string" + }, + "full" : { + "description" : "Create a full copy of all disks. This is always done when you clone a normal VM. For VM templates, we try to create a linked clone by default.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "Set a name for the new VM.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "newid" : { + "description" : "VMID for the clone.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Add the new VM to the specified pool.", + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Target storage for full clone.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node. Only allowed if the original VM is on shared storage.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/vms/{vmid}", + [ + "VM.Clone" + ] + ], + [ + "or", + [ + "perm", + "/vms/{newid}", + [ + "VM.Allocate" + ] + ], + [ + "perm", + "/pool/{pool}", + [ + "VM.Allocate" + ], + "require_param", + "pool" + ] + ] + ], + "description" : "You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions on /vms/{newid} (or on the VM pool /pool/{pool}). You also need 'Datastore.AllocateSpace' on any used storage and 'SDN.Use' on any used bridge/vnet" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/clone", + "text" : "clone" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Move volume to different storage or to a different VM.", + "method" : "POST", + "name" : "move_vm_disk", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "move limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "delete" : { + "default" : 0, + "description" : "Delete the original disk after successful copy. By default the original disk is kept as unused disk.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disk" : { + "description" : "The disk you want to move.", + "enum" : [ + "ide0", + "ide1", + "ide2", + "ide3", + "scsi0", + "scsi1", + "scsi2", + "scsi3", + "scsi4", + "scsi5", + "scsi6", + "scsi7", + "scsi8", + "scsi9", + "scsi10", + "scsi11", + "scsi12", + "scsi13", + "scsi14", + "scsi15", + "scsi16", + "scsi17", + "scsi18", + "scsi19", + "scsi20", + "scsi21", + "scsi22", + "scsi23", + "scsi24", + "scsi25", + "scsi26", + "scsi27", + "scsi28", + "scsi29", + "scsi30", + "virtio0", + "virtio1", + "virtio2", + "virtio3", + "virtio4", + "virtio5", + "virtio6", + "virtio7", + "virtio8", + "virtio9", + "virtio10", + "virtio11", + "virtio12", + "virtio13", + "virtio14", + "virtio15", + "sata0", + "sata1", + "sata2", + "sata3", + "sata4", + "sata5", + "efidisk0", + "tpmstate0", + "unused0", + "unused1", + "unused2", + "unused3", + "unused4", + "unused5", + "unused6", + "unused7", + "unused8", + "unused9", + "unused10", + "unused11", + "unused12", + "unused13", + "unused14", + "unused15", + "unused16", + "unused17", + "unused18", + "unused19", + "unused20", + "unused21", + "unused22", + "unused23", + "unused24", + "unused25", + "unused26", + "unused27", + "unused28", + "unused29", + "unused30", + "unused31", + "unused32", + "unused33", + "unused34", + "unused35", + "unused36", + "unused37", + "unused38", + "unused39", + "unused40", + "unused41", + "unused42", + "unused43", + "unused44", + "unused45", + "unused46", + "unused47", + "unused48", + "unused49", + "unused50", + "unused51", + "unused52", + "unused53", + "unused54", + "unused55", + "unused56", + "unused57", + "unused58", + "unused59", + "unused60", + "unused61", + "unused62", + "unused63", + "unused64", + "unused65", + "unused66", + "unused67", + "unused68", + "unused69", + "unused70", + "unused71", + "unused72", + "unused73", + "unused74", + "unused75", + "unused76", + "unused77", + "unused78", + "unused79", + "unused80", + "unused81", + "unused82", + "unused83", + "unused84", + "unused85", + "unused86", + "unused87", + "unused88", + "unused89", + "unused90", + "unused91", + "unused92", + "unused93", + "unused94", + "unused95", + "unused96", + "unused97", + "unused98", + "unused99", + "unused100", + "unused101", + "unused102", + "unused103", + "unused104", + "unused105", + "unused106", + "unused107", + "unused108", + "unused109", + "unused110", + "unused111", + "unused112", + "unused113", + "unused114", + "unused115", + "unused116", + "unused117", + "unused118", + "unused119", + "unused120", + "unused121", + "unused122", + "unused123", + "unused124", + "unused125", + "unused126", + "unused127", + "unused128", + "unused129", + "unused130", + "unused131", + "unused132", + "unused133", + "unused134", + "unused135", + "unused136", + "unused137", + "unused138", + "unused139", + "unused140", + "unused141", + "unused142", + "unused143", + "unused144", + "unused145", + "unused146", + "unused147", + "unused148", + "unused149", + "unused150", + "unused151", + "unused152", + "unused153", + "unused154", + "unused155", + "unused156", + "unused157", + "unused158", + "unused159", + "unused160", + "unused161", + "unused162", + "unused163", + "unused164", + "unused165", + "unused166", + "unused167", + "unused168", + "unused169", + "unused170", + "unused171", + "unused172", + "unused173", + "unused174", + "unused175", + "unused176", + "unused177", + "unused178", + "unused179", + "unused180", + "unused181", + "unused182", + "unused183", + "unused184", + "unused185", + "unused186", + "unused187", + "unused188", + "unused189", + "unused190", + "unused191", + "unused192", + "unused193", + "unused194", + "unused195", + "unused196", + "unused197", + "unused198", + "unused199", + "unused200", + "unused201", + "unused202", + "unused203", + "unused204", + "unused205", + "unused206", + "unused207", + "unused208", + "unused209", + "unused210", + "unused211", + "unused212", + "unused213", + "unused214", + "unused215", + "unused216", + "unused217", + "unused218", + "unused219", + "unused220", + "unused221", + "unused222", + "unused223", + "unused224", + "unused225", + "unused226", + "unused227", + "unused228", + "unused229", + "unused230", + "unused231", + "unused232", + "unused233", + "unused234", + "unused235", + "unused236", + "unused237", + "unused238", + "unused239", + "unused240", + "unused241", + "unused242", + "unused243", + "unused244", + "unused245", + "unused246", + "unused247", + "unused248", + "unused249", + "unused250", + "unused251", + "unused252", + "unused253", + "unused254", + "unused255" + ], + "type" : "string" + }, + "format" : { + "description" : "Target Format.", + "enum" : [ + "raw", + "qcow2", + "vmdk" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Target storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target-digest" : { + "description" : "Prevent changes if the current config file of the target VM has a different SHA1 digest. This can be used to detect concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target-disk" : { + "description" : "The config key the disk will be moved to on the target VM (for example, ide0 or scsi1). Default is the source disk key.", + "enum" : [ + "ide0", + "ide1", + "ide2", + "ide3", + "scsi0", + "scsi1", + "scsi2", + "scsi3", + "scsi4", + "scsi5", + "scsi6", + "scsi7", + "scsi8", + "scsi9", + "scsi10", + "scsi11", + "scsi12", + "scsi13", + "scsi14", + "scsi15", + "scsi16", + "scsi17", + "scsi18", + "scsi19", + "scsi20", + "scsi21", + "scsi22", + "scsi23", + "scsi24", + "scsi25", + "scsi26", + "scsi27", + "scsi28", + "scsi29", + "scsi30", + "virtio0", + "virtio1", + "virtio2", + "virtio3", + "virtio4", + "virtio5", + "virtio6", + "virtio7", + "virtio8", + "virtio9", + "virtio10", + "virtio11", + "virtio12", + "virtio13", + "virtio14", + "virtio15", + "sata0", + "sata1", + "sata2", + "sata3", + "sata4", + "sata5", + "efidisk0", + "tpmstate0", + "unused0", + "unused1", + "unused2", + "unused3", + "unused4", + "unused5", + "unused6", + "unused7", + "unused8", + "unused9", + "unused10", + "unused11", + "unused12", + "unused13", + "unused14", + "unused15", + "unused16", + "unused17", + "unused18", + "unused19", + "unused20", + "unused21", + "unused22", + "unused23", + "unused24", + "unused25", + "unused26", + "unused27", + "unused28", + "unused29", + "unused30", + "unused31", + "unused32", + "unused33", + "unused34", + "unused35", + "unused36", + "unused37", + "unused38", + "unused39", + "unused40", + "unused41", + "unused42", + "unused43", + "unused44", + "unused45", + "unused46", + "unused47", + "unused48", + "unused49", + "unused50", + "unused51", + "unused52", + "unused53", + "unused54", + "unused55", + "unused56", + "unused57", + "unused58", + "unused59", + "unused60", + "unused61", + "unused62", + "unused63", + "unused64", + "unused65", + "unused66", + "unused67", + "unused68", + "unused69", + "unused70", + "unused71", + "unused72", + "unused73", + "unused74", + "unused75", + "unused76", + "unused77", + "unused78", + "unused79", + "unused80", + "unused81", + "unused82", + "unused83", + "unused84", + "unused85", + "unused86", + "unused87", + "unused88", + "unused89", + "unused90", + "unused91", + "unused92", + "unused93", + "unused94", + "unused95", + "unused96", + "unused97", + "unused98", + "unused99", + "unused100", + "unused101", + "unused102", + "unused103", + "unused104", + "unused105", + "unused106", + "unused107", + "unused108", + "unused109", + "unused110", + "unused111", + "unused112", + "unused113", + "unused114", + "unused115", + "unused116", + "unused117", + "unused118", + "unused119", + "unused120", + "unused121", + "unused122", + "unused123", + "unused124", + "unused125", + "unused126", + "unused127", + "unused128", + "unused129", + "unused130", + "unused131", + "unused132", + "unused133", + "unused134", + "unused135", + "unused136", + "unused137", + "unused138", + "unused139", + "unused140", + "unused141", + "unused142", + "unused143", + "unused144", + "unused145", + "unused146", + "unused147", + "unused148", + "unused149", + "unused150", + "unused151", + "unused152", + "unused153", + "unused154", + "unused155", + "unused156", + "unused157", + "unused158", + "unused159", + "unused160", + "unused161", + "unused162", + "unused163", + "unused164", + "unused165", + "unused166", + "unused167", + "unused168", + "unused169", + "unused170", + "unused171", + "unused172", + "unused173", + "unused174", + "unused175", + "unused176", + "unused177", + "unused178", + "unused179", + "unused180", + "unused181", + "unused182", + "unused183", + "unused184", + "unused185", + "unused186", + "unused187", + "unused188", + "unused189", + "unused190", + "unused191", + "unused192", + "unused193", + "unused194", + "unused195", + "unused196", + "unused197", + "unused198", + "unused199", + "unused200", + "unused201", + "unused202", + "unused203", + "unused204", + "unused205", + "unused206", + "unused207", + "unused208", + "unused209", + "unused210", + "unused211", + "unused212", + "unused213", + "unused214", + "unused215", + "unused216", + "unused217", + "unused218", + "unused219", + "unused220", + "unused221", + "unused222", + "unused223", + "unused224", + "unused225", + "unused226", + "unused227", + "unused228", + "unused229", + "unused230", + "unused231", + "unused232", + "unused233", + "unused234", + "unused235", + "unused236", + "unused237", + "unused238", + "unused239", + "unused240", + "unused241", + "unused242", + "unused243", + "unused244", + "unused245", + "unused246", + "unused247", + "unused248", + "unused249", + "unused250", + "unused251", + "unused252", + "unused253", + "unused254", + "unused255" + ], + "optional" : 1, + "type" : "string" + }, + "target-vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ], + "description" : "You need 'VM.Config.Disk' permissions on /vms/{vmid}, and 'Datastore.AllocateSpace' permissions on the storage. To move a disk to another VM, you need the permissions on the target VM as well." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/move_disk", + "text" : "move_disk" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get preconditions for migration.", + "method" : "GET", + "name" : "migrate_vm_precondition", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "allowed_nodes" : { + "description" : "List of nodes allowed for migration.", + "items" : { + "description" : "An allowed node", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "dependent-ha-resources" : { + "description" : "HA resources, which will be migrated to the same target node as the VM, because these are in positive affinity with the VM.", + "items" : { + "description" : "The ':' resource IDs of a HA resource with a positive affinity rule to this VM.", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "has-dbus-vmstate" : { + "description" : "Whether the VM host supports migrating additional VM state, such as conntrack entries.", + "type" : "boolean" + }, + "local_disks" : { + "description" : "List local disks including CD-Rom, unused and not referenced disks", + "items" : { + "properties" : { + "cdrom" : { + "description" : "True if the disk is a cdrom.", + "type" : "boolean" + }, + "is_unused" : { + "description" : "True if the disk is unused.", + "type" : "boolean" + }, + "size" : { + "description" : "The size of the disk in bytes.", + "type" : "integer" + }, + "volid" : { + "description" : "The volid of the disk.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "local_resources" : { + "description" : "List local resources (e.g. pci, usb) that block migration.", + "items" : { + "description" : "A local resource", + "type" : "string" + }, + "type" : "array" + }, + "mapped-resource-info" : { + "description" : "Object of mapped resources with additional information such if they're live migratable.", + "type" : "object" + }, + "mapped-resources" : { + "description" : "List of mapped resources e.g. pci, usb. Deprecated, use 'mapped-resource-info' instead.", + "items" : { + "description" : "A mapped resource", + "type" : "string" + }, + "type" : "array" + }, + "not_allowed_nodes" : { + "description" : "List of not allowed nodes with additional information.", + "optional" : 1, + "properties" : { + "blocking-ha-resources" : { + "description" : "HA resources, which are blocking the VM from being migrated to the node.", + "items" : { + "description" : "A blocking HA resource", + "properties" : { + "cause" : { + "description" : "The reason why the HA resource is blocking the migration.", + "enum" : [ + "node-affinity", + "resource-affinity" + ], + "type" : "string" + }, + "sid" : { + "description" : "The blocking HA resource id", + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "unavailable_storages" : { + "description" : "A list of not available storages.", + "items" : { + "description" : "A storage", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + }, + "running" : { + "description" : "Determines if the VM is running.", + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Migrate virtual machine. Creates a new migration task.", + "method" : "POST", + "name" : "migrate_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "migrate limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "force" : { + "description" : "Allow to migrate VMs which use local devices. Only root may use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "migration_network" : { + "description" : "CIDR of the (sub) network that is used for migration.", + "format" : "CIDR", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "migration_type" : { + "description" : "Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.", + "enum" : [ + "secure", + "insecure" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "online" : { + "description" : "Use online/live migration if VM is running. Ignored if VM is stopped.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "targetstorage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storage-pair-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "with-conntrack-state" : { + "default" : 0, + "description" : "Whether to migrate conntrack entries for running VMs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "with-local-disks" : { + "description" : "Enable live storage migration for local disk", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/migrate", + "text" : "migrate" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migrate virtual machine to a remote cluster. Creates a new migration task. EXPERIMENTAL feature!", + "method" : "POST", + "name" : "remote_migrate_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "migrate limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "delete" : { + "default" : 0, + "description" : "Delete the original VM and related data after successful migration. By default the original VM is kept on the source cluster in a stopped state.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "online" : { + "description" : "Use online/live migration if VM is running. Ignored if VM is stopped.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target-bridge" : { + "description" : "Mapping from source to target bridges. Providing only a single bridge ID maps all source bridges to that bridge. Providing the special value '1' will map each source bridge to itself.", + "format" : "bridge-pair-list", + "type" : "string", + "typetext" : "" + }, + "target-endpoint" : { + "description" : "Remote target endpoint", + "format" : "proxmox-remote", + "type" : "string", + "typetext" : "apitoken= ,host=
[,fingerprint=] [,port=]" + }, + "target-storage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storage-pair-list", + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "target-vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/remote_migrate", + "text" : "remote_migrate" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute QEMU monitor commands.", + "method" : "POST", + "name" : "monitor", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "command" : { + "description" : "The monitor command.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ], + "description" : "The following commands do not require any additional privilege: ?, help, info\n\nThe following commands require 'Sys.Modify': announce_self, backup_cancel, balloon, block_job_cancel, block_job_complete, block_job_pause, block_job_resume, block_job_set_speed, block_resize, block_set_io_throttle, boot_set, c, calc_dirty_rate, cancel_vcpu_dirty_limit, chardev-send-break, closefd, commit, cont, cpu, delvm, eject, exit_preconfig, expire_password, getfd, gpa2hpa, gpa2hva, gva2gpa, i, loadvm, log, migrate_cancel, migrate_continue, migrate_pause, migrate_set_capability, migrate_set_parameter, migrate_start_postcopy, mouse_button, mouse_move, mouse_set, one-insn-per-tb, p, print, q, qemu-io, qom-get, qom-list, quit, replay_break, replay_delete_break, replay_seek, ringbuf_read, ringbuf_write, s, savevm, sendkey, set_link, set_password, set_vcpu_dirty_limit, snapshot_blkdev_internal, snapshot_delete_blkdev_internal, stop, stopcapture, sum, sync-profile, system_powerdown, system_reset, system_wakeup, trace-event, x, x_colo_lost_heartbeat, xp\n\nThe following commands are root-only: backup, block_stream, change, chardev-add, chardev-change, chardev-remove, client_migrate_info, device_add, device_del, drive_add, drive_backup, drive_del, drive_mirror, dump-guest-memory, dumpdtb, gdbserver, hostfwd_add, hostfwd_remove, logfile, mce, memsave, migrate, migrate_incoming, migrate_recover, nbd_server_add, nbd_server_remove, nbd_server_start, nbd_server_stop, netdev_add, netdev_del, nmi, o, object_add, object_del, pcie_aer_inject_error, pmemsave, qom-set, savevm-end, savevm-start, screendump, snapshot_blkdev, watchdog_action, wavcapture, xen-event-inject, xen-event-list\n\nThe following commands are deprecated: stopcapture, wavcapture\n" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/monitor", + "text" : "monitor" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Extend volume size.", + "method" : "PUT", + "name" : "resize_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disk" : { + "description" : "The disk you want to resize.", + "enum" : [ + "ide0", + "ide1", + "ide2", + "ide3", + "scsi0", + "scsi1", + "scsi2", + "scsi3", + "scsi4", + "scsi5", + "scsi6", + "scsi7", + "scsi8", + "scsi9", + "scsi10", + "scsi11", + "scsi12", + "scsi13", + "scsi14", + "scsi15", + "scsi16", + "scsi17", + "scsi18", + "scsi19", + "scsi20", + "scsi21", + "scsi22", + "scsi23", + "scsi24", + "scsi25", + "scsi26", + "scsi27", + "scsi28", + "scsi29", + "scsi30", + "virtio0", + "virtio1", + "virtio2", + "virtio3", + "virtio4", + "virtio5", + "virtio6", + "virtio7", + "virtio8", + "virtio9", + "virtio10", + "virtio11", + "virtio12", + "virtio13", + "virtio14", + "virtio15", + "sata0", + "sata1", + "sata2", + "sata3", + "sata4", + "sata5", + "efidisk0", + "tpmstate0" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "size" : { + "description" : "The new size. With the `+` sign the value is added to the actual size of the volume and without it, the value is taken as an absolute one. Shrinking disk size is not supported.", + "pattern" : "\\+?\\d+(\\.\\d+)?[KMGT]?", + "type" : "string" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/resize", + "text" : "resize" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get snapshot configuration", + "method" : "GET", + "name" : "get_snapshot_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback", + "VM.Audit" + ], + "any", + 1 + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update snapshot metadata.", + "method" : "PUT", + "name" : "update_snapshot_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A textual description or comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "text" : "config" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Rollback VM state to specified snapshot.", + "method" : "POST", + "name" : "rollback", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Whether the VM should get started after rolling back successfully. (Note: VMs will be automatically started if the snapshot includes RAM.)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback", + "text" : "rollback" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete a VM snapshot.", + "method" : "DELETE", + "name" : "delsnapshot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "For removal from config file, even if removing disk snapshots fails.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "snapshot_cmd_idx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{cmd}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "text" : "{snapname}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all snapshots.", + "method" : "GET", + "name" : "snapshot_list", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "description" : { + "description" : "Snapshot description.", + "type" : "string" + }, + "name" : { + "description" : "Snapshot identifier. Value 'current' identifies the current VM.", + "type" : "string" + }, + "parent" : { + "description" : "Parent snapshot identifier.", + "optional" : 1, + "type" : "string" + }, + "snaptime" : { + "description" : "Snapshot creation time", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "vmstate" : { + "description" : "Snapshot includes RAM.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Snapshot a VM.", + "method" : "POST", + "name" : "snapshot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A textual description or comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vmstate" : { + "description" : "Save the vmstate", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/snapshot", + "text" : "snapshot" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a Template.", + "method" : "POST", + "name" : "template", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "disk" : { + "description" : "If you want to convert only 1 disk to base image.", + "enum" : [ + "ide0", + "ide1", + "ide2", + "ide3", + "scsi0", + "scsi1", + "scsi2", + "scsi3", + "scsi4", + "scsi5", + "scsi6", + "scsi7", + "scsi8", + "scsi9", + "scsi10", + "scsi11", + "scsi12", + "scsi13", + "scsi14", + "scsi15", + "scsi16", + "scsi17", + "scsi18", + "scsi19", + "scsi20", + "scsi21", + "scsi22", + "scsi23", + "scsi24", + "scsi25", + "scsi26", + "scsi27", + "scsi28", + "scsi29", + "scsi30", + "virtio0", + "virtio1", + "virtio2", + "virtio3", + "virtio4", + "virtio5", + "virtio6", + "virtio7", + "virtio8", + "virtio9", + "virtio10", + "virtio11", + "virtio12", + "virtio13", + "virtio14", + "virtio15", + "sata0", + "sata1", + "sata2", + "sata3", + "sata4", + "sata5", + "efidisk0", + "tpmstate0" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + "description" : "You need 'VM.Allocate' permissions on /vms/{vmid}" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/template", + "text" : "template" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migration tunnel endpoint - only for internal use by VM migration.", + "method" : "POST", + "name" : "mtunnel", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bridges" : { + "description" : "List of network bridges to check availability. Will be checked again for actually used bridges during migration.", + "format" : "pve-bridge-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storages" : { + "description" : "List of storages to check permission and availability. Will be checked again for all actually used storages during migration.", + "format" : "pve-storage-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + [ + "perm", + "/", + [ + "Sys.Incoming" + ] + ] + ], + "description" : "You need 'VM.Allocate' permissions on '/vms/{vmid}' and Sys.Incoming on '/'. Further permission checks happen during the actual migration." + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "socket" : { + "type" : "string" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/mtunnel", + "text" : "mtunnel" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration.", + "method" : "GET", + "name" : "mtunnelwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "socket" : { + "description" : "unix socket to forward to", + "type" : "string", + "typetext" : "" + }, + "ticket" : { + "description" : "ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "description" : "You need to pass a ticket valid for the selected socket. Tickets can be created via the mtunnel API call, which will check permissions accordingly.", + "user" : "all" + }, + "returns" : { + "properties" : { + "port" : { + "optional" : 1, + "type" : "string" + }, + "socket" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/mtunnelwebsocket", + "text" : "mtunnelwebsocket" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Control the dbus-vmstate helper for a given running VM.", + "method" : "POST", + "name" : "dbus_vmstate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Action to perform on the DBus VMState helper.", + "enum" : [ + "start", + "stop" + ], + "optional" : 0, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/dbus-vmstate", + "text" : "dbus-vmstate" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy the VM and all used/owned volumes. Removes any VM specific permissions and firewall rules", + "method" : "DELETE", + "name" : "destroy_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "destroy-unreferenced-disks" : { + "default" : 0, + "description" : "If set, destroy additionally all disks not referenced in the config but with a matching VMID from all enabled storages.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "purge" : { + "description" : "Remove VMID from configurations, like backup & replication jobs and HA.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "vmdiridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}", + "text" : "{vmid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Virtual machine index (per node).", + "method" : "GET", + "name" : "vmlist", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "full" : { + "description" : "Determine the full status of active VMs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list VMs where you have VM.Audit permissions on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "cpu" : { + "description" : "Current CPU usage.", + "optional" : 1, + "type" : "number" + }, + "cpus" : { + "description" : "Maximum usable CPUs.", + "optional" : 1, + "type" : "number" + }, + "diskread" : { + "description" : "The amount of bytes the guest read from it's block devices since the guest was started. (Note: This info is not available for all storage types.)", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "diskwrite" : { + "description" : "The amount of bytes the guest wrote from it's block devices since the guest was started. (Note: This info is not available for all storage types.)", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "lock" : { + "description" : "The current config lock, if any.", + "optional" : 1, + "type" : "string" + }, + "maxdisk" : { + "description" : "Root disk size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Maximum memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "mem" : { + "description" : "Currently used memory in bytes. Does not take into account kernel same-page merging (KSM). Uses information from ballooning when available.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "memhost" : { + "description" : "Current memory usage on the host. Does not take into account kernel same-page merging (KSM).", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "VM (host)name.", + "optional" : 1, + "type" : "string" + }, + "netin" : { + "description" : "The amount of traffic in bytes that was sent to the guest over the network since it was started.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "netout" : { + "description" : "The amount of traffic in bytes that was sent from the guest over the network since it was started.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "pid" : { + "description" : "PID of the QEMU process, if the VM is running.", + "optional" : 1, + "type" : "integer" + }, + "pressurecpufull" : { + "description" : "CPU Full pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressurecpusome" : { + "description" : "CPU Some pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressureiofull" : { + "description" : "IO Full pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressureiosome" : { + "description" : "IO Some pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressurememoryfull" : { + "description" : "Memory Full pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressurememorysome" : { + "description" : "Memory Some pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "qmpstatus" : { + "description" : "VM run state from the 'query-status' QMP monitor command.", + "optional" : 1, + "type" : "string" + }, + "running-machine" : { + "description" : "The currently running machine type (if running).", + "optional" : 1, + "type" : "string" + }, + "running-qemu" : { + "description" : "The QEMU version the VM is currently using (if running).", + "optional" : 1, + "type" : "string" + }, + "serial" : { + "description" : "Guest has serial device configured.", + "optional" : 1, + "type" : "boolean" + }, + "status" : { + "description" : "QEMU process status.", + "enum" : [ + "stopped", + "running" + ], + "type" : "string" + }, + "tags" : { + "description" : "The current configured tags, if any", + "optional" : 1, + "type" : "string" + }, + "template" : { + "default" : 0, + "description" : "Determines if the guest is a template.", + "optional" : 1, + "type" : "boolean" + }, + "uptime" : { + "description" : "Uptime in seconds.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{vmid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create or restore a virtual machine.", + "method" : "POST", + "name" : "create_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acpi" : { + "default" : 1, + "description" : "Enable/disable ACPI.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "affinity" : { + "description" : "List of host cores used to execute guest processes, for example: 0,5,8-11", + "format" : "pve-cpuset", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "agent" : { + "description" : "Enable/disable communication with the QEMU Guest Agent and its properties.", + "format" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.", + "type" : "boolean" + }, + "freeze-fs" : { + "default" : 1, + "description" : "Freeze guest filesystems through QGA for consistent disk state on operations such as snapshots, backups, replications and clones.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Whether to issue the guest-fsfreeze-freeze and guest-fsfreeze-thaw QEMU guest agent commands. Backups in snapshot mode, clones, snapshots without RAM, importing disks from a running guest, and replications normally issue a guest-fsfreeze-freeze and a respective thaw command when the QEMU Guest agent option is enabled in the guest's configuration and the agent is running inside of the guest.\n\nThe deprecated 'freeze-fs-on-backup' setting is treated as an alias for this setting." + }, + "freeze-fs-on-backup" : { + "alias" : "freeze-fs" + }, + "fstrim_cloned_disks" : { + "default" : 0, + "description" : "Run fstrim after moving a disk or migrating the VM.", + "optional" : 1, + "type" : "boolean" + }, + "guest-fsfreeze" : { + "alias" : "freeze-fs" + }, + "type" : { + "default" : "virtio", + "description" : "Select the agent type", + "enum" : [ + "virtio", + "isa" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[enabled=]<1|0> [,freeze-fs=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]" + }, + "allow-ksm" : { + "default" : 1, + "description" : "Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "amd-sev" : { + "description" : "Secure Encrypted Virtualization (SEV) features by AMD CPUs", + "format" : "pve-qemu-sev-fmt", + "optional" : 1, + "type" : "string", + "typetext" : "[type=] [,allow-smt=<1|0>] [,kernel-hashes=<1|0>] [,no-debug=<1|0>] [,no-key-sharing=<1|0>]" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host architecture.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "archive" : { + "description" : "The backup archive. Either the file system path to a .tar or .vma file (use '-' to pipe data from stdin) or a proxmox storage backup volume identifier.", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "args" : { + "description" : "Arbitrary arguments passed to kvm.", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -smbios 'type=0,vendor=FOO'\n\nNOTE: this option is for experts only.\n" + }, + "audio0" : { + "description" : "Configure a audio device, useful in combination with QXL/Spice.", + "format" : { + "device" : { + "description" : "Configure an audio device.", + "enum" : [ + "ich9-intel-hda", + "intel-hda", + "AC97" + ], + "type" : "string" + }, + "driver" : { + "default" : "spice", + "description" : "Driver backend for the audio device.", + "enum" : [ + "spice", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "device= [,driver=]" + }, + "autostart" : { + "default" : 0, + "description" : "Automatic restart after crash (currently ignored).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "balloon" : { + "description" : "Amount of target RAM for the VM in MiB. The balloon driver is enabled by default, unless it is explicitly disabled by setting the value to zero.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "bios" : { + "default" : "seabios", + "description" : "Select BIOS implementation.", + "enum" : [ + "seabios", + "ovmf" + ], + "optional" : 1, + "type" : "string" + }, + "boot" : { + "description" : "Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.", + "format" : "pve-qm-boot", + "optional" : 1, + "type" : "string", + "typetext" : "[[legacy=]<[acdn]{1,4}>] [,order=]" + }, + "bootdisk" : { + "description" : "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format" : "pve-qm-bootdisk", + "optional" : 1, + "pattern" : "(ide|sata|scsi|virtio)\\d+", + "type" : "string" + }, + "bwlimit" : { + "default" : "restore limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "cdrom" : { + "description" : "This is an alias for option -ide2", + "format" : "pve-qm-ide", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cicustom" : { + "description" : "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format" : "pve-qm-cicustom", + "optional" : 1, + "type" : "string", + "typetext" : "[meta=] [,network=] [,user=] [,vendor=]" + }, + "cipassword" : { + "description" : "cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "citype" : { + "description" : "Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.", + "enum" : [ + "configdrive2", + "nocloud", + "opennebula" + ], + "optional" : 1, + "type" : "string" + }, + "ciupgrade" : { + "default" : 1, + "description" : "cloud-init: do an automatic package upgrade after the first boot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ciuser" : { + "description" : "cloud-init: User name to change ssh keys and password for instead of the image's configured default user.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cores" : { + "default" : 1, + "description" : "The number of cores per socket.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "cpu" : { + "description" : "Emulated CPU type.", + "format" : "pve-vm-cpu-conf", + "optional" : 1, + "type" : "string", + "typetext" : "[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,guest-phys-bits=] [,hidden=<1|0>] [,hv-vendor-id=] [,level=] [,phys-bits=<8-64|host>] [,reported-model=]" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 128)", + "verbose_description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit." + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 262144, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 262144)", + "verbose_description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs." + }, + "description" : { + "description" : "Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "efidisk0" : { + "description" : "Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "efitype" : { + "default" : "2m", + "description" : "Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarch64 (ARM).", + "enum" : [ + "2m", + "4m" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "ms-cert" : { + "default" : "2011", + "description" : "Informational marker indicating the version of the latest Microsoft UEFI certificates that have been enrolled by Proxmox VE. The value '2023k' means that the 'Microsoft UEFI CA 2023', the 'Windows UEFI CA 2023' and the 'Microsoft Corporation KEK 2K CA 2023' certificates are included. The values '2023' and '2023w' are deprecated and for compatibility only.", + "enum" : [ + "2011", + "2023", + "2023w", + "2023k" + ], + "optional" : 1, + "type" : "string" + }, + "pre-enrolled-keys" : { + "default" : 0, + "description" : "Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,ms-cert=] [,pre-enrolled-keys=<1|0>] [,size=]" + }, + "force" : { + "description" : "Allow to overwrite existing VM.", + "optional" : 1, + "requires" : "archive", + "type" : "boolean", + "typetext" : "" + }, + "freeze" : { + "description" : "Freeze CPU at startup (use 'c' monitor command to start execution).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ha-managed" : { + "default" : 0, + "description" : "Add the VM as a HA resource after it was created.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the vms lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostpci[n]" : { + "description" : "Map host PCI devices into guest.", + "format" : "pve-qm-hostpci", + "optional" : 1, + "type" : "string", + "typetext" : "[[host=]] [,device-id=] [,driver=] [,legacy-igd=<1|0>] [,mapping=] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]", + "verbose_description" : "Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "hotplug" : { + "default" : "network,disk,usb", + "description" : "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.", + "format" : "pve-hotplug-features", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hugepages" : { + "description" : "Enables hugepages memory.\n\nSets the size of hugepages in MiB. If the value is set to 'any' then 1 GiB hugepages will be used if possible, otherwise the size will fall back to 2 MiB.", + "enum" : [ + "any", + "2", + "1024" + ], + "optional" : 1, + "type" : "string" + }, + "ide[n]" : { + "description" : "Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "model" : { + "description" : "The drive's reported model name, url-encoded, up to 40 bytes long.", + "format" : "urlencoded", + "format_description" : "model", + "maxLength" : 120, + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,werror=] [,wwn=]" + }, + "import-working-storage" : { + "description" : "A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "intel-tdx" : { + "description" : "Trusted Domain Extension (TDX) features by Intel CPUs", + "format" : "pve-qemu-tdx-fmt", + "optional" : 1, + "type" : "string", + "typetext" : "[type=] ,attestation=<1|0> [,vsock-cid=] [,vsock-port=]" + }, + "ipconfig[n]" : { + "description" : "cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n", + "format" : "pve-qm-ipconfig", + "optional" : 1, + "type" : "string", + "typetext" : "[gw=] [,gw6=] [,ip=] [,ip6=]" + }, + "ivshmem" : { + "description" : "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + "format" : { + "name" : { + "description" : "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + "format_description" : "string", + "optional" : 1, + "pattern" : "[a-zA-Z0-9\\-]+", + "type" : "string" + }, + "size" : { + "description" : "The size of the file in MB.", + "minimum" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "size= [,name=]" + }, + "keephugepages" : { + "default" : 0, + "description" : "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "keyboard" : { + "default" : null, + "description" : "Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "kvm" : { + "default" : 1, + "description" : "Enable/disable KVM hardware virtualization.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "live-restore" : { + "description" : "Start the VM immediately while importing or restoring in the background.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "localtime" : { + "description" : "Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ], + "optional" : 1, + "type" : "string" + }, + "machine" : { + "description" : "Specify the QEMU machine.", + "format" : { + "aw-bits" : { + "description" : "Specifies the vIOMMU address space bit width.", + "maximum" : 64, + "minimum" : 32, + "optional" : 1, + "type" : "number", + "verbose_description" : "Specifies the vIOMMU address space bit width.\n\nIntel vIOMMU supports a bit width of either 39 or 48 bits and VirtIO vIOMMU supports any bit width between 32 and 64 bits." + }, + "enable-s3" : { + "description" : "Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "enable-s4" : { + "description" : "Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default_key" : 1, + "description" : "Specifies the QEMU machine type.", + "format_description" : "machine type", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "viommu" : { + "description" : "Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).", + "enum" : [ + "intel", + "virtio" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,aw-bits=] [,enable-s3=<1|0>] [,enable-s4=<1|0>] [,viommu=]" + }, + "memory" : { + "description" : "Memory properties.", + "format" : { + "current" : { + "default" : 512, + "default_key" : 1, + "description" : "Current amount of online RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.", + "minimum" : 16, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[current=]" + }, + "migrate_downtime" : { + "default" : 0.1, + "description" : "Set maximum tolerated downtime (in seconds) for migrations. Should the migration not be able to converge in the very end, because too much newly dirtied RAM needs to be transferred, the limit will be increased automatically step-by-step until migration can converge. Will be capped to 2000 seconds (maximum in QEMU).", + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "migrate_speed" : { + "default" : 0, + "description" : "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "name" : { + "description" : "Set a name for the VM. Only used on the configuration web interface.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nameserver" : { + "description" : "cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "format" : "address-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specify network devices.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n", + "format" : "pve-bridge-id", + "format_description" : "bridge", + "optional" : 1, + "type" : "string" + }, + "e1000" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82540em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82544gc" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82545em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000e" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "firewall" : { + "description" : "Whether this interface should be protected by the firewall.", + "optional" : 1, + "type" : "boolean" + }, + "i82551" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82557b" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82559er" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "macaddr" : { + "description" : "MAC address. That address must be unique within your network. This is automatically generated if not specified.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "model" : { + "default_key" : 1, + "description" : "Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.", + "enum" : [ + "e1000", + "e1000-82540em", + "e1000-82544gc", + "e1000-82545em", + "e1000e", + "i82551", + "i82557b", + "i82559er", + "ne2k_isa", + "ne2k_pci", + "pcnet", + "rtl8139", + "virtio", + "vmxnet3" + ], + "type" : "string" + }, + "mtu" : { + "description" : "Force MTU of network device (VirtIO only). Setting to '1' or empty will use the bridge MTU", + "maximum" : 65520, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "ne2k_isa" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "ne2k_pci" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "pcnet" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "queues" : { + "description" : "Number of packet queues to be used on the device.", + "maximum" : 64, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "rtl8139" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "tag" : { + "description" : "VLAN tag to apply to packets on this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN trunks to pass through this interface.", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "virtio" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "vmxnet3" : { + "alias" : "macaddr", + "keyAlias" : "model" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "numa" : { + "default" : 0, + "description" : "Enable/disable NUMA.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "numa[n]" : { + "description" : "NUMA topology.", + "format" : { + "cpus" : { + "description" : "CPUs accessing this NUMA node.", + "format_description" : "id[-id];...", + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "hostnodes" : { + "description" : "Host NUMA nodes to use.", + "format_description" : "id[-id];...", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "memory" : { + "description" : "Amount of memory this NUMA node provides.", + "optional" : 1, + "type" : "number" + }, + "policy" : { + "description" : "NUMA allocation policy.", + "enum" : [ + "preferred", + "bind", + "interleave" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "cpus= [,hostnodes=] [,memory=] [,policy=]" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostype" : { + "default" : "other", + "description" : "Specify guest operating system.", + "enum" : [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "win11", + "l24", + "l26", + "solaris" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022/2025\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 7.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n" + }, + "parallel[n]" : { + "description" : "Map host parallel devices (n is 0 to 2).", + "optional" : 1, + "pattern" : "/dev/parport\\d+|/dev/usb/lp\\d+", + "type" : "string", + "verbose_description" : "Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "pool" : { + "description" : "Add the VM to the specified pool.", + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "reboot" : { + "default" : 1, + "description" : "Allow reboot. If set to '0' the VM exit on reboot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "rng0" : { + "description" : "Configure a VirtIO-based Random Number Generator.", + "format" : "pve-qm-rng", + "optional" : 1, + "type" : "string", + "typetext" : "[source=] [,max_bytes=] [,period=]" + }, + "sata[n]" : { + "description" : "Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,werror=] [,wwn=]" + }, + "scsi[n]" : { + "description" : "Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "product" : { + "description" : "The drive's product name, up to 16 bytes long.", + "format_description" : "product", + "optional" : 1, + "pattern" : "[A-Za-z0-9\\-_\\s]{,16}", + "type" : "string" + }, + "queues" : { + "description" : "Number of queues.", + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "scsiblock" : { + "default" : 0, + "description" : "whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host", + "optional" : 1, + "type" : "boolean" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "vendor" : { + "description" : "The drive's vendor name, up to 8 bytes long.", + "format_description" : "vendor", + "optional" : 1, + "pattern" : "[A-Za-z0-9\\-_\\s]{,8}", + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,product=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,vendor=] [,werror=] [,wwn=]" + }, + "scsihw" : { + "default" : "lsi", + "description" : "SCSI controller model", + "enum" : [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "serial[n]" : { + "description" : "Create a serial device inside the VM (n is 0 to 3)", + "optional" : 1, + "pattern" : "(/dev/[^,]+|socket)", + "type" : "string", + "verbose_description" : "Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "shares" : { + "default" : 1000, + "description" : "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.", + "maximum" : 50000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 50000)" + }, + "smbios1" : { + "description" : "Specify SMBIOS type 1 fields.", + "format" : "pve-qm-smbios1", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]" + }, + "smp" : { + "default" : 1, + "description" : "The number of CPUs. Please use option -sockets instead.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "sockets" : { + "default" : 1, + "description" : "The number of CPU sockets.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "spice_enhancements" : { + "description" : "Configure additional enhancements for SPICE.", + "format" : { + "foldersharing" : { + "default" : "0", + "description" : "Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.", + "optional" : 1, + "type" : "boolean" + }, + "videostreaming" : { + "default" : "off", + "description" : "Enable video streaming. Uses compression for detected video streams.", + "enum" : [ + "off", + "all", + "filter" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[foldersharing=<1|0>] [,videostreaming=]" + }, + "sshkeys" : { + "description" : "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format" : "urlencoded", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Start VM after it was created successfully.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "startdate" : { + "default" : "now", + "description" : "Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.", + "optional" : 1, + "pattern" : "(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)", + "type" : "string", + "typetext" : "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "storage" : { + "description" : "Default storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tablet" : { + "default" : 1, + "description" : "Enable/disable the USB tablet device.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)." + }, + "tags" : { + "description" : "Tags of the VM. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tdf" : { + "default" : 0, + "description" : "Enable/disable time drift fix.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tpmstate0" : { + "description" : "Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "Format of the image.", + "enum" : [ + "raw", + "qcow2", + "vmdk" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "version" : { + "default" : "v1.2", + "description" : "The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.", + "enum" : [ + "v1.2", + "v2.0" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,format=] [,import-from=] [,size=] [,version=]" + }, + "unique" : { + "description" : "Assign a unique random ethernet address.", + "optional" : 1, + "requires" : "archive", + "type" : "boolean", + "typetext" : "" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=]" + }, + "usb[n]" : { + "description" : "Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).", + "format" : { + "host" : { + "default_key" : 1, + "description" : "The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadecimal numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n\nEither this or the 'mapping' key must be set.\n", + "format_description" : "HOSTUSBDEVICE|spice", + "optional" : 1, + "pattern" : "(?^:(?:(?:(?^:(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})))|(?:(?^:(\\d+)\\-(\\d+(\\.\\d+)*)))|[Ss][Pp][Ii][Cc][Ee]))", + "type" : "string" + }, + "mapping" : { + "description" : "The ID of a cluster wide mapping. Either this or the default-key 'host' must be set.", + "format" : "pve-configid", + "format_description" : "mapping-id", + "optional" : 1, + "type" : "string" + }, + "usb3" : { + "default" : 0, + "description" : "Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[host=]] [,mapping=] [,usb3=<1|0>]" + }, + "vcpus" : { + "default" : 0, + "description" : "Number of hotplugged vcpus.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vga" : { + "description" : "Configure the VGA hardware.", + "format" : { + "clipboard" : { + "description" : "Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Live migration with a VNC clipboard is not possible with QEMU machine version < 10.1.", + "enum" : [ + "vnc" + ], + "optional" : 1, + "type" : "string" + }, + "memory" : { + "description" : "Sets the VGA memory (in MiB). Has no effect with serial display.", + "maximum" : 512, + "minimum" : 4, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "default" : "std", + "default_key" : 1, + "description" : "Select the VGA type. Using type 'cirrus' is not recommended.", + "enum" : [ + "cirrus", + "qxl", + "qxl2", + "qxl3", + "qxl4", + "none", + "serial0", + "serial1", + "serial2", + "serial3", + "std", + "virtio", + "virtio-gl", + "vmware" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,clipboard=] [,memory=]", + "verbose_description" : "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal." + }, + "virtio[n]" : { + "description" : "Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,werror=]" + }, + "virtiofs[n]" : { + "description" : "Configuration for sharing a directory between host and guest using Virtio-fs.", + "format" : { + "cache" : { + "default" : "auto", + "description" : "The caching policy the file system should use (auto, always, metadata, never).", + "enum" : [ + "auto", + "always", + "metadata", + "never" + ], + "optional" : 1, + "type" : "string" + }, + "direct-io" : { + "default" : 0, + "description" : "Honor the O_DIRECT flag passed down by guest applications.", + "optional" : 1, + "type" : "boolean" + }, + "dirid" : { + "default_key" : 1, + "description" : "Mapping identifier of the directory mapping to be shared with the guest. Also used as a mount tag inside the VM.", + "format" : "pve-configid", + "format_description" : "mapping-id", + "type" : "string" + }, + "expose-acl" : { + "default" : 0, + "description" : "Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.", + "optional" : 1, + "type" : "boolean" + }, + "expose-xattr" : { + "default" : 0, + "description" : "Enable support for extended attributes for this mount.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[dirid=] [,cache=] [,direct-io=<1|0>] [,expose-acl=<1|0>] [,expose-xattr=<1|0>]" + }, + "vmgenid" : { + "default" : "1 (autogenerated)", + "description" : "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "format_description" : "UUID", + "optional" : 1, + "pattern" : "(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])", + "type" : "string", + "verbose_description" : "The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file." + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vmstatestorage" : { + "description" : "Default storage for VM state volumes/files.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "watchdog" : { + "description" : "Create a virtual hardware watchdog device.", + "format" : "pve-qm-watchdog", + "optional" : 1, + "type" : "string", + "typetext" : "[[model=]] [,action=]", + "verbose_description" : "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)" + } + } + }, + "permissions" : { + "description" : "You need 'VM.Allocate' permissions on /vms/{vmid} or on the VM pool /pool/{pool}. For restore (option 'archive'), it is enough if the user has 'VM.Backup' permission and the VM already exists. If you create disks you need 'Datastore.AllocateSpace' on any used storage.If you use a bridge/vlan, you need 'SDN.Use' on any used bridge/vlan.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu", + "text" : "qemu" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get container configuration.", + "method" : "GET", + "name" : "vm_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "current" : { + "default" : 0, + "description" : "Get current values (instead of pending values).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapshot" : { + "description" : "Fetch config values from given snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "arch" : { + "default" : "amd64", + "description" : "OS architecture type.", + "enum" : [ + "amd64", + "i386", + "arm64", + "armhf", + "riscv32", + "riscv64" + ], + "optional" : 1, + "type" : "string" + }, + "cmode" : { + "default" : "tty", + "description" : "Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).", + "enum" : [ + "shell", + "console", + "tty" + ], + "optional" : 1, + "type" : "string" + }, + "console" : { + "default" : 1, + "description" : "Attach a console device (/dev/console) to the container.", + "optional" : 1, + "type" : "boolean" + }, + "cores" : { + "description" : "The number of cores assigned to the container. A container can use all available cores by default.", + "maximum" : 8192, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.", + "maximum" : 8192, + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 500000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "verbose_description" : "CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests." + }, + "debug" : { + "default" : 0, + "description" : "Try to be more verbose. For now this only enables debug log-level on start.", + "optional" : 1, + "type" : "boolean" + }, + "description" : { + "description" : "Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string" + }, + "dev[n]" : { + "description" : "Device to pass through to the container", + "format" : { + "deny-write" : { + "default" : 0, + "description" : "Deny the container to write to the device", + "optional" : 1, + "type" : "boolean" + }, + "gid" : { + "description" : "Group ID to be assigned to the device node", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "mode" : { + "description" : "Access mode to be set on the device node", + "format_description" : "Octal access mode", + "optional" : 1, + "pattern" : "0[0-7]{3}", + "type" : "string" + }, + "path" : { + "default_key" : 1, + "description" : "Device to pass through to the container", + "format" : "pve-lxc-dev-string", + "format_description" : "Path", + "optional" : 1, + "type" : "string", + "verbose_description" : "Path to the device to pass through to the container" + }, + "uid" : { + "description" : "User ID to be assigned to the device node", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "SHA1 digest of configuration file. This can be used to prevent concurrent modifications.", + "type" : "string" + }, + "entrypoint" : { + "default" : "/sbin/init", + "description" : "Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH.", + "optional" : 1, + "pattern" : "(?^:[^\\x00-\\x08\\x0a-\\x1F\\x7F]+)", + "type" : "string" + }, + "env" : { + "description" : "The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config.", + "optional" : 1, + "pattern" : "(?^:(?:\\w+=[^\\x00-\\x08\\x0a-\\x1F\\x7F]*)(?:\\0\\w+=[^\\x00-\\x08\\x0a-\\x1F\\x7F]*)*)", + "type" : "string" + }, + "features" : { + "description" : "Allow containers access to advanced features.", + "format" : { + "force_rw_sys" : { + "default" : 0, + "description" : "Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.", + "optional" : 1, + "type" : "boolean" + }, + "fuse" : { + "default" : 0, + "description" : "Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.", + "optional" : 1, + "type" : "boolean" + }, + "keyctl" : { + "default" : 0, + "description" : "For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.", + "optional" : 1, + "type" : "boolean" + }, + "mknod" : { + "default" : 0, + "description" : "Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.", + "optional" : 1, + "type" : "boolean" + }, + "mount" : { + "description" : "Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.", + "format_description" : "fstype;fstype;...", + "optional" : 1, + "pattern" : "(?^:[a-zA-Z0-9_; ]+)", + "type" : "string" + }, + "nesting" : { + "default" : 0, + "description" : "Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest. This is also required by systemd to isolate services.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the containers lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string" + }, + "hostname" : { + "description" : "Set a host name for the container.", + "format" : "dns-name", + "maxLength" : 255, + "optional" : 1, + "type" : "string" + }, + "lock" : { + "description" : "Lock/unlock the container.", + "enum" : [ + "backup", + "create", + "destroyed", + "disk", + "fstrim", + "migrate", + "mounted", + "rollback", + "snapshot", + "snapshot-delete" + ], + "optional" : 1, + "type" : "string" + }, + "lxc" : { + "description" : "Array of lxc low-level configurations ([[key1, value1], [key2, value2] ...]).", + "items" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "optional" : 1, + "type" : "array" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the container in MB.", + "minimum" : 16, + "optional" : 1, + "type" : "integer" + }, + "mp[n]" : { + "description" : "Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "backup" : { + "description" : "Whether to include the mount point in backups.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Whether to include the mount point in backups (only used for volume mount points)." + }, + "idmap" : { + "description" : "Map specific container UIDs/GIDs to underlying disk UIDs/GIDs for this mount point", + "format_description" : "type:container:disk:range-size[;type:container:disk:range-size;...]", + "optional" : 1, + "pattern" : "(?^:^(?:passthrough|[ug]:[0-9]+:[0-9]+:[1-9][0-9]*(?:;[ug]:[0-9]+:[0-9]+:[1-9][0-9]*)*)$)", + "type" : "string", + "verbose_description" : "Customize UID/GID mappings that override the container's `lxc.idmap` for this mount point. Accepts a semicolon-separated list of `type:container:disk:range-size` entries.\n\n`type` is `u` for UID or `g` for GID.\n\n`container` is the first ID as seen inside the container.\n\n`disk` is the first corresponding ID on the underlying filesystem.\n\n`range-size` is the number of consecutive IDs to map.\n\nUnmapped IDs fall back to the container's `lxc.idmap`.\n\nExample 1: `u:123:456:1` maps UID 123 in the container to UID 456 on the disk. Files owned by UID 456 on the disk will appear as UID 123 inside the container.\n\nExample 2: `g:100:50:5` maps 5 consecutive GIDs, such that GIDs 100-104 in the container are mapped to GIDs 50-54 on the disk.\n\nExample 3: `passthrough` identity-maps all UIDs and GIDs, meaning IDs inside the container will match the IDs on the disk." + }, + "keepattrs" : { + "default" : 0, + "description" : "Inherit ownership and permissions from the mount point directory.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Inherit UID, GID and access mode from the mount point directory, if it exists already." + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)", + "type" : "string" + }, + "mp" : { + "description" : "Path to the mount point as seen from inside the container (must not contain symlinks).", + "format" : "pve-lxc-mp-string", + "format_description" : "Path", + "type" : "string", + "verbose_description" : "Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons." + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "nameserver" : { + "description" : "Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "lxc-ip-with-ll-iface-list", + "optional" : 1, + "type" : "string" + }, + "net[n]" : { + "description" : "Specifies network interfaces for the container.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to.", + "format_description" : "bridge", + "optional" : 1, + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "firewall" : { + "description" : "Controls whether this interface's firewall rules should be used.", + "optional" : 1, + "type" : "boolean" + }, + "gw" : { + "description" : "Default gateway for IPv4 traffic.", + "format" : "ipv4", + "format_description" : "GatewayIPv4", + "optional" : 1, + "type" : "string" + }, + "gw6" : { + "description" : "Default gateway for IPv6 traffic.", + "format" : "ipv6", + "format_description" : "GatewayIPv6", + "optional" : 1, + "type" : "string" + }, + "host-managed" : { + "description" : "Whether this interface's IP configuration should be managed by the host. When enabled, the host (rather than the container) is responsible for the interface's IP configuration. The container should not run its own DHCP client or network manager on this interface. This is useful for containers that lack an internal network management stack, like many application containers.", + "optional" : 1, + "type" : "boolean" + }, + "hwaddr" : { + "description" : "The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "ip" : { + "description" : "IPv4 address in CIDR format.", + "format" : "pve-ipv4-config", + "format_description" : "(IPv4/CIDR|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address in CIDR format.", + "format" : "pve-ipv6-config", + "format_description" : "(IPv6/CIDR|auto|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "mtu" : { + "description" : "Maximum transfer unit of the interface. (lxc.network.mtu)", + "maximum" : 65535, + "minimum" : 64, + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "Name of the network device as seen from inside the container. (lxc.network.name)", + "format_description" : "string", + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "rate" : { + "description" : "Apply rate limiting to the interface", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "tag" : { + "description" : "VLAN tag for this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN ids to pass through the interface", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:;\\d+)*)", + "type" : "string" + }, + "type" : { + "description" : "Network interface type.", + "enum" : [ + "veth" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a container will be started during system bootup.", + "optional" : 1, + "type" : "boolean" + }, + "ostype" : { + "description" : "OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.", + "enum" : [ + "debian", + "devuan", + "ubuntu", + "centos", + "fedora", + "opensuse", + "archlinux", + "alpine", + "gentoo", + "nixos", + "unmanaged" + ], + "optional" : 1, + "type" : "string" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.", + "optional" : 1, + "type" : "boolean" + }, + "rootfs" : { + "description" : "Use volume as container root.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "idmap" : { + "description" : "Map specific container UIDs/GIDs to underlying disk UIDs/GIDs for this mount point", + "format_description" : "type:container:disk:range-size[;type:container:disk:range-size;...]", + "optional" : 1, + "pattern" : "(?^:^(?:passthrough|[ug]:[0-9]+:[0-9]+:[1-9][0-9]*(?:;[ug]:[0-9]+:[0-9]+:[1-9][0-9]*)*)$)", + "type" : "string", + "verbose_description" : "Customize UID/GID mappings that override the container's `lxc.idmap` for this mount point. Accepts a semicolon-separated list of `type:container:disk:range-size` entries.\n\n`type` is `u` for UID or `g` for GID.\n\n`container` is the first ID as seen inside the container.\n\n`disk` is the first corresponding ID on the underlying filesystem.\n\n`range-size` is the number of consecutive IDs to map.\n\nUnmapped IDs fall back to the container's `lxc.idmap`.\n\nExample 1: `u:123:456:1` maps UID 123 in the container to UID 456 on the disk. Files owned by UID 456 on the disk will appear as UID 123 inside the container.\n\nExample 2: `g:100:50:5` maps 5 consecutive GIDs, such that GIDs 100-104 in the container are mapped to GIDs 50-54 on the disk.\n\nExample 3: `passthrough` identity-maps all UIDs and GIDs, meaning IDs inside the container will match the IDs on the disk." + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)", + "type" : "string" + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "dns-name-list", + "optional" : 1, + "type" : "string" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "swap" : { + "default" : 512, + "description" : "Amount of SWAP for the container in MB.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "tags" : { + "description" : "Tags of the Container. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean" + }, + "timezone" : { + "description" : "Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab", + "format" : "pve-ct-timezone", + "optional" : 1, + "type" : "string" + }, + "tty" : { + "default" : 2, + "description" : "Specify the number of tty available to the container", + "maximum" : 6, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "unprivileged" : { + "default" : 0, + "description" : "Makes the container run as unprivileged user. For creation, the default is 1. For restore, the default is the value from the backup. (Should not be modified manually.)", + "optional" : 1, + "type" : "boolean" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "volume" : { + "default_key" : 1, + "description" : "The volume that is not used currently.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set container options.", + "method" : "PUT", + "name" : "update_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "arch" : { + "default" : "amd64", + "description" : "OS architecture type.", + "enum" : [ + "amd64", + "i386", + "arm64", + "armhf", + "riscv32", + "riscv64" + ], + "optional" : 1, + "type" : "string" + }, + "cmode" : { + "default" : "tty", + "description" : "Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).", + "enum" : [ + "shell", + "console", + "tty" + ], + "optional" : 1, + "type" : "string" + }, + "console" : { + "default" : 1, + "description" : "Attach a console device (/dev/console) to the container.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cores" : { + "description" : "The number of cores assigned to the container. A container can use all available cores by default.", + "maximum" : 8192, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 8192)" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.", + "maximum" : 8192, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 8192)" + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 500000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 500000)", + "verbose_description" : "CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests." + }, + "debug" : { + "default" : 0, + "description" : "Try to be more verbose. For now this only enables debug log-level on start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dev[n]" : { + "description" : "Device to pass through to the container", + "format" : { + "deny-write" : { + "default" : 0, + "description" : "Deny the container to write to the device", + "optional" : 1, + "type" : "boolean" + }, + "gid" : { + "description" : "Group ID to be assigned to the device node", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "mode" : { + "description" : "Access mode to be set on the device node", + "format_description" : "Octal access mode", + "optional" : 1, + "pattern" : "0[0-7]{3}", + "type" : "string" + }, + "path" : { + "default_key" : 1, + "description" : "Device to pass through to the container", + "format" : "pve-lxc-dev-string", + "format_description" : "Path", + "optional" : 1, + "type" : "string", + "verbose_description" : "Path to the device to pass through to the container" + }, + "uid" : { + "description" : "User ID to be assigned to the device node", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[path=]] [,deny-write=<1|0>] [,gid=] [,mode=] [,uid=]" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "entrypoint" : { + "default" : "/sbin/init", + "description" : "Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH.", + "optional" : 1, + "pattern" : "(?^:[^\\x00-\\x08\\x0a-\\x1F\\x7F]+)", + "type" : "string" + }, + "env" : { + "description" : "The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config.", + "optional" : 1, + "pattern" : "(?^:(?:\\w+=[^\\x00-\\x08\\x0a-\\x1F\\x7F]*)(?:\\0\\w+=[^\\x00-\\x08\\x0a-\\x1F\\x7F]*)*)", + "type" : "string" + }, + "features" : { + "description" : "Allow containers access to advanced features.", + "format" : { + "force_rw_sys" : { + "default" : 0, + "description" : "Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.", + "optional" : 1, + "type" : "boolean" + }, + "fuse" : { + "default" : 0, + "description" : "Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.", + "optional" : 1, + "type" : "boolean" + }, + "keyctl" : { + "default" : 0, + "description" : "For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.", + "optional" : 1, + "type" : "boolean" + }, + "mknod" : { + "default" : 0, + "description" : "Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.", + "optional" : 1, + "type" : "boolean" + }, + "mount" : { + "description" : "Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.", + "format_description" : "fstype;fstype;...", + "optional" : 1, + "pattern" : "(?^:[a-zA-Z0-9_; ]+)", + "type" : "string" + }, + "nesting" : { + "default" : 0, + "description" : "Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest. This is also required by systemd to isolate services.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[force_rw_sys=<1|0>] [,fuse=<1|0>] [,keyctl=<1|0>] [,mknod=<1|0>] [,mount=] [,nesting=<1|0>]" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the containers lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostname" : { + "description" : "Set a host name for the container.", + "format" : "dns-name", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the container.", + "enum" : [ + "backup", + "create", + "destroyed", + "disk", + "fstrim", + "migrate", + "mounted", + "rollback", + "snapshot", + "snapshot-delete" + ], + "optional" : 1, + "type" : "string" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the container in MB.", + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - N)" + }, + "mp[n]" : { + "description" : "Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "backup" : { + "description" : "Whether to include the mount point in backups.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Whether to include the mount point in backups (only used for volume mount points)." + }, + "idmap" : { + "description" : "Map specific container UIDs/GIDs to underlying disk UIDs/GIDs for this mount point", + "format_description" : "type:container:disk:range-size[;type:container:disk:range-size;...]", + "optional" : 1, + "pattern" : "(?^:^(?:passthrough|[ug]:[0-9]+:[0-9]+:[1-9][0-9]*(?:;[ug]:[0-9]+:[0-9]+:[1-9][0-9]*)*)$)", + "type" : "string", + "verbose_description" : "Customize UID/GID mappings that override the container's `lxc.idmap` for this mount point. Accepts a semicolon-separated list of `type:container:disk:range-size` entries.\n\n`type` is `u` for UID or `g` for GID.\n\n`container` is the first ID as seen inside the container.\n\n`disk` is the first corresponding ID on the underlying filesystem.\n\n`range-size` is the number of consecutive IDs to map.\n\nUnmapped IDs fall back to the container's `lxc.idmap`.\n\nExample 1: `u:123:456:1` maps UID 123 in the container to UID 456 on the disk. Files owned by UID 456 on the disk will appear as UID 123 inside the container.\n\nExample 2: `g:100:50:5` maps 5 consecutive GIDs, such that GIDs 100-104 in the container are mapped to GIDs 50-54 on the disk.\n\nExample 3: `passthrough` identity-maps all UIDs and GIDs, meaning IDs inside the container will match the IDs on the disk." + }, + "keepattrs" : { + "default" : 0, + "description" : "Inherit ownership and permissions from the mount point directory.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Inherit UID, GID and access mode from the mount point directory, if it exists already." + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)", + "type" : "string" + }, + "mp" : { + "description" : "Path to the mount point as seen from inside the container (must not contain symlinks).", + "format" : "pve-lxc-mp-string", + "format_description" : "Path", + "type" : "string", + "verbose_description" : "Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons." + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=] ,mp= [,acl=<1|0>] [,backup=<1|0>] [,idmap=] [,keepattrs=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]" + }, + "nameserver" : { + "description" : "Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "lxc-ip-with-ll-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specifies network interfaces for the container.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to.", + "format_description" : "bridge", + "optional" : 1, + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "firewall" : { + "description" : "Controls whether this interface's firewall rules should be used.", + "optional" : 1, + "type" : "boolean" + }, + "gw" : { + "description" : "Default gateway for IPv4 traffic.", + "format" : "ipv4", + "format_description" : "GatewayIPv4", + "optional" : 1, + "type" : "string" + }, + "gw6" : { + "description" : "Default gateway for IPv6 traffic.", + "format" : "ipv6", + "format_description" : "GatewayIPv6", + "optional" : 1, + "type" : "string" + }, + "host-managed" : { + "description" : "Whether this interface's IP configuration should be managed by the host. When enabled, the host (rather than the container) is responsible for the interface's IP configuration. The container should not run its own DHCP client or network manager on this interface. This is useful for containers that lack an internal network management stack, like many application containers.", + "optional" : 1, + "type" : "boolean" + }, + "hwaddr" : { + "description" : "The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "ip" : { + "description" : "IPv4 address in CIDR format.", + "format" : "pve-ipv4-config", + "format_description" : "(IPv4/CIDR|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address in CIDR format.", + "format" : "pve-ipv6-config", + "format_description" : "(IPv6/CIDR|auto|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "mtu" : { + "description" : "Maximum transfer unit of the interface. (lxc.network.mtu)", + "maximum" : 65535, + "minimum" : 64, + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "Name of the network device as seen from inside the container. (lxc.network.name)", + "format_description" : "string", + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "rate" : { + "description" : "Apply rate limiting to the interface", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "tag" : { + "description" : "VLAN tag for this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN ids to pass through the interface", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:;\\d+)*)", + "type" : "string" + }, + "type" : { + "description" : "Network interface type.", + "enum" : [ + "veth" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "name= [,bridge=] [,firewall=<1|0>] [,gw=] [,gw6=] [,host-managed=<1|0>] [,hwaddr=] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=<(IPv6/CIDR|auto|dhcp|manual)>] [,link_down=<1|0>] [,mtu=] [,rate=] [,tag=] [,trunks=] [,type=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a container will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostype" : { + "description" : "OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.", + "enum" : [ + "debian", + "devuan", + "ubuntu", + "centos", + "fedora", + "opensuse", + "archlinux", + "alpine", + "gentoo", + "nixos", + "unmanaged" + ], + "optional" : 1, + "type" : "string" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "revert" : { + "description" : "Revert a pending change.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rootfs" : { + "description" : "Use volume as container root.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "idmap" : { + "description" : "Map specific container UIDs/GIDs to underlying disk UIDs/GIDs for this mount point", + "format_description" : "type:container:disk:range-size[;type:container:disk:range-size;...]", + "optional" : 1, + "pattern" : "(?^:^(?:passthrough|[ug]:[0-9]+:[0-9]+:[1-9][0-9]*(?:;[ug]:[0-9]+:[0-9]+:[1-9][0-9]*)*)$)", + "type" : "string", + "verbose_description" : "Customize UID/GID mappings that override the container's `lxc.idmap` for this mount point. Accepts a semicolon-separated list of `type:container:disk:range-size` entries.\n\n`type` is `u` for UID or `g` for GID.\n\n`container` is the first ID as seen inside the container.\n\n`disk` is the first corresponding ID on the underlying filesystem.\n\n`range-size` is the number of consecutive IDs to map.\n\nUnmapped IDs fall back to the container's `lxc.idmap`.\n\nExample 1: `u:123:456:1` maps UID 123 in the container to UID 456 on the disk. Files owned by UID 456 on the disk will appear as UID 123 inside the container.\n\nExample 2: `g:100:50:5` maps 5 consecutive GIDs, such that GIDs 100-104 in the container are mapped to GIDs 50-54 on the disk.\n\nExample 3: `passthrough` identity-maps all UIDs and GIDs, meaning IDs inside the container will match the IDs on the disk." + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)", + "type" : "string" + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=] [,acl=<1|0>] [,idmap=] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]" + }, + "searchdomain" : { + "description" : "Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "dns-name-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "swap" : { + "default" : 512, + "description" : "Amount of SWAP for the container in MB.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "tags" : { + "description" : "Tags of the Container. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "timezone" : { + "description" : "Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab", + "format" : "pve-ct-timezone", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tty" : { + "default" : 2, + "description" : "Specify the number of tty available to the container", + "maximum" : 6, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 6)" + }, + "unprivileged" : { + "default" : 0, + "description" : "Makes the container run as unprivileged user. For creation, the default is 1. For restore, the default is the value from the backup. (Should not be modified manually.)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "volume" : { + "default_key" : 1, + "description" : "The volume that is not used currently.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=]" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk", + "VM.Config.CPU", + "VM.Config.Memory", + "VM.Config.Network", + "VM.Config.Options" + ], + "any", + 1 + ], + "description" : "non-volume mount points in rootfs and mp[n] are restricted to root@pam" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/config", + "text" : "config" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get virtual machine status.", + "method" : "GET", + "name" : "vm_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "cpu" : { + "description" : "Current CPU usage.", + "optional" : 1, + "type" : "number" + }, + "cpus" : { + "description" : "Maximum usable CPUs.", + "optional" : 1, + "type" : "number" + }, + "disk" : { + "description" : "Root disk image space-usage in bytes.", + "minimum" : 0, + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "diskread" : { + "description" : "The amount of bytes the guest read from it's block devices since the guest was started. (Note: This info is not available for all storage types.)", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "diskwrite" : { + "description" : "The amount of bytes the guest wrote from it's block devices since the guest was started. (Note: This info is not available for all storage types.)", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "ha" : { + "description" : "HA manager service status.", + "type" : "object" + }, + "lock" : { + "description" : "The current config lock, if any.", + "optional" : 1, + "type" : "string" + }, + "maxdisk" : { + "description" : "Root disk image size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Maximum memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxswap" : { + "description" : "Maximum SWAP memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "mem" : { + "description" : "Currently used memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "Container name.", + "optional" : 1, + "type" : "string" + }, + "netin" : { + "description" : "The amount of traffic in bytes that was sent to the guest over the network since it was started.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "netout" : { + "description" : "The amount of traffic in bytes that was sent from the guest over the network since it was started.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "pressurecpusome" : { + "description" : "CPU Some pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressureiofull" : { + "description" : "IO Full pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressureiosome" : { + "description" : "IO Some pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressurememoryfull" : { + "description" : "Memory Full pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressurememorysome" : { + "description" : "Memory Some pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "status" : { + "description" : "LXC Container status.", + "enum" : [ + "stopped", + "running" + ], + "type" : "string" + }, + "tags" : { + "description" : "The current configured tags, if any.", + "optional" : 1, + "type" : "string" + }, + "template" : { + "default" : 0, + "description" : "Determines if the guest is a template.", + "optional" : 1, + "type" : "boolean" + }, + "uptime" : { + "description" : "Uptime in seconds.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/current", + "text" : "current" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start the container.", + "method" : "POST", + "name" : "vm_start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "debug" : { + "default" : 0, + "description" : "If set, enables very verbose debug log-level on start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop the container. This will abruptly stop all processes running in the container.", + "method" : "POST", + "name" : "vm_stop", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "overrule-shutdown" : { + "default" : 0, + "description" : "Try to abort active 'vzshutdown' tasks before stopping.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/stop", + "text" : "stop" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Shutdown the container. This will trigger a clean shutdown of the container, see lxc-stop(1) for details.", + "method" : "POST", + "name" : "vm_shutdown", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "forceStop" : { + "default" : 0, + "description" : "Make sure the Container stops.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 60, + "description" : "Wait maximal timeout seconds.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/shutdown", + "text" : "shutdown" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Suspend the container. This is experimental.", + "method" : "POST", + "name" : "vm_suspend", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/suspend", + "text" : "suspend" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Resume the container.", + "method" : "POST", + "name" : "vm_resume", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/resume", + "text" : "resume" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Reboot the container by shutting it down, and starting it again. Applies pending changes.", + "method" : "POST", + "name" : "vm_reboot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "description" : "Wait maximal timeout seconds for the shutdown.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/reboot", + "text" : "reboot" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "vmcmdidx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/status", + "text" : "status" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Rollback LXC state to specified snapshot.", + "method" : "POST", + "name" : "rollback", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Whether the container should get started after rolling back successfully", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback", + "text" : "rollback" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get snapshot configuration", + "method" : "GET", + "name" : "get_snapshot_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback", + "VM.Audit" + ], + "any", + 1 + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update snapshot metadata.", + "method" : "PUT", + "name" : "update_snapshot_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A textual description or comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "text" : "config" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete a LXC snapshot.", + "method" : "DELETE", + "name" : "delsnapshot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "For removal from config file, even if removing disk snapshots fails.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "snapshot_cmd_idx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{cmd}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "text" : "{snapname}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all snapshots.", + "method" : "GET", + "name" : "list", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "description" : { + "description" : "Snapshot description.", + "type" : "string" + }, + "name" : { + "description" : "Snapshot identifier. Value 'current' identifies the current VM.", + "type" : "string" + }, + "parent" : { + "description" : "Parent snapshot identifier.", + "optional" : 1, + "type" : "string" + }, + "snaptime" : { + "description" : "Snapshot creation time", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Snapshot a container.", + "method" : "POST", + "name" : "snapshot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A textual description or comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/snapshot", + "text" : "snapshot" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment", + "optional" : 1, + "type" : "string" + }, + "dest" : { + "description" : "Restrict packet destination address", + "optional" : 1, + "type" : "string" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port", + "optional" : 1, + "type" : "string" + }, + "enable" : { + "description" : "Flag to enable/disable a rule", + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers", + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "description" : "IP version (4 or 6) - automatically determined from source/dest addresses", + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro", + "optional" : 1, + "type" : "string" + }, + "pos" : { + "description" : "Rule position in the ruleset", + "type" : "integer" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "Restrict packet source address", + "optional" : 1, + "type" : "string" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Rule type", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment", + "optional" : 1, + "type" : "string" + }, + "dest" : { + "description" : "Restrict packet destination address", + "optional" : 1, + "type" : "string" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port", + "optional" : 1, + "type" : "string" + }, + "enable" : { + "description" : "Flag to enable/disable a rule", + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers", + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "description" : "IP version (4 or 6) - automatically determined from source/dest addresses", + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro", + "optional" : 1, + "type" : "string" + }, + "pos" : { + "description" : "Rule position in the ruleset", + "type" : "integer" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "Restrict packet source address", + "optional" : 1, + "type" : "string" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Rule type", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 0, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/rules", + "text" : "rules" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network alias.", + "method" : "DELETE", + "name" : "remove_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read alias.", + "method" : "GET", + "name" : "read_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network alias.", + "method" : "PUT", + "name" : "update_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "rename" : { + "description" : "Rename an existing alias.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List aliases", + "method" : "GET", + "name" : "get_aliases", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create IP or Network Alias.", + "method" : "POST", + "name" : "create_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/aliases", + "text" : "aliases" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network from IPSet.", + "method" : "DELETE", + "name" : "remove_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read IP or Network settings from IPSet.", + "method" : "GET", + "name" : "read_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network settings", + "method" : "PUT", + "name" : "update_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "text" : "{cidr}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete IPSet", + "method" : "DELETE", + "name" : "delete_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "Delete all members of the IPSet, if there are any.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List IPSet content", + "method" : "GET", + "name" : "get_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{cidr}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add IP or Network to IPSet.", + "method" : "POST", + "name" : "create_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List IPSets", + "method" : "GET", + "name" : "ipset_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new IPSet", + "method" : "POST", + "name" : "create_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "rename" : { + "description" : "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/ipset", + "text" : "ipset" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get VM firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "dhcp" : { + "default" : 0, + "description" : "Enable DHCP.", + "optional" : 1, + "type" : "boolean" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean" + }, + "ipfilter" : { + "description" : "Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.", + "optional" : 1, + "type" : "boolean" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macfilter" : { + "default" : 1, + "description" : "Enable/disable MAC address filter.", + "optional" : 1, + "type" : "boolean" + }, + "ndp" : { + "default" : 1, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "radv" : { + "description" : "Allow sending Router Advertisement.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp" : { + "default" : 0, + "description" : "Enable DHCP.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ipfilter" : { + "description" : "Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macfilter" : { + "default" : 1, + "description" : "Enable/disable MAC address filter.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ndp" : { + "default" : 1, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "radv" : { + "description" : "Allow sending Router Advertisement.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read firewall log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display log since this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "until" : { + "description" : "Display log until this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Lists possible IPSet/Alias reference which are allowed in source/dest properties.", + "method" : "GET", + "name" : "refs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Only list references of specified type.", + "enum" : [ + "alias", + "ipset" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "ref" : { + "type" : "string" + }, + "scope" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "alias", + "ipset" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/refs", + "text" : "refs" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall", + "text" : "firewall" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read VM RRD statistics (returns PNG)", + "method" : "GET", + "name" : "rrd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "ds" : { + "description" : "The list of datasources you want to display.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "filename" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/rrd", + "text" : "rrd" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read VM RRD statistics", + "method" : "GET", + "name" : "rrddata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/rrddata", + "text" : "rrddata" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a TCP VNC proxy connections.", + "method" : "POST", + "name" : "vncproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "height" : { + "description" : "sets the height of the console in pixels.", + "maximum" : 2160, + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - 2160)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "websocket" : { + "description" : "use websocket instead of standard VNC.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "width" : { + "description" : "sets the width of the console in pixels.", + "maximum" : 4096, + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - 4096)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "cert" : { + "type" : "string" + }, + "password" : { + "description" : "Password used for authentication within the VNC protocol. Consists of printable ASCII characters ('!' .. '~').", + "optional" : 1, + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/vncproxy", + "text" : "vncproxy" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a TCP proxy connection.", + "method" : "POST", + "name" : "termproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/termproxy", + "text" : "termproxy" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Opens a websocket for VNC traffic.", + "method" : "GET", + "name" : "vncwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Port number returned by previous vncproxy call.", + "maximum" : 5999, + "minimum" : 5900, + "type" : "integer", + "typetext" : " (5900 - 5999)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vncticket" : { + "description" : "Ticket from previous call to vncproxy.", + "maxLength" : 512, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ], + "description" : "You also need to pass a valid ticket (vncticket)." + }, + "returns" : { + "properties" : { + "port" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/vncwebsocket", + "text" : "vncwebsocket" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Returns a SPICE configuration to connect to the CT.", + "method" : "POST", + "name" : "spiceproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "proxy" : { + "description" : "SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).", + "format" : "address", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 1, + "description" : "Returned values can be directly passed to the 'remote-viewer' application.", + "properties" : { + "host" : { + "type" : "string" + }, + "password" : { + "type" : "string" + }, + "proxy" : { + "type" : "string" + }, + "tls-port" : { + "type" : "integer" + }, + "type" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/spiceproxy", + "text" : "spiceproxy" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migrate the container to another cluster. Creates a new migration task. EXPERIMENTAL feature!", + "method" : "POST", + "name" : "remote_migrate_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "migrate limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "delete" : { + "default" : 0, + "description" : "Delete the original CT and related data after successful migration. By default the original CT is kept on the source cluster in a stopped state.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "online" : { + "description" : "Use online/live migration.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restart" : { + "description" : "Use restart migration", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target-bridge" : { + "description" : "Mapping from source to target bridges. Providing only a single bridge ID maps all source bridges to that bridge. Providing the special value '1' will map each source bridge to itself.", + "format" : "bridge-pair-list", + "type" : "string", + "typetext" : "" + }, + "target-endpoint" : { + "description" : "Remote target endpoint", + "format" : "proxmox-remote", + "type" : "string", + "typetext" : "apitoken= ,host=
[,fingerprint=] [,port=]" + }, + "target-storage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storage-pair-list", + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "target-vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "timeout" : { + "default" : 180, + "description" : "Timeout in seconds for shutdown for restart migration", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/remote_migrate", + "text" : "remote_migrate" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get preconditions for migration.", + "method" : "GET", + "name" : "migrate_vm_precondition", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "allowed-nodes" : { + "description" : "List of nodes allowed for migration.", + "items" : { + "description" : "An allowed node", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "dependent-ha-resources" : { + "description" : "HA resources, which will be migrated to the same target node as the VM, because these are in positive affinity with the VM.", + "items" : { + "description" : "The ':' resource IDs of a HA resource with a positive affinity rule to this CT.", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "not-allowed-nodes" : { + "description" : "List of not allowed nodes with additional information.", + "optional" : 1, + "properties" : { + "blocking-ha-resources" : { + "description" : "HA resources, which are blocking the container from being migrated to the node.", + "items" : { + "description" : "A blocking HA resource", + "properties" : { + "cause" : { + "description" : "The reason why the HA resource is blocking the migration.", + "enum" : [ + "node-affinity", + "resource-affinity" + ], + "type" : "string" + }, + "sid" : { + "description" : "The blocking HA resource id", + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + }, + "running" : { + "description" : "Determines if the container is running.", + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Migrate the container to another node. Creates a new migration task.", + "method" : "POST", + "name" : "migrate_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "migrate limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "online" : { + "description" : "Use online/live migration.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restart" : { + "description" : "Use restart migration", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "target-storage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storage-pair-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 180, + "description" : "Timeout in seconds for shutdown for restart migration", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/migrate", + "text" : "migrate" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Check if feature for virtual machine is available.", + "method" : "GET", + "name" : "vm_feature", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "feature" : { + "description" : "Feature to check.", + "enum" : [ + "snapshot", + "clone", + "copy" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "hasFeature" : { + "type" : "boolean" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/feature", + "text" : "feature" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a Template.", + "method" : "POST", + "name" : "template", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + "description" : "You need 'VM.Allocate' permissions on /vms/{vmid}" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/template", + "text" : "template" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a container clone/copy", + "method" : "POST", + "name" : "clone_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "clone limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "description" : { + "description" : "Description for the new CT.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "full" : { + "description" : "Create a full copy of all disks. This is always done when you clone a normal CT. For CT templates, we try to create a linked clone by default.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hostname" : { + "description" : "Set a hostname for the new CT.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "newid" : { + "description" : "VMID for the clone.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Add the new CT to the specified pool.", + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Target storage for full clone.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node. Only allowed if the original VM is on shared storage.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/vms/{vmid}", + [ + "VM.Clone" + ] + ], + [ + "or", + [ + "perm", + "/vms/{newid}", + [ + "VM.Allocate" + ] + ], + [ + "perm", + "/pool/{pool}", + [ + "VM.Allocate" + ], + "require_param", + "pool" + ] + ] + ], + "description" : "You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions on /vms/{newid} (or on the VM pool /pool/{pool}). You also need 'Datastore.AllocateSpace' on any used storage, and 'SDN.Use' on any bridge." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/clone", + "text" : "clone" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Resize a container mount point.", + "method" : "PUT", + "name" : "resize_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disk" : { + "description" : "The disk you want to resize.", + "enum" : [ + "rootfs", + "mp0", + "mp1", + "mp2", + "mp3", + "mp4", + "mp5", + "mp6", + "mp7", + "mp8", + "mp9", + "mp10", + "mp11", + "mp12", + "mp13", + "mp14", + "mp15", + "mp16", + "mp17", + "mp18", + "mp19", + "mp20", + "mp21", + "mp22", + "mp23", + "mp24", + "mp25", + "mp26", + "mp27", + "mp28", + "mp29", + "mp30", + "mp31", + "mp32", + "mp33", + "mp34", + "mp35", + "mp36", + "mp37", + "mp38", + "mp39", + "mp40", + "mp41", + "mp42", + "mp43", + "mp44", + "mp45", + "mp46", + "mp47", + "mp48", + "mp49", + "mp50", + "mp51", + "mp52", + "mp53", + "mp54", + "mp55", + "mp56", + "mp57", + "mp58", + "mp59", + "mp60", + "mp61", + "mp62", + "mp63", + "mp64", + "mp65", + "mp66", + "mp67", + "mp68", + "mp69", + "mp70", + "mp71", + "mp72", + "mp73", + "mp74", + "mp75", + "mp76", + "mp77", + "mp78", + "mp79", + "mp80", + "mp81", + "mp82", + "mp83", + "mp84", + "mp85", + "mp86", + "mp87", + "mp88", + "mp89", + "mp90", + "mp91", + "mp92", + "mp93", + "mp94", + "mp95", + "mp96", + "mp97", + "mp98", + "mp99", + "mp100", + "mp101", + "mp102", + "mp103", + "mp104", + "mp105", + "mp106", + "mp107", + "mp108", + "mp109", + "mp110", + "mp111", + "mp112", + "mp113", + "mp114", + "mp115", + "mp116", + "mp117", + "mp118", + "mp119", + "mp120", + "mp121", + "mp122", + "mp123", + "mp124", + "mp125", + "mp126", + "mp127", + "mp128", + "mp129", + "mp130", + "mp131", + "mp132", + "mp133", + "mp134", + "mp135", + "mp136", + "mp137", + "mp138", + "mp139", + "mp140", + "mp141", + "mp142", + "mp143", + "mp144", + "mp145", + "mp146", + "mp147", + "mp148", + "mp149", + "mp150", + "mp151", + "mp152", + "mp153", + "mp154", + "mp155", + "mp156", + "mp157", + "mp158", + "mp159", + "mp160", + "mp161", + "mp162", + "mp163", + "mp164", + "mp165", + "mp166", + "mp167", + "mp168", + "mp169", + "mp170", + "mp171", + "mp172", + "mp173", + "mp174", + "mp175", + "mp176", + "mp177", + "mp178", + "mp179", + "mp180", + "mp181", + "mp182", + "mp183", + "mp184", + "mp185", + "mp186", + "mp187", + "mp188", + "mp189", + "mp190", + "mp191", + "mp192", + "mp193", + "mp194", + "mp195", + "mp196", + "mp197", + "mp198", + "mp199", + "mp200", + "mp201", + "mp202", + "mp203", + "mp204", + "mp205", + "mp206", + "mp207", + "mp208", + "mp209", + "mp210", + "mp211", + "mp212", + "mp213", + "mp214", + "mp215", + "mp216", + "mp217", + "mp218", + "mp219", + "mp220", + "mp221", + "mp222", + "mp223", + "mp224", + "mp225", + "mp226", + "mp227", + "mp228", + "mp229", + "mp230", + "mp231", + "mp232", + "mp233", + "mp234", + "mp235", + "mp236", + "mp237", + "mp238", + "mp239", + "mp240", + "mp241", + "mp242", + "mp243", + "mp244", + "mp245", + "mp246", + "mp247", + "mp248", + "mp249", + "mp250", + "mp251", + "mp252", + "mp253", + "mp254", + "mp255" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "size" : { + "description" : "The new size. With the '+' sign the value is added to the actual size of the volume and without it, the value is taken as an absolute one. Shrinking disk size is not supported.", + "pattern" : "\\+?\\d+(\\.\\d+)?[KMGT]?", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/resize", + "text" : "resize" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Move a rootfs-/mp-volume to a different storage or to a different container.", + "method" : "POST", + "name" : "move_volume", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "clone limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "delete" : { + "default" : 0, + "description" : "Delete the original volume after successful copy. By default the original is kept as an unused volume entry.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 \" .\n\t\t \"digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Target Storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target-digest" : { + "description" : "Prevent changes if current configuration file of the target \" .\n\t\t \"container has a different SHA1 digest. This can be used to prevent \" .\n\t\t \"concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target-vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "target-volume" : { + "description" : "The config key the volume will be moved to. Default is the source volume key.", + "enum" : [ + "rootfs", + "mp0", + "mp1", + "mp2", + "mp3", + "mp4", + "mp5", + "mp6", + "mp7", + "mp8", + "mp9", + "mp10", + "mp11", + "mp12", + "mp13", + "mp14", + "mp15", + "mp16", + "mp17", + "mp18", + "mp19", + "mp20", + "mp21", + "mp22", + "mp23", + "mp24", + "mp25", + "mp26", + "mp27", + "mp28", + "mp29", + "mp30", + "mp31", + "mp32", + "mp33", + "mp34", + "mp35", + "mp36", + "mp37", + "mp38", + "mp39", + "mp40", + "mp41", + "mp42", + "mp43", + "mp44", + "mp45", + "mp46", + "mp47", + "mp48", + "mp49", + "mp50", + "mp51", + "mp52", + "mp53", + "mp54", + "mp55", + "mp56", + "mp57", + "mp58", + "mp59", + "mp60", + "mp61", + "mp62", + "mp63", + "mp64", + "mp65", + "mp66", + "mp67", + "mp68", + "mp69", + "mp70", + "mp71", + "mp72", + "mp73", + "mp74", + "mp75", + "mp76", + "mp77", + "mp78", + "mp79", + "mp80", + "mp81", + "mp82", + "mp83", + "mp84", + "mp85", + "mp86", + "mp87", + "mp88", + "mp89", + "mp90", + "mp91", + "mp92", + "mp93", + "mp94", + "mp95", + "mp96", + "mp97", + "mp98", + "mp99", + "mp100", + "mp101", + "mp102", + "mp103", + "mp104", + "mp105", + "mp106", + "mp107", + "mp108", + "mp109", + "mp110", + "mp111", + "mp112", + "mp113", + "mp114", + "mp115", + "mp116", + "mp117", + "mp118", + "mp119", + "mp120", + "mp121", + "mp122", + "mp123", + "mp124", + "mp125", + "mp126", + "mp127", + "mp128", + "mp129", + "mp130", + "mp131", + "mp132", + "mp133", + "mp134", + "mp135", + "mp136", + "mp137", + "mp138", + "mp139", + "mp140", + "mp141", + "mp142", + "mp143", + "mp144", + "mp145", + "mp146", + "mp147", + "mp148", + "mp149", + "mp150", + "mp151", + "mp152", + "mp153", + "mp154", + "mp155", + "mp156", + "mp157", + "mp158", + "mp159", + "mp160", + "mp161", + "mp162", + "mp163", + "mp164", + "mp165", + "mp166", + "mp167", + "mp168", + "mp169", + "mp170", + "mp171", + "mp172", + "mp173", + "mp174", + "mp175", + "mp176", + "mp177", + "mp178", + "mp179", + "mp180", + "mp181", + "mp182", + "mp183", + "mp184", + "mp185", + "mp186", + "mp187", + "mp188", + "mp189", + "mp190", + "mp191", + "mp192", + "mp193", + "mp194", + "mp195", + "mp196", + "mp197", + "mp198", + "mp199", + "mp200", + "mp201", + "mp202", + "mp203", + "mp204", + "mp205", + "mp206", + "mp207", + "mp208", + "mp209", + "mp210", + "mp211", + "mp212", + "mp213", + "mp214", + "mp215", + "mp216", + "mp217", + "mp218", + "mp219", + "mp220", + "mp221", + "mp222", + "mp223", + "mp224", + "mp225", + "mp226", + "mp227", + "mp228", + "mp229", + "mp230", + "mp231", + "mp232", + "mp233", + "mp234", + "mp235", + "mp236", + "mp237", + "mp238", + "mp239", + "mp240", + "mp241", + "mp242", + "mp243", + "mp244", + "mp245", + "mp246", + "mp247", + "mp248", + "mp249", + "mp250", + "mp251", + "mp252", + "mp253", + "mp254", + "mp255", + "unused0", + "unused1", + "unused2", + "unused3", + "unused4", + "unused5", + "unused6", + "unused7", + "unused8", + "unused9", + "unused10", + "unused11", + "unused12", + "unused13", + "unused14", + "unused15", + "unused16", + "unused17", + "unused18", + "unused19", + "unused20", + "unused21", + "unused22", + "unused23", + "unused24", + "unused25", + "unused26", + "unused27", + "unused28", + "unused29", + "unused30", + "unused31", + "unused32", + "unused33", + "unused34", + "unused35", + "unused36", + "unused37", + "unused38", + "unused39", + "unused40", + "unused41", + "unused42", + "unused43", + "unused44", + "unused45", + "unused46", + "unused47", + "unused48", + "unused49", + "unused50", + "unused51", + "unused52", + "unused53", + "unused54", + "unused55", + "unused56", + "unused57", + "unused58", + "unused59", + "unused60", + "unused61", + "unused62", + "unused63", + "unused64", + "unused65", + "unused66", + "unused67", + "unused68", + "unused69", + "unused70", + "unused71", + "unused72", + "unused73", + "unused74", + "unused75", + "unused76", + "unused77", + "unused78", + "unused79", + "unused80", + "unused81", + "unused82", + "unused83", + "unused84", + "unused85", + "unused86", + "unused87", + "unused88", + "unused89", + "unused90", + "unused91", + "unused92", + "unused93", + "unused94", + "unused95", + "unused96", + "unused97", + "unused98", + "unused99", + "unused100", + "unused101", + "unused102", + "unused103", + "unused104", + "unused105", + "unused106", + "unused107", + "unused108", + "unused109", + "unused110", + "unused111", + "unused112", + "unused113", + "unused114", + "unused115", + "unused116", + "unused117", + "unused118", + "unused119", + "unused120", + "unused121", + "unused122", + "unused123", + "unused124", + "unused125", + "unused126", + "unused127", + "unused128", + "unused129", + "unused130", + "unused131", + "unused132", + "unused133", + "unused134", + "unused135", + "unused136", + "unused137", + "unused138", + "unused139", + "unused140", + "unused141", + "unused142", + "unused143", + "unused144", + "unused145", + "unused146", + "unused147", + "unused148", + "unused149", + "unused150", + "unused151", + "unused152", + "unused153", + "unused154", + "unused155", + "unused156", + "unused157", + "unused158", + "unused159", + "unused160", + "unused161", + "unused162", + "unused163", + "unused164", + "unused165", + "unused166", + "unused167", + "unused168", + "unused169", + "unused170", + "unused171", + "unused172", + "unused173", + "unused174", + "unused175", + "unused176", + "unused177", + "unused178", + "unused179", + "unused180", + "unused181", + "unused182", + "unused183", + "unused184", + "unused185", + "unused186", + "unused187", + "unused188", + "unused189", + "unused190", + "unused191", + "unused192", + "unused193", + "unused194", + "unused195", + "unused196", + "unused197", + "unused198", + "unused199", + "unused200", + "unused201", + "unused202", + "unused203", + "unused204", + "unused205", + "unused206", + "unused207", + "unused208", + "unused209", + "unused210", + "unused211", + "unused212", + "unused213", + "unused214", + "unused215", + "unused216", + "unused217", + "unused218", + "unused219", + "unused220", + "unused221", + "unused222", + "unused223", + "unused224", + "unused225", + "unused226", + "unused227", + "unused228", + "unused229", + "unused230", + "unused231", + "unused232", + "unused233", + "unused234", + "unused235", + "unused236", + "unused237", + "unused238", + "unused239", + "unused240", + "unused241", + "unused242", + "unused243", + "unused244", + "unused245", + "unused246", + "unused247", + "unused248", + "unused249", + "unused250", + "unused251", + "unused252", + "unused253", + "unused254", + "unused255" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "volume" : { + "description" : "Volume which will be moved.", + "enum" : [ + "rootfs", + "mp0", + "mp1", + "mp2", + "mp3", + "mp4", + "mp5", + "mp6", + "mp7", + "mp8", + "mp9", + "mp10", + "mp11", + "mp12", + "mp13", + "mp14", + "mp15", + "mp16", + "mp17", + "mp18", + "mp19", + "mp20", + "mp21", + "mp22", + "mp23", + "mp24", + "mp25", + "mp26", + "mp27", + "mp28", + "mp29", + "mp30", + "mp31", + "mp32", + "mp33", + "mp34", + "mp35", + "mp36", + "mp37", + "mp38", + "mp39", + "mp40", + "mp41", + "mp42", + "mp43", + "mp44", + "mp45", + "mp46", + "mp47", + "mp48", + "mp49", + "mp50", + "mp51", + "mp52", + "mp53", + "mp54", + "mp55", + "mp56", + "mp57", + "mp58", + "mp59", + "mp60", + "mp61", + "mp62", + "mp63", + "mp64", + "mp65", + "mp66", + "mp67", + "mp68", + "mp69", + "mp70", + "mp71", + "mp72", + "mp73", + "mp74", + "mp75", + "mp76", + "mp77", + "mp78", + "mp79", + "mp80", + "mp81", + "mp82", + "mp83", + "mp84", + "mp85", + "mp86", + "mp87", + "mp88", + "mp89", + "mp90", + "mp91", + "mp92", + "mp93", + "mp94", + "mp95", + "mp96", + "mp97", + "mp98", + "mp99", + "mp100", + "mp101", + "mp102", + "mp103", + "mp104", + "mp105", + "mp106", + "mp107", + "mp108", + "mp109", + "mp110", + "mp111", + "mp112", + "mp113", + "mp114", + "mp115", + "mp116", + "mp117", + "mp118", + "mp119", + "mp120", + "mp121", + "mp122", + "mp123", + "mp124", + "mp125", + "mp126", + "mp127", + "mp128", + "mp129", + "mp130", + "mp131", + "mp132", + "mp133", + "mp134", + "mp135", + "mp136", + "mp137", + "mp138", + "mp139", + "mp140", + "mp141", + "mp142", + "mp143", + "mp144", + "mp145", + "mp146", + "mp147", + "mp148", + "mp149", + "mp150", + "mp151", + "mp152", + "mp153", + "mp154", + "mp155", + "mp156", + "mp157", + "mp158", + "mp159", + "mp160", + "mp161", + "mp162", + "mp163", + "mp164", + "mp165", + "mp166", + "mp167", + "mp168", + "mp169", + "mp170", + "mp171", + "mp172", + "mp173", + "mp174", + "mp175", + "mp176", + "mp177", + "mp178", + "mp179", + "mp180", + "mp181", + "mp182", + "mp183", + "mp184", + "mp185", + "mp186", + "mp187", + "mp188", + "mp189", + "mp190", + "mp191", + "mp192", + "mp193", + "mp194", + "mp195", + "mp196", + "mp197", + "mp198", + "mp199", + "mp200", + "mp201", + "mp202", + "mp203", + "mp204", + "mp205", + "mp206", + "mp207", + "mp208", + "mp209", + "mp210", + "mp211", + "mp212", + "mp213", + "mp214", + "mp215", + "mp216", + "mp217", + "mp218", + "mp219", + "mp220", + "mp221", + "mp222", + "mp223", + "mp224", + "mp225", + "mp226", + "mp227", + "mp228", + "mp229", + "mp230", + "mp231", + "mp232", + "mp233", + "mp234", + "mp235", + "mp236", + "mp237", + "mp238", + "mp239", + "mp240", + "mp241", + "mp242", + "mp243", + "mp244", + "mp245", + "mp246", + "mp247", + "mp248", + "mp249", + "mp250", + "mp251", + "mp252", + "mp253", + "mp254", + "mp255", + "unused0", + "unused1", + "unused2", + "unused3", + "unused4", + "unused5", + "unused6", + "unused7", + "unused8", + "unused9", + "unused10", + "unused11", + "unused12", + "unused13", + "unused14", + "unused15", + "unused16", + "unused17", + "unused18", + "unused19", + "unused20", + "unused21", + "unused22", + "unused23", + "unused24", + "unused25", + "unused26", + "unused27", + "unused28", + "unused29", + "unused30", + "unused31", + "unused32", + "unused33", + "unused34", + "unused35", + "unused36", + "unused37", + "unused38", + "unused39", + "unused40", + "unused41", + "unused42", + "unused43", + "unused44", + "unused45", + "unused46", + "unused47", + "unused48", + "unused49", + "unused50", + "unused51", + "unused52", + "unused53", + "unused54", + "unused55", + "unused56", + "unused57", + "unused58", + "unused59", + "unused60", + "unused61", + "unused62", + "unused63", + "unused64", + "unused65", + "unused66", + "unused67", + "unused68", + "unused69", + "unused70", + "unused71", + "unused72", + "unused73", + "unused74", + "unused75", + "unused76", + "unused77", + "unused78", + "unused79", + "unused80", + "unused81", + "unused82", + "unused83", + "unused84", + "unused85", + "unused86", + "unused87", + "unused88", + "unused89", + "unused90", + "unused91", + "unused92", + "unused93", + "unused94", + "unused95", + "unused96", + "unused97", + "unused98", + "unused99", + "unused100", + "unused101", + "unused102", + "unused103", + "unused104", + "unused105", + "unused106", + "unused107", + "unused108", + "unused109", + "unused110", + "unused111", + "unused112", + "unused113", + "unused114", + "unused115", + "unused116", + "unused117", + "unused118", + "unused119", + "unused120", + "unused121", + "unused122", + "unused123", + "unused124", + "unused125", + "unused126", + "unused127", + "unused128", + "unused129", + "unused130", + "unused131", + "unused132", + "unused133", + "unused134", + "unused135", + "unused136", + "unused137", + "unused138", + "unused139", + "unused140", + "unused141", + "unused142", + "unused143", + "unused144", + "unused145", + "unused146", + "unused147", + "unused148", + "unused149", + "unused150", + "unused151", + "unused152", + "unused153", + "unused154", + "unused155", + "unused156", + "unused157", + "unused158", + "unused159", + "unused160", + "unused161", + "unused162", + "unused163", + "unused164", + "unused165", + "unused166", + "unused167", + "unused168", + "unused169", + "unused170", + "unused171", + "unused172", + "unused173", + "unused174", + "unused175", + "unused176", + "unused177", + "unused178", + "unused179", + "unused180", + "unused181", + "unused182", + "unused183", + "unused184", + "unused185", + "unused186", + "unused187", + "unused188", + "unused189", + "unused190", + "unused191", + "unused192", + "unused193", + "unused194", + "unused195", + "unused196", + "unused197", + "unused198", + "unused199", + "unused200", + "unused201", + "unused202", + "unused203", + "unused204", + "unused205", + "unused206", + "unused207", + "unused208", + "unused209", + "unused210", + "unused211", + "unused212", + "unused213", + "unused214", + "unused215", + "unused216", + "unused217", + "unused218", + "unused219", + "unused220", + "unused221", + "unused222", + "unused223", + "unused224", + "unused225", + "unused226", + "unused227", + "unused228", + "unused229", + "unused230", + "unused231", + "unused232", + "unused233", + "unused234", + "unused235", + "unused236", + "unused237", + "unused238", + "unused239", + "unused240", + "unused241", + "unused242", + "unused243", + "unused244", + "unused245", + "unused246", + "unused247", + "unused248", + "unused249", + "unused250", + "unused251", + "unused252", + "unused253", + "unused254", + "unused255" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ], + "description" : "You need 'VM.Config.Disk' permissions on /vms/{vmid}, and 'Datastore.AllocateSpace' permissions on the storage. To move a volume to another container, you need the permissions on the target container as well." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/move_volume", + "text" : "move_volume" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get container configuration, including pending changes.", + "method" : "GET", + "name" : "vm_pending", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "delete" : { + "description" : "Indicates a pending delete request if present and not 0.", + "maximum" : 2, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "key" : { + "description" : "Configuration option name.", + "type" : "string" + }, + "pending" : { + "description" : "Pending value.", + "optional" : 1, + "type" : "string" + }, + "value" : { + "description" : "Current value.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/pending", + "text" : "pending" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get IP addresses of the specified container interface.", + "method" : "GET", + "name" : "ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "hardware-address" : { + "description" : "The MAC address of the interface", + "optional" : 0, + "type" : "string" + }, + "hwaddr" : { + "description" : "The MAC address of the interface", + "optional" : 0, + "type" : "string" + }, + "inet" : { + "description" : "The IPv4 address of the interface", + "optional" : 1, + "type" : "string" + }, + "inet6" : { + "description" : "The IPv6 address of the interface", + "optional" : 1, + "type" : "string" + }, + "ip-addresses" : { + "description" : "The addresses of the interface", + "items" : { + "properties" : { + "ip-address" : { + "description" : "IP-Address", + "optional" : 1, + "type" : "string" + }, + "ip-address-type" : { + "description" : "IP-Family", + "optional" : 1, + "type" : "string" + }, + "prefix" : { + "description" : "IP-Prefix", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "optional" : 0, + "type" : "array" + }, + "name" : { + "description" : "The name of the interface", + "optional" : 0, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/interfaces", + "text" : "interfaces" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migration tunnel endpoint - only for internal use by CT migration.", + "method" : "POST", + "name" : "mtunnel", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bridges" : { + "description" : "List of network bridges to check availability. Will be checked again for actually used bridges during migration.", + "format" : "pve-bridge-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storages" : { + "description" : "List of storages to check permission and availability. Will be checked again for all actually used storages during migration.", + "format" : "pve-storage-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + [ + "perm", + "/", + [ + "Sys.Incoming" + ] + ] + ], + "description" : "You need 'VM.Allocate' permissions on '/vms/{vmid}' and Sys.Incoming on '/'. Further permission checks happen during the actual migration." + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "socket" : { + "type" : "string" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/mtunnel", + "text" : "mtunnel" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration.", + "method" : "GET", + "name" : "mtunnelwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "socket" : { + "description" : "unix socket to forward to", + "type" : "string", + "typetext" : "" + }, + "ticket" : { + "description" : "ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "description" : "You need to pass a ticket valid for the selected socket. Tickets can be created via the mtunnel API call, which will check permissions accordingly.", + "user" : "all" + }, + "returns" : { + "properties" : { + "port" : { + "optional" : 1, + "type" : "string" + }, + "socket" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/mtunnelwebsocket", + "text" : "mtunnelwebsocket" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy the container (also delete all uses files).", + "method" : "DELETE", + "name" : "destroy_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "destroy-unreferenced-disks" : { + "description" : "If set, destroy additionally all disks with the VMID from all enabled storages which are not referenced in the config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "force" : { + "default" : 0, + "description" : "Force destroy, even if running.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "purge" : { + "default" : 0, + "description" : "Remove container from all related configurations. For example, backup jobs, replication jobs or HA. Related ACLs and Firewall entries will *always* be removed.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "vmdiridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}", + "text" : "{vmid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "LXC container index (per node).", + "method" : "GET", + "name" : "vmlist", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list CTs where you have VM.Audit permission on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "cpu" : { + "description" : "Current CPU usage.", + "optional" : 1, + "type" : "number" + }, + "cpus" : { + "description" : "Maximum usable CPUs.", + "optional" : 1, + "type" : "number" + }, + "disk" : { + "description" : "Root disk image space-usage in bytes.", + "minimum" : 0, + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "diskread" : { + "description" : "The amount of bytes the guest read from it's block devices since the guest was started. (Note: This info is not available for all storage types.)", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "diskwrite" : { + "description" : "The amount of bytes the guest wrote from it's block devices since the guest was started. (Note: This info is not available for all storage types.)", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "lock" : { + "description" : "The current config lock, if any.", + "optional" : 1, + "type" : "string" + }, + "maxdisk" : { + "description" : "Root disk image size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Maximum memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxswap" : { + "description" : "Maximum SWAP memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "mem" : { + "description" : "Currently used memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "Container name.", + "optional" : 1, + "type" : "string" + }, + "netin" : { + "description" : "The amount of traffic in bytes that was sent to the guest over the network since it was started.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "netout" : { + "description" : "The amount of traffic in bytes that was sent from the guest over the network since it was started.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "pressurecpusome" : { + "description" : "CPU Some pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressureiofull" : { + "description" : "IO Full pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressureiosome" : { + "description" : "IO Some pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressurememoryfull" : { + "description" : "Memory Full pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "pressurememorysome" : { + "description" : "Memory Some pressure stall average over the last 10 seconds.", + "optional" : 1, + "type" : "number" + }, + "status" : { + "description" : "LXC Container status.", + "enum" : [ + "stopped", + "running" + ], + "type" : "string" + }, + "tags" : { + "description" : "The current configured tags, if any.", + "optional" : 1, + "type" : "string" + }, + "template" : { + "default" : 0, + "description" : "Determines if the guest is a template.", + "optional" : 1, + "type" : "boolean" + }, + "uptime" : { + "description" : "Uptime in seconds.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{vmid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create or restore a container.", + "method" : "POST", + "name" : "create_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "arch" : { + "default" : "amd64", + "description" : "OS architecture type.", + "enum" : [ + "amd64", + "i386", + "arm64", + "armhf", + "riscv32", + "riscv64" + ], + "optional" : 1, + "type" : "string" + }, + "bwlimit" : { + "default" : "restore limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "cmode" : { + "default" : "tty", + "description" : "Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).", + "enum" : [ + "shell", + "console", + "tty" + ], + "optional" : 1, + "type" : "string" + }, + "console" : { + "default" : 1, + "description" : "Attach a console device (/dev/console) to the container.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cores" : { + "description" : "The number of cores assigned to the container. A container can use all available cores by default.", + "maximum" : 8192, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 8192)" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.", + "maximum" : 8192, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 8192)" + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 500000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 500000)", + "verbose_description" : "CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests." + }, + "debug" : { + "default" : 0, + "description" : "Try to be more verbose. For now this only enables debug log-level on start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "description" : { + "description" : "Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dev[n]" : { + "description" : "Device to pass through to the container", + "format" : { + "deny-write" : { + "default" : 0, + "description" : "Deny the container to write to the device", + "optional" : 1, + "type" : "boolean" + }, + "gid" : { + "description" : "Group ID to be assigned to the device node", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "mode" : { + "description" : "Access mode to be set on the device node", + "format_description" : "Octal access mode", + "optional" : 1, + "pattern" : "0[0-7]{3}", + "type" : "string" + }, + "path" : { + "default_key" : 1, + "description" : "Device to pass through to the container", + "format" : "pve-lxc-dev-string", + "format_description" : "Path", + "optional" : 1, + "type" : "string", + "verbose_description" : "Path to the device to pass through to the container" + }, + "uid" : { + "description" : "User ID to be assigned to the device node", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[path=]] [,deny-write=<1|0>] [,gid=] [,mode=] [,uid=]" + }, + "entrypoint" : { + "default" : "/sbin/init", + "description" : "Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH.", + "optional" : 1, + "pattern" : "(?^:[^\\x00-\\x08\\x0a-\\x1F\\x7F]+)", + "type" : "string" + }, + "env" : { + "description" : "The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config.", + "optional" : 1, + "pattern" : "(?^:(?:\\w+=[^\\x00-\\x08\\x0a-\\x1F\\x7F]*)(?:\\0\\w+=[^\\x00-\\x08\\x0a-\\x1F\\x7F]*)*)", + "type" : "string" + }, + "features" : { + "description" : "Allow containers access to advanced features.", + "format" : { + "force_rw_sys" : { + "default" : 0, + "description" : "Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.", + "optional" : 1, + "type" : "boolean" + }, + "fuse" : { + "default" : 0, + "description" : "Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.", + "optional" : 1, + "type" : "boolean" + }, + "keyctl" : { + "default" : 0, + "description" : "For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.", + "optional" : 1, + "type" : "boolean" + }, + "mknod" : { + "default" : 0, + "description" : "Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.", + "optional" : 1, + "type" : "boolean" + }, + "mount" : { + "description" : "Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.", + "format_description" : "fstype;fstype;...", + "optional" : 1, + "pattern" : "(?^:[a-zA-Z0-9_; ]+)", + "type" : "string" + }, + "nesting" : { + "default" : 0, + "description" : "Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest. This is also required by systemd to isolate services.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[force_rw_sys=<1|0>] [,fuse=<1|0>] [,keyctl=<1|0>] [,mknod=<1|0>] [,mount=] [,nesting=<1|0>]" + }, + "force" : { + "description" : "Allow to overwrite existing container.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ha-managed" : { + "default" : 0, + "description" : "Add the CT as a HA resource after it was created.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the containers lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostname" : { + "description" : "Set a host name for the container.", + "format" : "dns-name", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ignore-unpack-errors" : { + "description" : "Ignore errors when extracting the template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the container.", + "enum" : [ + "backup", + "create", + "destroyed", + "disk", + "fstrim", + "migrate", + "mounted", + "rollback", + "snapshot", + "snapshot-delete" + ], + "optional" : 1, + "type" : "string" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the container in MB.", + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - N)" + }, + "mp[n]" : { + "description" : "Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "backup" : { + "description" : "Whether to include the mount point in backups.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Whether to include the mount point in backups (only used for volume mount points)." + }, + "idmap" : { + "description" : "Map specific container UIDs/GIDs to underlying disk UIDs/GIDs for this mount point", + "format_description" : "type:container:disk:range-size[;type:container:disk:range-size;...]", + "optional" : 1, + "pattern" : "(?^:^(?:passthrough|[ug]:[0-9]+:[0-9]+:[1-9][0-9]*(?:;[ug]:[0-9]+:[0-9]+:[1-9][0-9]*)*)$)", + "type" : "string", + "verbose_description" : "Customize UID/GID mappings that override the container's `lxc.idmap` for this mount point. Accepts a semicolon-separated list of `type:container:disk:range-size` entries.\n\n`type` is `u` for UID or `g` for GID.\n\n`container` is the first ID as seen inside the container.\n\n`disk` is the first corresponding ID on the underlying filesystem.\n\n`range-size` is the number of consecutive IDs to map.\n\nUnmapped IDs fall back to the container's `lxc.idmap`.\n\nExample 1: `u:123:456:1` maps UID 123 in the container to UID 456 on the disk. Files owned by UID 456 on the disk will appear as UID 123 inside the container.\n\nExample 2: `g:100:50:5` maps 5 consecutive GIDs, such that GIDs 100-104 in the container are mapped to GIDs 50-54 on the disk.\n\nExample 3: `passthrough` identity-maps all UIDs and GIDs, meaning IDs inside the container will match the IDs on the disk." + }, + "keepattrs" : { + "default" : 0, + "description" : "Inherit ownership and permissions from the mount point directory.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Inherit UID, GID and access mode from the mount point directory, if it exists already." + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)", + "type" : "string" + }, + "mp" : { + "description" : "Path to the mount point as seen from inside the container (must not contain symlinks).", + "format" : "pve-lxc-mp-string", + "format_description" : "Path", + "type" : "string", + "verbose_description" : "Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons." + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=] ,mp= [,acl=<1|0>] [,backup=<1|0>] [,idmap=] [,keepattrs=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]" + }, + "nameserver" : { + "description" : "Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "lxc-ip-with-ll-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specifies network interfaces for the container.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to.", + "format_description" : "bridge", + "optional" : 1, + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "firewall" : { + "description" : "Controls whether this interface's firewall rules should be used.", + "optional" : 1, + "type" : "boolean" + }, + "gw" : { + "description" : "Default gateway for IPv4 traffic.", + "format" : "ipv4", + "format_description" : "GatewayIPv4", + "optional" : 1, + "type" : "string" + }, + "gw6" : { + "description" : "Default gateway for IPv6 traffic.", + "format" : "ipv6", + "format_description" : "GatewayIPv6", + "optional" : 1, + "type" : "string" + }, + "host-managed" : { + "description" : "Whether this interface's IP configuration should be managed by the host. When enabled, the host (rather than the container) is responsible for the interface's IP configuration. The container should not run its own DHCP client or network manager on this interface. This is useful for containers that lack an internal network management stack, like many application containers.", + "optional" : 1, + "type" : "boolean" + }, + "hwaddr" : { + "description" : "The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "ip" : { + "description" : "IPv4 address in CIDR format.", + "format" : "pve-ipv4-config", + "format_description" : "(IPv4/CIDR|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address in CIDR format.", + "format" : "pve-ipv6-config", + "format_description" : "(IPv6/CIDR|auto|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "mtu" : { + "description" : "Maximum transfer unit of the interface. (lxc.network.mtu)", + "maximum" : 65535, + "minimum" : 64, + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "Name of the network device as seen from inside the container. (lxc.network.name)", + "format_description" : "string", + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "rate" : { + "description" : "Apply rate limiting to the interface", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "tag" : { + "description" : "VLAN tag for this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN ids to pass through the interface", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:;\\d+)*)", + "type" : "string" + }, + "type" : { + "description" : "Network interface type.", + "enum" : [ + "veth" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "name= [,bridge=] [,firewall=<1|0>] [,gw=] [,gw6=] [,host-managed=<1|0>] [,hwaddr=] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=<(IPv6/CIDR|auto|dhcp|manual)>] [,link_down=<1|0>] [,mtu=] [,rate=] [,tag=] [,trunks=] [,type=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a container will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostemplate" : { + "description" : "The OS template or backup file.", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + }, + "ostype" : { + "description" : "OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.", + "enum" : [ + "debian", + "devuan", + "ubuntu", + "centos", + "fedora", + "opensuse", + "archlinux", + "alpine", + "gentoo", + "nixos", + "unmanaged" + ], + "optional" : 1, + "type" : "string" + }, + "password" : { + "description" : "Sets root password inside container.", + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Add the VM to the specified pool.", + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restore" : { + "description" : "Mark this as restore task.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "rootfs" : { + "description" : "Use volume as container root.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "idmap" : { + "description" : "Map specific container UIDs/GIDs to underlying disk UIDs/GIDs for this mount point", + "format_description" : "type:container:disk:range-size[;type:container:disk:range-size;...]", + "optional" : 1, + "pattern" : "(?^:^(?:passthrough|[ug]:[0-9]+:[0-9]+:[1-9][0-9]*(?:;[ug]:[0-9]+:[0-9]+:[1-9][0-9]*)*)$)", + "type" : "string", + "verbose_description" : "Customize UID/GID mappings that override the container's `lxc.idmap` for this mount point. Accepts a semicolon-separated list of `type:container:disk:range-size` entries.\n\n`type` is `u` for UID or `g` for GID.\n\n`container` is the first ID as seen inside the container.\n\n`disk` is the first corresponding ID on the underlying filesystem.\n\n`range-size` is the number of consecutive IDs to map.\n\nUnmapped IDs fall back to the container's `lxc.idmap`.\n\nExample 1: `u:123:456:1` maps UID 123 in the container to UID 456 on the disk. Files owned by UID 456 on the disk will appear as UID 123 inside the container.\n\nExample 2: `g:100:50:5` maps 5 consecutive GIDs, such that GIDs 100-104 in the container are mapped to GIDs 50-54 on the disk.\n\nExample 3: `passthrough` identity-maps all UIDs and GIDs, meaning IDs inside the container will match the IDs on the disk." + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)", + "type" : "string" + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=] [,acl=<1|0>] [,idmap=] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]" + }, + "searchdomain" : { + "description" : "Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "dns-name-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ssh-public-keys" : { + "description" : "Setup public SSH keys (one key per line, OpenSSH format).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Start the CT after its creation finished successfully.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "storage" : { + "default" : "local", + "description" : "Default Storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "swap" : { + "default" : 512, + "description" : "Amount of SWAP for the container in MB.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "tags" : { + "description" : "Tags of the Container. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "timezone" : { + "description" : "Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab", + "format" : "pve-ct-timezone", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tty" : { + "default" : 2, + "description" : "Specify the number of tty available to the container", + "maximum" : 6, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 6)" + }, + "unique" : { + "description" : "Assign a unique random ethernet address.", + "optional" : 1, + "requires" : "restore", + "type" : "boolean", + "typetext" : "" + }, + "unprivileged" : { + "default" : 0, + "description" : "Makes the container run as unprivileged user. For creation, the default is 1. For restore, the default is the value from the backup. (Should not be modified manually.)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "volume" : { + "default_key" : 1, + "description" : "The volume that is not used currently.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=]" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "description" : "You need 'VM.Allocate' permission on /vms/{vmid} or on the VM pool /pool/{pool}. For restore, it is enough if the user has 'VM.Backup' permission and the VM already exists. You also need 'Datastore.AllocateSpace' permissions on the storage. For privileged containers, 'Sys.Modify' permissions on '/' are required.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc", + "text" : "lxc" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the Ceph configuration file.", + "method" : "GET", + "name" : "raw", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/cfg/raw", + "text" : "raw" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the Ceph configuration database.", + "method" : "GET", + "name" : "db", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "can_update_at_runtime" : { + "description" : "Set if the value can be changed at runtime without restarting the affected daemons. Emitted as the integer 1/0 to match the existing PVE wire convention.", + "type" : "boolean" + }, + "level" : { + "description" : "Config level the entry is exposed at: 'basic' for operator-visible settings, 'advanced' for tuning parameters, 'dev' for developer-only knobs.", + "enum" : [ + "basic", + "advanced", + "dev" + ], + "type" : "string" + }, + "mask" : { + "description" : "Match expression restricting the entry's scope; empty when the entry has no mask. Examples: 'host:foo', 'class:ssd'.", + "type" : "string" + }, + "name" : { + "description" : "Config key name.", + "type" : "string" + }, + "section" : { + "description" : "Ceph config section the entry applies to: 'global', a daemon type ('mon', 'osd', 'mgr', 'mds', 'client'), or a specific daemon (e.g. 'osd.0', 'mon.').", + "type" : "string" + }, + "value" : { + "description" : "Configured value for the key (always serialised as a string by Ceph, regardless of the option's underlying type).", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/cfg/db", + "text" : "db" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get configured values from either ceph.conf or the mon config DB. Underscores in section and key names are normalised to hyphens in the response, regardless of how they're written in the source.", + "method" : "GET", + "name" : "value", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "config-keys" : { + "description" : "List of
: items separated by semicolon, comma or space.", + "maxLength" : 4096, + "pattern" : "(?^:^(?:(?^i:[0-9a-z\\-_\\.]+:[0-9a-zA-Z\\-_]+))(?:[;, ](?^i:[0-9a-z\\-_\\.]+:[0-9a-zA-Z\\-_]+))*$)", + "type" : "string", + "typetext" : "
:[;|,|
:]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Two-level map of {section} -> {key} -> value. Underscores in section and key names are normalised to hyphens.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/cfg/value", + "text" : "value" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/cfg", + "text" : "cfg" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get OSD details", + "method" : "GET", + "name" : "osddetails", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "devices" : { + "description" : "Array containing data about devices", + "items" : { + "properties" : { + "dev_node" : { + "description" : "Device node", + "type" : "string" + }, + "device" : { + "description" : "Kind of OSD device", + "enum" : [ + "block", + "db", + "wal" + ], + "type" : "string" + }, + "physical_device" : { + "description" : "Underlying physical device(s) used by this OSD device (comma- or space-joined when multiple).", + "type" : "string" + }, + "size" : { + "description" : "Size of the OSD device in bytes.", + "type" : "integer" + }, + "support_discard" : { + "description" : "Whether the underlying physical device supports discard/TRIM.", + "type" : "boolean" + }, + "type" : { + "description" : "Type of device. For example, hdd or ssd", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "osd" : { + "description" : "General information about the OSD", + "properties" : { + "back_addr" : { + "description" : "Address and port used to talk to other OSDs.", + "type" : "string" + }, + "encrypted" : { + "description" : "Whether the OSD is encrypted with LUKS via dm-crypt.", + "type" : "boolean" + }, + "front_addr" : { + "description" : "Address and port used to talk to clients and monitors.", + "type" : "string" + }, + "hb_back_addr" : { + "description" : "Heartbeat address and port for other OSDs.", + "type" : "string" + }, + "hb_front_addr" : { + "description" : "Heartbeat address and port for clients and monitors.", + "type" : "string" + }, + "hostname" : { + "description" : "Name of the host containing the OSD.", + "type" : "string" + }, + "id" : { + "description" : "ID of the OSD.", + "type" : "integer" + }, + "mem_usage" : { + "description" : "Proportional set size (PSS) memory usage of the OSD daemon process in bytes; 0 when the process is not running.", + "type" : "integer" + }, + "osd_data" : { + "description" : "Path to the OSD's data directory.", + "type" : "string" + }, + "osd_objectstore" : { + "description" : "The type of object store used.", + "type" : "string" + }, + "pid" : { + "description" : "OSD process ID; absent if the systemd unit for this OSD is not currently running.", + "optional" : 1, + "type" : "integer" + }, + "version" : { + "description" : "Ceph version of the OSD service.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/metadata", + "text" : "metadata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get OSD volume details", + "method" : "GET", + "name" : "osdvolume", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + }, + "type" : { + "default" : "block", + "description" : "OSD device type", + "enum" : [ + "block", + "db", + "wal" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "creation_time" : { + "description" : "Creation time as reported by `lvs`.", + "type" : "string" + }, + "lv_name" : { + "description" : "Name of the logical volume (LV).", + "type" : "string" + }, + "lv_path" : { + "description" : "Path to the logical volume (LV).", + "type" : "string" + }, + "lv_size" : { + "description" : "Size of the logical volume (LV).", + "type" : "integer" + }, + "lv_uuid" : { + "description" : "UUID of the logical volume (LV).", + "type" : "string" + }, + "vg_name" : { + "description" : "Name of the volume group (VG).", + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/lv-info", + "text" : "lv-info" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "ceph osd in", + "method" : "POST", + "name" : "in", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/in", + "text" : "in" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "ceph osd out", + "method" : "POST", + "name" : "out", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/out", + "text" : "out" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Instruct the OSD to scrub.", + "method" : "POST", + "name" : "scrub", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "deep" : { + "default" : 0, + "description" : "If set, instructs a deep scrub instead of a normal one.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/scrub", + "text" : "scrub" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy OSD", + "method" : "DELETE", + "name" : "destroyosd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cleanup" : { + "default" : 0, + "description" : "If set, also destroy the underlying logical volumes via 'ceph-volume lvm zap --destroy', remove the volume group's physical volume with pvremove, and wipe any journal/block.db/block.wal partitions left over from filestore OSDs. Without this flag the LVs and partitions are left intact for inspection.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "OSD index.", + "method" : "GET", + "name" : "osdindex", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/osd/{osdid}", + "text" : "{osdid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Ceph osd list/tree.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 1, + "properties" : { + "flags" : { + "description" : "Comma-joined list of currently-set OSD flags; absent when no flags are set on the cluster.", + "optional" : 1, + "type" : "string" + }, + "root" : { + "additionalProperties" : 1, + "description" : "Top-level CRUSH bucket; recursive structure with 'children' lists holding nested buckets and OSD leaves. Per-node properties (status, weight, in, usage, latencies, etc.) vary by node type and are not statically typed here.", + "type" : "object" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create OSD", + "method" : "POST", + "name" : "createosd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "crush-device-class" : { + "description" : "Set the device class of the OSD in crush.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "db_dev" : { + "description" : "Block device name for block.db.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "db_dev_size" : { + "description" : "Size in GiB for block.db.", + "minimum" : 1, + "optional" : 1, + "requires" : "db_dev", + "type" : "number", + "typetext" : " (1 - N)", + "verbose_description" : "If a block.db is requested but the size is not given, will be automatically selected by: bluestore_block_db_size from the ceph database (osd or global section) or config (osd or global section) in that order. If this is not available, it will be sized 10% of the size of the OSD device. Fails if the available size is not enough." + }, + "dev" : { + "description" : "Block device name.", + "type" : "string", + "typetext" : "" + }, + "encrypted" : { + "default" : 0, + "description" : "Enables encryption of the OSD.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osds-per-device" : { + "description" : "OSD services per physical device. Only useful for fast NVMe devices to utilize their performance better. Mutually exclusive with 'db_dev' and 'wal_dev'.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "wal_dev" : { + "description" : "Block device name for block.wal.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "wal_dev_size" : { + "description" : "Size in GiB for block.wal.", + "minimum" : 0.5, + "optional" : 1, + "requires" : "wal_dev", + "type" : "number", + "typetext" : " (0.5 - N)", + "verbose_description" : "If a block.wal is requested but the size is not given, will be automatically selected by: bluestore_block_wal_size from the ceph database (osd or global section) or config (osd or global section) in that order. If this is not available, it will be sized 1% of the size of the OSD device. Fails if the available size is not enough." + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/osd", + "text" : "osd" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy Ceph Metadata Server", + "method" : "DELETE", + "name" : "destroymds", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The name (ID) of the mds", + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Ceph Metadata Server (MDS)", + "method" : "POST", + "name" : "createmds", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "hotstandby" : { + "default" : 0, + "description" : "Determines whether a ceph-mds daemon should poll and replay the log of an active MDS. Faster switch on MDS failure, but needs more idle resources.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "default" : "nodename", + "description" : "The ID for the mds, when omitted the same as the nodename", + "maxLength" : 200, + "optional" : 1, + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/mds/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "MDS directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "addr" : { + "description" : "Address as advertised by the MDS; Ceph-formatted (typically 'IP:PORT/NONCE').", + "optional" : 1, + "type" : "string" + }, + "ceph_version" : { + "description" : "Full Ceph version string of the MDS daemon.", + "optional" : 1, + "type" : "string" + }, + "ceph_version_short" : { + "description" : "Short Ceph version string of the MDS daemon (e.g. '19.2.0').", + "optional" : 1, + "type" : "string" + }, + "direxists" : { + "description" : "Set when the MDS's data directory exists on this node.", + "optional" : 1, + "type" : "boolean" + }, + "fs_name" : { + "description" : "Name of the CephFS this MDS is bound to; absent or null for standby MDSes not currently serving a rank.", + "optional" : 1, + "type" : "string" + }, + "host" : { + "description" : "Host the MDS runs on.", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name (ID) for the MDS.", + "type" : "string" + }, + "rank" : { + "description" : "MDS rank within the file system; -1 for standby MDSes not currently bound to a rank.", + "optional" : 1, + "type" : "integer" + }, + "service" : { + "description" : "Set if a ceph-mds@ systemd unit is enabled on the hosting node; absent otherwise.", + "optional" : 1, + "type" : "boolean" + }, + "standby_replay" : { + "description" : "If true, the standby MDS is polling the active MDS for faster recovery (hot standby).", + "optional" : 1, + "type" : "boolean" + }, + "state" : { + "description" : "MDS state: Ceph-reported run state (e.g. 'up:active', 'up:standby', 'up:standby-replay') for daemons known to the cluster; 'stopped' or 'unknown' for configured daemons not visible to the cluster.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/mds", + "text" : "mds" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy Ceph Manager.", + "method" : "DELETE", + "name" : "destroymgr", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The ID of the manager", + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Ceph Manager", + "method" : "POST", + "name" : "createmgr", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "default" : "nodename", + "description" : "The ID for the manager, when omitted the same as the nodename.", + "maxLength" : 200, + "optional" : 1, + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/mgr/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "MGR directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "addr" : { + "description" : "Address as advertised by the manager; Ceph-formatted (typically 'IP:PORT/NONCE').", + "optional" : 1, + "type" : "string" + }, + "ceph_version" : { + "description" : "Full Ceph version string of the manager daemon.", + "optional" : 1, + "type" : "string" + }, + "ceph_version_short" : { + "description" : "Short Ceph version string of the manager daemon (e.g. '19.2.0').", + "optional" : 1, + "type" : "string" + }, + "direxists" : { + "description" : "Set when the manager's data directory exists on this node.", + "optional" : 1, + "type" : "boolean" + }, + "host" : { + "description" : "Host the manager runs on.", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name (ID) for the MGR.", + "type" : "string" + }, + "service" : { + "description" : "Set if a ceph-mgr@ systemd unit is enabled on the hosting node; absent otherwise.", + "optional" : 1, + "type" : "boolean" + }, + "state" : { + "description" : "Manager state: 'active' or 'standby' for daemons visible to the mgr cluster, 'stopped' or 'unknown' for configured daemons not currently visible.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/mgr", + "text" : "mgr" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy a Ceph Monitor. Refuses to remove the last monitor of the cluster. Does not destroy any Manager on the same node; use /nodes/{node}/ceph/mgr/{id} for that.", + "method" : "DELETE", + "name" : "destroymon", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "monid" : { + "description" : "Monitor ID", + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a Ceph Monitor. Also auto-creates a Manager for the first monitor.", + "method" : "POST", + "name" : "createmon", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "mon-address" : { + "description" : "Overwrites autodetected monitor IP address(es). Must be in the public network(s) of Ceph.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "monid" : { + "default" : "nodename", + "description" : "The ID for the monitor, when omitted the same as the nodename.", + "maxLength" : 200, + "optional" : 1, + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/mon/{monid}", + "text" : "{monid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Ceph monitor list.", + "method" : "GET", + "name" : "listmon", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "addr" : { + "description" : "Address as advertised by the monitor; Ceph-formatted (typically 'IP:PORT/NONCE', possibly as a messenger-v2 vector depending on Ceph version and ceph.conf shape).", + "optional" : 1, + "type" : "string" + }, + "ceph_version" : { + "description" : "Full Ceph version string of the monitor daemon.", + "optional" : 1, + "type" : "string" + }, + "ceph_version_short" : { + "description" : "Short Ceph version string of the monitor daemon (e.g. '19.2.0').", + "optional" : 1, + "type" : "string" + }, + "direxists" : { + "description" : "Set when the monitor's data directory exists on this node.", + "optional" : 1, + "type" : "boolean" + }, + "host" : { + "description" : "Host the monitor runs on.", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Monitor id (typically the hostname).", + "type" : "string" + }, + "quorum" : { + "description" : "Set when the monitor is part of the current quorum.", + "optional" : 1, + "type" : "boolean" + }, + "rank" : { + "description" : "Rank of the monitor within the mon map.", + "optional" : 1, + "type" : "integer" + }, + "service" : { + "description" : "Set if a ceph-mon@ systemd unit is enabled on the hosting node; absent otherwise.", + "optional" : 1, + "type" : "boolean" + }, + "state" : { + "description" : "Run state of the monitor: 'running' (in quorum), 'stopped' (systemd unit configured but daemon not visible to the cluster), or 'unknown' (no rados access).", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/mon", + "text" : "mon" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy a Ceph filesystem. Refuses if any PVE storage entry of type 'cephfs' still references the filesystem and is not disabled. Optionally also removes the storage entries and/or the underlying metadata and data pools.", + "method" : "DELETE", + "name" : "destroyfs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The Ceph filesystem name.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "remove-pools" : { + "default" : 0, + "description" : "Remove the metadata and data pools used by this filesystem.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove-storages" : { + "default" : 0, + "description" : "Remove pveceph-managed storages configured for this filesystem.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a Ceph filesystem", + "method" : "POST", + "name" : "createfs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add-storage" : { + "default" : 0, + "description" : "Configure the created CephFS as storage for this cluster.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "default" : "cephfs", + "description" : "The ceph filesystem name.", + "optional" : 1, + "pattern" : "(?^:^[^:/\\s]+$)", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_num" : { + "default" : 128, + "description" : "Number of placement groups for the backing data pool. The metadata pool will use a quarter of this.", + "maximum" : 32768, + "minimum" : 8, + "optional" : 1, + "type" : "integer", + "typetext" : " (8 - 32768)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/fs/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "data_pool" : { + "description" : "Name of the filesystem's first data pool. A CephFS can have more than one data pool; consumers interested in the full set should read 'data_pools' instead. Kept for backwards compatibility.", + "type" : "string" + }, + "data_pool_ids" : { + "description" : "Numeric ids of the data pools.", + "items" : { + "description" : "Data pool id.", + "type" : "integer" + }, + "optional" : 1, + "type" : "array" + }, + "data_pools" : { + "description" : "Names of all data pools assigned to the filesystem; a CephFS can have multiple data pools (e.g. replicated metadata plus EC data, or multiple device-class-specific data pools).", + "items" : { + "description" : "Data pool name.", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "metadata_pool" : { + "description" : "Name of the metadata pool.", + "type" : "string" + }, + "metadata_pool_id" : { + "description" : "Numeric id of the metadata pool.", + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "The ceph filesystem name.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/fs", + "text" : "fs" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Show the current pool status.", + "method" : "GET", + "name" : "getpool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The name of the pool. It must be unique.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "verbose" : { + "default" : 0, + "description" : "If enabled, will display additional data(eg. statistics).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "application" : { + "default" : "rbd", + "description" : "The application of the pool.", + "enum" : [ + "rbd", + "cephfs", + "rgw" + ], + "optional" : 1, + "title" : "Application", + "type" : "string" + }, + "application_list" : { + "description" : "Names of applications currently associated with the pool.", + "items" : { + "description" : "Application name (e.g. 'rbd', 'cephfs', 'rgw').", + "type" : "string" + }, + "optional" : 1, + "title" : "Application", + "type" : "array" + }, + "autoscale_status" : { + "description" : "Raw pg_autoscaler status object for this pool; shape varies between Ceph releases.", + "optional" : 1, + "title" : "Autoscale Status", + "type" : "object" + }, + "crush_rule" : { + "description" : "The rule to use for mapping object placement in the cluster.", + "optional" : 1, + "title" : "Crush Rule Name", + "type" : "string" + }, + "fast_read" : { + "description" : "Set if the pool uses fast-read for erasure-coded reads.", + "title" : "Fast Read", + "type" : "boolean" + }, + "hashpspool" : { + "description" : "Set if the pool hashes pool id into its CRUSH placement-seed.", + "title" : "hashpspool", + "type" : "boolean" + }, + "id" : { + "description" : "Numeric pool id assigned by Ceph.", + "title" : "ID", + "type" : "integer" + }, + "min_size" : { + "default" : 2, + "description" : "Minimum number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Min Size", + "type" : "integer" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "pattern" : "(?^:^[^:/\\s]+$)", + "title" : "Name", + "type" : "string" + }, + "nodeep-scrub" : { + "description" : "Set if deep-scrubbing is disabled for this pool.", + "title" : "nodeep-scrub", + "type" : "boolean" + }, + "nodelete" : { + "description" : "Set if pool delete is blocked.", + "title" : "nodelete", + "type" : "boolean" + }, + "nopgchange" : { + "description" : "Set if changing the placement-group count is blocked.", + "title" : "nopgchange", + "type" : "boolean" + }, + "noscrub" : { + "description" : "Set if scrubbing is disabled for this pool.", + "title" : "noscrub", + "type" : "boolean" + }, + "nosizechange" : { + "description" : "Set if changing the replication size is blocked.", + "title" : "nosizechange", + "type" : "boolean" + }, + "pg_autoscale_mode" : { + "default" : "warn", + "description" : "The automatic PG scaling mode of the pool.", + "enum" : [ + "on", + "off", + "warn" + ], + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "default" : 128, + "description" : "Number of placement groups.", + "maximum" : 32768, + "minimum" : 1, + "optional" : 1, + "title" : "PG Num", + "type" : "integer" + }, + "pg_num_min" : { + "description" : "Minimal number of placement groups.", + "maximum" : 32768, + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer" + }, + "pgp_num" : { + "description" : "Placement-group-for-placement count.", + "title" : "PGP num", + "type" : "integer" + }, + "size" : { + "default" : 3, + "description" : "Number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Size", + "type" : "integer" + }, + "statistics" : { + "description" : "Optional pool usage and IO statistics (only present when verbose=1 is requested).", + "optional" : 1, + "title" : "Statistics", + "type" : "object" + }, + "target_size" : { + "description" : "The estimated target size of the pool for the PG autoscaler.", + "optional" : 1, + "pattern" : "^(\\d+(\\.\\d+)?)([KMGT])?$", + "title" : "PG Autoscale Target Size", + "type" : "string" + }, + "target_size_ratio" : { + "description" : "The estimated target ratio of the pool for the PG autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number" + }, + "use_gmt_hitset" : { + "description" : "Set if hitsets use GMT timestamps (for cache-tier pools).", + "title" : "use_gmt_hitset", + "type" : "boolean" + }, + "write_fadvise_dontneed" : { + "description" : "Set if the pool sets the FADV_DONTNEED hint on writes.", + "title" : "write_fadvise_dontneed", + "type" : "boolean" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/pool/{name}/status", + "text" : "status" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy pool", + "method" : "DELETE", + "name" : "destroypool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "If true, destroys pool even if in use", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "remove_ecprofile" : { + "default" : 1, + "description" : "Remove the erasure code profile. Defaults to true, if applicable.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove_storages" : { + "default" : 0, + "description" : "Remove all pveceph-managed storages configured for this pool", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Pool index.", + "method" : "GET", + "name" : "poolindex", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The name of the pool.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Change POOL settings", + "method" : "PUT", + "name" : "setpool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "application" : { + "description" : "The application of the pool.", + "enum" : [ + "rbd", + "cephfs", + "rgw" + ], + "optional" : 1, + "title" : "Application", + "type" : "string" + }, + "crush_rule" : { + "description" : "The rule to use for mapping object placement in the cluster.", + "optional" : 1, + "title" : "Crush Rule Name", + "type" : "string", + "typetext" : "" + }, + "min_size" : { + "description" : "Minimum number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Min Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "pattern" : "(?^:^[^:/\\s]+$)", + "title" : "Name", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_autoscale_mode" : { + "description" : "The automatic PG scaling mode of the pool.", + "enum" : [ + "on", + "off", + "warn" + ], + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "description" : "Number of placement groups.", + "maximum" : 32768, + "minimum" : 1, + "optional" : 1, + "title" : "PG Num", + "type" : "integer", + "typetext" : " (1 - 32768)" + }, + "pg_num_min" : { + "description" : "Minimal number of placement groups.", + "maximum" : 32768, + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer", + "typetext" : " (-N - 32768)" + }, + "size" : { + "description" : "Number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "target_size" : { + "description" : "The estimated target size of the pool for the PG autoscaler.", + "optional" : 1, + "pattern" : "^(\\d+(\\.\\d+)?)([KMGT])?$", + "title" : "PG Autoscale Target Size", + "type" : "string" + }, + "target_size_ratio" : { + "description" : "The estimated target ratio of the pool for the PG autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/pool/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all pools and their settings (which are settable by the POST/PUT endpoints).", + "method" : "GET", + "name" : "lspools", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "application_metadata" : { + "description" : "Application tags attached to the pool (mapping of application name to its metadata object).", + "optional" : 1, + "title" : "Associated Applications", + "type" : "object" + }, + "autoscale_status" : { + "description" : "Raw pg_autoscaler status object for this pool; shape varies between Ceph releases.", + "optional" : 1, + "title" : "Autoscale Status", + "type" : "object" + }, + "bytes_used" : { + "description" : "Bytes currently used in the pool; absent if no usage statistics are reported.", + "optional" : 1, + "renderer" : "bytes", + "title" : "Used", + "type" : "integer" + }, + "crush_rule" : { + "description" : "Numeric id of the CRUSH rule used by this pool.", + "title" : "Crush Rule", + "type" : "integer" + }, + "crush_rule_name" : { + "description" : "Human-readable name of the CRUSH rule used by this pool; absent if the rule id is not in the current CRUSH map.", + "optional" : 1, + "title" : "Crush Rule Name", + "type" : "string" + }, + "min_size" : { + "description" : "Minimum number of replicas required to accept writes.", + "title" : "Min Size", + "type" : "integer" + }, + "percent_used" : { + "description" : "Percentage of pool capacity currently used; absent if no usage statistics are reported.", + "optional" : 1, + "title" : "%-Used", + "type" : "number" + }, + "pg_autoscale_mode" : { + "description" : "Placement-group autoscaler mode ('on', 'warn' or 'off').", + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "description" : "Current placement-group count.", + "title" : "PG Num", + "type" : "integer" + }, + "pg_num_final" : { + "description" : "Optimal placement-group count computed by pg_autoscaler.", + "optional" : 1, + "title" : "Optimal PG Num", + "type" : "integer" + }, + "pg_num_min" : { + "description" : "Minimum placement-group count the pg_autoscaler may choose.", + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer" + }, + "pool" : { + "description" : "Numeric pool id assigned by Ceph.", + "title" : "ID", + "type" : "integer" + }, + "pool_name" : { + "description" : "Operator-visible name of the pool.", + "title" : "Name", + "type" : "string" + }, + "size" : { + "description" : "Replication factor (target number of object replicas).", + "title" : "Size", + "type" : "integer" + }, + "target_size" : { + "description" : "Operator-supplied target size in bytes; hints the pg_autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Size", + "type" : "integer" + }, + "target_size_ratio" : { + "description" : "Operator-supplied target ratio of total pool capacity; hints the pg_autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number" + }, + "type" : { + "description" : "Pool type: 'replicated' for n-way replication, 'erasure' for an erasure-coded pool, 'unknown' for types PVE does not yet map.", + "enum" : [ + "replicated", + "erasure", + "unknown" + ], + "title" : "Type", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pool_name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Ceph pool", + "method" : "POST", + "name" : "createpool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storages" : { + "default" : 0, + "description" : "Configure VM and CT storage using the new pool. Defaults to false for replicated pools and to true for erasure-coded pools (since EC pools are typically only useful when wired up to storage).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "application" : { + "default" : "rbd", + "description" : "The application of the pool.", + "enum" : [ + "rbd", + "cephfs", + "rgw" + ], + "optional" : 1, + "title" : "Application", + "type" : "string" + }, + "crush_rule" : { + "description" : "The rule to use for mapping object placement in the cluster.", + "optional" : 1, + "title" : "Crush Rule Name", + "type" : "string", + "typetext" : "" + }, + "erasure-coding" : { + "description" : "Create an erasure coded pool for RBD with an accompaning replicated pool for metadata storage. With EC, the common ceph options 'size', 'min_size' and 'crush_rule' parameters will be applied to the metadata pool.", + "format" : { + "device-class" : { + "description" : "CRUSH device class. Will create an erasure coded pool plus a replicated pool for metadata.", + "format_description" : "class", + "optional" : 1, + "type" : "string" + }, + "failure-domain" : { + "default" : "host", + "description" : "CRUSH failure domain. Default is 'host'. Will create an erasure coded pool plus a replicated pool for metadata.", + "format_description" : "domain", + "optional" : 1, + "type" : "string" + }, + "k" : { + "description" : "Number of data chunks. Will create an erasure coded pool plus a replicated pool for metadata.", + "minimum" : 2, + "type" : "integer" + }, + "m" : { + "description" : "Number of coding chunks. Will create an erasure coded pool plus a replicated pool for metadata.", + "minimum" : 1, + "type" : "integer" + }, + "profile" : { + "description" : "Override the erasure code (EC) profile to use. Will create an erasure coded pool plus a replicated pool for metadata.", + "format_description" : "profile", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "k= ,m= [,device-class=] [,failure-domain=] [,profile=]" + }, + "min_size" : { + "default" : 2, + "description" : "Minimum number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Min Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "pattern" : "(?^:^[^:/\\s]+$)", + "title" : "Name", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_autoscale_mode" : { + "default" : "warn", + "description" : "The automatic PG scaling mode of the pool.", + "enum" : [ + "on", + "off", + "warn" + ], + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "default" : 128, + "description" : "Number of placement groups.", + "maximum" : 32768, + "minimum" : 1, + "optional" : 1, + "title" : "PG Num", + "type" : "integer", + "typetext" : " (1 - 32768)" + }, + "pg_num_min" : { + "description" : "Minimal number of placement groups.", + "maximum" : 32768, + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer", + "typetext" : " (-N - 32768)" + }, + "size" : { + "default" : 3, + "description" : "Number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "target_size" : { + "description" : "The estimated target size of the pool for the PG autoscaler.", + "optional" : 1, + "pattern" : "^(\\d+(\\.\\d+)?)([KMGT])?$", + "title" : "PG Autoscale Target Size", + "type" : "string" + }, + "target_size_ratio" : { + "description" : "The estimated target ratio of the pool for the PG autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/pool", + "text" : "pool" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create the initial Ceph default configuration and set up symlinks. Idempotent on re-call: if a [global] section already exists in ceph.conf, the existing fsid / auth / pool defaults are preserved and most parameters are silently ignored.", + "method" : "POST", + "name" : "init", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cluster-network" : { + "description" : "Declare a separate cluster network, OSDs will route heartbeat, object replication and recovery traffic over it", + "format" : "CIDR", + "maxLength" : 128, + "optional" : 1, + "requires" : "network", + "type" : "string", + "typetext" : "" + }, + "disable_cephx" : { + "default" : 0, + "description" : "Disable cephx authentication.\n\nWARNING: cephx is a security feature protecting against man-in-the-middle attacks. Only consider disabling cephx if your network is private!", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "min_size" : { + "default" : 2, + "description" : "Minimum number of available replicas per object to allow I/O", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "network" : { + "description" : "Use specific network for all ceph related traffic", + "format" : "CIDR", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_bits" : { + "default" : 6, + "description" : "Placement group bits, used to specify the default number of placement groups.\n\nDepreacted. This setting was deprecated in recent Ceph versions.", + "maximum" : 14, + "minimum" : 6, + "optional" : 1, + "type" : "integer", + "typetext" : " (6 - 14)" + }, + "size" : { + "default" : 3, + "description" : "Targeted number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 7)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/init", + "text" : "init" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop ceph services.", + "method" : "POST", + "name" : "stop", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "default" : "ceph.target", + "description" : "Ceph service name.", + "optional" : 1, + "pattern" : "(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/stop", + "text" : "stop" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start ceph services.", + "method" : "POST", + "name" : "start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "default" : "ceph.target", + "description" : "Ceph service name.", + "optional" : 1, + "pattern" : "(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Restart ceph services.", + "method" : "POST", + "name" : "restart", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "default" : "ceph.target", + "description" : "Ceph service name.", + "optional" : 1, + "pattern" : "(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/restart", + "text" : "restart" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the Ceph cluster status (raw 'ceph status' output). The response is cluster-wide and identical to /cluster/ceph/status; this node-level alias exists for operator convenience.", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get OSD crush map", + "method" : "GET", + "name" : "crush", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/crush", + "text" : "crush" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read ceph log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "description" : "Maximum number of log lines to return. Defaults to the dump_logfile limit (typically 50) when omitted.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "start" : { + "description" : "Offset of the first log line to return (0-based).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Log-file line number (1-based).", + "type" : "integer" + }, + "t" : { + "description" : "Log line text.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List ceph rules.", + "method" : "GET", + "name" : "rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "name" : { + "description" : "Name of the CRUSH rule.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/rules", + "text" : "rules" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Heuristical check if it is safe to perform an action.", + "method" : "GET", + "name" : "cmd_safety", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Action to check", + "enum" : [ + "stop", + "destroy" + ], + "type" : "string" + }, + "id" : { + "description" : "ID of the service", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service type", + "enum" : [ + "osd", + "mon", + "mds" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "properties" : { + "safe" : { + "description" : "True if Ceph reports the requested action is safe.", + "type" : "boolean" + }, + "status" : { + "description" : "Human-readable status message from Ceph (typically the reason an action is not safe); absent when Ceph returned no message.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/cmd-safety", + "text" : "cmd-safety" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph", + "text" : "ceph" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the currently configured vzdump defaults.", + "method" : "GET", + "name" : "defaults", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions for the specified storage (or default storage if none specified). Some properties are only returned when the user has 'Sys.Audit' permissions for the node.", + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (in KiB/s).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "fleecing" : { + "description" : "Options for backup fleecing (VM only).", + "format" : "backup-fleecing", + "optional" : 1, + "type" : "string" + }, + "ionice" : { + "default" : 7, + "description" : "Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "mailnotification" : { + "default" : "always", + "description" : "Deprecated: use notification targets/matchers instead. Specify when to send a notification mail", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string" + }, + "notes-template" : { + "description" : "Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.", + "maxLength" : 1024, + "optional" : 1, + "requires" : "storage", + "type" : "string" + }, + "notification-mode" : { + "default" : "auto", + "description" : "Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.", + "enum" : [ + "auto", + "legacy-sendmail", + "notification-system" + ], + "optional" : 1, + "type" : "string" + }, + "pbs-change-detection-mode" : { + "description" : "PBS mode used to detect file changes and switch encoding format for container backups.", + "enum" : [ + "legacy", + "data", + "metadata" + ], + "optional" : 1, + "type" : "string" + }, + "performance" : { + "description" : "Other performance-related settings.", + "format" : "backup-performance", + "optional" : 1, + "type" : "string" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string" + }, + "protected" : { + "description" : "If true, mark backup(s) as protected.", + "optional" : 1, + "requires" : "storage", + "type" : "boolean" + }, + "prune-backups" : { + "default" : "keep-all=1", + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean" + }, + "remove" : { + "default" : 1, + "description" : "Prune older backups according to 'prune-backups'.", + "optional" : 1, + "type" : "boolean" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/vzdump/defaults", + "text" : "defaults" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Extract configuration from vzdump backup archive.", + "method" : "GET", + "name" : "extractconfig", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'VM.Backup' permissions on the backed up guest ID, and 'Datastore.AllocateSpace' on the backup storage.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/vzdump/extractconfig", + "text" : "extractconfig" + } + ], + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create backup.", + "method" : "POST", + "name" : "vzdump", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (in KiB/s).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "fleecing" : { + "description" : "Options for backup fleecing (VM only).", + "format" : "backup-fleecing", + "optional" : 1, + "type" : "string", + "typetext" : "[[enabled=]<1|0>] [,storage=]" + }, + "ionice" : { + "default" : 7, + "description" : "Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 8)" + }, + "job-id" : { + "description" : "The ID of the backup job. If set, the 'backup-job' metadata field of the backup notification will be set to this value. Only root@pam can set this parameter.", + "maxLength" : 50, + "optional" : 1, + "pattern" : "\\S+", + "type" : "string" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mailnotification" : { + "default" : "always", + "description" : "Deprecated: use notification targets/matchers instead. Specify when to send a notification mail", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "notes-template" : { + "description" : "Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.", + "maxLength" : 1024, + "optional" : 1, + "requires" : "storage", + "type" : "string", + "typetext" : "" + }, + "notification-mode" : { + "default" : "auto", + "description" : "Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.", + "enum" : [ + "auto", + "legacy-sendmail", + "notification-system" + ], + "optional" : 1, + "type" : "string" + }, + "pbs-change-detection-mode" : { + "description" : "PBS mode used to detect file changes and switch encoding format for container backups.", + "enum" : [ + "legacy", + "data", + "metadata" + ], + "optional" : 1, + "type" : "string" + }, + "performance" : { + "description" : "Other performance-related settings.", + "format" : "backup-performance", + "optional" : 1, + "type" : "string", + "typetext" : "[max-workers=] [,pbs-entries-max=]" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protected" : { + "description" : "If true, mark backup(s) as protected.", + "optional" : 1, + "requires" : "storage", + "type" : "boolean", + "typetext" : "" + }, + "prune-backups" : { + "default" : "keep-all=1", + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove" : { + "default" : 1, + "description" : "Prune older backups according to 'prune-backups'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stdout" : { + "description" : "Write tar to stdout, not to a file.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'VM.Backup' permissions on any VM, and 'Datastore.AllocateSpace' on the backup storage (and fleecing storage when fleecing is used). The 'tmpdir', 'dumpdir', 'script' and 'job-id' parameters are restricted to the 'root@pam' user. The 'prune-backups' setting requires 'Datastore.Allocate' on the backup storage. The 'bwlimit', 'performance' and 'ionice' parameters require 'Sys.Modify' on '/'.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/vzdump", + "text" : "vzdump" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read service properties", + "method" : "GET", + "name" : "service_state", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "lxcfs", + "postfix", + "proxmox-firewall", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pve-lxc-syscalld", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "qmeventd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "active-state" : { + "description" : "Current state of the service process (systemd ActiveState).", + "enum" : [ + "active", + "inactive", + "failed", + "activating", + "deactivating", + "maintenance", + "reloading", + "refreshing", + "unknown" + ], + "type" : "string" + }, + "desc" : { + "description" : "Description of the service.", + "type" : "string" + }, + "name" : { + "description" : "Short identifier for the service (e.g., \"pveproxy\").", + "type" : "string" + }, + "service" : { + "description" : "Systemd unit name (e.g., pveproxy).", + "type" : "string" + }, + "state" : { + "description" : "Execution status of the service (systemd SubState).", + "enum" : [ + "dead", + "condition", + "start-pre", + "start", + "start-post", + "running", + "exited", + "reload", + "reload-signal", + "reload-notify", + "mounting", + "stop", + "stop-watchdog", + "stop-sigterm", + "stop-sigkill", + "stop-post", + "final-watchdog", + "final-sigterm", + "final-sigkill", + "failed", + "dead-before-auto-restart", + "failed-before-auto-restart", + "dead-resources-pinned", + "auto-restart", + "auto-restart-queued", + "cleaning", + "unknown" + ], + "type" : "string" + }, + "unit-state" : { + "description" : "Whether the service is enabled (systemd UnitFileState).", + "enum" : [ + "enabled", + "enabled-runtime", + "linked", + "linked-runtime", + "alias", + "masked", + "masked-runtime", + "static", + "disabled", + "indirect", + "generated", + "transient", + "bad", + "not-found", + "unknown" + ], + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/state", + "text" : "state" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start service.", + "method" : "POST", + "name" : "service_start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "lxcfs", + "postfix", + "proxmox-firewall", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pve-lxc-syscalld", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "qmeventd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop service.", + "method" : "POST", + "name" : "service_stop", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "lxcfs", + "postfix", + "proxmox-firewall", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pve-lxc-syscalld", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "qmeventd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/stop", + "text" : "stop" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Hard restart service. Use reload if you want to reduce interruptions.", + "method" : "POST", + "name" : "service_restart", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "lxcfs", + "postfix", + "proxmox-firewall", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pve-lxc-syscalld", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "qmeventd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/restart", + "text" : "restart" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Reload service. Falls back to restart if service cannot be reloaded.", + "method" : "POST", + "name" : "service_reload", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "lxcfs", + "postfix", + "proxmox-firewall", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pve-lxc-syscalld", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "qmeventd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/reload", + "text" : "reload" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "srvcmdidx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "lxcfs", + "postfix", + "proxmox-firewall", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pve-lxc-syscalld", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "qmeventd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/services/{service}", + "text" : "{service}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Service list.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "active-state" : { + "description" : "Current state of the service process (systemd ActiveState).", + "enum" : [ + "active", + "inactive", + "failed", + "activating", + "deactivating", + "maintenance", + "reloading", + "refreshing", + "unknown" + ], + "type" : "string" + }, + "desc" : { + "description" : "Description of the service.", + "type" : "string" + }, + "name" : { + "description" : "Short identifier for the service (e.g., \"pveproxy\").", + "type" : "string" + }, + "service" : { + "description" : "Systemd unit name (e.g., pveproxy).", + "type" : "string" + }, + "state" : { + "description" : "Execution status of the service (systemd SubState).", + "enum" : [ + "dead", + "condition", + "start-pre", + "start", + "start-post", + "running", + "exited", + "reload", + "reload-signal", + "reload-notify", + "mounting", + "stop", + "stop-watchdog", + "stop-sigterm", + "stop-sigkill", + "stop-post", + "final-watchdog", + "final-sigterm", + "final-sigkill", + "failed", + "dead-before-auto-restart", + "failed-before-auto-restart", + "dead-resources-pinned", + "auto-restart", + "auto-restart-queued", + "cleaning", + "unknown" + ], + "type" : "string" + }, + "unit-state" : { + "description" : "Whether the service is enabled (systemd UnitFileState).", + "enum" : [ + "enabled", + "enabled-runtime", + "linked", + "linked-runtime", + "alias", + "masked", + "masked-runtime", + "static", + "disabled", + "indirect", + "generated", + "transient", + "bad", + "not-found", + "unknown" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{service}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/services", + "text" : "services" + }, + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete subscription key of this node.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read subscription info.", + "method" : "GET", + "name" : "get", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "properties" : { + "checktime" : { + "description" : "Timestamp of the last check done.", + "optional" : 1, + "type" : "integer" + }, + "key" : { + "description" : "The subscription key, if set and permitted to access.", + "optional" : 1, + "type" : "string" + }, + "level" : { + "description" : "A short code for the subscription level.", + "optional" : 1, + "type" : "string" + }, + "message" : { + "description" : "A more human readable status message.", + "optional" : 1, + "type" : "string" + }, + "nextduedate" : { + "description" : "Next due date of the set subscription.", + "optional" : 1, + "type" : "string" + }, + "productname" : { + "description" : "Human readable productname of the set subscription.", + "optional" : 1, + "type" : "string" + }, + "regdate" : { + "description" : "Register date of the set subscription.", + "optional" : 1, + "type" : "string" + }, + "serverid" : { + "description" : "The server ID, if permitted to access.", + "optional" : 1, + "type" : "string" + }, + "signature" : { + "description" : "Signature for offline keys", + "optional" : 1, + "type" : "string" + }, + "sockets" : { + "description" : "The number of sockets for this host.", + "optional" : 1, + "type" : "integer" + }, + "status" : { + "description" : "The current subscription status.", + "enum" : [ + "new", + "notfound", + "active", + "invalid", + "expired", + "suspended" + ], + "type" : "string" + }, + "url" : { + "description" : "URL to the web shop.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Update subscription info.", + "method" : "POST", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "Always connect to server, even if local cache is still valid.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set subscription key.", + "method" : "PUT", + "name" : "set", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "key" : { + "description" : "Proxmox VE subscription key", + "maxLength" : 32, + "pattern" : "\\s*pve([1248])([cbsp])-[0-9a-f]{10}\\s*", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/subscription", + "text" : "subscription" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete network device configuration", + "method" : "DELETE", + "name" : "delete_network", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read network device configuration", + "method" : "GET", + "name" : "network_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "method" : { + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update network device configuration", + "method" : "PUT", + "name" : "update_network", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "address" : { + "description" : "IP address.", + "format" : "ipv4", + "optional" : 1, + "requires" : "netmask", + "type" : "string", + "typetext" : "" + }, + "address6" : { + "description" : "IP address.", + "format" : "ipv6", + "optional" : 1, + "requires" : "netmask6", + "type" : "string", + "typetext" : "" + }, + "autostart" : { + "description" : "Automatically start interface on boot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bond-primary" : { + "description" : "Specify the primary interface for active-backup bond.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bond_mode" : { + "description" : "Bonding mode.", + "enum" : [ + "balance-rr", + "active-backup", + "balance-xor", + "broadcast", + "802.3ad", + "balance-tlb", + "balance-alb", + "balance-slb", + "lacp-balance-slb", + "lacp-balance-tcp" + ], + "optional" : 1, + "type" : "string" + }, + "bond_xmit_hash_policy" : { + "description" : "Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.", + "enum" : [ + "layer2", + "layer2+3", + "layer3+4" + ], + "optional" : 1, + "type" : "string" + }, + "bridge_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge_vids" : { + "description" : "Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.", + "format" : "pve-vlan-id-or-range-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge_vlan_aware" : { + "description" : "Enable bridge vlan support.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cidr" : { + "description" : "IPv4 CIDR.", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cidr6" : { + "description" : "IPv6 CIDR.", + "format" : "CIDRv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comments" : { + "description" : "Comments", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comments6" : { + "description" : "Comments", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway" : { + "description" : "Default gateway address.", + "format" : "ipv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway6" : { + "description" : "Default ipv6 gateway address.", + "format" : "ipv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string", + "typetext" : "" + }, + "mtu" : { + "description" : "MTU.", + "maximum" : 65520, + "minimum" : 1280, + "optional" : 1, + "type" : "integer", + "typetext" : " (1280 - 65520)" + }, + "netmask" : { + "description" : "Network mask.", + "format" : "ipv4mask", + "optional" : 1, + "requires" : "address", + "type" : "string", + "typetext" : "" + }, + "netmask6" : { + "description" : "Network mask.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "requires" : "address6", + "type" : "integer", + "typetext" : " (0 - 128)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "ovs_bonds" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_bridge" : { + "description" : "The OVS bridge associated with a OVS port. This is required when you create an OVS port.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_options" : { + "description" : "OVS interface options.", + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_tag" : { + "description" : "Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4094)" + }, + "slaves" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Network interface type", + "enum" : [ + "bridge", + "bond", + "eth", + "alias", + "vlan", + "fabric", + "OVSBridge", + "OVSBond", + "OVSPort", + "OVSIntPort", + "vnet", + "unknown" + ], + "type" : "string" + }, + "vlan-id" : { + "description" : "vlan-id for a custom named vlan interface (ifupdown2 only).", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4094)" + }, + "vlan-raw-device" : { + "description" : "Specify the raw interface for the vlan interface.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/network/{iface}", + "text" : "{iface}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Revert network configuration changes.", + "method" : "DELETE", + "name" : "revert_network_changes", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List available networks", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Only list specific interface types.", + "enum" : [ + "bridge", + "bond", + "eth", + "alias", + "vlan", + "fabric", + "OVSBridge", + "OVSBond", + "OVSPort", + "OVSIntPort", + "vnet", + "any_bridge", + "any_local_bridge", + "include_sdn" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "active" : { + "description" : "Set to true if the interface is active.", + "optional" : 1, + "type" : "boolean" + }, + "address" : { + "description" : "IP address.", + "format" : "ipv4", + "optional" : 1, + "requires" : "netmask", + "type" : "string" + }, + "address6" : { + "description" : "IP address.", + "format" : "ipv6", + "optional" : 1, + "requires" : "netmask6", + "type" : "string" + }, + "autostart" : { + "description" : "Automatically start interface on boot.", + "optional" : 1, + "type" : "boolean" + }, + "bond-primary" : { + "description" : "Specify the primary interface for active-backup bond.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string" + }, + "bond_mode" : { + "description" : "Bonding mode.", + "enum" : [ + "balance-rr", + "active-backup", + "balance-xor", + "broadcast", + "802.3ad", + "balance-tlb", + "balance-alb", + "balance-slb", + "lacp-balance-slb", + "lacp-balance-tcp" + ], + "optional" : 1, + "type" : "string" + }, + "bond_xmit_hash_policy" : { + "description" : "Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.", + "enum" : [ + "layer2", + "layer2+3", + "layer3+4" + ], + "optional" : 1, + "type" : "string" + }, + "bridge-access" : { + "description" : "The bridge port access VLAN.", + "optional" : 1, + "type" : "integer" + }, + "bridge-arp-nd-suppress" : { + "description" : "Bridge port ARP/ND suppress flag.", + "optional" : 1, + "type" : "boolean" + }, + "bridge-learning" : { + "description" : "Bridge port learning flag.", + "optional" : 1, + "type" : "boolean" + }, + "bridge-multicast-flood" : { + "description" : "Bridge port multicast flood flag.", + "optional" : 1, + "type" : "boolean" + }, + "bridge-unicast-flood" : { + "description" : "Bridge port unicast flood flag.", + "optional" : 1, + "type" : "boolean" + }, + "bridge_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string" + }, + "bridge_vids" : { + "description" : "Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.", + "format" : "pve-vlan-id-or-range-list", + "optional" : 1, + "type" : "string" + }, + "bridge_vlan_aware" : { + "description" : "Enable bridge vlan support.", + "optional" : 1, + "type" : "boolean" + }, + "cidr" : { + "description" : "IPv4 CIDR.", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string" + }, + "cidr6" : { + "description" : "IPv6 CIDR.", + "format" : "CIDRv6", + "optional" : 1, + "type" : "string" + }, + "comments" : { + "description" : "Comments", + "optional" : 1, + "type" : "string" + }, + "comments6" : { + "description" : "Comments", + "optional" : 1, + "type" : "string" + }, + "exists" : { + "description" : "Set to true if the interface physically exists.", + "optional" : 1, + "type" : "boolean" + }, + "families" : { + "description" : "The network families.", + "items" : { + "description" : "A network family.", + "enum" : [ + "inet", + "inet6" + ], + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "gateway" : { + "description" : "Default gateway address.", + "format" : "ipv4", + "optional" : 1, + "type" : "string" + }, + "gateway6" : { + "description" : "Default ipv6 gateway address.", + "format" : "ipv6", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string" + }, + "link-type" : { + "description" : "The link type.", + "optional" : 1, + "type" : "string" + }, + "method" : { + "description" : "The network configuration method for IPv4.", + "enum" : [ + "loopback", + "dhcp", + "manual", + "static", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "method6" : { + "description" : "The network configuration method for IPv6.", + "enum" : [ + "loopback", + "dhcp", + "manual", + "static", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "mtu" : { + "description" : "MTU.", + "maximum" : 65520, + "minimum" : 1280, + "optional" : 1, + "type" : "integer" + }, + "netmask" : { + "description" : "Network mask.", + "format" : "ipv4mask", + "optional" : 1, + "requires" : "address", + "type" : "string" + }, + "netmask6" : { + "description" : "Network mask.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "requires" : "address6", + "type" : "integer" + }, + "options" : { + "description" : "A list of additional interface options for IPv4.", + "items" : { + "description" : "An interface property.", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "options6" : { + "description" : "A list of additional interface options for IPv6.", + "items" : { + "description" : "An interface property.", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "ovs_bonds" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string" + }, + "ovs_bridge" : { + "description" : "The OVS bridge associated with a OVS port. This is required when you create an OVS port.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string" + }, + "ovs_options" : { + "description" : "OVS interface options.", + "maxLength" : 1024, + "optional" : 1, + "type" : "string" + }, + "ovs_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string" + }, + "ovs_tag" : { + "description" : "Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "priority" : { + "description" : "The order of the interface.", + "optional" : 1, + "type" : "integer" + }, + "slaves" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Network interface type", + "enum" : [ + "bridge", + "bond", + "eth", + "alias", + "vlan", + "fabric", + "OVSBridge", + "OVSBond", + "OVSPort", + "OVSIntPort", + "vnet", + "unknown" + ], + "type" : "string" + }, + "uplink-id" : { + "description" : "The uplink ID.", + "optional" : 1, + "type" : "string" + }, + "vlan-id" : { + "description" : "vlan-id for a custom named vlan interface (ifupdown2 only).", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "vlan-protocol" : { + "description" : "The VLAN protocol.", + "enum" : [ + "802.1ad", + "802.1q" + ], + "optional" : 1, + "type" : "string" + }, + "vlan-raw-device" : { + "description" : "Specify the raw interface for the vlan interface.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string" + }, + "vxlan-id" : { + "description" : "The VXLAN ID.", + "optional" : 1, + "type" : "integer" + }, + "vxlan-local-tunnelip" : { + "description" : "The VXLAN local tunnel IP.", + "optional" : 1, + "type" : "string" + }, + "vxlan-physdev" : { + "description" : "The physical device for the VXLAN tunnel.", + "optional" : 1, + "type" : "string" + }, + "vxlan-svcnodeip" : { + "description" : "The VXLAN SVC node IP.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{iface}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create network device configuration", + "method" : "POST", + "name" : "create_network", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "address" : { + "description" : "IP address.", + "format" : "ipv4", + "optional" : 1, + "requires" : "netmask", + "type" : "string", + "typetext" : "" + }, + "address6" : { + "description" : "IP address.", + "format" : "ipv6", + "optional" : 1, + "requires" : "netmask6", + "type" : "string", + "typetext" : "" + }, + "autostart" : { + "description" : "Automatically start interface on boot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bond-primary" : { + "description" : "Specify the primary interface for active-backup bond.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bond_mode" : { + "description" : "Bonding mode.", + "enum" : [ + "balance-rr", + "active-backup", + "balance-xor", + "broadcast", + "802.3ad", + "balance-tlb", + "balance-alb", + "balance-slb", + "lacp-balance-slb", + "lacp-balance-tcp" + ], + "optional" : 1, + "type" : "string" + }, + "bond_xmit_hash_policy" : { + "description" : "Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.", + "enum" : [ + "layer2", + "layer2+3", + "layer3+4" + ], + "optional" : 1, + "type" : "string" + }, + "bridge_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge_vids" : { + "description" : "Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.", + "format" : "pve-vlan-id-or-range-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge_vlan_aware" : { + "description" : "Enable bridge vlan support.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cidr" : { + "description" : "IPv4 CIDR.", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cidr6" : { + "description" : "IPv6 CIDR.", + "format" : "CIDRv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comments" : { + "description" : "Comments", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comments6" : { + "description" : "Comments", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway" : { + "description" : "Default gateway address.", + "format" : "ipv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway6" : { + "description" : "Default ipv6 gateway address.", + "format" : "ipv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string", + "typetext" : "" + }, + "mtu" : { + "description" : "MTU.", + "maximum" : 65520, + "minimum" : 1280, + "optional" : 1, + "type" : "integer", + "typetext" : " (1280 - 65520)" + }, + "netmask" : { + "description" : "Network mask.", + "format" : "ipv4mask", + "optional" : 1, + "requires" : "address", + "type" : "string", + "typetext" : "" + }, + "netmask6" : { + "description" : "Network mask.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "requires" : "address6", + "type" : "integer", + "typetext" : " (0 - 128)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "ovs_bonds" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_bridge" : { + "description" : "The OVS bridge associated with a OVS port. This is required when you create an OVS port.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_options" : { + "description" : "OVS interface options.", + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_tag" : { + "description" : "Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4094)" + }, + "slaves" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Network interface type", + "enum" : [ + "bridge", + "bond", + "eth", + "alias", + "vlan", + "fabric", + "OVSBridge", + "OVSBond", + "OVSPort", + "OVSIntPort", + "vnet", + "unknown" + ], + "type" : "string" + }, + "vlan-id" : { + "description" : "vlan-id for a custom named vlan interface (ifupdown2 only).", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4094)" + }, + "vlan-raw-device" : { + "description" : "Specify the raw interface for the vlan interface.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Reload network configuration", + "method" : "PUT", + "name" : "reload_network_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "regenerate-frr" : { + "default" : 0, + "description" : "Whether FRR config generation should get skipped or not.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/network", + "text" : "network" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read task log.", + "download_allowed" : 1, + "method" : "GET", + "name" : "read_task_log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "download" : { + "description" : "Whether the tasklog file should be downloaded. This parameter can't be used in conjunction with other parameters", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "limit" : { + "default" : 50, + "description" : "The number of lines to read from the tasklog.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Start at this line when reading the tasklog", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "upid" : { + "description" : "The task's unique ID.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'Sys.Audit' permissions on '/nodes/' if they aren't the owner of the task.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/tasks/{upid}/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read task status.", + "method" : "GET", + "name" : "read_task_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "upid" : { + "description" : "The task's unique ID.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'Sys.Audit' permissions on '/nodes/' if they are not the owner of the task.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "exitstatus" : { + "optional" : 1, + "type" : "string" + }, + "id" : { + "type" : "string" + }, + "node" : { + "type" : "string" + }, + "pid" : { + "type" : "integer" + }, + "pstart" : { + "type" : "integer" + }, + "starttime" : { + "type" : "integer" + }, + "status" : { + "enum" : [ + "running", + "stopped" + ], + "type" : "string" + }, + "type" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/tasks/{upid}/status", + "text" : "status" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Stop a task.", + "method" : "DELETE", + "name" : "stop_task", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "upid" : { + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'Sys.Modify' permissions on '/nodes/' if they aren't the owner of the task.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "upid_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "upid" : { + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/tasks/{upid}", + "text" : "{upid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read task list for one node (finished tasks).", + "method" : "GET", + "name" : "node_tasks", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "errors" : { + "default" : 0, + "description" : "Only list tasks with a status of ERROR.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "limit" : { + "default" : 50, + "description" : "Only list this number of tasks.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Only list tasks since this UNIX epoch.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "source" : { + "default" : "archive", + "description" : "List archived, active or all tasks.", + "enum" : [ + "archive", + "active", + "all" + ], + "optional" : 1, + "type" : "string" + }, + "start" : { + "default" : 0, + "description" : "List tasks beginning from this offset.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "statusfilter" : { + "description" : "List of Task States that should be returned.", + "format" : "pve-task-status-type-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "typefilter" : { + "description" : "Only list tasks of this type (e.g., vzstart, vzdump).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "until" : { + "description" : "Only list tasks until this UNIX epoch.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "userfilter" : { + "description" : "Only list tasks from this user.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "Only list tasks for this VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "description" : "List task associated with the current user, or all task the user has 'Sys.Audit' permissions on /nodes/ (the the task runs on).", + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "endtime" : { + "optional" : 1, + "renderer" : "timestamp", + "title" : "Endtime", + "type" : "integer" + }, + "id" : { + "title" : "ID", + "type" : "string" + }, + "node" : { + "title" : "Node", + "type" : "string" + }, + "pid" : { + "title" : "PID", + "type" : "integer" + }, + "pstart" : { + "type" : "integer" + }, + "starttime" : { + "renderer" : "timestamp", + "title" : "Starttime", + "type" : "integer" + }, + "status" : { + "optional" : 1, + "title" : "Status", + "type" : "string" + }, + "type" : { + "title" : "Type", + "type" : "string" + }, + "upid" : { + "title" : "UPID", + "type" : "string" + }, + "user" : { + "title" : "User", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{upid}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/tasks", + "text" : "tasks" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote NFS server.", + "method" : "GET", + "name" : "nfsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "The server address (name or IP).", + "format" : "pve-storage-server", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "options" : { + "description" : "NFS export options.", + "type" : "string" + }, + "path" : { + "description" : "The exported path.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/nfs", + "text" : "nfs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote CIFS server.", + "method" : "GET", + "name" : "cifsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "domain" : { + "description" : "SMB domain (Workgroup).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "User password.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "The server address (name or IP).", + "format" : "pve-storage-server", + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "User name.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "description" : { + "description" : "Descriptive text from server.", + "type" : "string" + }, + "share" : { + "description" : "The cifs share name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/cifs", + "text" : "cifs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote Proxmox Backup Server.", + "method" : "GET", + "name" : "pbsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "User password or API token secret.", + "type" : "string", + "typetext" : "" + }, + "port" : { + "default" : 8007, + "description" : "Optional port.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "server" : { + "description" : "The server address (name or IP).", + "format" : "pve-storage-server", + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "User-name or API token-ID.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "Comment from server.", + "optional" : 1, + "type" : "string" + }, + "store" : { + "description" : "The datastore name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/pbs", + "text" : "pbs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote iSCSI server.", + "method" : "GET", + "name" : "iscsiscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "portal" : { + "description" : "The iSCSI portal (IP or DNS name with optional port).", + "format" : "pve-storage-portal-dns", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "portal" : { + "description" : "The iSCSI portal name.", + "type" : "string" + }, + "target" : { + "description" : "The iSCSI target name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/iscsi", + "text" : "iscsi" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local LVM volume groups.", + "method" : "GET", + "name" : "lvmscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "vg" : { + "description" : "The LVM logical volume group name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/lvm", + "text" : "lvm" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local LVM Thin Pools.", + "method" : "GET", + "name" : "lvmthinscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vg" : { + "maxLength" : 100, + "pattern" : "[a-zA-Z0-9\\.\\+\\_][a-zA-Z0-9\\.\\+\\_\\-]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "lv" : { + "description" : "The LVM Thin Pool name (LVM logical volume).", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/lvmthin", + "text" : "lvmthin" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan zfs pool list on local node.", + "method" : "GET", + "name" : "zfsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "pool" : { + "description" : "ZFS pool name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/zfs", + "text" : "zfs" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index of available scan methods", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "method" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{method}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/scan", + "text" : "scan" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List mediated device types for given PCI device.", + "method" : "GET", + "name" : "mdevscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pci-id-or-mapping" : { + "description" : "The PCI ID or mapping to list the mdev types for.", + "pattern" : "(?:(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\\.[0-9a-fA-F])|([a-zA-Z][a-zA-Z0-9_-]+)", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "available" : { + "description" : "The number of still available instances of this type.", + "type" : "integer" + }, + "description" : { + "description" : "Additional description of the type.", + "type" : "string" + }, + "name" : { + "description" : "A human readable name for the type.", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "The name of the mdev type.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev", + "text" : "mdev" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index of available pci methods", + "method" : "GET", + "name" : "pci_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pci-id-or-mapping" : { + "pattern" : "(?:(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\\.[0-9a-fA-F])|([a-zA-Z][a-zA-Z0-9_-]+)", + "type" : "string" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "method" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{method}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/hardware/pci/{pci-id-or-mapping}", + "text" : "{pci-id-or-mapping}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local PCI devices.", + "method" : "GET", + "name" : "pci_scan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pci-class-blacklist" : { + "default" : "05;06;0b", + "description" : "A list of blacklisted PCI classes, which will not be returned. Following are filtered by default: Memory Controller (05), Bridge (06) and Processor (0b).", + "format" : "string-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "verbose" : { + "default" : 1, + "description" : "If disabled, does only print the PCI IDs. Otherwise, additional information like vendor and device will be returned.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "class" : { + "description" : "The PCI Class of the device.", + "type" : "string" + }, + "device" : { + "description" : "The Device ID.", + "type" : "string" + }, + "device_name" : { + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "The PCI ID.", + "type" : "string" + }, + "iommugroup" : { + "description" : "The IOMMU group in which the device is in. If no IOMMU group is detected, it is set to -1.", + "type" : "integer" + }, + "mdev" : { + "description" : "If set, marks that the device is capable of creating mediated devices.", + "optional" : 1, + "type" : "boolean" + }, + "subsystem_device" : { + "description" : "The Subsystem Device ID.", + "optional" : 1, + "type" : "string" + }, + "subsystem_device_name" : { + "optional" : 1, + "type" : "string" + }, + "subsystem_vendor" : { + "description" : "The Subsystem Vendor ID.", + "optional" : 1, + "type" : "string" + }, + "subsystem_vendor_name" : { + "optional" : 1, + "type" : "string" + }, + "vendor" : { + "description" : "The Vendor ID.", + "type" : "string" + }, + "vendor_name" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/hardware/pci", + "text" : "pci" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local USB devices.", + "method" : "GET", + "name" : "usbscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "busnum" : { + "type" : "integer" + }, + "class" : { + "type" : "integer" + }, + "devnum" : { + "type" : "integer" + }, + "level" : { + "type" : "integer" + }, + "manufacturer" : { + "optional" : 1, + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "prodid" : { + "type" : "string" + }, + "product" : { + "optional" : 1, + "type" : "string" + }, + "serial" : { + "optional" : 1, + "type" : "string" + }, + "speed" : { + "type" : "string" + }, + "usbpath" : { + "optional" : 1, + "type" : "string" + }, + "vendid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/hardware/usb", + "text" : "usb" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index of hardware types", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{type}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/hardware", + "text" : "hardware" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all custom and default CPU models.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host architecture.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Custom models are filtered to those the current user has any of Mapping.{Audit,Use,Modify} on /mapping/cpu/; Sys.Audit on /nodes continues to grant visibility of all custom models for back-compat.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "abstract" : { + "description" : "True for PVE-internal abstract profiles like x86-64-v2, -v3, -v4. These do not correspond to a QEMU CPU type and cannot be used as a custom model's 'reported-model'.", + "optional" : 1, + "type" : "boolean" + }, + "custom" : { + "description" : "True if this is a custom CPU model.", + "type" : "boolean" + }, + "name" : { + "description" : "Name of the CPU model. Identifies it for subsequent API calls. Prefixed with 'custom-' for custom models.", + "type" : "string" + }, + "vendor" : { + "description" : "CPU vendor visible to the guest when this model is selected. Vendor of 'reported-model' in case of custom models.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/capabilities/qemu/cpu", + "text" : "cpu" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List of available VM-specific CPU flags. Returns an empty list for 'aarch64' as no VM-specific flags are defined for it yet.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "accel" : { + "default" : "kvm", + "description" : "Acceleration type to check node compatibility for.", + "enum" : [ + "kvm", + "tcg" + ], + "optional" : 1, + "type" : "string" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host architecture.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "description" : { + "description" : "Description of the CPU flag.", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the CPU flag.", + "type" : "string" + }, + "supported-on" : { + "description" : "List of nodes supporting the CPU flag with the selected acceleration type (\"accel\").", + "items" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/capabilities/qemu/cpu-flags", + "text" : "cpu-flags" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get available QEMU/KVM machine types.", + "method" : "GET", + "name" : "types", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host architecture.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "changes" : { + "description" : "Notable changes of a version, currently only set for +pveX versions.", + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "Full name of machine type and version.", + "type" : "string" + }, + "type" : { + "description" : "The machine type.", + "enum" : [ + "q35", + "i440fx" + ], + "type" : "string" + }, + "version" : { + "description" : "The machine version.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/capabilities/qemu/machines", + "text" : "machines" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get node-specific QEMU migration capabilities of the node. Requires the 'Sys.Audit' permission on '/nodes/'.", + "method" : "GET", + "name" : "capabilities", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "properties" : { + "has-dbus-vmstate" : { + "description" : "Whether the host supports live-migrating additional VM state via the dbus-vmstate helper.", + "type" : "boolean" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/capabilities/qemu/migration", + "text" : "migration" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "QEMU capabilities index.", + "method" : "GET", + "name" : "qemu_caps_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/capabilities/qemu", + "text" : "qemu" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Node capabilities index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/capabilities", + "text" : "capabilities" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Prune backups. Only those using the standard naming scheme are considered.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "prune-backups" : { + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Either 'qemu' or 'lxc'. Only consider backups for guests of this type.", + "enum" : [ + "qemu", + "lxc" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "Only prune backups for this VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "description" : "You need the 'Datastore.Allocate' privilege on the storage (or if a VM ID is specified, 'Datastore.AllocateSpace' and 'VM.Backup' for the VM).", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get prune information for backups. NOTE: this is only a preview and might not be what a subsequent prune call does if backups are removed/added in the meantime.", + "method" : "GET", + "name" : "dryrun", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "prune-backups" : { + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Either 'qemu' or 'lxc'. Only consider backups for guests of this type.", + "enum" : [ + "qemu", + "lxc" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "Only consider backups for this guest.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "ctime" : { + "description" : "Creation time of the backup (seconds since the UNIX epoch).", + "type" : "integer" + }, + "mark" : { + "description" : "Whether the backup would be kept or removed. Backups that are protected or don't use the standard naming scheme are not removed.", + "enum" : [ + "keep", + "remove", + "protected", + "renamed" + ], + "type" : "string" + }, + "type" : { + "description" : "One of 'qemu', 'lxc', 'openvz' or 'unknown'.", + "type" : "string" + }, + "vmid" : { + "description" : "The VM the backup belongs to.", + "optional" : 1, + "type" : "integer" + }, + "volid" : { + "description" : "Backup volume ID.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/prunebackups", + "text" : "prunebackups" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete volume", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delay" : { + "description" : "Time to wait for the task to finish. We return 'null' if the task finish within that time.", + "maximum" : 30, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 30)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need 'Datastore.Allocate' privilege on the storage (or 'Datastore.AllocateSpace' for backup volumes if you have VM.Backup privilege on the VM).", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "optional" : 1, + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get volume attributes", + "method" : "GET", + "name" : "info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "format" : { + "description" : "Format identifier ('raw', 'qcow2', 'subvol', 'iso', 'tgz' ...)", + "type" : "string" + }, + "notes" : { + "description" : "Optional notes.", + "optional" : 1, + "type" : "string" + }, + "path" : { + "description" : "The Path", + "type" : "string" + }, + "protected" : { + "description" : "Protection status. Currently only supported for backups.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Volume size in bytes.", + "renderer" : "bytes", + "type" : "integer" + }, + "used" : { + "description" : "Used space. Please note that most storage plugins do not report anything useful here.", + "renderer" : "bytes", + "type" : "integer" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Copy a volume. This is experimental code - do not use.", + "method" : "POST", + "name" : "copy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target volume identifier", + "type" : "string", + "typetext" : "" + }, + "target_node" : { + "description" : "Target node. Default is local node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Source volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update volume attributes", + "method" : "PUT", + "name" : "updateattributes", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "notes" : { + "description" : "The new notes.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protected" : { + "description" : "Protection status. Currently only supported for backups.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/content/{volume}", + "text" : "{volume}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List storage content.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "content" : { + "description" : "Only list content of this type.", + "format" : "pve-storage-content", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "Only list images for this VM", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "approximate-size" : { + "description" : "Approximate volume size in bytes. Present instead of 'size' for storages where determining the exact size has technical limitations. Will typically be an upper bound on the actual size, but the exact semantics depend on the storage plugin.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "ctime" : { + "description" : "Creation time (seconds since the UNIX Epoch).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "encrypted" : { + "description" : "If whole backup is encrypted, value is the fingerprint or '1' if encrypted. Only useful for the Proxmox Backup Server storage type.", + "optional" : 1, + "type" : "string" + }, + "format" : { + "description" : "Format identifier ('raw', 'qcow2', 'subvol', 'iso', 'tgz' ...)", + "type" : "string" + }, + "notes" : { + "description" : "Optional notes. If they contain multiple lines, only the first one is returned here.", + "optional" : 1, + "type" : "string" + }, + "parent" : { + "description" : "Volume identifier of parent (for linked cloned).", + "optional" : 1, + "type" : "string" + }, + "protected" : { + "description" : "Protection status. Currently only supported for backups.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Volume size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "used" : { + "description" : "Used space. Please note that most storage plugins do not report anything useful here.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "verification" : { + "description" : "Last backup verification result, only useful for PBS storages.", + "optional" : 1, + "properties" : { + "state" : { + "description" : "Last backup verification state.", + "type" : "string" + }, + "upid" : { + "description" : "Last backup verification UPID.", + "type" : "string" + } + }, + "type" : "object" + }, + "vmid" : { + "description" : "Associated Owner VMID.", + "optional" : 1, + "type" : "integer" + }, + "volid" : { + "description" : "Volume identifier.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{volid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Allocate disk images.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "filename" : { + "description" : "The name of the file to create.", + "type" : "string", + "typetext" : "" + }, + "format" : { + "description" : "Format of the image.", + "enum" : [ + "raw", + "qcow2", + "subvol", + "vmdk" + ], + "optional" : 1, + "requires" : "size", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "size" : { + "description" : "Size in kilobyte (1024 bytes). Optional suffixes 'M' (megabyte, 1024K) and 'G' (gigabyte, 1024M)", + "pattern" : "\\d+[MG]?", + "type" : "string" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "Specify owner VM", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateSpace" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Volume identifier", + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/storage/{storage}/content", + "text" : "content" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List files and directories for single file restore under the given path.", + "method" : "GET", + "name" : "list", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "filepath" : { + "description" : "base64-path to the directory or file being listed, or \"/\".", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Backup volume ID or name. Currently only PBS snapshots are supported.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "filepath" : { + "description" : "base64 path of the current entry", + "type" : "string" + }, + "leaf" : { + "description" : "If this entry is a leaf in the directory graph.", + "type" : "boolean" + }, + "mtime" : { + "description" : "Entry last-modified time (unix timestamp).", + "optional" : 1, + "type" : "integer" + }, + "size" : { + "description" : "Entry file size.", + "optional" : 1, + "type" : "integer" + }, + "text" : { + "description" : "Entry display text.", + "type" : "string" + }, + "type" : { + "description" : "Entry type.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/file-restore/list", + "text" : "list" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Extract a file or directory (as zip archive) from a PBS backup.", + "download_allowed" : 1, + "method" : "GET", + "name" : "download", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "filepath" : { + "description" : "base64-path to the directory or file to download.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "tar" : { + "default" : 0, + "description" : "Download dirs as 'tar.zst' instead of 'zip'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "volume" : { + "description" : "Backup volume ID or name. Currently only PBS snapshots are supported.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "any" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/file-restore/download", + "text" : "download" + } + ], + "leaf" : 0, + "path" : "/nodes/{node}/storage/{storage}/file-restore", + "text" : "file-restore" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read storage status.", + "method" : "GET", + "name" : "read_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "active" : { + "description" : "Set when storage is accessible.", + "optional" : 1, + "type" : "boolean" + }, + "avail" : { + "description" : "Available storage space in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "content" : { + "description" : "Allowed storage content types.", + "format" : "pve-storage-content-list", + "type" : "string" + }, + "enabled" : { + "description" : "Set when storage is enabled (not disabled).", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "description" : "Shared flag from storage configuration.", + "optional" : 1, + "type" : "boolean" + }, + "total" : { + "description" : "Total storage space in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "type" : { + "description" : "Storage type.", + "type" : "string" + }, + "used" : { + "description" : "Used storage space in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read storage RRD statistics (returns PNG).", + "method" : "GET", + "name" : "rrd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "ds" : { + "description" : "The list of datasources you want to display.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "filename" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/rrd", + "text" : "rrd" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read storage RRD statistics.", + "method" : "GET", + "name" : "rrddata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/rrddata", + "text" : "rrddata" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Upload templates, ISO images, OVAs and VM images.", + "method" : "POST", + "name" : "upload", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "checksum" : { + "description" : "The expected checksum of the file.", + "optional" : 1, + "requires" : "checksum-algorithm", + "type" : "string", + "typetext" : "" + }, + "checksum-algorithm" : { + "description" : "The algorithm to calculate the checksum of the file.", + "enum" : [ + "md5", + "sha1", + "sha224", + "sha256", + "sha384", + "sha512" + ], + "optional" : 1, + "requires" : "checksum", + "type" : "string" + }, + "content" : { + "description" : "Content type.", + "enum" : [ + "iso", + "vztmpl", + "import" + ], + "format" : "pve-storage-content", + "type" : "string" + }, + "filename" : { + "description" : "The name of the file to create. Caution: This will be normalized!", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "tmpfilename" : { + "description" : "The source file name. This parameter is usually set by the REST handler. You can only overwrite it when connecting to the trusted port on localhost.", + "optional" : 1, + "pattern" : "/var/tmp/pveupload-[0-9a-f]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/upload", + "text" : "upload" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Download templates, ISO images, OVAs and VM images by using an URL.", + "method" : "POST", + "name" : "download_url", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "checksum" : { + "description" : "The expected checksum of the file.", + "optional" : 1, + "requires" : "checksum-algorithm", + "type" : "string", + "typetext" : "" + }, + "checksum-algorithm" : { + "description" : "The algorithm to calculate the checksum of the file.", + "enum" : [ + "md5", + "sha1", + "sha224", + "sha256", + "sha384", + "sha512" + ], + "optional" : 1, + "requires" : "checksum", + "type" : "string" + }, + "compression" : { + "description" : "Decompress the downloaded file using the specified compression algorithm.", + "enum" : null, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "content" : { + "description" : "Content type.", + "enum" : [ + "iso", + "vztmpl", + "import" + ], + "format" : "pve-storage-content", + "type" : "string" + }, + "filename" : { + "description" : "The name of the file to create. Caution: This will be normalized!", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "url" : { + "description" : "The URL to download the file from.", + "pattern" : "https?://.*", + "type" : "string" + }, + "verify-certificates" : { + "default" : 1, + "description" : "If false, no SSL/TLS certificates will be verified.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.AccessNetwork" + ] + ] + ] + ], + "description" : "Requires allocation access on the storage and as this allows one to probe the (local!) host network indirectly it also requires one of Sys.Modify on / (for backwards compatibility) or the newer Sys.AccessNetwork privilege on the node." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/download-url", + "text" : "download-url" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Pull an OCI image from a registry.", + "method" : "POST", + "name" : "oci_registry_pull", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "filename" : { + "description" : "Custom destination file name of the OCI image. Caution: This will be normalized!", + "maxLength" : 255, + "minLength" : 1, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "reference" : { + "description" : "The reference to the OCI image to download.", + "pattern" : "^(?:(?:[a-zA-Z\\d]|[a-zA-Z\\d][a-zA-Z\\d-]*[a-zA-Z\\d])(?:\\.(?:[a-zA-Z\\d]|[a-zA-Z\\d][a-zA-Z\\d-]*[a-zA-Z\\d]))*(?::\\d+)?/)?[a-z\\d]+(?:(?:[._]|__|[-]*)[a-z\\d]+)*(?:/[a-z\\d]+(?:(?:[._]|__|[-]*)[a-z\\d]+)*)*:\\w[\\w.-]{0,127}$", + "type" : "string" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.AccessNetwork" + ] + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/oci-registry-pull", + "text" : "oci-registry-pull" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the base parameters for creating a guest which imports data from a foreign importable guest, like an ESXi VM", + "method" : "GET", + "name" : "get_import_metadata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier for the guest archive/entry.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "description" : "Information about how to import a guest.", + "properties" : { + "create-args" : { + "additionalProperties" : 1, + "description" : "Parameters which can be used in a call to create a VM or container.", + "type" : "object" + }, + "disks" : { + "additionalProperties" : 1, + "description" : "Recognised disk volumes as `$bus$id` => `$storeid:$path` map.", + "optional" : 1, + "type" : "object" + }, + "net" : { + "additionalProperties" : 1, + "description" : "Recognised network interfaces as `net$id` => { ...params } object.", + "optional" : 1, + "type" : "object" + }, + "source" : { + "description" : "The type of the import-source of this guest volume.", + "enum" : [ + "esxi" + ], + "type" : "string" + }, + "type" : { + "description" : "The type of guest this is going to produce.", + "enum" : [ + "vm" + ], + "type" : "string" + }, + "warnings" : { + "description" : "List of known issues that can affect the import of a guest. Note that lack of warning does not imply that there cannot be any problems.", + "items" : { + "additionalProperties" : 1, + "properties" : { + "key" : { + "description" : "Related subject (config) key of warning.", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "What this warning is about.", + "enum" : [ + "cdrom-image-ignored", + "efi-state-lost", + "guest-is-running", + "nvme-unsupported", + "ova-needs-extracting", + "ovmf-with-lsi-unsupported", + "serial-port-socket-only" + ], + "type" : "string" + }, + "value" : { + "description" : "Related subject (config) value of warning.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/import-metadata", + "text" : "import-metadata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Return identity information for this storage instance.", + "method" : "GET", + "name" : "identity", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "id" : { + "description" : "Unique identifier for this storage instance. The exact format and semantics depend on the storage plugin type.", + "type" : "string" + }, + "type" : { + "description" : "The type of the storage.", + "enum" : [ + "btrfs", + "cephfs", + "cifs", + "dir", + "esxi", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/identity", + "text" : "identity" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "diridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/storage/{storage}", + "text" : "{storage}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get status for all datastores.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "content" : { + "description" : "Only list stores which support this content type.", + "format" : "pve-storage-content-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enabled" : { + "default" : 0, + "description" : "Only list stores which are enabled (not disabled in config).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "format" : { + "default" : 0, + "description" : "Include information about formats", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Only list status for specified storage", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "If target is different to 'node', we only lists shared storages which content is accessible on this 'node' and the specified 'target' node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "active" : { + "description" : "Set when storage is accessible.", + "optional" : 1, + "type" : "boolean" + }, + "avail" : { + "description" : "Available storage space in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "content" : { + "description" : "Allowed storage content types.", + "format" : "pve-storage-content-list", + "type" : "string" + }, + "enabled" : { + "description" : "Set when storage is enabled (not disabled).", + "optional" : 1, + "type" : "boolean" + }, + "formats" : { + "description" : "Lists the supported and default format. Use 'formats' instead. Only included if 'format' parameter is set.", + "optional" : 1, + "properties" : { + "default" : { + "description" : "The default format of the storage.", + "enum" : [ + "qcow2", + "raw", + "subvol", + "vmdk" + ], + "type" : "string" + }, + "supported" : { + "description" : "The list of supported formats", + "items" : { + "enum" : [ + "qcow2", + "raw", + "subvol", + "vmdk" + ], + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "select_existing" : { + "description" : "Instead of creating new volumes, one must select one that is already existing. Only included if 'format' parameter is set.", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "description" : "Shared flag from storage configuration.", + "optional" : 1, + "type" : "boolean" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string" + }, + "total" : { + "description" : "Total storage space in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "type" : { + "description" : "Storage type.", + "type" : "string" + }, + "used" : { + "description" : "Used storage space in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "used_fraction" : { + "description" : "Used fraction (used/total).", + "optional" : 1, + "renderer" : "fraction_as_percentage", + "type" : "number" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{storage}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/storage", + "text" : "storage" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove an LVM Volume Group.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cleanup-config" : { + "default" : 0, + "description" : "Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cleanup-disks" : { + "default" : 0, + "description" : "Also wipe disks so they can be repurposed afterwards.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/lvm/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List LVM Volume Groups", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "children" : { + "items" : { + "properties" : { + "children" : { + "description" : "The underlying physical volumes", + "items" : { + "properties" : { + "free" : { + "description" : "The free bytes in the physical volume", + "type" : "integer" + }, + "leaf" : { + "type" : "boolean" + }, + "name" : { + "description" : "The name of the physical volume", + "type" : "string" + }, + "size" : { + "description" : "The size of the physical volume in bytes", + "type" : "integer" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "free" : { + "description" : "The free bytes in the volume group", + "type" : "integer" + }, + "leaf" : { + "type" : "boolean" + }, + "name" : { + "description" : "The name of the volume group", + "type" : "string" + }, + "size" : { + "description" : "The size of the volume group in bytes", + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "leaf" : { + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create an LVM Volume Group", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storage" : { + "default" : 0, + "description" : "Configure storage using the Volume Group", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "device" : { + "description" : "The block device you want to create the volume group on", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks/lvm", + "text" : "lvm" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove an LVM thin pool.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cleanup-config" : { + "default" : 0, + "description" : "Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cleanup-disks" : { + "default" : 0, + "description" : "Also wipe disks so they can be repurposed afterwards.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "volume-group" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/lvmthin/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List LVM thinpools", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "lv" : { + "description" : "The name of the thinpool.", + "type" : "string" + }, + "lv_size" : { + "description" : "The size of the thinpool in bytes.", + "type" : "integer" + }, + "metadata_size" : { + "description" : "The size of the metadata lv in bytes.", + "type" : "integer" + }, + "metadata_used" : { + "description" : "The used bytes of the metadata lv.", + "type" : "integer" + }, + "used" : { + "description" : "The used bytes of the thinpool.", + "type" : "integer" + }, + "vg" : { + "description" : "The associated volume group.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create an LVM thinpool", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storage" : { + "default" : 0, + "description" : "Configure storage using the thinpool.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "device" : { + "description" : "The block device you want to create the thinpool on.", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks/lvmthin", + "text" : "lvmthin" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Unmounts the storage and removes the mount unit.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cleanup-config" : { + "default" : 0, + "description" : "Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cleanup-disks" : { + "default" : 0, + "description" : "Also wipe disk so it can be repurposed afterwards.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/directory/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "PVE Managed Directory storages.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "device" : { + "description" : "The mounted device.", + "type" : "string" + }, + "options" : { + "description" : "The mount options.", + "type" : "string" + }, + "path" : { + "description" : "The mount path.", + "type" : "string" + }, + "type" : { + "description" : "The filesystem type.", + "type" : "string" + }, + "unitfile" : { + "description" : "The path of the mount unit.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a Filesystem on an unused disk. Will be mounted under '/mnt/pve/NAME'.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storage" : { + "default" : 0, + "description" : "Configure storage using the directory.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "device" : { + "description" : "The block device you want to create the filesystem on.", + "type" : "string", + "typetext" : "" + }, + "filesystem" : { + "default" : "ext4", + "description" : "The desired filesystem.", + "enum" : [ + "ext4", + "xfs" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks/directory", + "text" : "directory" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy a ZFS pool.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cleanup-config" : { + "default" : 0, + "description" : "Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cleanup-disks" : { + "default" : 0, + "description" : "Also wipe disks so they can be repurposed afterwards.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get details about a zpool.", + "method" : "GET", + "name" : "detail", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "action" : { + "description" : "Information about the recommended action to fix the state.", + "optional" : 1, + "type" : "string" + }, + "children" : { + "description" : "The pool configuration information, including the vdevs for each section (e.g. spares, cache), may be nested.", + "items" : { + "properties" : { + "cksum" : { + "optional" : 1, + "type" : "number" + }, + "msg" : { + "description" : "An optional message about the vdev.", + "type" : "string" + }, + "name" : { + "description" : "The name of the vdev or section.", + "type" : "string" + }, + "read" : { + "optional" : 1, + "type" : "number" + }, + "state" : { + "description" : "The state of the vdev.", + "optional" : 1, + "type" : "string" + }, + "write" : { + "optional" : 1, + "type" : "number" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "errors" : { + "description" : "Information about the errors on the zpool.", + "type" : "string" + }, + "name" : { + "description" : "The name of the zpool.", + "type" : "string" + }, + "scan" : { + "description" : "Information about the last/current scrub.", + "optional" : 1, + "type" : "string" + }, + "state" : { + "description" : "The state of the zpool.", + "type" : "string" + }, + "status" : { + "description" : "Information about the state of the zpool.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/zfs/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List Zpools.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "alloc" : { + "description" : "", + "type" : "integer" + }, + "dedup" : { + "description" : "", + "type" : "number" + }, + "frag" : { + "description" : "", + "type" : "integer" + }, + "free" : { + "description" : "", + "type" : "integer" + }, + "health" : { + "description" : "", + "type" : "string" + }, + "name" : { + "description" : "", + "type" : "string" + }, + "size" : { + "description" : "", + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a ZFS pool.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storage" : { + "default" : 0, + "description" : "Configure storage using the zpool.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ashift" : { + "default" : 12, + "description" : "Pool sector size exponent.", + "maximum" : 16, + "minimum" : 9, + "optional" : 1, + "type" : "integer", + "typetext" : " (9 - 16)" + }, + "compression" : { + "default" : "on", + "description" : "The compression algorithm to use.", + "enum" : [ + "on", + "off", + "gzip", + "lz4", + "lzjb", + "zle", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "devices" : { + "description" : "The block devices you want to create the zpool on.", + "format" : "string-list", + "type" : "string", + "typetext" : "" + }, + "draid-config" : { + "format" : { + "data" : { + "description" : "The number of data devices per redundancy group. (dRAID)", + "minimum" : 1, + "type" : "integer" + }, + "spares" : { + "description" : "Number of dRAID spares.", + "minimum" : 0, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "data= ,spares=" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "raidlevel" : { + "description" : "The RAID level to use.", + "enum" : [ + "single", + "mirror", + "raid10", + "raidz", + "raidz2", + "raidz3", + "draid", + "draid2", + "draid3" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks/zfs", + "text" : "zfs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local disks.", + "method" : "GET", + "name" : "list", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "include-partitions" : { + "default" : 0, + "description" : "Also include partitions.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skipsmart" : { + "default" : 0, + "description" : "Skip smart checks.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "type" : { + "description" : "Only list specific types of disks.", + "enum" : [ + "unused", + "journal_disks" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit" + ] + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "devpath" : { + "description" : "The device path", + "type" : "string" + }, + "gpt" : { + "type" : "boolean" + }, + "health" : { + "optional" : 1, + "type" : "string" + }, + "model" : { + "optional" : 1, + "type" : "string" + }, + "mounted" : { + "type" : "boolean" + }, + "osdid" : { + "type" : "integer" + }, + "osdid-list" : { + "items" : { + "type" : "integer" + }, + "type" : "array" + }, + "parent" : { + "description" : "For partitions only. The device path of the disk the partition resides on.", + "optional" : 1, + "type" : "string" + }, + "serial" : { + "optional" : 1, + "type" : "string" + }, + "size" : { + "type" : "integer" + }, + "used" : { + "optional" : 1, + "type" : "string" + }, + "vendor" : { + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/list", + "text" : "list" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get SMART Health of a disk.", + "method" : "GET", + "name" : "smart", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "disk" : { + "description" : "Block device name", + "pattern" : "^/dev/[a-zA-Z0-9\\/]+$", + "type" : "string" + }, + "healthonly" : { + "description" : "If true returns only the health status", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "attributes" : { + "optional" : 1, + "type" : "array" + }, + "health" : { + "type" : "string" + }, + "text" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/smart", + "text" : "smart" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Initialize Disk with GPT", + "method" : "POST", + "name" : "initgpt", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "disk" : { + "description" : "Block device name", + "pattern" : "^/dev/[a-zA-Z0-9\\/]+$", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "uuid" : { + "description" : "UUID for the GPT table", + "maxLength" : 36, + "optional" : 1, + "pattern" : "[a-fA-F0-9\\-]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/initgpt", + "text" : "initgpt" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Wipe a disk or partition.", + "method" : "PUT", + "name" : "wipe_disk", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "disk" : { + "description" : "Block device name", + "pattern" : "^/dev/[a-zA-Z0-9\\/]+$", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/wipedisk", + "text" : "wipedisk" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Node index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks", + "text" : "disks" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List available updates.", + "method" : "GET", + "name" : "list_updates", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "Arch" : { + "description" : "Package Architecture.", + "enum" : [ + "armhf", + "arm64", + "amd64", + "ppc64el", + "risc64", + "s390x", + "all" + ], + "type" : "string" + }, + "Description" : { + "description" : "Package description.", + "type" : "string" + }, + "NotifyStatus" : { + "description" : "Version for which PVE has already sent an update notification for.", + "optional" : 1, + "type" : "string" + }, + "OldVersion" : { + "description" : "Old version currently installed.", + "optional" : 1, + "type" : "string" + }, + "Origin" : { + "description" : "Package origin, e.g., 'Proxmox' or 'Debian'.", + "type" : "string" + }, + "Package" : { + "description" : "Package name.", + "type" : "string" + }, + "Priority" : { + "description" : "Package priority.", + "type" : "string" + }, + "Section" : { + "description" : "Package section.", + "type" : "string" + }, + "Title" : { + "description" : "Package title.", + "type" : "string" + }, + "Version" : { + "description" : "New version to be updated to.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "This is used to resynchronize the package index files from their sources (apt-get update).", + "method" : "POST", + "name" : "update_database", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "notify" : { + "default" : 0, + "description" : "Send notification about new packages.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "quiet" : { + "default" : 0, + "description" : "Only produces output suitable for logging, omitting progress indicators.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/apt/update", + "text" : "update" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get package changelogs.", + "method" : "GET", + "name" : "changelog", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Package name.", + "pattern" : "(?^:[a-z0-9][-+.a-z0-9:]+)", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "version" : { + "description" : "Package version.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/apt/changelog", + "text" : "changelog" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get APT repository information.", + "method" : "GET", + "name" : "repositories", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "description" : "Result from parsing the APT repository files in /etc/apt/.", + "properties" : { + "digest" : { + "description" : "Common digest of all files.", + "type" : "string" + }, + "errors" : { + "description" : "List of problematic repository files.", + "items" : { + "properties" : { + "error" : { + "description" : "The error message", + "type" : "string" + }, + "path" : { + "description" : "Path to the problematic file.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "files" : { + "description" : "List of parsed repository files.", + "items" : { + "properties" : { + "digest" : { + "description" : "Digest of the file as bytes.", + "items" : { + "type" : "integer" + }, + "type" : "array" + }, + "file-type" : { + "description" : "Format of the file.", + "enum" : [ + "list", + "sources" + ], + "type" : "string" + }, + "path" : { + "description" : "Path to the problematic file.", + "type" : "string" + }, + "repositories" : { + "description" : "The parsed repositories.", + "items" : { + "properties" : { + "Comment" : { + "description" : "Associated comment", + "optional" : 1, + "type" : "string" + }, + "Components" : { + "description" : "List of repository components", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "Enabled" : { + "description" : "Whether the repository is enabled or not", + "type" : "boolean" + }, + "FileType" : { + "description" : "Format of the defining file.", + "enum" : [ + "list", + "sources" + ], + "type" : "string" + }, + "Options" : { + "description" : "Additional options", + "items" : { + "properties" : { + "Key" : { + "type" : "string" + }, + "Values" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "Suites" : { + "description" : "List of package distribuitions", + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "Types" : { + "description" : "List of package types.", + "items" : { + "enum" : [ + "deb", + "deb-src" + ], + "type" : "string" + }, + "type" : "array" + }, + "URIs" : { + "description" : "List of repository URIs.", + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "infos" : { + "description" : "Additional information/warnings for APT repositories.", + "items" : { + "properties" : { + "index" : { + "description" : "Index of the associated repository within the file.", + "type" : "string" + }, + "kind" : { + "description" : "Kind of the information (e.g. warning).", + "type" : "string" + }, + "message" : { + "description" : "Information message.", + "type" : "string" + }, + "path" : { + "description" : "Path to the associated file.", + "type" : "string" + }, + "property" : { + "description" : "Property from which the info originates.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "standard-repos" : { + "description" : "List of standard repositories and their configuration status", + "items" : { + "properties" : { + "handle" : { + "description" : "Handle to identify the repository.", + "type" : "string" + }, + "name" : { + "description" : "Full name of the repository.", + "type" : "string" + }, + "status" : { + "description" : "Indicating enabled/disabled status, if the repository is configured.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Change the properties of a repository. Currently only allows enabling/disabling.", + "method" : "POST", + "name" : "change_repository", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Digest to detect modifications.", + "maxLength" : 80, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enabled" : { + "description" : "Whether the repository should be enabled or not.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "index" : { + "description" : "Index within the file (starting from 0).", + "type" : "integer", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "Path to the containing file.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Add a standard repository to the configuration", + "method" : "PUT", + "name" : "add_repository", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Digest to detect modifications.", + "maxLength" : 80, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "handle" : { + "description" : "Handle that identifies a repository.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/apt/repositories", + "text" : "repositories" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get package information for important Proxmox packages.", + "method" : "GET", + "name" : "versions", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "Arch" : { + "description" : "Package Architecture.", + "enum" : [ + "armhf", + "arm64", + "amd64", + "ppc64el", + "risc64", + "s390x", + "all" + ], + "type" : "string" + }, + "CurrentState" : { + "description" : "Current state of the package installed on the system.", + "enum" : [ + "Installed", + "NotInstalled", + "UnPacked", + "HalfConfigured", + "HalfInstalled", + "ConfigFiles" + ], + "type" : "string" + }, + "Description" : { + "description" : "Package description.", + "type" : "string" + }, + "ManagerVersion" : { + "description" : "Version of the currently running pve-manager API server.", + "optional" : 1, + "type" : "string" + }, + "NotifyStatus" : { + "description" : "Version for which PVE has already sent an update notification for.", + "optional" : 1, + "type" : "string" + }, + "OldVersion" : { + "description" : "Old version currently installed.", + "optional" : 1, + "type" : "string" + }, + "Origin" : { + "description" : "Package origin, e.g., 'Proxmox' or 'Debian'.", + "type" : "string" + }, + "Package" : { + "description" : "Package name.", + "type" : "string" + }, + "Priority" : { + "description" : "Package priority.", + "type" : "string" + }, + "RunningKernel" : { + "description" : "Kernel release, only for package 'proxmox-ve'.", + "optional" : 1, + "type" : "string" + }, + "Section" : { + "description" : "Package section.", + "type" : "string" + }, + "Title" : { + "description" : "Package title.", + "type" : "string" + }, + "Version" : { + "description" : "New version to be updated to.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/apt/versions", + "text" : "versions" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index for apt (Advanced Package Tool).", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/apt", + "text" : "apt" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment", + "optional" : 1, + "type" : "string" + }, + "dest" : { + "description" : "Restrict packet destination address", + "optional" : 1, + "type" : "string" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port", + "optional" : 1, + "type" : "string" + }, + "enable" : { + "description" : "Flag to enable/disable a rule", + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers", + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "description" : "IP version (4 or 6) - automatically determined from source/dest addresses", + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro", + "optional" : 1, + "type" : "string" + }, + "pos" : { + "description" : "Rule position in the ruleset", + "type" : "integer" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "Restrict packet source address", + "optional" : 1, + "type" : "string" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Rule type", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment", + "optional" : 1, + "type" : "string" + }, + "dest" : { + "description" : "Restrict packet destination address", + "optional" : 1, + "type" : "string" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port", + "optional" : 1, + "type" : "string" + }, + "enable" : { + "description" : "Flag to enable/disable a rule", + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers", + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "description" : "IP version (4 or 6) - automatically determined from source/dest addresses", + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro", + "optional" : 1, + "type" : "string" + }, + "pos" : { + "description" : "Rule position in the ruleset", + "type" : "integer" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'", + "optional" : 1, + "type" : "string" + }, + "source" : { + "description" : "Restrict packet source address", + "optional" : 1, + "type" : "string" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Rule type", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 0, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/firewall/rules", + "text" : "rules" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get host firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "enable" : { + "default" : 1, + "description" : "Enable host firewall rules.", + "optional" : 1, + "type" : "boolean" + }, + "log_level_forward" : { + "description" : "Log level for forwarded traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_nf_conntrack" : { + "default" : 0, + "description" : "Enable logging of conntrack information.", + "optional" : 1, + "type" : "boolean" + }, + "ndp" : { + "default" : 1, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean" + }, + "nf_conntrack_allow_invalid" : { + "default" : 0, + "description" : "Allow invalid packets on connection tracking.", + "optional" : 1, + "type" : "boolean" + }, + "nf_conntrack_helpers" : { + "default" : "", + "description" : "Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp", + "format" : "pve-fw-conntrack-helper", + "optional" : 1, + "type" : "string" + }, + "nf_conntrack_max" : { + "default" : 262144, + "description" : "Maximum number of tracked connections.", + "minimum" : 32768, + "optional" : 1, + "type" : "integer" + }, + "nf_conntrack_tcp_timeout_established" : { + "default" : 432000, + "description" : "Conntrack established timeout.", + "minimum" : 7875, + "optional" : 1, + "type" : "integer" + }, + "nf_conntrack_tcp_timeout_syn_recv" : { + "default" : 60, + "description" : "Conntrack syn recv timeout.", + "maximum" : 60, + "minimum" : 30, + "optional" : 1, + "type" : "integer" + }, + "nftables" : { + "default" : 0, + "description" : "Enable nftables based firewall (tech preview)", + "optional" : 1, + "type" : "boolean" + }, + "nosmurfs" : { + "description" : "Enable SMURFS filter.", + "optional" : 1, + "type" : "boolean" + }, + "protection_synflood" : { + "default" : 0, + "description" : "Enable synflood protection", + "optional" : 1, + "type" : "boolean" + }, + "protection_synflood_burst" : { + "default" : 1000, + "description" : "Synflood protection rate burst by ip src.", + "optional" : 1, + "type" : "integer" + }, + "protection_synflood_rate" : { + "default" : 200, + "description" : "Synflood protection rate syn/sec by ip src.", + "optional" : 1, + "type" : "integer" + }, + "smurf_log_level" : { + "description" : "Log level for SMURFS filter.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "tcp_flags_log_level" : { + "description" : "Log level for illegal tcp flags filter.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "tcpflags" : { + "default" : 0, + "description" : "Filter illegal combinations of TCP flags.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 1, + "description" : "Enable host firewall rules.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "log_level_forward" : { + "description" : "Log level for forwarded traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_nf_conntrack" : { + "default" : 0, + "description" : "Enable logging of conntrack information.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ndp" : { + "default" : 1, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nf_conntrack_allow_invalid" : { + "default" : 0, + "description" : "Allow invalid packets on connection tracking.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nf_conntrack_helpers" : { + "default" : "", + "description" : "Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp", + "format" : "pve-fw-conntrack-helper", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nf_conntrack_max" : { + "default" : 262144, + "description" : "Maximum number of tracked connections.", + "minimum" : 32768, + "optional" : 1, + "type" : "integer", + "typetext" : " (32768 - N)" + }, + "nf_conntrack_tcp_timeout_established" : { + "default" : 432000, + "description" : "Conntrack established timeout.", + "minimum" : 7875, + "optional" : 1, + "type" : "integer", + "typetext" : " (7875 - N)" + }, + "nf_conntrack_tcp_timeout_syn_recv" : { + "default" : 60, + "description" : "Conntrack syn recv timeout.", + "maximum" : 60, + "minimum" : 30, + "optional" : 1, + "type" : "integer", + "typetext" : " (30 - 60)" + }, + "nftables" : { + "default" : 0, + "description" : "Enable nftables based firewall (tech preview)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nosmurfs" : { + "description" : "Enable SMURFS filter.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "protection_synflood" : { + "default" : 0, + "description" : "Enable synflood protection", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "protection_synflood_burst" : { + "default" : 1000, + "description" : "Synflood protection rate burst by ip src.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "protection_synflood_rate" : { + "default" : 200, + "description" : "Synflood protection rate syn/sec by ip src.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "smurf_log_level" : { + "description" : "Log level for SMURFS filter.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "tcp_flags_log_level" : { + "description" : "Log level for illegal tcp flags filter.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "tcpflags" : { + "default" : 0, + "description" : "Filter illegal combinations of TCP flags.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/firewall/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read firewall log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display log since this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "until" : { + "description" : "Display log until this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/firewall/log", + "text" : "log" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/firewall", + "text" : "firewall" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get replication job status.", + "method" : "GET", + "name" : "job_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/replication/{id}/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read replication job log.", + "method" : "GET", + "name" : "read_job_log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/, or 'Sys.Audit' on '/nodes/'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/replication/{id}/log", + "text" : "log" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Schedule replication job to start as soon as possible.", + "method" : "POST", + "name" : "schedule_now", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Replicate permission on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/replication/{id}/schedule_now", + "text" : "schedule_now" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/replication/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List status of all replication jobs on this node.", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "guest" : { + "description" : "Only list replication jobs for this guest.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/replication", + "text" : "replication" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Revoke existing certificate from CA.", + "method" : "DELETE", + "name" : "revoke_certificate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Order a new certificate from ACME-compatible CA.", + "method" : "POST", + "name" : "new_certificate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "Overwrite existing custom certificate.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Renew existing certificate from CA.", + "method" : "PUT", + "name" : "renew_certificate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "Force renewal even if expiry is more than 30 days away.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/certificates/acme/certificate", + "text" : "certificate" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "ACME index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/certificates/acme", + "text" : "acme" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get information about node's certificates.", + "method" : "GET", + "name" : "info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "filename" : { + "optional" : 1, + "type" : "string" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "issuer" : { + "description" : "Certificate issuer name.", + "optional" : 1, + "type" : "string" + }, + "notafter" : { + "description" : "Certificate's notAfter timestamp (UNIX epoch).", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "notbefore" : { + "description" : "Certificate's notBefore timestamp (UNIX epoch).", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "pem" : { + "description" : "Certificate in PEM format", + "format" : "pem-certificate", + "optional" : 1, + "type" : "string" + }, + "public-key-bits" : { + "description" : "Certificate's public key size", + "optional" : 1, + "type" : "integer" + }, + "public-key-type" : { + "description" : "Certificate's public key algorithm", + "optional" : 1, + "type" : "string" + }, + "san" : { + "description" : "List of Certificate's SubjectAlternativeName entries.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "renderer" : "yaml", + "type" : "array" + }, + "subject" : { + "description" : "Certificate subject name.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/certificates/info", + "text" : "info" + }, + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "DELETE custom certificate chain and key.", + "method" : "DELETE", + "name" : "remove_custom_cert", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "restart" : { + "default" : 0, + "description" : "Restart pveproxy.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Upload or update custom certificate chain and key.", + "method" : "POST", + "name" : "upload_custom_cert", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "certificates" : { + "description" : "PEM encoded certificate (chain).", + "format" : "pem-certificate-chain", + "type" : "string", + "typetext" : "" + }, + "force" : { + "default" : 0, + "description" : "Overwrite existing custom or ACME certificate files.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "key" : { + "description" : "PEM encoded private key.", + "format" : "pem-string", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "restart" : { + "default" : 0, + "description" : "Restart pveproxy.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "filename" : { + "optional" : 1, + "type" : "string" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "issuer" : { + "description" : "Certificate issuer name.", + "optional" : 1, + "type" : "string" + }, + "notafter" : { + "description" : "Certificate's notAfter timestamp (UNIX epoch).", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "notbefore" : { + "description" : "Certificate's notBefore timestamp (UNIX epoch).", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "pem" : { + "description" : "Certificate in PEM format", + "format" : "pem-certificate", + "optional" : 1, + "type" : "string" + }, + "public-key-bits" : { + "description" : "Certificate's public key size", + "optional" : 1, + "type" : "integer" + }, + "public-key-type" : { + "description" : "Certificate's public key algorithm", + "optional" : 1, + "type" : "string" + }, + "san" : { + "description" : "List of Certificate's SubjectAlternativeName entries.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "renderer" : "yaml", + "type" : "array" + }, + "subject" : { + "description" : "Certificate subject name.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/certificates/custom", + "text" : "custom" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Node index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/certificates", + "text" : "certificates" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get node configuration options.", + "method" : "GET", + "name" : "get_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "property" : { + "default" : "all", + "description" : "Return only a specific property from the node configuration.", + "enum" : [ + "acme", + "acmedomain0", + "acmedomain1", + "acmedomain2", + "acmedomain3", + "acmedomain4", + "acmedomain5", + "ballooning-target", + "description", + "location", + "startall-onboot-delay", + "wakeonlan" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "acme" : { + "description" : "Node specific ACME settings.", + "format" : { + "account" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string" + }, + "domains" : { + "description" : "List of domains for this node's ACME certificate", + "format" : "pve-acme-domain-list", + "format_description" : "domain[;domain;...]", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "acmedomain[n]" : { + "description" : "ACME domain and validation plugin", + "format" : { + "alias" : { + "description" : "Alias for the Domain to verify ACME Challenge over DNS", + "format" : "pve-acme-alias", + "format_description" : "domain", + "optional" : 1, + "type" : "string" + }, + "domain" : { + "default_key" : 1, + "description" : "domain for this node's ACME certificate", + "format" : "pve-acme-domain", + "format_description" : "domain", + "type" : "string" + }, + "plugin" : { + "default" : "standalone", + "description" : "The ACME plugin ID", + "format" : "pve-configid", + "format_description" : "name of the plugin configuration", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "ballooning-target" : { + "default" : 80, + "description" : "RAM usage target for ballooning (in percent of total memory)", + "maximum" : 100, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "description" : { + "description" : "Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.", + "maxLength" : 65536, + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string" + }, + "location" : { + "description" : "The location of the node. Overrides the default from the datacenter config.", + "format" : { + "latitude" : { + "description" : "The latitude of the nodes location in degrees.", + "maximum" : 90, + "minimum" : -90, + "type" : "number" + }, + "longitude" : { + "description" : "The longitude of the nodes location in degrees.", + "maximum" : 180, + "minimum" : -180, + "type" : "number" + }, + "name" : { + "description" : "The name of the location of this node", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "optional" : 1, + "type" : "string" + }, + "startall-onboot-delay" : { + "default" : 0, + "description" : "Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.", + "maximum" : 300, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "wakeonlan" : { + "description" : "Node specific wake on LAN settings.", + "format" : { + "bind-interface" : { + "default" : "The interface carrying the default route", + "description" : "Bind to this interface when sending wake on LAN packet", + "format" : "pve-iface", + "format_description" : "bind interface", + "optional" : 1, + "type" : "string" + }, + "broadcast-address" : { + "default" : "255.255.255.255", + "description" : "IPv4 broadcast address to use when sending wake on LAN packet", + "format" : "ipv4", + "format_description" : "IPv4 broadcast address", + "optional" : 1, + "type" : "string" + }, + "mac" : { + "default_key" : 1, + "description" : "MAC address for wake on LAN", + "format" : "mac-addr", + "format_description" : "MAC address", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set node configuration options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acme" : { + "description" : "Node specific ACME settings.", + "format" : { + "account" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string" + }, + "domains" : { + "description" : "List of domains for this node's ACME certificate", + "format" : "pve-acme-domain-list", + "format_description" : "domain[;domain;...]", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[account=] [,domains=]" + }, + "acmedomain[n]" : { + "description" : "ACME domain and validation plugin", + "format" : { + "alias" : { + "description" : "Alias for the Domain to verify ACME Challenge over DNS", + "format" : "pve-acme-alias", + "format_description" : "domain", + "optional" : 1, + "type" : "string" + }, + "domain" : { + "default_key" : 1, + "description" : "domain for this node's ACME certificate", + "format" : "pve-acme-domain", + "format_description" : "domain", + "type" : "string" + }, + "plugin" : { + "default" : "standalone", + "description" : "The ACME plugin ID", + "format" : "pve-configid", + "format_description" : "name of the plugin configuration", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[domain=] [,alias=] [,plugin=]" + }, + "ballooning-target" : { + "default" : 80, + "description" : "RAM usage target for ballooning (in percent of total memory)", + "maximum" : 100, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 100)" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.", + "maxLength" : 65536, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "location" : { + "description" : "The location of the node. Overrides the default from the datacenter config.", + "format" : { + "latitude" : { + "description" : "The latitude of the nodes location in degrees.", + "maximum" : 90, + "minimum" : -90, + "type" : "number" + }, + "longitude" : { + "description" : "The longitude of the nodes location in degrees.", + "maximum" : 180, + "minimum" : -180, + "type" : "number" + }, + "name" : { + "description" : "The name of the location of this node", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "latitude= ,longitude= [,name=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "startall-onboot-delay" : { + "default" : 0, + "description" : "Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.", + "maximum" : 300, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 300)" + }, + "wakeonlan" : { + "description" : "Node specific wake on LAN settings.", + "format" : { + "bind-interface" : { + "default" : "The interface carrying the default route", + "description" : "Bind to this interface when sending wake on LAN packet", + "format" : "pve-iface", + "format_description" : "bind interface", + "optional" : 1, + "type" : "string" + }, + "broadcast-address" : { + "default" : "255.255.255.255", + "description" : "IPv4 broadcast address to use when sending wake on LAN packet", + "format" : "ipv4", + "format_description" : "IPv4 broadcast address", + "optional" : 1, + "type" : "string" + }, + "mac" : { + "default_key" : 1, + "description" : "MAC address for wake on LAN", + "format" : "mac-addr", + "format_description" : "MAC address", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[mac=] [,bind-interface=] [,broadcast-address=]" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/config", + "text" : "config" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get all routes for a fabric.", + "method" : "GET", + "name" : "routes", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "fabric" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/fabrics/{fabric}", + [ + "SDN.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "route" : { + "description" : "The CIDR block for this routing table entry.", + "type" : "string" + }, + "via" : { + "description" : "A list of nexthops for that route.", + "items" : { + "description" : "The IP address of the nexthop.", + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/sdn/fabrics/{fabric}/routes", + "text" : "routes" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get all neighbors for a fabric.", + "method" : "GET", + "name" : "neighbors", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "fabric" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/fabrics/{fabric}", + [ + "SDN.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "neighbor" : { + "description" : "The IP or hostname of the neighbor.", + "type" : "string" + }, + "status" : { + "description" : "The status of the neighbor, as returned by FRR.", + "type" : "string" + }, + "uptime" : { + "description" : "The uptime of this neighbor, as returned by FRR (e.g. 8h24m12s).", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/sdn/fabrics/{fabric}/neighbors", + "text" : "neighbors" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get all interfaces for a fabric.", + "method" : "GET", + "name" : "interfaces", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "fabric" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/fabrics/{fabric}", + [ + "SDN.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "name" : { + "description" : "The name of the network interface.", + "type" : "string" + }, + "state" : { + "description" : "The current state of the interface.", + "type" : "string" + }, + "type" : { + "description" : "The type of this interface in the fabric (e.g. Point-to-Point, Broadcast, ..).", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/sdn/fabrics/{fabric}/interfaces", + "text" : "interfaces" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index for SDN fabric status.", + "method" : "GET", + "name" : "diridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "fabric" : { + "description" : "Identifier for SDN fabrics", + "format" : "pve-sdn-fabric-id", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/fabrics/{fabric}", + [ + "SDN.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/sdn/fabrics/{fabric}", + "text" : "{fabric}" + } + ], + "leaf" : 0, + "path" : "/nodes/{node}/sdn/fabrics", + "text" : "fabrics" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List zone content.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "status" : { + "description" : "Status.", + "optional" : 1, + "type" : "string" + }, + "statusmsg" : { + "description" : "Status details", + "optional" : 1, + "type" : "string" + }, + "vnet" : { + "description" : "Vnet identifier.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{vnet}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/sdn/zones/{zone}/content", + "text" : "content" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get a list of all bridges (vnets) that are part of a zone, as well as the ports that are members of that bridge.", + "method" : "GET", + "name" : "bridges", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "zone name or \"localnetwork\"", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "description" : "List of bridges contained in the SDN zone.", + "properties" : { + "name" : { + "description" : "Name of the bridge.", + "type" : "string" + }, + "ports" : { + "description" : "All ports that are members of the bridge", + "items" : { + "description" : "Information about bridge ports.", + "properties" : { + "index" : { + "description" : "The index of the guests network device that this interface belongs to.", + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name of the bridge port.", + "type" : "string" + }, + "primary_vlan" : { + "description" : "The primary VLAN configured for the port of this bridge (= PVID). Only for VLAN-aware bridges.", + "optional" : 1, + "type" : "number" + }, + "vlans" : { + "description" : "A list of VLANs and VLAN ranges that are allowed for this bridge port in addition to the primary VLAN. Only for VLAN-aware bridges.", + "items" : { + "description" : "A single VLAN (123) or a VLAN range (234-435).", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "vmid" : { + "description" : "The ID of the guest that this interface belongs to.", + "optional" : 1, + "type" : "number" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "vlan_filtering" : { + "description" : "Whether VLAN filtering is enabled for this bridge (= VLAN-aware).", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/sdn/zones/{zone}/bridges", + "text" : "bridges" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the IP VRF of an EVPN zone.", + "method" : "GET", + "name" : "ip-vrf", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "Name of an EVPN zone.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "All entries in the VRF table of zone {zone} of the node.This does not include /32 routes for guests on this host,since they are handled via the respective vnet bridge directly.", + "items" : { + "properties" : { + "ip" : { + "description" : "The CIDR of the route table entry.", + "format" : "CIDR", + "type" : "string" + }, + "metric" : { + "description" : "This route's metric.", + "type" : "integer" + }, + "nexthops" : { + "description" : "A list of nexthops for the route table entry.", + "items" : { + "description" : "the interface name or ip address of the next hop", + "type" : "string" + }, + "type" : "array" + }, + "protocol" : { + "description" : "The protocol where this route was learned from (e.g. BGP).", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/sdn/zones/{zone}/ip-vrf", + "text" : "ip-vrf" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index for SDN zone status.", + "method" : "GET", + "name" : "diridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/sdn/zones/{zone}", + "text" : "{zone}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get status for all zones.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "status" : { + "description" : "Status of zone", + "enum" : [ + "available", + "pending", + "error" + ], + "type" : "string" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{zone}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/sdn/zones", + "text" : "zones" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the MAC VRF for a VNet in an EVPN zone.", + "method" : "GET", + "name" : "mac-vrf", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Require 'SDN.Audit' permissions on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "All routes from the MAC VRF that this node self-originates or has learned via BGP.", + "items" : { + "properties" : { + "ip" : { + "description" : "The IP address of the MAC VRF entry.", + "format" : "ip", + "type" : "string" + }, + "mac" : { + "description" : "The MAC address of the MAC VRF entry.", + "format" : "mac-addr", + "type" : "string" + }, + "nexthop" : { + "description" : "The IP address of the nexthop.", + "format" : "ip", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/sdn/vnets/{vnet}/mac-vrf", + "text" : "mac-vrf" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "diridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "maxLength" : 8, + "minLength" : 2, + "pattern" : "[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Require 'SDN.Audit' permissions on '/sdn/zones//'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/sdn/vnets/{vnet}", + "text" : "{vnet}" + } + ], + "leaf" : 0, + "path" : "/nodes/{node}/sdn/vnets", + "text" : "vnets" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN index.", + "method" : "GET", + "name" : "sdnindex", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/sdn", + "text" : "sdn" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "API version details", + "method" : "GET", + "name" : "version", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "release" : { + "description" : "The current installed Proxmox VE Release", + "type" : "string" + }, + "repoid" : { + "description" : "The short git commit hash ID from which this version was build", + "type" : "string" + }, + "version" : { + "description" : "The current installed pve-manager package version", + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/version", + "text" : "version" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read node status", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 1, + "properties" : { + "boot-info" : { + "description" : "Meta-information about the boot mode.", + "properties" : { + "mode" : { + "description" : "Through which firmware the system got booted.", + "enum" : [ + "efi", + "legacy-bios" + ], + "type" : "string" + }, + "secureboot" : { + "description" : "System is booted in secure mode, only applicable for the \"efi\" mode.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "cpu" : { + "description" : "The current cpu usage.", + "type" : "number" + }, + "cpuinfo" : { + "properties" : { + "cores" : { + "description" : "The number of physical cores of the CPU.", + "type" : "integer" + }, + "cpus" : { + "description" : "The number of logical threads of the CPU.", + "type" : "integer" + }, + "model" : { + "description" : "The CPU model", + "type" : "string" + }, + "sockets" : { + "description" : "The number of logical threads of the CPU.", + "type" : "integer" + } + }, + "type" : "object" + }, + "current-kernel" : { + "description" : "Meta-information about the currently booted kernel of this node.", + "properties" : { + "machine" : { + "description" : "Hardware (architecture) type", + "type" : "string" + }, + "release" : { + "description" : "OS kernel release (e.g., \"6.8.0\")", + "type" : "string" + }, + "sysname" : { + "description" : "OS kernel name (e.g., \"Linux\")", + "type" : "string" + }, + "version" : { + "description" : "OS kernel version with build info", + "type" : "string" + } + }, + "type" : "object" + }, + "loadavg" : { + "description" : "An array of load avg for 1, 5 and 15 minutes respectively.", + "items" : { + "description" : "The value of the load.", + "type" : "string" + }, + "type" : "array" + }, + "memory" : { + "properties" : { + "available" : { + "description" : "The available memory in bytes.", + "type" : "integer" + }, + "free" : { + "description" : "The free memory in bytes.", + "type" : "integer" + }, + "total" : { + "description" : "The total memory in bytes.", + "type" : "integer" + }, + "used" : { + "description" : "The used memory in bytes.", + "type" : "integer" + } + }, + "type" : "object" + }, + "pveversion" : { + "description" : "The PVE version string.", + "type" : "string" + }, + "rootfs" : { + "properties" : { + "avail" : { + "description" : "The available bytes in the root filesystem.", + "type" : "integer" + }, + "free" : { + "description" : "The free bytes on the root filesystem.", + "type" : "integer" + }, + "total" : { + "description" : "The total size of the root filesystem in bytes.", + "type" : "integer" + }, + "used" : { + "description" : "The used bytes in the root filesystem.", + "type" : "integer" + } + }, + "type" : "object" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Reboot or shutdown a node.", + "method" : "POST", + "name" : "node_cmd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "command" : { + "description" : "Specify the command.", + "enum" : [ + "reboot", + "shutdown" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read tap/vm network device interface counters", + "method" : "GET", + "name" : "netstat", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/netstat", + "text" : "netstat" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute multiple commands in order, root only.", + "method" : "POST", + "name" : "execute", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "commands" : { + "description" : "JSON encoded array of commands.", + "format" : "pve-command-batch", + "type" : "string", + "typetext" : "", + "verbose_description" : "JSON encoded array of commands, where each command is an object with the following properties:\n args: \n\t A set of parameter names and their values.\n\n method: (GET|POST|PUT|DELETE)\n\t A method related to the API endpoint (GET, POST etc.).\n\n path: \n\t A relative path to an API endpoint on this node.\n\n" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/execute", + "text" : "execute" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Try to wake a node via 'wake on LAN' network packet.", + "method" : "POST", + "name" : "wakeonlan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "target node for wake on LAN packet", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.PowerMgmt" + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "MAC address used to assemble the WoL magic packet.", + "format" : "mac-addr", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/wakeonlan", + "text" : "wakeonlan" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read node RRD statistics (returns PNG)", + "method" : "GET", + "name" : "rrd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "ds" : { + "description" : "The list of datasources you want to display.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year", + "decade" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "filename" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/rrd", + "text" : "rrd" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read node RRD statistics", + "method" : "GET", + "name" : "rrddata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year", + "decade" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/rrddata", + "text" : "rrddata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read system log", + "method" : "GET", + "name" : "syslog", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display all log since this date-time string.", + "optional" : 1, + "pattern" : "^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$", + "type" : "string" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "until" : { + "description" : "Display all log until this date-time string.", + "optional" : 1, + "pattern" : "^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/syslog", + "text" : "syslog" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read Journal", + "download_allowed" : 1, + "method" : "GET", + "name" : "journal", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "endcursor" : { + "description" : "End before the given Cursor. Conflicts with 'until'", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lastentries" : { + "description" : "Limit to the last X lines. Conflicts with a range.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display all log since this UNIX epoch. Conflicts with 'startcursor'.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "startcursor" : { + "description" : "Start after the given Cursor. Conflicts with 'since'", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "until" : { + "description" : "Display all log until this UNIX epoch. Conflicts with 'endcursor'.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/journal", + "text" : "journal" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a VNC Shell proxy.", + "method" : "POST", + "name" : "vncshell", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cmd" : { + "default" : "login", + "description" : "Run specific command or default to login (requires 'root@pam')", + "enum" : [ + "ceph_install", + "login", + "upgrade" + ], + "optional" : 1, + "type" : "string" + }, + "cmd-opts" : { + "default" : "", + "description" : "Add parameters to a command. Encoded as null terminated strings.", + "optional" : 1, + "requires" : "cmd", + "type" : "string", + "typetext" : "" + }, + "height" : { + "description" : "sets the height of the console in pixels.", + "maximum" : 2160, + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - 2160)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "websocket" : { + "description" : "use websocket instead of standard vnc.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "width" : { + "description" : "sets the width of the console in pixels.", + "maximum" : 4096, + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - 4096)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "cert" : { + "type" : "string" + }, + "password" : { + "description" : "Password used for authentication within the VNC protocol. Consists of printable ASCII characters ('!' .. '~').", + "optional" : 1, + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/vncshell", + "text" : "vncshell" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a VNC Shell proxy.", + "method" : "POST", + "name" : "termproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cmd" : { + "default" : "login", + "description" : "Run specific command or default to login (requires 'root@pam')", + "enum" : [ + "ceph_install", + "login", + "upgrade" + ], + "optional" : 1, + "type" : "string" + }, + "cmd-opts" : { + "default" : "", + "description" : "Add parameters to a command. Encoded as null terminated strings.", + "optional" : 1, + "requires" : "cmd", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "port" : { + "description" : "port used to bind termproxy to.", + "type" : "integer" + }, + "ticket" : { + "description" : "VNC ticket used to verify websocket connection.", + "type" : "string" + }, + "upid" : { + "description" : "UPID for termproxy worker task.", + "type" : "string" + }, + "user" : { + "description" : "user/token that generated the VNC ticket in `ticket`.", + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/termproxy", + "text" : "termproxy" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Opens a websocket for VNC traffic.", + "method" : "GET", + "name" : "vncwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Port number returned by previous 'vncshell' call.", + "maximum" : 5999, + "minimum" : 5900, + "type" : "integer", + "typetext" : " (5900 - 5999)" + }, + "vncticket" : { + "description" : "Ticket from previous call to 'vncshell'.", + "maxLength" : 512, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ], + "description" : "You also need to pass a valid ticket (vncticket)." + }, + "returns" : { + "properties" : { + "port" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/vncwebsocket", + "text" : "vncwebsocket" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a SPICE shell.", + "method" : "POST", + "name" : "spiceshell", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cmd" : { + "default" : "login", + "description" : "Run specific command or default to login (requires 'root@pam')", + "enum" : [ + "ceph_install", + "login", + "upgrade" + ], + "optional" : 1, + "type" : "string" + }, + "cmd-opts" : { + "default" : "", + "description" : "Add parameters to a command. Encoded as null terminated strings.", + "optional" : 1, + "requires" : "cmd", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "proxy" : { + "description" : "SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).", + "format" : "address", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 1, + "description" : "Returned values can be directly passed to the 'remote-viewer' application.", + "properties" : { + "host" : { + "type" : "string" + }, + "password" : { + "type" : "string" + }, + "proxy" : { + "type" : "string" + }, + "tls-port" : { + "type" : "integer" + }, + "type" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/spiceshell", + "text" : "spiceshell" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read DNS settings.", + "method" : "GET", + "name" : "dns", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "properties" : { + "dns1" : { + "description" : "First name server IP address.", + "optional" : 1, + "type" : "string" + }, + "dns2" : { + "description" : "Second name server IP address.", + "optional" : 1, + "type" : "string" + }, + "dns3" : { + "description" : "Third name server IP address.", + "optional" : 1, + "type" : "string" + }, + "search" : { + "description" : "Search domain for host-name lookup.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Write DNS settings.", + "method" : "PUT", + "name" : "update_dns", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dns1" : { + "description" : "First name server IP address.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dns2" : { + "description" : "Second name server IP address.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dns3" : { + "description" : "Third name server IP address.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "search" : { + "description" : "Search domain for host-name lookup.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/dns", + "text" : "dns" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read server time and time zone settings.", + "method" : "GET", + "name" : "time", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "properties" : { + "localtime" : { + "description" : "Seconds since 1970-01-01 00:00:00 (local time)", + "minimum" : 1297163644, + "renderer" : "timestamp_gmt", + "type" : "integer" + }, + "time" : { + "description" : "Seconds since 1970-01-01 00:00:00 UTC.", + "minimum" : 1297163644, + "renderer" : "timestamp", + "type" : "integer" + }, + "timezone" : { + "description" : "Time zone", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set time zone.", + "method" : "PUT", + "name" : "set_timezone", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timezone" : { + "description" : "Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/time", + "text" : "time" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get list of appliances.", + "method" : "GET", + "name" : "aplinfo", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Download appliance templates.", + "method" : "POST", + "name" : "apl_download", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage where the template will be stored", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "template" : { + "description" : "The template which will downloaded", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/aplinfo", + "text" : "aplinfo" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all tags for an OCI repository reference.", + "method" : "GET", + "name" : "query_oci_repo_tags", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "reference" : { + "description" : "The reference to the repository to query tags from.", + "pattern" : "^(?:(?:[a-zA-Z\\d]|[a-zA-Z\\d][a-zA-Z\\d-]*[a-zA-Z\\d])(?:\\.(?:[a-zA-Z\\d]|[a-zA-Z\\d][a-zA-Z\\d-]*[a-zA-Z\\d]))*(?::\\d+)?/)?[a-z\\d]+(?:(?:[._]|__|[-]*)[a-z\\d]+)*(?:/[a-z\\d]+(?:(?:[._]|__|[-]*)[a-z\\d]+)*)*$", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.AccessNetwork" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/query-oci-repo-tags", + "text" : "query-oci-repo-tags" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Query metadata of an URL: file size, file name and mime type.", + "method" : "GET", + "name" : "query_url_metadata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "url" : { + "description" : "The URL to query the metadata from.", + "pattern" : "https?://.*", + "type" : "string" + }, + "verify-certificates" : { + "default" : 1, + "description" : "If false, no SSL/TLS certificates will be verified.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.AccessNetwork" + ] + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "filename" : { + "optional" : 1, + "type" : "string" + }, + "mimetype" : { + "optional" : 1, + "type" : "string" + }, + "size" : { + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/query-url-metadata", + "text" : "query-url-metadata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Gather various systems information about a node", + "method" : "GET", + "name" : "report", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/report", + "text" : "report" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start all VMs and containers located on this node (by default only those with onboot=1).", + "method" : "POST", + "name" : "startall", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : "off", + "description" : "Issue start command even if virtual guest have 'onboot' not set or set to off.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "max-workers" : { + "description" : "Defines the maximum number of tasks running concurrently. If not set, uses 'max_workers' from datacenter.cfg, and if that's not set, the available CPU threads, clamped to a maximum of 8, are used.", + "maximum" : 64, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 64)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "Only consider guests from this comma separated list of VMIDs.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/startall", + "text" : "startall" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop all VMs and Containers.", + "method" : "POST", + "name" : "stopall", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force-stop" : { + "default" : 1, + "description" : "Force a hard-stop after the timeout.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "max-workers" : { + "description" : "Defines the maximum number of tasks running concurrently. If not set, uses 'max_workers' from datacenter.cfg, and if that's not set, the available CPU threads, clamped to a maximum of 8, are used.", + "maximum" : 64, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 64)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 180, + "description" : "Timeout for each guest shutdown task. Depending on `force-stop`, the shutdown gets then simply aborted or a hard-stop is forced.", + "maximum" : 7200, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 7200)" + }, + "vms" : { + "description" : "Only consider Guests with these IDs.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/stopall", + "text" : "stopall" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Suspend all VMs.", + "method" : "POST", + "name" : "suspendall", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "max-workers" : { + "description" : "Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg, and if that's not set the available'\n .' CPU threads, clamped to a maximum of 8, are used.", + "maximum" : 64, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 64)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "Only consider Guests with these IDs.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter. Additionally, you need 'VM.Config.Disk' on the '/vms/{vmid}' path and 'Datastore.AllocateSpace' for the configured state-storage(s)", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/suspendall", + "text" : "suspendall" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migrate all VMs and Containers.", + "method" : "POST", + "name" : "migrateall", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "max-workers" : { + "description" : "Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg. One of both must be set!", + "maximum" : 64, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 64)" + }, + "maxworkers" : { + "description" : "Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg. One of both must be set!Deprecated, use 'max-workers' instead.", + "maximum" : 64, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 64)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "Only consider Guests with these IDs.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "with-local-disks" : { + "description" : "Enable live storage migration for local disk", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The 'VM.Migrate' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/migrateall", + "text" : "migrateall" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the content of /etc/hosts.", + "method" : "GET", + "name" : "get_etc_hosts", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "data" : { + "description" : "The content of /etc/hosts.", + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Write /etc/hosts.", + "method" : "POST", + "name" : "write_etc_hosts", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "data" : { + "description" : "The target content of /etc/hosts.", + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/hosts", + "text" : "hosts" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Node index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}", + "text" : "{node}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Cluster node index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "cpu" : { + "description" : "CPU utilization.", + "optional" : 1, + "renderer" : "fraction_as_percentage", + "type" : "number" + }, + "level" : { + "description" : "Support level.", + "optional" : 1, + "type" : "string" + }, + "maxcpu" : { + "description" : "Number of available CPUs.", + "optional" : 1, + "type" : "integer" + }, + "maxmem" : { + "description" : "Number of available memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "mem" : { + "description" : "Used memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "ssl_fingerprint" : { + "description" : "The SSL fingerprint for the node certificate.", + "optional" : 1, + "type" : "string" + }, + "status" : { + "description" : "Node status.", + "enum" : [ + "unknown", + "online", + "offline" + ], + "type" : "string" + }, + "uptime" : { + "description" : "Node uptime in seconds.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{node}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes", + "text" : "nodes" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete storage configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read storage configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update storage configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "blocksize" : { + "description" : "ZFS block size", + "format" : "pve-storage-zfs-blocksize", + "format_description" : "a power of 2 with optional k or m suffix", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bwlimit" : { + "description" : "Set I/O bandwidth limit for various operations (in KiB/s).", + "format" : { + "clone" : { + "description" : "bandwidth limit in KiB/s for cloning disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "default" : { + "description" : "default bandwidth limit in KiB/s", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "migration" : { + "description" : "bandwidth limit in KiB/s for migrating guests (including moving local disks)", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "move" : { + "description" : "bandwidth limit in KiB/s for moving disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "restore" : { + "description" : "bandwidth limit in KiB/s for restoring guests from backups", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[clone=] [,default=] [,migration=] [,move=] [,restore=]" + }, + "comstar_hg" : { + "description" : "host group for comstar views", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comstar_tg" : { + "description" : "target group for comstar views", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "content" : { + "description" : "Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n", + "format" : "pve-storage-content-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "content-dirs" : { + "description" : "Overrides for default content type directories.", + "format" : "pve-dir-override-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "create-base-path" : { + "default" : "yes", + "description" : "Create the base directory if it doesn't exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "create-subdirs" : { + "default" : "yes", + "description" : "Populate the directory with the default structure.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "data-pool" : { + "description" : "Data Pool (for erasure coding only)", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the storage.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "domain" : { + "description" : "CIFS domain.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "encryption-key" : { + "description" : "Encryption key. Use 'autogen' to generate one automatically without passphrase.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "format" : { + "description" : "Default image format.", + "enum" : [ + "raw", + "qcow2", + "subvol", + "vmdk" + ], + "optional" : 1, + "type" : "string" + }, + "fs-name" : { + "description" : "The Ceph filesystem name.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fuse" : { + "description" : "Mount CephFS through FUSE.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "is_mountpoint" : { + "default" : "no", + "description" : "Assume the given path is an externally managed mountpoint and consider the storage offline if it is not mounted. Using a boolean (yes/no) value serves as a shortcut to using the target path in this field.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "keyring" : { + "description" : "Client keyring contents (for external clusters).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "krbd" : { + "default" : 0, + "description" : "Always access rbd through krbd kernel module.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lio_tpg" : { + "description" : "target portal group for Linux LIO targets", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "master-pubkey" : { + "description" : "Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "max-protected-backups" : { + "default" : "Unlimited for users with Datastore.Allocate privilege, 5 for other users", + "description" : "Maximal number of protected backups per guest. Use '-1' for unlimited.", + "minimum" : -1, + "optional" : 1, + "type" : "integer", + "typetext" : " (-1 - N)" + }, + "mkdir" : { + "default" : "yes", + "description" : "Create the directory if it doesn't exist and populate it with default sub-dirs. NOTE: Deprecated, use the 'create-base-path' and 'create-subdirs' options instead.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "monhost" : { + "description" : "IP addresses of monitors (for external clusters).", + "format" : "pve-storage-portal-dns-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mountpoint" : { + "description" : "mount point", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "namespace" : { + "description" : "Namespace.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nocow" : { + "default" : 0, + "description" : "Set the NOCOW flag on files. Disables data checksumming and causes data errors to be unrecoverable from while allowing direct I/O. Only use this if data does not need to be any more safe than on a single ext4 formatted disk with no underlying raid system.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nodes" : { + "description" : "List of nodes for which the storage configuration applies.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nowritecache" : { + "description" : "disable write caching on the target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "options" : { + "description" : "NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')", + "format" : "pve-storage-options", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "Password for accessing the share/datastore.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Use this port to connect to the storage instead of the default one (for example, with PBS or ESXi). For NFS and CIFS, use the 'options' option to configure the port via the mount options.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "preallocation" : { + "default" : "metadata", + "description" : "Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off.", + "enum" : [ + "off", + "metadata", + "falloc", + "full" + ], + "optional" : 1, + "type" : "string" + }, + "prune-backups" : { + "description" : "The retention options with shorter intervals are processed first with --keep-last being the very first one. Each option covers a specific period of time. We say that backups within this period are covered by this option. The next option does not take care of already covered backups and only considers older backups.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "saferemove" : { + "description" : "Zero-out data when removing LVs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "saferemove-stepsize" : { + "default" : 32, + "description" : "Wipe step size in MiB. It will be capped to the maximum supported by the storage.", + "enum" : [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "optional" : 1, + "type" : "integer" + }, + "saferemove_throughput" : { + "description" : "Wipe throughput (cstream -t parameter value).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "Server IP or DNS name.", + "format" : "pve-storage-server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "shared" : { + "description" : "Indicate that this is a single storage with the same contents on all nodes (or all listed in the 'nodes' option). It will not make the contents of a local storage automatically accessible to other nodes, it just marks an already shared storage as such!", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "skip-cert-verification" : { + "default" : "false", + "description" : "Disable TLS certificate verification, only enable on fully trusted networks!", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "smbversion" : { + "default" : "default", + "description" : "SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server.", + "enum" : [ + "default", + "2.0", + "2.1", + "3", + "3.0", + "3.11" + ], + "optional" : 1, + "type" : "string" + }, + "snapshot-as-volume-chain" : { + "default" : 0, + "description" : "Enable support for creating storage-vendor agnostic snapshot through volume backing-chains.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "sparse" : { + "description" : "use sparse volumes", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "subdir" : { + "description" : "Subdir to mount.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tagged_only" : { + "description" : "Only list logical volumes tagged with 'pve-vm-ID'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "username" : { + "description" : "RBD Id.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "zfs-base-path" : { + "description" : "Base path where to look for the created ZFS block devices. Set automatically during creation if not specified. Usually '/dev/zvol'.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "config" : { + "additionalProperties" : 1, + "description" : "Partial, possibly server generated, configuration properties.", + "optional" : 1, + "properties" : { + "encryption-key" : { + "description" : "The, possibly auto-generated, encryption-key.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "storage" : { + "description" : "The ID of the created storage.", + "type" : "string" + }, + "type" : { + "description" : "The type of the created storage.", + "enum" : [ + "btrfs", + "cephfs", + "cifs", + "dir", + "esxi", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/storage/{storage}", + "text" : "{storage}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Storage index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list storage of specific type", + "enum" : [ + "btrfs", + "cephfs", + "cifs", + "dir", + "esxi", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "storage" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{storage}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new storage.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "authsupported" : { + "description" : "Authsupported.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "base" : { + "description" : "Base volume. This volume is automatically activated.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "blocksize" : { + "description" : "ZFS block size", + "format" : "pve-storage-zfs-blocksize", + "format_description" : "a power of 2 with optional k or m suffix", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bwlimit" : { + "description" : "Set I/O bandwidth limit for various operations (in KiB/s).", + "format" : { + "clone" : { + "description" : "bandwidth limit in KiB/s for cloning disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "default" : { + "description" : "default bandwidth limit in KiB/s", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "migration" : { + "description" : "bandwidth limit in KiB/s for migrating guests (including moving local disks)", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "move" : { + "description" : "bandwidth limit in KiB/s for moving disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "restore" : { + "description" : "bandwidth limit in KiB/s for restoring guests from backups", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[clone=] [,default=] [,migration=] [,move=] [,restore=]" + }, + "comstar_hg" : { + "description" : "host group for comstar views", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comstar_tg" : { + "description" : "target group for comstar views", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "content" : { + "description" : "Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n", + "format" : "pve-storage-content-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "content-dirs" : { + "description" : "Overrides for default content type directories.", + "format" : "pve-dir-override-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "create-base-path" : { + "default" : "yes", + "description" : "Create the base directory if it doesn't exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "create-subdirs" : { + "default" : "yes", + "description" : "Populate the directory with the default structure.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "data-pool" : { + "description" : "Data Pool (for erasure coding only)", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "datastore" : { + "description" : "Proxmox Backup Server datastore name.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the storage.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "domain" : { + "description" : "CIFS domain.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "encryption-key" : { + "description" : "Encryption key. Use 'autogen' to generate one automatically without passphrase.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "export" : { + "description" : "NFS export path.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "format" : { + "description" : "Default image format.", + "enum" : [ + "raw", + "qcow2", + "subvol", + "vmdk" + ], + "optional" : 1, + "type" : "string" + }, + "fs-name" : { + "description" : "The Ceph filesystem name.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fuse" : { + "description" : "Mount CephFS through FUSE.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "is_mountpoint" : { + "default" : "no", + "description" : "Assume the given path is an externally managed mountpoint and consider the storage offline if it is not mounted. Using a boolean (yes/no) value serves as a shortcut to using the target path in this field.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iscsiprovider" : { + "description" : "iscsi provider", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "keyring" : { + "description" : "Client keyring contents (for external clusters).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "krbd" : { + "default" : 0, + "description" : "Always access rbd through krbd kernel module.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lio_tpg" : { + "description" : "target portal group for Linux LIO targets", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "master-pubkey" : { + "description" : "Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "max-protected-backups" : { + "default" : "Unlimited for users with Datastore.Allocate privilege, 5 for other users", + "description" : "Maximal number of protected backups per guest. Use '-1' for unlimited.", + "minimum" : -1, + "optional" : 1, + "type" : "integer", + "typetext" : " (-1 - N)" + }, + "mkdir" : { + "default" : "yes", + "description" : "Create the directory if it doesn't exist and populate it with default sub-dirs. NOTE: Deprecated, use the 'create-base-path' and 'create-subdirs' options instead.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "monhost" : { + "description" : "IP addresses of monitors (for external clusters).", + "format" : "pve-storage-portal-dns-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mountpoint" : { + "description" : "mount point", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "namespace" : { + "description" : "Namespace.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nocow" : { + "default" : 0, + "description" : "Set the NOCOW flag on files. Disables data checksumming and causes data errors to be unrecoverable from while allowing direct I/O. Only use this if data does not need to be any more safe than on a single ext4 formatted disk with no underlying raid system.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nodes" : { + "description" : "List of nodes for which the storage configuration applies.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nowritecache" : { + "description" : "disable write caching on the target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "options" : { + "description" : "NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')", + "format" : "pve-storage-options", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "Password for accessing the share/datastore.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "File system path.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Use this port to connect to the storage instead of the default one (for example, with PBS or ESXi). For NFS and CIFS, use the 'options' option to configure the port via the mount options.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "portal" : { + "description" : "iSCSI portal (IP or DNS name with optional port).", + "format" : "pve-storage-portal-dns", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "preallocation" : { + "default" : "metadata", + "description" : "Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off.", + "enum" : [ + "off", + "metadata", + "falloc", + "full" + ], + "optional" : 1, + "type" : "string" + }, + "prune-backups" : { + "description" : "The retention options with shorter intervals are processed first with --keep-last being the very first one. Each option covers a specific period of time. We say that backups within this period are covered by this option. The next option does not take care of already covered backups and only considers older backups.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "saferemove" : { + "description" : "Zero-out data when removing LVs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "saferemove-stepsize" : { + "default" : 32, + "description" : "Wipe step size in MiB. It will be capped to the maximum supported by the storage.", + "enum" : [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "optional" : 1, + "type" : "integer" + }, + "saferemove_throughput" : { + "description" : "Wipe throughput (cstream -t parameter value).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "Server IP or DNS name.", + "format" : "pve-storage-server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "share" : { + "description" : "CIFS share.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "shared" : { + "description" : "Indicate that this is a single storage with the same contents on all nodes (or all listed in the 'nodes' option). It will not make the contents of a local storage automatically accessible to other nodes, it just marks an already shared storage as such!", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "skip-cert-verification" : { + "default" : "false", + "description" : "Disable TLS certificate verification, only enable on fully trusted networks!", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "smbversion" : { + "default" : "default", + "description" : "SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server.", + "enum" : [ + "default", + "2.0", + "2.1", + "3", + "3.0", + "3.11" + ], + "optional" : 1, + "type" : "string" + }, + "snapshot-as-volume-chain" : { + "default" : 0, + "description" : "Enable support for creating storage-vendor agnostic snapshot through volume backing-chains.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "sparse" : { + "description" : "use sparse volumes", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "subdir" : { + "description" : "Subdir to mount.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tagged_only" : { + "description" : "Only list logical volumes tagged with 'pve-vm-ID'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target" : { + "description" : "iSCSI target.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "thinpool" : { + "description" : "LVM thin pool LV name.", + "format" : "pve-storage-vgname", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Storage type.", + "enum" : [ + "btrfs", + "cephfs", + "cifs", + "dir", + "esxi", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "type" : "string" + }, + "username" : { + "description" : "RBD Id.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vgname" : { + "description" : "Volume group name.", + "format" : "pve-storage-vgname", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "zfs-base-path" : { + "description" : "Base path where to look for the created ZFS block devices. Set automatically during creation if not specified. Usually '/dev/zvol'.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "config" : { + "additionalProperties" : 1, + "description" : "Partial, possibly server generated, configuration properties.", + "optional" : 1, + "properties" : { + "encryption-key" : { + "description" : "The, possibly auto-generated, encryption-key.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "storage" : { + "description" : "The ID of the created storage.", + "type" : "string" + }, + "type" : { + "description" : "The type of the created storage.", + "enum" : [ + "btrfs", + "cephfs", + "cifs", + "dir", + "esxi", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 0, + "path" : "/storage", + "text" : "storage" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get user TFA types (Personal and Realm).", + "method" : "GET", + "name" : "read_user_tfa_type", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "multiple" : { + "default" : 0, + "description" : "Request all entries as an array.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "realm" : { + "description" : "The type of TFA the users realm has set, if any.", + "enum" : [ + "oath", + "yubico" + ], + "optional" : 1, + "type" : "string" + }, + "types" : { + "description" : "Array of the user configured TFA types, if any. Only available if 'multiple' was not passed.", + "items" : { + "description" : "A TFA type.", + "enum" : [ + "totp", + "u2f", + "yubico", + "webauthn", + "recovedry" + ], + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "user" : { + "description" : "The type of TFA the user has set, if any. Only set if 'multiple' was not passed.", + "enum" : [ + "oath", + "u2f" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/users/{userid}/tfa", + "text" : "tfa" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Unlock a user's TFA authentication.", + "method" : "PUT", + "name" : "unlock_tfa", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "userid-group", + [ + "User.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "boolean" + } + } + }, + "leaf" : 1, + "path" : "/access/users/{userid}/unlock-tfa", + "text" : "unlock-tfa" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove API token for a specific user.", + "method" : "DELETE", + "name" : "remove_token", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get specific API token information.", + "method" : "GET", + "name" : "read_token", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "returns" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Generate a new API token for a specific user. NOTE: returns API token value, which needs to be stored as it cannot be retrieved afterwards!", + "method" : "POST", + "name" : "generate_token", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "full-tokenid" : { + "description" : "The full token id.", + "format_description" : "!", + "type" : "string" + }, + "info" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "value" : { + "description" : "API token value used for authentication.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update API token for a specific user. NOTE: when 'regenerate' is set, the returned token value needs to be stored as it cannot be retrieved afterwards!", + "method" : "PUT", + "name" : "update_token_info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "regenerate" : { + "default" : 0, + "description" : "Regenerate the token's secret value. All users of the previous secret will lose access after this operation.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "full-tokenid" : { + "description" : "The full token id. Only set when 'regenerate' was set.", + "format_description" : "!", + "optional" : 1, + "type" : "string" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + }, + "value" : { + "description" : "API token value used for authentication. Only set when 'regenerate' was set.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/users/{userid}/token/{tokenid}", + "text" : "{tokenid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get user API tokens.", + "method" : "GET", + "name" : "token_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + }, + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{tokenid}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/access/users/{userid}/token", + "text" : "token" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete user.", + "method" : "DELETE", + "name" : "delete_user", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get user configuration.", + "method" : "GET", + "name" : "read_user", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "maxLength" : 2048, + "optional" : 1, + "type" : "string" + }, + "email" : { + "format" : "email-opt", + "maxLength" : 254, + "optional" : 1, + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Enable the account (default). You can set this to '0' to disable the account", + "optional" : 1, + "type" : "boolean" + }, + "expire" : { + "description" : "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "firstname" : { + "maxLength" : 1024, + "optional" : 1, + "type" : "string" + }, + "groups" : { + "items" : { + "format" : "pve-groupid", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "keys" : { + "description" : "Keys for two factor auth (yubico).", + "optional" : 1, + "pattern" : "[0-9a-zA-Z!=]{0,4096}", + "type" : "string" + }, + "lastname" : { + "maxLength" : 1024, + "optional" : 1, + "type" : "string" + }, + "tokens" : { + "additionalProperties" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "object" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update user configuration.", + "method" : "PUT", + "name" : "update_user", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "append" : { + "optional" : 1, + "requires" : "groups", + "type" : "boolean", + "typetext" : "" + }, + "comment" : { + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "email" : { + "format" : "email-opt", + "maxLength" : 254, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 1, + "description" : "Enable the account (default). You can set this to '0' to disable the account", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "expire" : { + "description" : "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "firstname" : { + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groups" : { + "format" : "pve-groupid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "keys" : { + "description" : "Keys for two factor auth (yubico).", + "optional" : 1, + "pattern" : "[0-9a-zA-Z!=]{0,4096}", + "type" : "string" + }, + "lastname" : { + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "userid-group", + [ + "User.Modify" + ], + "groups_param", + "update" + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/users/{userid}", + "text" : "{userid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "User index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "enabled" : { + "description" : "Optional filter for enable property.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "full" : { + "default" : 0, + "description" : "Include group and token information.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The returned list is restricted to users where you have 'User.Modify' or 'Sys.Audit' permissions on '/access/groups' or on a group the user belongs too. But it always includes the current (authenticated) user.", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "maxLength" : 2048, + "optional" : 1, + "type" : "string" + }, + "email" : { + "format" : "email-opt", + "maxLength" : 254, + "optional" : 1, + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Enable the account (default). You can set this to '0' to disable the account", + "optional" : 1, + "type" : "boolean" + }, + "expire" : { + "description" : "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "firstname" : { + "maxLength" : 1024, + "optional" : 1, + "type" : "string" + }, + "groups" : { + "format" : "pve-groupid-list", + "optional" : 1, + "type" : "string" + }, + "keys" : { + "description" : "Keys for two factor auth (yubico).", + "optional" : 1, + "pattern" : "[0-9a-zA-Z!=]{0,4096}", + "type" : "string" + }, + "lastname" : { + "maxLength" : 1024, + "optional" : 1, + "type" : "string" + }, + "realm-type" : { + "description" : "The type of the users realm", + "format" : "pve-realm", + "optional" : 1, + "type" : "string" + }, + "tfa-locked-until" : { + "description" : "Contains a timestamp until when a user is locked out of 2nd factors.", + "optional" : 1, + "type" : "integer" + }, + "tokens" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + }, + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "totp-locked" : { + "description" : "True if the user is currently locked out of TOTP factors.", + "optional" : 1, + "type" : "boolean" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{userid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new user.", + "method" : "POST", + "name" : "create_user", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "email" : { + "format" : "email-opt", + "maxLength" : 254, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 1, + "description" : "Enable the account (default). You can set this to '0' to disable the account", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "expire" : { + "description" : "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "firstname" : { + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groups" : { + "format" : "pve-groupid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "keys" : { + "description" : "Keys for two factor auth (yubico).", + "optional" : 1, + "pattern" : "[0-9a-zA-Z!=]{0,4096}", + "type" : "string" + }, + "lastname" : { + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "Initial password.", + "maxLength" : 64, + "minLength" : 8, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ], + "groups_param", + "create" + ] + ], + "description" : "You need 'Realm.AllocateUser' on '/access/realm/' on the realm of user , and 'User.Modify' permissions to '/access/groups/' for any group specified (or 'User.Modify' on '/access/groups' if you pass no groups." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/users", + "text" : "users" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete group.", + "method" : "DELETE", + "name" : "delete_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "groupid" : { + "format" : "pve-groupid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get group configuration.", + "method" : "GET", + "name" : "read_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "groupid" : { + "format" : "pve-groupid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/groups", + [ + "Sys.Audit", + "Group.Allocate" + ], + "any", + 1 + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "members" : { + "items" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update group data.", + "method" : "PUT", + "name" : "update_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groupid" : { + "format" : "pve-groupid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/groups/{groupid}", + "text" : "{groupid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Group index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "The returned list is restricted to groups where you have 'User.Modify', 'Sys.Audit' or 'Group.Allocate' permissions on /access/groups/.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "groupid" : { + "format" : "pve-groupid", + "type" : "string" + }, + "users" : { + "description" : "list of users which form this group", + "format" : "pve-userid-list", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{groupid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new group.", + "method" : "POST", + "name" : "create_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groupid" : { + "format" : "pve-groupid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/groups", + "text" : "groups" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete role.", + "method" : "DELETE", + "name" : "delete_role", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "roleid" : { + "format" : "pve-roleid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get role configuration.", + "method" : "GET", + "name" : "read_role", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "roleid" : { + "format" : "pve-roleid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "Datastore.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "Datastore.AllocateSpace" : { + "optional" : 1, + "type" : "boolean" + }, + "Datastore.AllocateTemplate" : { + "optional" : 1, + "type" : "boolean" + }, + "Datastore.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "Group.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "Mapping.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "Mapping.Modify" : { + "optional" : 1, + "type" : "boolean" + }, + "Mapping.Use" : { + "optional" : 1, + "type" : "boolean" + }, + "Permissions.Modify" : { + "optional" : 1, + "type" : "boolean" + }, + "Pool.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "Pool.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "Realm.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "Realm.AllocateUser" : { + "optional" : 1, + "type" : "boolean" + }, + "SDN.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "SDN.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "SDN.Use" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.AccessNetwork" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Console" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Incoming" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Modify" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.PowerMgmt" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Syslog" : { + "optional" : 1, + "type" : "boolean" + }, + "User.Modify" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Backup" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Clone" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.CDROM" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.CPU" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Cloudinit" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Disk" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.HWType" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Memory" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Network" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Options" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Console" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.GuestAgent.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.GuestAgent.FileRead" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.GuestAgent.FileSystemMgmt" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.GuestAgent.FileWrite" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.GuestAgent.Unrestricted" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Migrate" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.PowerMgmt" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Replicate" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Snapshot" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Snapshot.Rollback" : { + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update an existing role.", + "method" : "PUT", + "name" : "update_role", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "append" : { + "optional" : 1, + "requires" : "privs", + "type" : "boolean", + "typetext" : "" + }, + "privs" : { + "format" : "pve-priv-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "roleid" : { + "format" : "pve-roleid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/roles/{roleid}", + "text" : "{roleid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Role index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "privs" : { + "format" : "pve-priv-list", + "optional" : 1, + "type" : "string" + }, + "roleid" : { + "format" : "pve-roleid", + "type" : "string" + }, + "special" : { + "default" : 0, + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{roleid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new role.", + "method" : "POST", + "name" : "create_role", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "privs" : { + "format" : "pve-priv-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "roleid" : { + "format" : "pve-roleid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/roles", + "text" : "roles" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Access Control List (ACLs).", + "method" : "GET", + "name" : "read_acl", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "The returned list is restricted to objects where you have rights to modify permissions.", + "user" : "all" + }, + "returns" : { + "items" : { + "additionalProperties" : 0, + "properties" : { + "path" : { + "description" : "Access control path", + "type" : "string" + }, + "propagate" : { + "default" : 1, + "description" : "Allow to propagate (inherit) permissions.", + "optional" : 1, + "type" : "boolean" + }, + "roleid" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "user", + "group", + "token" + ], + "type" : "string" + }, + "ugid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update Access Control List (add or remove permissions).", + "method" : "PUT", + "name" : "update_acl", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "Remove permissions (instead of adding it).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "groups" : { + "description" : "List of groups.", + "format" : "pve-groupid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "Access control path", + "type" : "string", + "typetext" : "" + }, + "propagate" : { + "default" : 1, + "description" : "Allow to propagate (inherit) permissions.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "roles" : { + "description" : "List of roles.", + "format" : "pve-roleid-list", + "type" : "string", + "typetext" : "" + }, + "tokens" : { + "description" : "List of API tokens.", + "format" : "pve-tokenid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "users" : { + "description" : "List of users.", + "format" : "pve-userid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm-modify", + "{path}" + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/acl", + "text" : "acl" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Syncs users and/or groups from the configured LDAP to user.cfg. NOTE: Synced groups will have the name 'name-$realm', so make sure those groups do not exist to prevent overwriting.", + "method" : "POST", + "name" : "sync", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dry-run" : { + "default" : 0, + "description" : "If set, does not write anything.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "enable-new" : { + "default" : "1", + "description" : "Enable newly synced users immediately.", + "optional" : "1", + "type" : "boolean", + "typetext" : "" + }, + "full" : { + "description" : "DEPRECATED: use 'remove-vanished' instead. If set, uses the LDAP Directory as source of truth, deleting users or groups not returned from the sync and removing all locally modified properties of synced users. If not set, only syncs information which is present in the synced data, and does not delete or modify anything else.", + "optional" : "1", + "type" : "boolean", + "typetext" : "" + }, + "purge" : { + "description" : "DEPRECATED: use 'remove-vanished' instead. Remove ACLs for users or groups which were removed from the config during a sync.", + "optional" : "1", + "type" : "boolean", + "typetext" : "" + }, + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + }, + "remove-vanished" : { + "default" : "none", + "description" : "A semicolon-separated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).", + "optional" : "1", + "pattern" : "(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none", + "type" : "string", + "typetext" : "([acl];[properties];[entry])|none" + }, + "scope" : { + "description" : "Select what to sync.", + "enum" : [ + "users", + "groups", + "both" + ], + "optional" : "1", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/access/realm/{realm}", + [ + "Realm.AllocateUser" + ] + ], + [ + "perm", + "/access/groups", + [ + "User.Modify" + ] + ] + ], + "description" : "'Realm.AllocateUser' on '/access/realm/' and 'User.Modify' permissions to '/access/groups/'." + }, + "protected" : 1, + "returns" : { + "description" : "Worker Task-UPID", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/access/domains/{realm}/sync", + "text" : "sync" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete an authentication server.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get auth server configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/realm", + [ + "Realm.Allocate", + "Sys.Audit" + ], + "any", + 1 + ] + }, + "returns" : {} + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update authentication server settings.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acr-values" : { + "description" : "Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.", + "optional" : 1, + "pattern" : "^[^\\x00-\\x1F\\x7F <>#\"]*$", + "type" : "string" + }, + "audiences" : { + "description" : "A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'.", + "optional" : 1, + "pattern" : "^[^\\x00-\\x1F\\x7F <>#\"]*$", + "type" : "string" + }, + "autocreate" : { + "default" : 0, + "description" : "Automatically create users if they do not exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "base_dn" : { + "description" : "LDAP base domain name", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bind_dn" : { + "description" : "LDAP bind domain name", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "capath" : { + "default" : "/etc/ssl/certs", + "description" : "Path to the CA certificate store", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "case-sensitive" : { + "default" : 1, + "description" : "username is case-sensitive", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cert" : { + "description" : "Path to the client certificate", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "certkey" : { + "description" : "Path to the client certificate key", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "check-connection" : { + "default" : 0, + "description" : "Check bind connection to the server.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "client-id" : { + "description" : "OpenID Client ID", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "client-key" : { + "description" : "OpenID Client Key", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "default" : { + "description" : "Use this as default realm", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "domain" : { + "description" : "AD domain name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\S+", + "type" : "string" + }, + "filter" : { + "description" : "LDAP filter for user sync.", + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_classes" : { + "default" : "groupOfNames, group, univentionGroup, ipausergroup", + "description" : "The objectclasses for groups.", + "format" : "ldap-simple-attr-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_dn" : { + "description" : "LDAP base domain name for group sync. If not set, the base_dn will be used.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_filter" : { + "description" : "LDAP filter for group sync.", + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_name_attr" : { + "description" : "LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.", + "format" : "ldap-simple-attr", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groups-autocreate" : { + "default" : 0, + "description" : "Automatically create groups if they do not exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "groups-claim" : { + "description" : "OpenID claim used to retrieve groups with.", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^:[A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "groups-overwrite" : { + "default" : 0, + "description" : "All groups will be overwritten for the user on login.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "issuer-url" : { + "description" : "OpenID Issuer Url", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mode" : { + "default" : "ldap", + "description" : "LDAP protocol mode.", + "enum" : [ + "ldap", + "ldaps", + "ldap+starttls" + ], + "optional" : 1, + "type" : "string" + }, + "password" : { + "description" : "LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Server port.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "prompt" : { + "description" : "Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.", + "optional" : 1, + "pattern" : "(?:none|login|consent|select_account|\\S+)", + "type" : "string" + }, + "query-userinfo" : { + "default" : 1, + "description" : "Enables querying the userinfo endpoint for claims values.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + }, + "scopes" : { + "default" : "email profile", + "description" : "Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "secure" : { + "description" : "Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "server1" : { + "description" : "Server IP address (or DNS name)", + "format" : "address", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server2" : { + "description" : "Fallback Server IP address (or DNS name)", + "format" : "address", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sslversion" : { + "description" : "LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!", + "enum" : [ + "tlsv1", + "tlsv1_1", + "tlsv1_2", + "tlsv1_3" + ], + "optional" : 1, + "type" : "string" + }, + "sync-defaults-options" : { + "description" : "The default options for behavior of synchronizations.", + "format" : "realm-sync-options", + "optional" : 1, + "type" : "string", + "typetext" : "[enable-new=<1|0>] [,full=<1|0>] [,purge=<1|0>] [,remove-vanished=([acl];[properties];[entry])|none] [,scope=]" + }, + "sync_attributes" : { + "description" : "Comma separated list of key=value pairs for specifying which LDAP attributes map to which PVE user field. For example, to map the LDAP attribute 'mail' to PVEs 'email', write 'email=mail'. By default, each PVE user field is represented by an LDAP attribute of the same name.", + "optional" : 1, + "pattern" : "\\w+=[^,]+(,\\s*\\w+=[^,]+)*", + "type" : "string" + }, + "tfa" : { + "description" : "Use Two-factor authentication.", + "format" : "pve-tfa-config", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "type= [,digits=] [,id=] [,key=] [,step=] [,url=]" + }, + "user_attr" : { + "description" : "LDAP user attribute name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\S{2,}", + "type" : "string" + }, + "user_classes" : { + "default" : "inetorgperson, posixaccount, person, user", + "description" : "The objectclasses for users.", + "format" : "ldap-simple-attr-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "verify" : { + "default" : 0, + "description" : "Verify the server's SSL certificate", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/domains/{realm}", + "text" : "{realm}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Authentication domain index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "Anyone can access that, because we need that list for the login box (before the user is authenticated).", + "user" : "world" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "A comment. The GUI use this text when you select a domain (Realm) on the login window.", + "optional" : 1, + "type" : "string" + }, + "realm" : { + "type" : "string" + }, + "tfa" : { + "description" : "Two-factor authentication provider.", + "enum" : [ + "yubico", + "oath" + ], + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{realm}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add an authentication server.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acr-values" : { + "description" : "Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.", + "optional" : 1, + "pattern" : "^[^\\x00-\\x1F\\x7F <>#\"]*$", + "type" : "string" + }, + "audiences" : { + "description" : "A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'.", + "optional" : 1, + "pattern" : "^[^\\x00-\\x1F\\x7F <>#\"]*$", + "type" : "string" + }, + "autocreate" : { + "default" : 0, + "description" : "Automatically create users if they do not exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "base_dn" : { + "description" : "LDAP base domain name", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bind_dn" : { + "description" : "LDAP bind domain name", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "capath" : { + "default" : "/etc/ssl/certs", + "description" : "Path to the CA certificate store", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "case-sensitive" : { + "default" : 1, + "description" : "username is case-sensitive", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cert" : { + "description" : "Path to the client certificate", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "certkey" : { + "description" : "Path to the client certificate key", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "check-connection" : { + "default" : 0, + "description" : "Check bind connection to the server.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "client-id" : { + "description" : "OpenID Client ID", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "client-key" : { + "description" : "OpenID Client Key", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "default" : { + "description" : "Use this as default realm", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "domain" : { + "description" : "AD domain name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\S+", + "type" : "string" + }, + "filter" : { + "description" : "LDAP filter for user sync.", + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_classes" : { + "default" : "groupOfNames, group, univentionGroup, ipausergroup", + "description" : "The objectclasses for groups.", + "format" : "ldap-simple-attr-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_dn" : { + "description" : "LDAP base domain name for group sync. If not set, the base_dn will be used.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_filter" : { + "description" : "LDAP filter for group sync.", + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_name_attr" : { + "description" : "LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.", + "format" : "ldap-simple-attr", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groups-autocreate" : { + "default" : 0, + "description" : "Automatically create groups if they do not exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "groups-claim" : { + "description" : "OpenID claim used to retrieve groups with.", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^:[A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "groups-overwrite" : { + "default" : 0, + "description" : "All groups will be overwritten for the user on login.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "issuer-url" : { + "description" : "OpenID Issuer Url", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mode" : { + "default" : "ldap", + "description" : "LDAP protocol mode.", + "enum" : [ + "ldap", + "ldaps", + "ldap+starttls" + ], + "optional" : 1, + "type" : "string" + }, + "password" : { + "description" : "LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Server port.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "prompt" : { + "description" : "Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.", + "optional" : 1, + "pattern" : "(?:none|login|consent|select_account|\\S+)", + "type" : "string" + }, + "query-userinfo" : { + "default" : 1, + "description" : "Enables querying the userinfo endpoint for claims values.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + }, + "scopes" : { + "default" : "email profile", + "description" : "Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "secure" : { + "description" : "Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "server1" : { + "description" : "Server IP address (or DNS name)", + "format" : "address", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server2" : { + "description" : "Fallback Server IP address (or DNS name)", + "format" : "address", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sslversion" : { + "description" : "LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!", + "enum" : [ + "tlsv1", + "tlsv1_1", + "tlsv1_2", + "tlsv1_3" + ], + "optional" : 1, + "type" : "string" + }, + "sync-defaults-options" : { + "description" : "The default options for behavior of synchronizations.", + "format" : "realm-sync-options", + "optional" : 1, + "type" : "string", + "typetext" : "[enable-new=<1|0>] [,full=<1|0>] [,purge=<1|0>] [,remove-vanished=([acl];[properties];[entry])|none] [,scope=]" + }, + "sync_attributes" : { + "description" : "Comma separated list of key=value pairs for specifying which LDAP attributes map to which PVE user field. For example, to map the LDAP attribute 'mail' to PVEs 'email', write 'email=mail'. By default, each PVE user field is represented by an LDAP attribute of the same name.", + "optional" : 1, + "pattern" : "\\w+=[^,]+(,\\s*\\w+=[^,]+)*", + "type" : "string" + }, + "tfa" : { + "description" : "Use Two-factor authentication.", + "format" : "pve-tfa-config", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "type= [,digits=] [,id=] [,key=] [,step=] [,url=]" + }, + "type" : { + "description" : "Realm type.", + "enum" : [ + "ad", + "ldap", + "openid", + "pam", + "pve" + ], + "type" : "string" + }, + "user_attr" : { + "description" : "LDAP user attribute name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\S{2,}", + "type" : "string" + }, + "user_classes" : { + "default" : "inetorgperson, posixaccount, person, user", + "description" : "The objectclasses for users.", + "format" : "ldap-simple-attr-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "username-claim" : { + "description" : "OpenID claim used to generate the unique username.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "verify" : { + "default" : 0, + "description" : "Verify the server's SSL certificate", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/domains", + "text" : "domains" + }, + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Get the OpenId Authorization Url for the specified realm.", + "method" : "POST", + "name" : "auth_url", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + }, + "redirect-url" : { + "description" : "Redirection Url. The client should set this to the used server url (location.origin).", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "world" + }, + "protected" : 1, + "returns" : { + "description" : "Redirection URL.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/access/openid/auth-url", + "text" : "auth-url" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : " Verify OpenID authorization code and create a ticket.", + "method" : "POST", + "name" : "login", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "code" : { + "description" : "OpenId authorization code.", + "maxLength" : 4096, + "type" : "string", + "typetext" : "" + }, + "redirect-url" : { + "description" : "Redirection Url. The client should set this to the used server url (location.origin).", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + }, + "state" : { + "description" : "OpenId state.", + "maxLength" : 1024, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "world" + }, + "protected" : 1, + "returns" : { + "properties" : { + "CSRFPreventionToken" : { + "type" : "string" + }, + "cap" : { + "type" : "object" + }, + "clustername" : { + "optional" : 1, + "type" : "string" + }, + "ticket" : { + "type" : "string" + }, + "username" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/access/openid/login", + "text" : "login" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/access/openid", + "text" : "openid" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 0, + "description" : "Delete a TFA entry by ID.", + "method" : "DELETE", + "name" : "delete_tfa", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "A TFA entry id.", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The current password of the user performing the change.", + "maxLength" : 64, + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Fetch a requested TFA entry if present.", + "method" : "GET", + "name" : "get_tfa_entry", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "A TFA entry id.", + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "TFA Entry.", + "properties" : { + "created" : { + "description" : "Creation time of this entry as unix epoch.", + "type" : "integer" + }, + "description" : { + "description" : "User chosen description for this entry.", + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Whether this TFA entry is currently enabled.", + "optional" : 1, + "type" : "boolean" + }, + "id" : { + "description" : "The id used to reference this entry.", + "type" : "string" + }, + "type" : { + "description" : "TFA Entry Type.", + "enum" : [ + "totp", + "u2f", + "webauthn", + "recovery", + "yubico" + ], + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 0, + "description" : "Add a TFA entry for a user.", + "method" : "PUT", + "name" : "update_tfa_entry", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A description to distinguish multiple entries from one another", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Whether the entry should be enabled for login.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "A TFA entry id.", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The current password of the user performing the change.", + "maxLength" : 64, + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/tfa/{userid}/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List TFA configurations of users.", + "method" : "GET", + "name" : "list_user_tfa", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "A list of the user's TFA entries.", + "items" : { + "description" : "TFA Entry.", + "properties" : { + "created" : { + "description" : "Creation time of this entry as unix epoch.", + "type" : "integer" + }, + "description" : { + "description" : "User chosen description for this entry.", + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Whether this TFA entry is currently enabled.", + "optional" : 1, + "type" : "boolean" + }, + "id" : { + "description" : "The id used to reference this entry.", + "type" : "string" + }, + "type" : { + "description" : "TFA Entry Type.", + "enum" : [ + "totp", + "u2f", + "webauthn", + "recovery", + "yubico" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 0, + "description" : "Add a TFA entry for a user.", + "method" : "POST", + "name" : "add_tfa_entry", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "challenge" : { + "description" : "When responding to a u2f challenge: the original challenge string", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "A description to distinguish multiple entries from one another", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The current password of the user performing the change.", + "maxLength" : 64, + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "totp" : { + "description" : "A totp URI.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "TFA Entry Type.", + "enum" : [ + "totp", + "u2f", + "webauthn", + "recovery", + "yubico" + ], + "type" : "string" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + }, + "value" : { + "description" : "The current value for the provided totp URI, or a Webauthn/U2F challenge response", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "challenge" : { + "description" : "When adding u2f entries, this contains a challenge the user must respond to in order to finish the registration.", + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "The id of a newly added TFA entry.", + "type" : "string" + }, + "recovery" : { + "description" : "When adding recovery codes, this contains the list of codes to be displayed to the user", + "items" : { + "description" : "A recovery entry.", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 0, + "path" : "/access/tfa/{userid}", + "text" : "{userid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List TFA configurations of users.", + "method" : "GET", + "name" : "list_tfa", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "Returns all or just the logged-in user, depending on privileges.", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "description" : "The list tuples of user and TFA entries.", + "items" : { + "properties" : { + "entries" : { + "items" : { + "description" : "TFA Entry.", + "properties" : { + "created" : { + "description" : "Creation time of this entry as unix epoch.", + "type" : "integer" + }, + "description" : { + "description" : "User chosen description for this entry.", + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Whether this TFA entry is currently enabled.", + "optional" : 1, + "type" : "boolean" + }, + "id" : { + "description" : "The id used to reference this entry.", + "type" : "string" + }, + "type" : { + "description" : "TFA Entry Type.", + "enum" : [ + "totp", + "u2f", + "webauthn", + "recovery", + "yubico" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "tfa-locked-until" : { + "description" : "Contains a timestamp until when a user is locked out of 2nd factors.", + "optional" : 1, + "type" : "integer" + }, + "totp-locked" : { + "description" : "True if the user is currently locked out of TOTP factors.", + "optional" : 1, + "type" : "boolean" + }, + "userid" : { + "description" : "User this entry belongs to.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{userid}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/access/tfa", + "text" : "tfa" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Dummy. Useful for formatters which want to provide a login page.", + "method" : "GET", + "name" : "get_ticket", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "world" + }, + "returns" : { + "type" : "null" + } + }, + "POST" : { + "allowtoken" : 0, + "description" : "Create or verify authentication ticket.", + "method" : "POST", + "name" : "create_ticket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "new-format" : { + "default" : 1, + "description" : "This parameter is now ignored and assumed to be 1.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "otp" : { + "description" : "One-time password for Two-factor authentication.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The secret password. This can also be a valid ticket.", + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "Verify ticket, and check if user have access 'privs' on 'path'", + "maxLength" : 64, + "optional" : 1, + "requires" : "privs", + "type" : "string", + "typetext" : "" + }, + "privs" : { + "description" : "Verify ticket, and check if user have access 'privs' on 'path'", + "format" : "pve-priv-list", + "maxLength" : 64, + "optional" : 1, + "requires" : "path", + "type" : "string", + "typetext" : "" + }, + "realm" : { + "description" : "You can optionally pass the realm using this parameter. Normally the realm is simply added to the username @.", + "format" : "pve-realm", + "maxLength" : 32, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tfa-challenge" : { + "description" : "The signed TFA challenge string the user wants to respond to.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "User name", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need to pass valid credientials.", + "user" : "world" + }, + "protected" : 1, + "returns" : { + "properties" : { + "CSRFPreventionToken" : { + "optional" : 1, + "type" : "string" + }, + "clustername" : { + "optional" : 1, + "type" : "string" + }, + "ticket" : { + "optional" : 1, + "type" : "string" + }, + "username" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/ticket", + "text" : "ticket" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "verify VNC authentication ticket.", + "method" : "POST", + "name" : "verify_vnc_ticket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "authid" : { + "description" : "UserId or token", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "Verify ticket, and check if user have access 'privs' on 'path'", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Verify that the ticket is valid for this port.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "privs" : { + "description" : "Verify ticket, and check if user have access 'privs' on 'path'", + "format" : "pve-priv-list", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + }, + "vncticket" : { + "description" : "The VNC ticket.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need to pass valid credientials.", + "user" : "world" + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/vncticket", + "text" : "vncticket" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 0, + "description" : "Change user password.", + "method" : "PUT", + "name" : "change_password", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "confirmation-password" : { + "description" : "The current password of the user performing the change.", + "maxLength" : 64, + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The new password.", + "maxLength" : 64, + "minLength" : 8, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + ], + "description" : "Each user is allowed to change their own password. A user can change the password of another user if they have 'Realm.AllocateUser' (on the realm of user ) and 'User.Modify' permission on /access/groups/ on a group where user is member of. For the PAM realm, a password change does not take effect cluster-wide, but only applies to the local node." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/password", + "text" : "password" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Retrieve effective permissions of given user/token.", + "method" : "GET", + "name" : "permissions", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "path" : { + "description" : "Only dump this specific path, not the whole tree.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "User ID or full API token ID", + "optional" : 1, + "pattern" : "(?^:^(?^:[^\\s:/]+)\\@(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)(?:!(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+))?$)", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Each user/token is allowed to dump their own permissions (or that of owned tokens). A user can dump the permissions of another user or their tokens if they have 'Sys.Audit' permission on /access.", + "user" : "all" + }, + "returns" : { + "description" : "Map of \"path\" => (Map of \"privilege\" => \"propagate boolean\").", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/permissions", + "text" : "permissions" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/access", + "text" : "access" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete pool (deprecated, no support for nested pools, use 'DELETE /pools/?poolid={poolid}').", + "method" : "DELETE", + "name" : "delete_pool_deprecated", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description" : "You can only delete empty pools (no members)." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get pool configuration (deprecated, no support for nested pools, use 'GET /pools/?poolid={poolid}').", + "method" : "GET", + "name" : "read_pool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + }, + "type" : { + "enum" : [ + "qemu", + "lxc", + "storage" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Audit" + ] + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "members" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "id" : { + "type" : "string" + }, + "node" : { + "type" : "string" + }, + "storage" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "enum" : [ + "qemu", + "lxc", + "openvz", + "storage" + ], + "type" : "string" + }, + "vmid" : { + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update pool data (deprecated, no support for nested pools - use 'PUT /pools/?poolid={poolid}' instead).", + "method" : "PUT", + "name" : "update_pool_deprecated", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "allow-move" : { + "default" : 0, + "description" : "Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "default" : 0, + "description" : "Remove the passed VMIDs and/or storage IDs instead of adding them.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "List of storage IDs to add or remove from this pool.", + "format" : "pve-storage-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "List of guest VMIDs to add or remove from this pool.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description" : "You also need the right to modify permissions on any object you add/delete." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/pools/{poolid}", + "text" : "{poolid}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete pool.", + "method" : "DELETE", + "name" : "delete_pool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description" : "You can only delete empty pools (no members)." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List pools or get pool configuration.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "poolid" : { + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "enum" : [ + "qemu", + "lxc", + "storage" + ], + "optional" : 1, + "requires" : "poolid", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "List all pools where you have Pool.Audit permissions on /pool/, or the pool specific with {poolid}", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "members" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "id" : { + "type" : "string" + }, + "node" : { + "type" : "string" + }, + "storage" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "enum" : [ + "qemu", + "lxc", + "openvz", + "storage" + ], + "type" : "string" + }, + "vmid" : { + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "poolid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{poolid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new pool.", + "method" : "POST", + "name" : "create_pool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update pool.", + "method" : "PUT", + "name" : "update_pool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "allow-move" : { + "default" : 0, + "description" : "Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "default" : 0, + "description" : "Remove the passed VMIDs and/or storage IDs instead of adding them.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "List of storage IDs to add or remove from this pool.", + "format" : "pve-storage-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "List of guest VMIDs to add or remove from this pool.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description" : "You also need the right to modify permissions on any object you add/delete." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/pools", + "text" : "pools" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "API version details, including some parts of the global datacenter config.", + "method" : "GET", + "name" : "version", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "properties" : { + "console" : { + "description" : "The default console viewer to use.", + "enum" : [ + "applet", + "vv", + "html5", + "xtermjs" + ], + "optional" : 1, + "type" : "string" + }, + "release" : { + "description" : "The current Proxmox VE point release in `x.y` format.", + "type" : "string" + }, + "repoid" : { + "description" : "The short git revision from which this version was build.", + "pattern" : "[0-9a-fA-F]{8,64}", + "type" : "string" + }, + "version" : { + "description" : "The full pve-manager package version of this node.", + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/version", + "text" : "version" + } +] +; + +let method2cmd = { + GET: 'get', + POST: 'create', + PUT: 'set', + DELETE: 'delete' +}; + +function cliUsageRenderer(method, path) { + return ` CLI:pvesh ${method2cmd[method]} ${path}`; +} +/*global apiSchema*/ + +Ext.onReady(function () { + Ext.define('pmx-param-schema', { + extend: 'Ext.data.Model', + fields: [ + 'name', + 'type', + 'typetext', + 'description', + 'verbose_description', + 'enum', + 'minimum', + 'maximum', + 'minLength', + 'maxLength', + 'pattern', + 'title', + 'requires', + 'format', + 'default', + 'disallow', + 'extends', + 'links', + 'instance-types', + { + name: 'optional', + type: 'boolean', + }, + ], + }); + + let store = Ext.define('pmx-updated-treestore', { + extend: 'Ext.data.TreeStore', + model: Ext.define('pmx-api-doc', { + extend: 'Ext.data.Model', + fields: ['path', 'info', 'text'], + }), + proxy: { + type: 'memory', + data: apiSchema, + }, + sorters: [ + { + property: 'leaf', + direction: 'ASC', + }, + { + property: 'text', + direction: 'ASC', + }, + ], + filterer: 'bottomup', + doFilter: function (node) { + this.filterNodes(node, this.getFilters().getFilterFn(), true); + }, + + filterNodes: function (node, filterFn, parentVisible) { + let me = this; + + let match = + filterFn(node) && (parentVisible || (node.isRoot() && !me.getRootVisible())); + + if (node.childNodes && node.childNodes.length) { + let bottomUpFiltering = me.filterer === 'bottomup'; + let childMatch; + for (const child of node.childNodes) { + childMatch = + me.filterNodes(child, filterFn, match || bottomUpFiltering) || childMatch; + } + if (bottomUpFiltering) { + match = childMatch || match; + } + } + + node.set('visible', match, me._silentOptions); + return match; + }, + }).create(); + + let render_description = function (value, metaData, record) { + let pdef = record.data; + + value = pdef.verbose_description || value; + + // TODO: try to render asciidoc correctly + + metaData.style = 'white-space:pre-wrap;'; + + return Ext.htmlEncode(value); + }; + + let render_type = function (value, metaData, record) { + let pdef = record.data; + + return pdef.enum ? 'enum' : pdef.type || 'string'; + }; + + const renderFormatString = function (obj) { + if (!Ext.isObject(obj)) { + return obj; + } + const mandatory = []; + const optional = []; + Object.entries(obj).forEach(function ([name, param]) { + let list = param.optional ? optional : mandatory; + let str = param.default_key ? `[${name}=]` : `${name}=`; + if (param.alias) { + return; + } else if (param.enum) { + str += `(${param.enum?.join(' | ')})`; + } else { + str += `<${param.format_description || param.pattern || param.type}>`; + } + list.push(str); + }); + return mandatory.join(', ') + ' ' + optional.map((each) => `[,${each}]`).join(' '); + }; + + let render_simple_format = function (pdef, type_fallback) { + if (pdef.typetext) { + return pdef.typetext; + } + if (pdef.enum) { + return pdef.enum.join(' | '); + } + if (pdef.format) { + return renderFormatString(pdef.format); + } + if (pdef.pattern) { + return pdef.pattern; + } + if (pdef.type === 'boolean') { + return ``; + } + if (type_fallback && pdef.type) { + return `<${pdef.type}>`; + } + if (pdef.minimum || pdef.maximum) { + return `${pdef.minimum || 'N'} - ${pdef.maximum || 'N'}`; + } + return ''; + }; + + let render_format = function (value, metaData, record) { + let pdef = record.data; + + metaData.style = 'white-space:normal;'; + + if (pdef.type === 'array' && pdef.items) { + let format = render_simple_format(pdef.items, true); + return `[${Ext.htmlEncode(format)}, ...]`; + } + + return Ext.htmlEncode(render_simple_format(pdef)); + }; + + let real_path = function (path) { + if (!path.match(/^[/]/)) { + path = `/${path}`; + } + return path.replace(/^.*\/_upgrade_(\/)?/, '/'); + }; + + let permission_text = function (permission) { + let permhtml = ''; + + if (permission.user) { + if (!permission.description) { + if (permission.user === 'world') { + permhtml += 'Accessible without any authentication.'; + } else if (permission.user === 'all') { + permhtml += 'Accessible by all authenticated users.'; + } else { + permhtml += `Only accessible by user "${permission.user}"`; + } + } + } else if (permission.check) { + permhtml += `
Check: ${Ext.htmlEncode(JSON.stringify(permission.check))}
`; + } else if (permission.userParam) { + permhtml += `
Check if user matches parameter '${permission.userParam}'`; + } else if (permission.or) { + permhtml += "
Or
"; + permhtml += permission.or.map((v) => permission_text(v)).join(''); + permhtml += '
'; + } else if (permission.and) { + permhtml += "
And
"; + permhtml += permission.and.map((v) => permission_text(v)).join(''); + permhtml += '
'; + } else { + permhtml += 'Unknown syntax!'; + } + + return permhtml; + }; + + let render_docu = function (data) { + let md = data.info; + + let items = []; + + Ext.Array.each(['GET', 'POST', 'PUT', 'DELETE'], function (method) { + let info = md[method]; + if (info) { + let endpoint = real_path(data.path); + let usage = ``; + + if (typeof cliUsageRenderer === 'function') { + usage += cliUsageRenderer(method, endpoint); + } + + let sections = []; + + if (info.unstable) { + sections.push({ + title: 'Unstable', + html: `
+ + This API endpoint is marked as unstable. All information on this + page is subject to change, including input parameters, return values + and permissions. +
`, + }); + } + + sections.push( + { + title: 'Description', + html: Ext.htmlEncode(info.description), + bodyPadding: 10, + }, + { + title: 'Usage', + html: usage, + bodyPadding: 10, + }, + ); + + if (info.parameters && info.parameters.properties) { + let pstore = Ext.create('Ext.data.Store', { + model: 'pmx-param-schema', + proxy: { + type: 'memory', + }, + groupField: 'optional', + sorters: [ + { + property: 'instance-types', + direction: 'ASC', + }, + { + property: 'name', + direction: 'ASC', + }, + ], + }); + + let has_type_properties = false; + + Ext.Object.each(info.parameters.properties, function (name, pdef) { + if (pdef.oneOf) { + pdef.oneOf.forEach((alternative) => { + alternative.name = name; + pstore.add(alternative); + has_type_properties = true; + }); + } else if (pdef['instance-types']) { + pdef['instance-types'].forEach((type) => { + let typePdef = Ext.apply({}, pdef); + typePdef.name = name; + typePdef['instance-types'] = [type]; + pstore.add(typePdef); + has_type_properties = true; + }); + } else { + pdef.name = name; + pstore.add(pdef); + } + }); + + pstore.sort(); + + let groupingFeature = Ext.create('Ext.grid.feature.Grouping', { + enableGroupingMenu: false, + groupHeaderTpl: + 'OptionalRequired', + }); + + sections.push({ + xtype: 'gridpanel', + title: 'Parameters', + features: [groupingFeature], + store: pstore, + viewConfig: { + trackOver: false, + stripeRows: true, + enableTextSelection: true, + }, + columns: [ + { + header: 'Name', + dataIndex: 'name', + flex: 1, + }, + { + header: 'Type', + dataIndex: 'type', + renderer: render_type, + flex: 1, + }, + { + header: 'For Types', + dataIndex: 'instance-types', + hidden: !has_type_properties, + flex: 1, + }, + { + header: 'Default', + dataIndex: 'default', + flex: 1, + }, + { + header: 'Format', + dataIndex: 'type', + renderer: render_format, + flex: 2, + }, + { + header: 'Description', + dataIndex: 'description', + renderer: render_description, + flex: 6, + }, + ], + }); + } + + if (info.returns) { + let retinf = info.returns; + let rtype = retinf.type; + if (!rtype && retinf.items) { + rtype = 'array'; + } + if (!rtype) { + rtype = 'object'; + } + + let rpstore = Ext.create('Ext.data.Store', { + model: 'pmx-param-schema', + proxy: { + type: 'memory', + }, + groupField: 'optional', + sorters: [ + { + property: 'name', + direction: 'ASC', + }, + ], + }); + + let properties; + if (rtype === 'array' && retinf.items.properties) { + properties = retinf.items.properties; + } + + if (rtype === 'object' && retinf.properties) { + properties = retinf.properties; + } + + Ext.Object.each(properties, function (name, pdef) { + pdef.name = name; + rpstore.add(pdef); + }); + + rpstore.sort(); + + let groupingFeature = Ext.create('Ext.grid.feature.Grouping', { + enableGroupingMenu: false, + groupHeaderTpl: + 'OptionalObligatory', + }); + let returnhtml; + if (retinf.items) { + returnhtml = + '
items: ' +
+                            Ext.htmlEncode(JSON.stringify(retinf.items, null, 4)) +
+                            '
'; + } + + if (retinf.properties) { + returnhtml = returnhtml || ''; + returnhtml += + '
properties:' +
+                            Ext.htmlEncode(JSON.stringify(retinf.properties, null, 4)) +
+                            '
'; + } + + let rawSection = Ext.create('Ext.panel.Panel', { + bodyPadding: '0px 10px 10px 10px', + html: returnhtml, + hidden: true, + }); + + sections.push({ + xtype: 'panel', + title: 'Returns: ' + rtype, + items: [ + info.returns.description + ? { + html: Ext.htmlEncode(info.returns.description), + bodyPadding: '5px 10px 5px 10px', + } + : {}, + { + xtype: 'gridpanel', + features: [groupingFeature], + store: rpstore, + viewConfig: { + trackOver: false, + stripeRows: true, + enableTextSelection: true, + }, + columns: [ + { + header: 'Name', + dataIndex: 'name', + flex: 1, + }, + { + header: 'Type', + dataIndex: 'type', + renderer: render_type, + flex: 1, + }, + { + header: 'Default', + dataIndex: 'default', + flex: 1, + }, + { + header: 'Format', + dataIndex: 'type', + renderer: render_format, + flex: 2, + }, + { + header: 'Description', + dataIndex: 'description', + renderer: render_description, + flex: 6, + }, + ], + bbar: [ + { + xtype: 'button', + text: 'Show RAW', + handler: function (btn) { + rawSection.setVisible(!rawSection.isVisible()); + btn.setText( + rawSection.isVisible() ? 'Hide RAW' : 'Show RAW', + ); + }, + }, + ], + }, + ], + }); + + sections.push(rawSection); + } + + if (!data.path.match(/\/_upgrade_/)) { + let permhtml = ''; + + if (!info.permissions) { + permhtml = 'Root only.'; + } else { + if (info.permissions.description) { + permhtml += + "
" + + Ext.htmlEncode(info.permissions.description) + + '
'; + } + permhtml += permission_text(info.permissions); + } + + if (info.allowtoken !== undefined && !info.allowtoken) { + permhtml += '
This API endpoint is not available for API tokens.'; + } + + sections.push({ + title: 'Required permissions', + bodyPadding: 10, + html: permhtml, + }); + } + + items.push({ + title: method, + autoScroll: true, + defaults: { + border: false, + }, + items: sections, + }); + } + }); + + let ct = Ext.getCmp('docview'); + ct.setTitle('Path: ' + real_path(data.path)); + ct.removeAll(true); + ct.add(items); + ct.setActiveTab(0); + }; + + Ext.define('Ext.form.SearchField', { + extend: 'Ext.form.field.Text', + alias: 'widget.searchfield', + + emptyText: 'Search...', + + flex: 1, + + inputType: 'search', + listeners: { + change: function () { + let value = this.getValue(); + if (!Ext.isEmpty(value)) { + store.filter({ + property: 'path', + value: value, + anyMatch: true, + }); + } else { + store.clearFilter(); + } + }, + }, + }); + + let treePanel = Ext.create('Ext.tree.Panel', { + title: 'Resource Tree', + tbar: [ + { + xtype: 'searchfield', + }, + ], + tools: [ + { + type: 'expand', + tooltip: 'Expand all', + tooltipType: 'title', + callback: (tree) => tree.expandAll(), + }, + { + type: 'collapse', + tooltip: 'Collapse all', + tooltipType: 'title', + callback: (tree) => tree.collapseAll(), + }, + ], + store: store, + width: 200, + region: 'west', + split: true, + margins: '5 0 5 5', + rootVisible: false, + listeners: { + selectionchange: function (v, selections) { + if (!selections[0]) { + return; + } + let rec = selections[0]; + render_docu(rec.data); + location.hash = '#' + rec.data.path; + }, + }, + }); + + Ext.create('Ext.container.Viewport', { + layout: 'border', + renderTo: Ext.getBody(), + items: [ + treePanel, + { + xtype: 'tabpanel', + title: 'Documentation', + id: 'docview', + region: 'center', + margins: '5 5 5 0', + layout: 'fit', + items: [], + }, + ], + }); + + let deepLink = function () { + let path = window.location.hash.substring(1).replace(/\/\s*$/, ''); + let endpoint = store.findNode('path', path); + + if (endpoint) { + treePanel.getSelectionModel().select(endpoint); + treePanel.expandPath(endpoint.getPath()); + render_docu(endpoint.data); + } + }; + window.onhashchange = deepLink; + + deepLink(); +}); diff --git a/contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/snapshot.json b/contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/snapshot.json new file mode 100644 index 0000000..d2890d9 --- /dev/null +++ b/contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/snapshot.json @@ -0,0 +1 @@ +{"extra":{"warning_count":0},"format_version":1,"method_count":675,"path_count":444,"paths":[{"extra":{},"methods":[{"allow_token":true,"checksum":"381dbe2603a3fe4644aef5716358b57a8c8df69ae5476d4204ec50da62e28f19","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/access"},{"extra":{},"methods":[{"allow_token":true,"checksum":"69d1196ad983a4e9b6440c4dc7050a74d305be5327ff2b7231df69a5f7300f0a","description":"Get Access Control List (ACLs).","extra":{},"name":"read_acl","parameters":[],"permissions":{"description":"The returned list is restricted to objects where you have rights to modify permissions.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":0},"properties":{"path":{"description":"Access control path","enum":[],"extra":{},"properties":{},"type":"string"},"propagate":{"default":1,"description":"Allow to propagate (inherit) permissions.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"roleid":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":["user","group","token"],"extra":{},"properties":{},"type":"string"},"ugid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f303163fa6559541cc81fcd57689b33e3ed216ea236d34d63cd9d35e3fce947a","description":"Update Access Control List (add or remove permissions).","extra":{},"name":"update_acl","parameters":[{"definition":{"description":"Remove permissions (instead of adding it).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"List of groups.","enum":[],"extra":{"typetext":""},"format":"pve-groupid-list","optional":true,"properties":{},"type":"string"},"name":"groups"},{"definition":{"description":"Access control path","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"path"},{"definition":{"default":1,"description":"Allow to propagate (inherit) permissions.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"propagate"},{"definition":{"description":"List of roles.","enum":[],"extra":{"typetext":""},"format":"pve-roleid-list","properties":{},"type":"string"},"name":"roles"},{"definition":{"description":"List of API tokens.","enum":[],"extra":{"typetext":""},"format":"pve-tokenid-list","optional":true,"properties":{},"type":"string"},"name":"tokens"},{"definition":{"description":"List of users.","enum":[],"extra":{"typetext":""},"format":"pve-userid-list","optional":true,"properties":{},"type":"string"},"name":"users"}],"permissions":{"expression":{"check":["perm-modify","{path}"]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/acl"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f6bd08a792d4f4d22aac7aaddba3d623b96b8333f6e0e464a8782c3ebc6c764b","description":"Authentication domain index.","extra":{},"name":"index","parameters":[],"permissions":{"description":"Anyone can access that, because we need that list for the login box (before the user is authenticated).","expression":{},"extra":{},"user":"world"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{realm}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"A comment. The GUI use this text when you select a domain (Realm) on the login window.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"realm":{"enum":[],"extra":{},"properties":{},"type":"string"},"tfa":{"description":"Two-factor authentication provider.","enum":["yubico","oath"],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"39327bb3ec3d52eb7683a4d210ec5159b7063f3387939cf64dce4d0143ac4edf","description":"Add an authentication server.","extra":{},"name":"create","parameters":[{"definition":{"description":"Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.","enum":[],"extra":{},"optional":true,"pattern":"^[^\\x00-\\x1F\\x7F <>#\"]*$","properties":{},"type":"string"},"name":"acr-values"},{"definition":{"description":"A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'.","enum":[],"extra":{},"optional":true,"pattern":"^[^\\x00-\\x1F\\x7F <>#\"]*$","properties":{},"type":"string"},"name":"audiences"},{"definition":{"default":0,"description":"Automatically create users if they do not exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autocreate"},{"definition":{"description":"LDAP base domain name","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"base_dn"},{"definition":{"description":"LDAP bind domain name","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"bind_dn"},{"definition":{"default":"/etc/ssl/certs","description":"Path to the CA certificate store","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"capath"},{"definition":{"default":1,"description":"username is case-sensitive","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"case-sensitive"},{"definition":{"description":"Path to the client certificate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cert"},{"definition":{"description":"Path to the client certificate key","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"certkey"},{"definition":{"default":0,"description":"Check bind connection to the server.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"check-connection"},{"definition":{"description":"OpenID Client ID","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"client-id"},{"definition":{"description":"OpenID Client Key","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"client-key"},{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Use this as default realm","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"default"},{"definition":{"description":"AD domain name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\S+","properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"LDAP filter for user sync.","enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"filter"},{"definition":{"default":"groupOfNames, group, univentionGroup, ipausergroup","description":"The objectclasses for groups.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr-list","optional":true,"properties":{},"type":"string"},"name":"group_classes"},{"definition":{"description":"LDAP base domain name for group sync. If not set, the base_dn will be used.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"group_dn"},{"definition":{"description":"LDAP filter for group sync.","enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"group_filter"},{"definition":{"description":"LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"group_name_attr"},{"definition":{"default":0,"description":"Automatically create groups if they do not exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"groups-autocreate"},{"definition":{"description":"OpenID claim used to retrieve groups with.","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^:[A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"groups-claim"},{"definition":{"default":0,"description":"All groups will be overwritten for the user on login.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"groups-overwrite"},{"definition":{"description":"OpenID Issuer Url","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"issuer-url"},{"definition":{"default":"ldap","description":"LDAP protocol mode.","enum":["ldap","ldaps","ldap+starttls"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Server port.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.","enum":[],"extra":{},"optional":true,"pattern":"(?:none|login|consent|select_account|\\S+)","properties":{},"type":"string"},"name":"prompt"},{"definition":{"default":1,"description":"Enables querying the userinfo endpoint for claims values.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"query-userinfo"},{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"},{"definition":{"default":"email profile","description":"Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"scopes"},{"definition":{"description":"Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"secure"},{"definition":{"description":"Server IP address (or DNS name)","enum":[],"extra":{"typetext":""},"format":"address","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"server1"},{"definition":{"description":"Fallback Server IP address (or DNS name)","enum":[],"extra":{"typetext":""},"format":"address","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"server2"},{"definition":{"description":"LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!","enum":["tlsv1","tlsv1_1","tlsv1_2","tlsv1_3"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"sslversion"},{"definition":{"description":"The default options for behavior of synchronizations.","enum":[],"extra":{"typetext":"[enable-new=<1|0>] [,full=<1|0>] [,purge=<1|0>] [,remove-vanished=([acl];[properties];[entry])|none] [,scope=]"},"format":"realm-sync-options","optional":true,"properties":{},"type":"string"},"name":"sync-defaults-options"},{"definition":{"description":"Comma separated list of key=value pairs for specifying which LDAP attributes map to which PVE user field. For example, to map the LDAP attribute 'mail' to PVEs 'email', write 'email=mail'. By default, each PVE user field is represented by an LDAP attribute of the same name.","enum":[],"extra":{},"optional":true,"pattern":"\\w+=[^,]+(,\\s*\\w+=[^,]+)*","properties":{},"type":"string"},"name":"sync_attributes"},{"definition":{"description":"Use Two-factor authentication.","enum":[],"extra":{"typetext":"type= [,digits=] [,id=] [,key=] [,step=] [,url=]"},"format":"pve-tfa-config","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"tfa"},{"definition":{"description":"Realm type.","enum":["ad","ldap","openid","pam","pve"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"LDAP user attribute name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\S{2,}","properties":{},"type":"string"},"name":"user_attr"},{"definition":{"default":"inetorgperson, posixaccount, person, user","description":"The objectclasses for users.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr-list","optional":true,"properties":{},"type":"string"},"name":"user_classes"},{"definition":{"description":"OpenID claim used to generate the unique username.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username-claim"},{"definition":{"default":0,"description":"Verify the server's SSL certificate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify"}],"permissions":{"expression":{"check":["perm","/access/realm",["Realm.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/domains"},{"extra":{},"methods":[{"allow_token":true,"checksum":"67ef2d8bf073fff13e3d81cd559ffa0c8d70b56f153a1a682bf52b5e6068f2ee","description":"Delete an authentication server.","extra":{},"name":"delete","parameters":[{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"}],"permissions":{"expression":{"check":["perm","/access/realm",["Realm.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"68ad3629142a043ace8f38217d65a6ecf29d34a83d21ff690c0def6efcdabd7c","description":"Get auth server configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"}],"permissions":{"expression":{"check":["perm","/access/realm",["Realm.Allocate","Sys.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{}},"verb":"GET"},{"allow_token":true,"checksum":"10fa662ad027c24c4827dd35cdd02d6efdfc4c03eb7ea5a262052d6e4ab1103a","description":"Update authentication server settings.","extra":{},"name":"update","parameters":[{"definition":{"description":"Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.","enum":[],"extra":{},"optional":true,"pattern":"^[^\\x00-\\x1F\\x7F <>#\"]*$","properties":{},"type":"string"},"name":"acr-values"},{"definition":{"description":"A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'.","enum":[],"extra":{},"optional":true,"pattern":"^[^\\x00-\\x1F\\x7F <>#\"]*$","properties":{},"type":"string"},"name":"audiences"},{"definition":{"default":0,"description":"Automatically create users if they do not exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autocreate"},{"definition":{"description":"LDAP base domain name","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"base_dn"},{"definition":{"description":"LDAP bind domain name","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"bind_dn"},{"definition":{"default":"/etc/ssl/certs","description":"Path to the CA certificate store","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"capath"},{"definition":{"default":1,"description":"username is case-sensitive","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"case-sensitive"},{"definition":{"description":"Path to the client certificate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cert"},{"definition":{"description":"Path to the client certificate key","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"certkey"},{"definition":{"default":0,"description":"Check bind connection to the server.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"check-connection"},{"definition":{"description":"OpenID Client ID","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"client-id"},{"definition":{"description":"OpenID Client Key","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"client-key"},{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Use this as default realm","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"default"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"AD domain name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\S+","properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"LDAP filter for user sync.","enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"filter"},{"definition":{"default":"groupOfNames, group, univentionGroup, ipausergroup","description":"The objectclasses for groups.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr-list","optional":true,"properties":{},"type":"string"},"name":"group_classes"},{"definition":{"description":"LDAP base domain name for group sync. If not set, the base_dn will be used.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"group_dn"},{"definition":{"description":"LDAP filter for group sync.","enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"group_filter"},{"definition":{"description":"LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"group_name_attr"},{"definition":{"default":0,"description":"Automatically create groups if they do not exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"groups-autocreate"},{"definition":{"description":"OpenID claim used to retrieve groups with.","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^:[A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"groups-claim"},{"definition":{"default":0,"description":"All groups will be overwritten for the user on login.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"groups-overwrite"},{"definition":{"description":"OpenID Issuer Url","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"issuer-url"},{"definition":{"default":"ldap","description":"LDAP protocol mode.","enum":["ldap","ldaps","ldap+starttls"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Server port.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.","enum":[],"extra":{},"optional":true,"pattern":"(?:none|login|consent|select_account|\\S+)","properties":{},"type":"string"},"name":"prompt"},{"definition":{"default":1,"description":"Enables querying the userinfo endpoint for claims values.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"query-userinfo"},{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"},{"definition":{"default":"email profile","description":"Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"scopes"},{"definition":{"description":"Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"secure"},{"definition":{"description":"Server IP address (or DNS name)","enum":[],"extra":{"typetext":""},"format":"address","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"server1"},{"definition":{"description":"Fallback Server IP address (or DNS name)","enum":[],"extra":{"typetext":""},"format":"address","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"server2"},{"definition":{"description":"LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!","enum":["tlsv1","tlsv1_1","tlsv1_2","tlsv1_3"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"sslversion"},{"definition":{"description":"The default options for behavior of synchronizations.","enum":[],"extra":{"typetext":"[enable-new=<1|0>] [,full=<1|0>] [,purge=<1|0>] [,remove-vanished=([acl];[properties];[entry])|none] [,scope=]"},"format":"realm-sync-options","optional":true,"properties":{},"type":"string"},"name":"sync-defaults-options"},{"definition":{"description":"Comma separated list of key=value pairs for specifying which LDAP attributes map to which PVE user field. For example, to map the LDAP attribute 'mail' to PVEs 'email', write 'email=mail'. By default, each PVE user field is represented by an LDAP attribute of the same name.","enum":[],"extra":{},"optional":true,"pattern":"\\w+=[^,]+(,\\s*\\w+=[^,]+)*","properties":{},"type":"string"},"name":"sync_attributes"},{"definition":{"description":"Use Two-factor authentication.","enum":[],"extra":{"typetext":"type= [,digits=] [,id=] [,key=] [,step=] [,url=]"},"format":"pve-tfa-config","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"tfa"},{"definition":{"description":"LDAP user attribute name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\S{2,}","properties":{},"type":"string"},"name":"user_attr"},{"definition":{"default":"inetorgperson, posixaccount, person, user","description":"The objectclasses for users.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr-list","optional":true,"properties":{},"type":"string"},"name":"user_classes"},{"definition":{"default":0,"description":"Verify the server's SSL certificate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify"}],"permissions":{"expression":{"check":["perm","/access/realm",["Realm.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/domains/{realm}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a1767738c2b9bc0ac0f8cd38d7d39bc6a0aa139bfc06fc7f92b6d6fce313c81f","description":"Syncs users and/or groups from the configured LDAP to user.cfg. NOTE: Synced groups will have the name 'name-$realm', so make sure those groups do not exist to prevent overwriting.","extra":{},"name":"sync","parameters":[{"definition":{"default":0,"description":"If set, does not write anything.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"dry-run"},{"definition":{"default":"1","description":"Enable newly synced users immediately.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable-new"},{"definition":{"description":"DEPRECATED: use 'remove-vanished' instead. If set, uses the LDAP Directory as source of truth, deleting users or groups not returned from the sync and removing all locally modified properties of synced users. If not set, only syncs information which is present in the synced data, and does not delete or modify anything else.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"},{"definition":{"description":"DEPRECATED: use 'remove-vanished' instead. Remove ACLs for users or groups which were removed from the config during a sync.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"purge"},{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"},{"definition":{"default":"none","description":"A semicolon-separated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).","enum":[],"extra":{"typetext":"([acl];[properties];[entry])|none"},"optional":true,"pattern":"(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none","properties":{},"type":"string"},"name":"remove-vanished"},{"definition":{"description":"Select what to sync.","enum":["users","groups","both"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scope"}],"permissions":{"description":"'Realm.AllocateUser' on '/access/realm/' and 'User.Modify' permissions to '/access/groups/'.","expression":{"check":["and",["perm","/access/realm/{realm}",["Realm.AllocateUser"]],["perm","/access/groups",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"description":"Worker Task-UPID","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/access/domains/{realm}/sync"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4c91cdccabc91aef686778145ca3abfc7c583221f55d71a6a63742c0c9e8620e","description":"Group index.","extra":{},"name":"index","parameters":[],"permissions":{"description":"The returned list is restricted to groups where you have 'User.Modify', 'Sys.Audit' or 'Group.Allocate' permissions on /access/groups/.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{groupid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"groupid":{"enum":[],"extra":{},"format":"pve-groupid","properties":{},"type":"string"},"users":{"description":"list of users which form this group","enum":[],"extra":{},"format":"pve-userid-list","optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f98ce64f3980dff63659bf39b78cfd90bc57491d5a6b16adf211ad89cb5bacbf","description":"Create new group.","extra":{},"name":"create_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid","properties":{},"type":"string"},"name":"groupid"}],"permissions":{"expression":{"check":["perm","/access/groups",["Group.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/groups"},{"extra":{},"methods":[{"allow_token":true,"checksum":"da8c8fd5b71fd2ffb0d9a877a6a55bf3fece5793e6e84103fd32ce8393b143a9","description":"Delete group.","extra":{},"name":"delete_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid","properties":{},"type":"string"},"name":"groupid"}],"permissions":{"expression":{"check":["perm","/access/groups",["Group.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"97141e0ff4c0c701de5667b1695e08f82f1c7ca0457b431a4544c6b1b2ebf164","description":"Get group configuration.","extra":{},"name":"read_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid","properties":{},"type":"string"},"name":"groupid"}],"permissions":{"expression":{"check":["perm","/access/groups",["Sys.Audit","Group.Allocate"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"members":{"enum":[],"extra":{},"items":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"acae7739337fa0edb0e0a31549c4d29be7fdf80fd872c3b0e65f946d447c8570","description":"Update group data.","extra":{},"name":"update_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid","properties":{},"type":"string"},"name":"groupid"}],"permissions":{"expression":{"check":["perm","/access/groups",["Group.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/groups/{groupid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"381dbe2603a3fe4644aef5716358b57a8c8df69ae5476d4204ec50da62e28f19","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/access/openid"},{"extra":{},"methods":[{"allow_token":true,"checksum":"11698bf61b11bf04b51047fbad48466f21c0e0de4d90d25ed9650486cab24fdb","description":"Get the OpenId Authorization Url for the specified realm.","extra":{},"name":"auth_url","parameters":[{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"},{"definition":{"description":"Redirection Url. The client should set this to the used server url (location.origin).","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"redirect-url"}],"permissions":{"expression":{},"extra":{},"user":"world"},"protected":true,"returns":{"description":"Redirection URL.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/access/openid/auth-url"},{"extra":{},"methods":[{"allow_token":true,"checksum":"19ede18ffcfecdd547ec697670a70a44b18fe1b9f0160ba1e02d8446072ad21d","description":" Verify OpenID authorization code and create a ticket.","extra":{},"name":"login","parameters":[{"definition":{"description":"OpenId authorization code.","enum":[],"extra":{"typetext":""},"max_length":4096,"properties":{},"type":"string"},"name":"code"},{"definition":{"description":"Redirection Url. The client should set this to the used server url (location.origin).","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"redirect-url"},{"definition":{"description":"OpenId state.","enum":[],"extra":{"typetext":""},"max_length":1024,"properties":{},"type":"string"},"name":"state"}],"permissions":{"expression":{},"extra":{},"user":"world"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"CSRFPreventionToken":{"enum":[],"extra":{},"properties":{},"type":"string"},"cap":{"enum":[],"extra":{},"properties":{},"type":"object"},"clustername":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"username":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/access/openid/login"},{"extra":{},"methods":[{"allow_token":false,"checksum":"89105df2fc31d5ef94c2383c01872c011a634de7c0e3241dc325311de9f11fa1","description":"Change user password.","extra":{},"name":"change_password","parameters":[{"definition":{"description":"The current password of the user performing the change.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"confirmation-password"},{"definition":{"description":"The new password.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":8,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"description":"Each user is allowed to change their own password. A user can change the password of another user if they have 'Realm.AllocateUser' (on the realm of user ) and 'User.Modify' permission on /access/groups/ on a group where user is member of. For the PAM realm, a password change does not take effect cluster-wide, but only applies to the local node.","expression":{"check":["or",["userid-param","self"],["and",["userid-param","Realm.AllocateUser"],["userid-group",["User.Modify"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/password"},{"extra":{},"methods":[{"allow_token":true,"checksum":"581500cf55715c5906b69cd6691c20d1372de35b8e557a473e8351db9bf8feb8","description":"Retrieve effective permissions of given user/token.","extra":{},"name":"permissions","parameters":[{"definition":{"description":"Only dump this specific path, not the whole tree.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"User ID or full API token ID","enum":[],"extra":{},"optional":true,"pattern":"(?^:^(?^:[^\\s:/]+)\\@(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)(?:!(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+))?$)","properties":{},"type":"string"},"name":"userid"}],"permissions":{"description":"Each user/token is allowed to dump their own permissions (or that of owned tokens). A user can dump the permissions of another user or their tokens if they have 'Sys.Audit' permission on /access.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"Map of \"path\" => (Map of \"privilege\" => \"propagate boolean\").","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/access/permissions"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7d4735a632ce33c51d1e2e47102b18f3b391b730e88f11993ab2319447462466","description":"Role index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{roleid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"privs":{"enum":[],"extra":{},"format":"pve-priv-list","optional":true,"properties":{},"type":"string"},"roleid":{"enum":[],"extra":{},"format":"pve-roleid","properties":{},"type":"string"},"special":{"default":0,"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f57a81b3de7e8d88ea26453fd9bf5d26eb5b707474daa5d903df0fd5883860d5","description":"Create new role.","extra":{},"name":"create_role","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-priv-list","optional":true,"properties":{},"type":"string"},"name":"privs"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-roleid","properties":{},"type":"string"},"name":"roleid"}],"permissions":{"expression":{"check":["perm","/access",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/roles"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f1877684ae2970429259e20a70086722eda0e3fbd75ec22dc770adfed8cdad01","description":"Delete role.","extra":{},"name":"delete_role","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-roleid","properties":{},"type":"string"},"name":"roleid"}],"permissions":{"expression":{"check":["perm","/access",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"7cc81f67d2e5b14a71d1bb9a95a6c827b3b0163c6e330898c7fe0dcb4642d6c4","description":"Get role configuration.","extra":{},"name":"read_role","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-roleid","properties":{},"type":"string"},"name":"roleid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"Datastore.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Datastore.AllocateSpace":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Datastore.AllocateTemplate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Datastore.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Group.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Mapping.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Mapping.Modify":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Mapping.Use":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Permissions.Modify":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Pool.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Pool.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Realm.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Realm.AllocateUser":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"SDN.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"SDN.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"SDN.Use":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.AccessNetwork":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Console":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Incoming":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Modify":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.PowerMgmt":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Syslog":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"User.Modify":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Backup":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Clone":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.CDROM":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.CPU":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Cloudinit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Disk":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.HWType":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Memory":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Network":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Options":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Console":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.GuestAgent.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.GuestAgent.FileRead":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.GuestAgent.FileSystemMgmt":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.GuestAgent.FileWrite":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.GuestAgent.Unrestricted":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Migrate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.PowerMgmt":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Replicate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Snapshot":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Snapshot.Rollback":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"de543d90c405a031a8d83dba37eaf7b9faa4301cd0cac388ad12bc18dfdeb306","description":"Update an existing role.","extra":{},"name":"update_role","parameters":[{"definition":{"enum":[],"extra":{"requires":"privs","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"append"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-priv-list","optional":true,"properties":{},"type":"string"},"name":"privs"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-roleid","properties":{},"type":"string"},"name":"roleid"}],"permissions":{"expression":{"check":["perm","/access",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/roles/{roleid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f91fc5c12c7b0b199c7707aac6752be2449378befab94de333882d63e260cb78","description":"List TFA configurations of users.","extra":{},"name":"list_tfa","parameters":[],"permissions":{"description":"Returns all or just the logged-in user, depending on privileges.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"description":"The list tuples of user and TFA entries.","enum":[],"extra":{"links":[{"href":"{userid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"entries":{"enum":[],"extra":{},"items":{"description":"TFA Entry.","enum":[],"extra":{},"properties":{"created":{"description":"Creation time of this entry as unix epoch.","enum":[],"extra":{},"properties":{},"type":"integer"},"description":{"description":"User chosen description for this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"enable":{"default":1,"description":"Whether this TFA entry is currently enabled.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"id":{"description":"The id used to reference this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"TFA Entry Type.","enum":["totp","u2f","webauthn","recovery","yubico"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"tfa-locked-until":{"description":"Contains a timestamp until when a user is locked out of 2nd factors.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"totp-locked":{"description":"True if the user is currently locked out of TOTP factors.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"userid":{"description":"User this entry belongs to.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/access/tfa"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9e9514c7d979e99e219e52f97e01d8dde204978341882b3b25607e285fa80386","description":"List TFA configurations of users.","extra":{},"name":"list_user_tfa","parameters":[{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify","Sys.Audit"]]]},"extra":{}},"protected":true,"returns":{"description":"A list of the user's TFA entries.","enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"description":"TFA Entry.","enum":[],"extra":{},"properties":{"created":{"description":"Creation time of this entry as unix epoch.","enum":[],"extra":{},"properties":{},"type":"integer"},"description":{"description":"User chosen description for this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"enable":{"default":1,"description":"Whether this TFA entry is currently enabled.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"id":{"description":"The id used to reference this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"TFA Entry Type.","enum":["totp","u2f","webauthn","recovery","yubico"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":false,"checksum":"25a61e1b13613dab8ffbddc3d215b6e902d7ca2074ffb050f4435f2196444f86","description":"Add a TFA entry for a user.","extra":{},"name":"add_tfa_entry","parameters":[{"definition":{"description":"When responding to a u2f challenge: the original challenge string","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"challenge"},{"definition":{"description":"A description to distinguish multiple entries from one another","enum":[],"extra":{"typetext":""},"max_length":255,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The current password of the user performing the change.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"A totp URI.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"totp"},{"definition":{"description":"TFA Entry Type.","enum":["totp","u2f","webauthn","recovery","yubico"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"},{"definition":{"description":"The current value for the provided totp URI, or a Webauthn/U2F challenge response","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"value"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"challenge":{"description":"When adding u2f entries, this contains a challenge the user must respond to in order to finish the registration.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"description":"The id of a newly added TFA entry.","enum":[],"extra":{},"properties":{},"type":"string"},"recovery":{"description":"When adding recovery codes, this contains the list of codes to be displayed to the user","enum":[],"extra":{},"items":{"description":"A recovery entry.","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"verb":"POST"}],"path":"/access/tfa/{userid}"},{"extra":{},"methods":[{"allow_token":false,"checksum":"7f5a4a103f311d4bd0cda2596ae1b4ac5a454f02629ef26f23055c1eca449482","description":"Delete a TFA entry by ID.","extra":{},"name":"delete_tfa","parameters":[{"definition":{"description":"A TFA entry id.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The current password of the user performing the change.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"0980e358fcccf5906073e67987deaae92d2c610d396aa4988af5b8356c102847","description":"Fetch a requested TFA entry if present.","extra":{},"name":"get_tfa_entry","parameters":[{"definition":{"description":"A TFA entry id.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"id"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify","Sys.Audit"]]]},"extra":{}},"protected":true,"returns":{"description":"TFA Entry.","enum":[],"extra":{},"properties":{"created":{"description":"Creation time of this entry as unix epoch.","enum":[],"extra":{},"properties":{},"type":"integer"},"description":{"description":"User chosen description for this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"enable":{"default":1,"description":"Whether this TFA entry is currently enabled.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"id":{"description":"The id used to reference this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"TFA Entry Type.","enum":["totp","u2f","webauthn","recovery","yubico"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":false,"checksum":"de5fbd256e20fa2c51750debf25afd3f80b7f1faf154d09718ae976814751769","description":"Add a TFA entry for a user.","extra":{},"name":"update_tfa_entry","parameters":[{"definition":{"description":"A description to distinguish multiple entries from one another","enum":[],"extra":{"typetext":""},"max_length":255,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Whether the entry should be enabled for login.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"A TFA entry id.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The current password of the user performing the change.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/tfa/{userid}/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b7321acfd13335fc9d66fb47358fa1b8f0ec6775a3c1733a8cdc617c3f9778b8","description":"Dummy. Useful for formatters which want to provide a login page.","extra":{},"name":"get_ticket","parameters":[],"permissions":{"expression":{},"extra":{},"user":"world"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"GET"},{"allow_token":false,"checksum":"ca41840815da5a2a32ab134298fee34856eb743cd283bc6eb453437982d6d7fc","description":"Create or verify authentication ticket.","extra":{},"name":"create_ticket","parameters":[{"definition":{"default":1,"description":"This parameter is now ignored and assumed to be 1.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"new-format"},{"definition":{"description":"One-time password for Two-factor authentication.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"otp"},{"definition":{"description":"The secret password. This can also be a valid ticket.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Verify ticket, and check if user have access 'privs' on 'path'","enum":[],"extra":{"requires":"privs","typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"Verify ticket, and check if user have access 'privs' on 'path'","enum":[],"extra":{"requires":"path","typetext":""},"format":"pve-priv-list","max_length":64,"optional":true,"properties":{},"type":"string"},"name":"privs"},{"definition":{"description":"You can optionally pass the realm using this parameter. Normally the realm is simply added to the username @.","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"optional":true,"properties":{},"type":"string"},"name":"realm"},{"definition":{"description":"The signed TFA challenge string the user wants to respond to.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tfa-challenge"},{"definition":{"description":"User name","enum":[],"extra":{"typetext":""},"max_length":64,"properties":{},"type":"string"},"name":"username"}],"permissions":{"description":"You need to pass valid credientials.","expression":{},"extra":{},"user":"world"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"CSRFPreventionToken":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"clustername":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ticket":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"username":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"POST"}],"path":"/access/ticket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c408f011c77c4c09143ff66a9a8318b74d1213818930e28ab8b349ee1a9dbc47","description":"User index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Optional filter for enable property.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"default":0,"description":"Include group and token information.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"}],"permissions":{"description":"The returned list is restricted to users where you have 'User.Modify' or 'Sys.Audit' permissions on '/access/groups' or on a group the user belongs too. But it always includes the current (authenticated) user.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{userid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"max_length":2048,"optional":true,"properties":{},"type":"string"},"email":{"enum":[],"extra":{},"format":"email-opt","max_length":254,"optional":true,"properties":{},"type":"string"},"enable":{"default":1,"description":"Enable the account (default). You can set this to '0' to disable the account","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"expire":{"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"firstname":{"enum":[],"extra":{},"max_length":1024,"optional":true,"properties":{},"type":"string"},"groups":{"enum":[],"extra":{},"format":"pve-groupid-list","optional":true,"properties":{},"type":"string"},"keys":{"description":"Keys for two factor auth (yubico).","enum":[],"extra":{},"optional":true,"pattern":"[0-9a-zA-Z!=]{0,4096}","properties":{},"type":"string"},"lastname":{"enum":[],"extra":{},"max_length":1024,"optional":true,"properties":{},"type":"string"},"realm-type":{"description":"The type of the users realm","enum":[],"extra":{},"format":"pve-realm","optional":true,"properties":{},"type":"string"},"tfa-locked-until":{"description":"Contains a timestamp until when a user is locked out of 2nd factors.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"tokens":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"tokenid":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"totp-locked":{"description":"True if the user is currently locked out of TOTP factors.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"userid":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{},"format":"pve-userid","max_length":64,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"8af1d16557cf5606431678f4758a50a5ff8af95deab3885d4d6dab9ea8d28f20","description":"Create new user.","extra":{},"name":"create_user","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"email-opt","max_length":254,"optional":true,"properties":{},"type":"string"},"name":"email"},{"definition":{"default":1,"description":"Enable the account (default). You can set this to '0' to disable the account","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"expire"},{"definition":{"enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"firstname"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid-list","optional":true,"properties":{},"type":"string"},"name":"groups"},{"definition":{"description":"Keys for two factor auth (yubico).","enum":[],"extra":{},"optional":true,"pattern":"[0-9a-zA-Z!=]{0,4096}","properties":{},"type":"string"},"name":"keys"},{"definition":{"enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"lastname"},{"definition":{"description":"Initial password.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":8,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"description":"You need 'Realm.AllocateUser' on '/access/realm/' on the realm of user , and 'User.Modify' permissions to '/access/groups/' for any group specified (or 'User.Modify' on '/access/groups' if you pass no groups.","expression":{"check":["and",["userid-param","Realm.AllocateUser"],["userid-group",["User.Modify"],"groups_param","create"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/users"},{"extra":{},"methods":[{"allow_token":true,"checksum":"22780e2427b9f89adfddae9c96331bf99e9988faa7d41c686fb83495858757ae","description":"Delete user.","extra":{},"name":"delete_user","parameters":[{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["and",["userid-param","Realm.AllocateUser"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"c9026bc7070e532432f03a9f4c8ac6708677d2006e8e4bce17376506d7fa06a2","description":"Get user configuration.","extra":{},"name":"read_user","parameters":[{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["userid-group",["User.Modify","Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"comment":{"enum":[],"extra":{},"max_length":2048,"optional":true,"properties":{},"type":"string"},"email":{"enum":[],"extra":{},"format":"email-opt","max_length":254,"optional":true,"properties":{},"type":"string"},"enable":{"default":1,"description":"Enable the account (default). You can set this to '0' to disable the account","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"expire":{"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"firstname":{"enum":[],"extra":{},"max_length":1024,"optional":true,"properties":{},"type":"string"},"groups":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"pve-groupid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"keys":{"description":"Keys for two factor auth (yubico).","enum":[],"extra":{},"optional":true,"pattern":"[0-9a-zA-Z!=]{0,4096}","properties":{},"type":"string"},"lastname":{"enum":[],"extra":{},"max_length":1024,"optional":true,"properties":{},"type":"string"},"tokens":{"enum":[],"extra":{"additionalProperties":{"properties":{"comment":{"optional":1,"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","minimum":0,"optional":1,"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","optional":1,"type":"boolean"}},"type":"object"}},"optional":true,"properties":{},"type":"object"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"6ebb05ae9a13766bb70f67f0f179cb5fedd4ec39339a7be78af0aafaf2a517a1","description":"Update user configuration.","extra":{},"name":"update_user","parameters":[{"definition":{"enum":[],"extra":{"requires":"groups","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"append"},{"definition":{"enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"email-opt","max_length":254,"optional":true,"properties":{},"type":"string"},"name":"email"},{"definition":{"default":1,"description":"Enable the account (default). You can set this to '0' to disable the account","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"expire"},{"definition":{"enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"firstname"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid-list","optional":true,"properties":{},"type":"string"},"name":"groups"},{"definition":{"description":"Keys for two factor auth (yubico).","enum":[],"extra":{},"optional":true,"pattern":"[0-9a-zA-Z!=]{0,4096}","properties":{},"type":"string"},"name":"keys"},{"definition":{"enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"lastname"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["userid-group",["User.Modify"],"groups_param","update"]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/users/{userid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"26f06a801f3aeabfcda58f7abde4e44ae2ea0b7d444bb45d43ab0a2b0ea914f6","description":"Get user TFA types (Personal and Realm).","extra":{},"name":"read_user_tfa_type","parameters":[{"definition":{"default":0,"description":"Request all entries as an array.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"multiple"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify","Sys.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"realm":{"description":"The type of TFA the users realm has set, if any.","enum":["oath","yubico"],"extra":{},"optional":true,"properties":{},"type":"string"},"types":{"description":"Array of the user configured TFA types, if any. Only available if 'multiple' was not passed.","enum":[],"extra":{},"items":{"description":"A TFA type.","enum":["totp","u2f","yubico","webauthn","recovedry"],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"user":{"description":"The type of TFA the user has set, if any. Only set if 'multiple' was not passed.","enum":["oath","u2f"],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/access/users/{userid}/tfa"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2360720a844aea0ccfa1e79e038d8f7e51fdbbf56b0326c4c494f6c74cda5c23","description":"Get user API tokens.","extra":{},"name":"token_index","parameters":[{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{tokenid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"tokenid":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/access/users/{userid}/token"},{"extra":{},"methods":[{"allow_token":true,"checksum":"90a204f61f32d1c0a9d7013a9d97a94ad045ddf8e8a632185529ef137603b2cf","description":"Remove API token for a specific user.","extra":{},"name":"remove_token","parameters":[{"definition":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"tokenid"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f828f02deaee05fa61e8f6f3a516e80c673e3378a5ee3207a542c04c0ec6ffeb","description":"Get specific API token information.","extra":{},"name":"read_token","parameters":[{"definition":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"tokenid"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"b49a880be0c3083d372de13e274dae7d56a3b454d854ae90924ed5ecde1cba28","description":"Generate a new API token for a specific user. NOTE: returns API token value, which needs to be stored as it cannot be retrieved afterwards!","extra":{},"name":"generate_token","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"expire"},{"definition":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"privsep"},{"definition":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"tokenid"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"full-tokenid":{"description":"The full token id.","enum":[],"extra":{"format_description":"!"},"properties":{},"type":"string"},"info":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"value":{"description":"API token value used for authentication.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"POST"},{"allow_token":true,"checksum":"dac3ee338a2ce04532b3806ebb3ec7c8788c0b1edaebf8c2866aef96e43e2cb4","description":"Update API token for a specific user. NOTE: when 'regenerate' is set, the returned token value needs to be stored as it cannot be retrieved afterwards!","extra":{},"name":"update_token_info","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"expire"},{"definition":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"privsep"},{"definition":{"default":0,"description":"Regenerate the token's secret value. All users of the previous secret will lose access after this operation.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"regenerate"},{"definition":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"tokenid"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"full-tokenid":{"description":"The full token id. Only set when 'regenerate' was set.","enum":[],"extra":{"format_description":"!"},"optional":true,"properties":{},"type":"string"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"value":{"description":"API token value used for authentication. Only set when 'regenerate' was set.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"PUT"}],"path":"/access/users/{userid}/token/{tokenid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5c931db6ab2df88bd52ec3eb4863aed7d21f91c49181ee08b7dc0c67734724ec","description":"Unlock a user's TFA authentication.","extra":{},"name":"unlock_tfa","parameters":[{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["userid-group",["User.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"verb":"PUT"}],"path":"/access/users/{userid}/unlock-tfa"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ec1f43c0e2d1432e2280936886a2d5b9c7be7bb225743fb66abc38627382bd95","description":"verify VNC authentication ticket.","extra":{},"name":"verify_vnc_ticket","parameters":[{"definition":{"description":"UserId or token","enum":[],"extra":{"typetext":""},"max_length":64,"properties":{},"type":"string"},"name":"authid"},{"definition":{"description":"Verify ticket, and check if user have access 'privs' on 'path'","enum":[],"extra":{"typetext":""},"max_length":64,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"Verify that the ticket is valid for this port.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Verify ticket, and check if user have access 'privs' on 'path'","enum":[],"extra":{"typetext":""},"format":"pve-priv-list","max_length":64,"properties":{},"type":"string"},"name":"privs"},{"definition":{"description":"The VNC ticket.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"vncticket"}],"permissions":{"description":"You need to pass valid credientials.","expression":{},"extra":{},"user":"world"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/vncticket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8208fe00dcce4afff6857aaaea1b384b09f47069978af63ec4017df08db2adc2","description":"Cluster index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster"},{"extra":{},"methods":[{"allow_token":true,"checksum":"454de9c8ff02ffa321a5cb4dec888a3a945bddc5bb7b099c0da6cca8fb62090b","description":"ACMEAccount index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/acme"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1effbffd5ff5a4763a2fe7769dff21fc58d70d542b250d7117b4d7aa2264e0ca","description":"ACMEAccount index.","extra":{},"name":"account_index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"ba9673f107c9c48f05ca853d7dd64c07a2f371b2cb565a1fd87c6dfcfa5255e3","description":"Register a new ACME account with CA.","extra":{},"name":"register_account","parameters":[{"definition":{"description":"Contact email addresses.","enum":[],"extra":{"typetext":""},"format":"email-list","properties":{},"type":"string"},"name":"contact"},{"definition":{"default":"https://acme-v02.api.letsencrypt.org/directory","description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"optional":true,"pattern":"^https?://.*","properties":{},"type":"string"},"name":"directory"},{"definition":{"description":"HMAC key for External Account Binding.","enum":[],"extra":{"requires":"eab-kid","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"eab-hmac-key"},{"definition":{"description":"Key Identifier for External Account Binding.","enum":[],"extra":{"requires":"eab-hmac-key","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"eab-kid"},{"definition":{"default":"default","description":"ACME account config file name.","enum":[],"extra":{"format_description":"name","typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"URL of CA TermsOfService - setting this indicates agreement.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tos_url"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/acme/account"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b454212b12e22548f4709a1c2a277a21c02818412eadbb2d14bd24d8352bddf8","description":"Deactivate existing ACME account at CA.","extra":{},"name":"deactivate_account","parameters":[{"definition":{"default":"default","description":"ACME account config file name.","enum":[],"extra":{"format_description":"name","typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"name"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"8a68ee3cda0d4d131277b3fe68cbea1ed1fb044dc7ecec47cb77afc513eef373","description":"Return existing ACME account information.","extra":{},"name":"get_account","parameters":[{"definition":{"default":"default","description":"ACME account config file name.","enum":[],"extra":{"format_description":"name","typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"name"}],"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"account":{"enum":[],"extra":{"renderer":"yaml"},"optional":true,"properties":{},"type":"object"},"directory":{"description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"optional":true,"pattern":"^https?://.*","properties":{},"type":"string"},"location":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"tos":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"d34253209420f70af9ce9636d062d86816aa0aaad6156da14616f0c62a52bf93","description":"Update existing ACME account information with CA. Note: not specifying any new account information triggers a refresh.","extra":{},"name":"update_account","parameters":[{"definition":{"description":"Contact email addresses.","enum":[],"extra":{"typetext":""},"format":"email-list","optional":true,"properties":{},"type":"string"},"name":"contact"},{"definition":{"default":"default","description":"ACME account config file name.","enum":[],"extra":{"format_description":"name","typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"name"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/cluster/acme/account/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bb3b64c0f654249ad36a0e6d6795943403662e273ec2511021fde72e27414433","description":"Get schema of ACME challenge types.","extra":{},"name":"challengeschema","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":0},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Human readable name, falls back to id","enum":[],"extra":{},"properties":{},"type":"string"},"schema":{"enum":[],"extra":{},"properties":{},"type":"object"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/acme/challenge-schema"},{"extra":{},"methods":[{"allow_token":true,"checksum":"83c926d16ce96312b6485852605650ec68d069e1004de1bf706cf88ce5230a8b","description":"Get named known ACME directory endpoints.","extra":{},"name":"get_directories","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":0},"properties":{"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"url":{"description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"pattern":"^https?://.*","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/acme/directories"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f2405d2a940e789c1d9b3b42f6da89d39e230861b91430071e8ea19b4446e74d","description":"Retrieve ACME Directory Meta Information","extra":{},"name":"get_meta","parameters":[{"definition":{"default":"https://acme-v02.api.letsencrypt.org/directory","description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"optional":true,"pattern":"^https?://.*","properties":{},"type":"string"},"name":"directory"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":1},"properties":{"caaIdentities":{"description":"Hostnames referring to the ACME servers.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"externalAccountRequired":{"description":"EAB Required","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"termsOfService":{"description":"ACME TermsOfService URL.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"website":{"description":"URL to more information about the ACME server.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/cluster/acme/meta"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3c017c347c32aaa2b9e7aa5fa830b473f8371a91b5d321266fc22e79a4759775","description":"ACME plugin index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list ACME plugins of a specific type","enum":["dns","standalone"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{plugin}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"api":{"description":"API plugin name","enum":["1984hosting","acmedns","acmeproxy","active24","ad","ali","alviy","anx","artfiles","arvan","aurora","autodns","aws","azion","azure","beget","bookmyname","bunny","cf","clouddns","cloudns","cn","conoha","constellix","cpanel","curanet","cyon","da","ddnss","desec","df","dgon","dnsexit","dnshome","dnsimple","dnsservices","doapi","domeneshop","dp","dpi","dreamhost","duckdns","durabledns","dyn","dynu","dynv6","easydns","edgecenter","edgedns","euserv","exoscale","fornex","freedns","freemyip","gandi_livedns","gcloud","gcore","gd","geoscaling","googledomains","he","he_ddns","hetzner","hetznercloud","hexonet","hostingde","huaweicloud","infoblox","infomaniak","internetbs","inwx","ionos","ionos_cloud","ipv64","ispconfig","jd","joker","kappernet","kas","kinghost","knot","la","leaseweb","lexicon","limacity","linode","linode_v4","loopia","lua","maradns","me","miab","mijnhost","misaka","myapi","mydevil","mydnsjp","mythic_beasts","namecheap","namecom","namesilo","nanelo","nederhost","neodigit","netcup","netlify","nic","njalla","nm","nsd","nsone","nsupdate","nw","oci","omglol","one","online","openprovider","openprovider_rest","openstack","opnsense","ovh","pdns","pleskxml","pointhq","porkbun","rackcorp","rackspace","rage4","rcode0","regru","scaleway","schlundtech","selectel","selfhost","servercow","simply","spaceship","technitium","tele3","tencent","timeweb","transip","udr","ultra","unoeuro","variomedia","veesp","vercel","vscale","vultr","websupport","west_cn","world4you","yandex360","yc","zilore","zone","zoneedit","zonomi"],"extra":{},"optional":true,"properties":{},"type":"string"},"data":{"description":"DNS plugin data. (base64 encoded)","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"disable":{"description":"Flag to disable the config.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"nodes":{"description":"List of cluster node names.","enum":[],"extra":{},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"plugin":{"description":"Unique identifier for ACME plugin instance.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"type":{"description":"ACME challenge type.","enum":["dns","standalone"],"extra":{},"properties":{},"type":"string"},"validation-delay":{"default":30,"description":"Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.","enum":[],"extra":{},"maximum":172800,"minimum":0,"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"1abea0505a3bf0b51a49356ba15375a4e65359d2d20aa0e9b393df126df123a0","description":"Add ACME plugin configuration.","extra":{},"name":"add_plugin","parameters":[{"definition":{"description":"API plugin name","enum":["1984hosting","acmedns","acmeproxy","active24","ad","ali","alviy","anx","artfiles","arvan","aurora","autodns","aws","azion","azure","beget","bookmyname","bunny","cf","clouddns","cloudns","cn","conoha","constellix","cpanel","curanet","cyon","da","ddnss","desec","df","dgon","dnsexit","dnshome","dnsimple","dnsservices","doapi","domeneshop","dp","dpi","dreamhost","duckdns","durabledns","dyn","dynu","dynv6","easydns","edgecenter","edgedns","euserv","exoscale","fornex","freedns","freemyip","gandi_livedns","gcloud","gcore","gd","geoscaling","googledomains","he","he_ddns","hetzner","hetznercloud","hexonet","hostingde","huaweicloud","infoblox","infomaniak","internetbs","inwx","ionos","ionos_cloud","ipv64","ispconfig","jd","joker","kappernet","kas","kinghost","knot","la","leaseweb","lexicon","limacity","linode","linode_v4","loopia","lua","maradns","me","miab","mijnhost","misaka","myapi","mydevil","mydnsjp","mythic_beasts","namecheap","namecom","namesilo","nanelo","nederhost","neodigit","netcup","netlify","nic","njalla","nm","nsd","nsone","nsupdate","nw","oci","omglol","one","online","openprovider","openprovider_rest","openstack","opnsense","ovh","pdns","pleskxml","pointhq","porkbun","rackcorp","rackspace","rage4","rcode0","regru","scaleway","schlundtech","selectel","selfhost","servercow","simply","spaceship","technitium","tele3","tencent","timeweb","transip","udr","ultra","unoeuro","variomedia","veesp","vercel","vscale","vultr","websupport","west_cn","world4you","yandex360","yc","zilore","zone","zoneedit","zonomi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"api"},{"definition":{"description":"DNS plugin data. (base64 encoded)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"data"},{"definition":{"description":"Flag to disable the config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"ACME Plugin ID name","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"ACME challenge type.","enum":["dns","standalone"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"default":30,"description":"Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.","enum":[],"extra":{"typetext":" (0 - 172800)"},"maximum":172800,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"validation-delay"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/acme/plugins"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e31513c49230a6793d02a258e1461555d3d724ed5007c688cdf61d6047f43335","description":"Delete ACME plugin configuration.","extra":{},"name":"delete_plugin","parameters":[{"definition":{"description":"Unique identifier for ACME plugin instance.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"af5fd06bd6b2c844a3be972aced39d2b01cbfc139e98c99dd62c5325552cb315","description":"Get ACME plugin configuration.","extra":{},"name":"get_plugin_config","parameters":[{"definition":{"description":"Unique identifier for ACME plugin instance.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"api":{"description":"API plugin name","enum":["1984hosting","acmedns","acmeproxy","active24","ad","ali","alviy","anx","artfiles","arvan","aurora","autodns","aws","azion","azure","beget","bookmyname","bunny","cf","clouddns","cloudns","cn","conoha","constellix","cpanel","curanet","cyon","da","ddnss","desec","df","dgon","dnsexit","dnshome","dnsimple","dnsservices","doapi","domeneshop","dp","dpi","dreamhost","duckdns","durabledns","dyn","dynu","dynv6","easydns","edgecenter","edgedns","euserv","exoscale","fornex","freedns","freemyip","gandi_livedns","gcloud","gcore","gd","geoscaling","googledomains","he","he_ddns","hetzner","hetznercloud","hexonet","hostingde","huaweicloud","infoblox","infomaniak","internetbs","inwx","ionos","ionos_cloud","ipv64","ispconfig","jd","joker","kappernet","kas","kinghost","knot","la","leaseweb","lexicon","limacity","linode","linode_v4","loopia","lua","maradns","me","miab","mijnhost","misaka","myapi","mydevil","mydnsjp","mythic_beasts","namecheap","namecom","namesilo","nanelo","nederhost","neodigit","netcup","netlify","nic","njalla","nm","nsd","nsone","nsupdate","nw","oci","omglol","one","online","openprovider","openprovider_rest","openstack","opnsense","ovh","pdns","pleskxml","pointhq","porkbun","rackcorp","rackspace","rage4","rcode0","regru","scaleway","schlundtech","selectel","selfhost","servercow","simply","spaceship","technitium","tele3","tencent","timeweb","transip","udr","ultra","unoeuro","variomedia","veesp","vercel","vscale","vultr","websupport","west_cn","world4you","yandex360","yc","zilore","zone","zoneedit","zonomi"],"extra":{},"optional":true,"properties":{},"type":"string"},"data":{"description":"DNS plugin data. (base64 encoded)","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"disable":{"description":"Flag to disable the config.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"nodes":{"description":"List of cluster node names.","enum":[],"extra":{},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"plugin":{"description":"Unique identifier for ACME plugin instance.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"type":{"description":"ACME challenge type.","enum":["dns","standalone"],"extra":{},"properties":{},"type":"string"},"validation-delay":{"default":30,"description":"Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.","enum":[],"extra":{},"maximum":172800,"minimum":0,"optional":true,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"6f595a1483104e8dcf9866359757de363a013c9884ebf1306cdbd10774b0bde0","description":"Update ACME plugin configuration.","extra":{},"name":"update_plugin","parameters":[{"definition":{"description":"API plugin name","enum":["1984hosting","acmedns","acmeproxy","active24","ad","ali","alviy","anx","artfiles","arvan","aurora","autodns","aws","azion","azure","beget","bookmyname","bunny","cf","clouddns","cloudns","cn","conoha","constellix","cpanel","curanet","cyon","da","ddnss","desec","df","dgon","dnsexit","dnshome","dnsimple","dnsservices","doapi","domeneshop","dp","dpi","dreamhost","duckdns","durabledns","dyn","dynu","dynv6","easydns","edgecenter","edgedns","euserv","exoscale","fornex","freedns","freemyip","gandi_livedns","gcloud","gcore","gd","geoscaling","googledomains","he","he_ddns","hetzner","hetznercloud","hexonet","hostingde","huaweicloud","infoblox","infomaniak","internetbs","inwx","ionos","ionos_cloud","ipv64","ispconfig","jd","joker","kappernet","kas","kinghost","knot","la","leaseweb","lexicon","limacity","linode","linode_v4","loopia","lua","maradns","me","miab","mijnhost","misaka","myapi","mydevil","mydnsjp","mythic_beasts","namecheap","namecom","namesilo","nanelo","nederhost","neodigit","netcup","netlify","nic","njalla","nm","nsd","nsone","nsupdate","nw","oci","omglol","one","online","openprovider","openprovider_rest","openstack","opnsense","ovh","pdns","pleskxml","pointhq","porkbun","rackcorp","rackspace","rage4","rcode0","regru","scaleway","schlundtech","selectel","selfhost","servercow","simply","spaceship","technitium","tele3","tencent","timeweb","transip","udr","ultra","unoeuro","variomedia","veesp","vercel","vscale","vultr","websupport","west_cn","world4you","yandex360","yc","zilore","zone","zoneedit","zonomi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"api"},{"definition":{"description":"DNS plugin data. (base64 encoded)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"data"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Flag to disable the config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"ACME Plugin ID name","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"default":30,"description":"Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.","enum":[],"extra":{"typetext":" (0 - 172800)"},"maximum":172800,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"validation-delay"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/acme/plugins/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0a3b5b1c3e86a6bd9d319c9aab8d847e27bd335e6c58329506b77f0ada2e7b53","description":"Retrieve ACME TermsOfService URL from CA. Deprecated, please use /cluster/acme/meta.","extra":{},"name":"get_tos","parameters":[{"definition":{"default":"https://acme-v02.api.letsencrypt.org/directory","description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"optional":true,"pattern":"^https?://.*","properties":{},"type":"string"},"name":"directory"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"ACME TermsOfService URL.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"verb":"GET"}],"path":"/cluster/acme/tos"},{"extra":{},"methods":[{"allow_token":true,"checksum":"16f64db7beca725b0a13f0fb12d9d2751b9a61e98ffefe04b1297ec27178bd2a","description":"List vzdump backup schedule.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"all":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bwlimit":{"default":0,"description":"Limit I/O bandwidth (in KiB/s).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"comment":{"description":"Description for the Job.","enum":[],"extra":{},"max_length":512,"optional":true,"properties":{},"type":"string"},"compress":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"dumpdir":{"description":"Store resulting files to specified directory.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enabled":{"default":"1","description":"Enable or disable the job.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"exclude":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"exclude-path":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"fleecing":{"description":"Options for backup fleecing (VM only).","enum":[],"extra":{},"optional":true,"properties":{"enabled":{"default":0,"description":"Enable backup fleecing. Cache backup data from blocks where new guest writes happen on specified storage instead of copying them directly to the backup target. This can help guest IO performance and even prevent hangs, at the cost of requiring more storage space.","enum":[],"extra":{"default_key":1},"optional":true,"properties":{},"type":"boolean"},"storage":{"description":"Use this storage to storage fleecing images. For efficient space usage, it's best to use a local storage that supports discard and either thin provisioning or sparse files.","enum":[],"extra":{"format_description":"storage ID"},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"}},"type":"object"},"id":{"description":"The job ID.","enum":[],"extra":{},"max_length":50,"pattern":"\\S+","properties":{},"type":"string"},"ionice":{"default":7,"description":"Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.","enum":[],"extra":{},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"lockwait":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"mailnotification":{"default":"always","description":"Deprecated: use notification targets/matchers instead. Specify when to send a notification mail","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"mailto":{"description":"Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"mode":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"next-run":{"description":"UNIX timestamp when this backup job will be executed next","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"node":{"description":"Only run if executed on this node.","enum":[],"extra":{},"format":"pve-node","optional":true,"properties":{},"type":"string"},"notes-template":{"description":"Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.","enum":[],"extra":{"requires":"storage"},"max_length":1024,"optional":true,"properties":{},"type":"string"},"notification-mode":{"default":"auto","description":"Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.","enum":["auto","legacy-sendmail","notification-system"],"extra":{},"optional":true,"properties":{},"type":"string"},"pbs-change-detection-mode":{"description":"PBS mode used to detect file changes and switch encoding format for container backups.","enum":["legacy","data","metadata"],"extra":{},"optional":true,"properties":{},"type":"string"},"performance":{"description":"Other performance-related settings.","enum":[],"extra":{},"optional":true,"properties":{"max-workers":{"default":16,"description":"Applies to VMs. Allow up to this many IO workers at the same time.","enum":[],"extra":{},"maximum":256,"minimum":1,"optional":true,"properties":{},"type":"integer"},"pbs-entries-max":{"default":1048576,"description":"Applies to container backups sent to PBS. Limits the number of entries allowed in memory at a given time to avoid unintended OOM situations. Increase it to enable backups of containers with a large amount of files.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"}},"type":"object"},"pigz":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"pool":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"protected":{"description":"If true, mark backup(s) as protected.","enum":[],"extra":{"requires":"storage"},"optional":true,"properties":{},"type":"boolean"},"prune-backups":{"description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{},"optional":true,"properties":{"keep-all":{"description":"Keep all backups. Conflicts with the other options when true.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"keep-daily":{"description":"Keep backups for the last different days. If there is morethan one backup for a single day, only the latest one is kept.","enum":[],"extra":{"format_description":"N"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"keep-hourly":{"description":"Keep backups for the last different hours. If there is morethan one backup for a single hour, only the latest one is kept.","enum":[],"extra":{"format_description":"N"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"keep-last":{"description":"Keep the last backups.","enum":[],"extra":{"format_description":"N"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"keep-monthly":{"description":"Keep backups for the last different months. If there is morethan one backup for a single month, only the latest one is kept.","enum":[],"extra":{"format_description":"N"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"keep-weekly":{"description":"Keep backups for the last different weeks. If there is morethan one backup for a single week, only the latest one is kept.","enum":[],"extra":{"format_description":"N"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"keep-yearly":{"description":"Keep backups for the last different years. If there is morethan one backup for a single year, only the latest one is kept.","enum":[],"extra":{"format_description":"N"},"minimum":0,"optional":true,"properties":{},"type":"integer"}},"type":"object"},"quiet":{"default":0,"description":"Be quiet.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"remove":{"default":1,"description":"Prune older backups according to 'prune-backups'.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"repeat-missed":{"default":0,"description":"If true, the job will be run as soon as possible if it was missed while the scheduler was not running.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"schedule":{"description":"Backup schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"script":{"description":"Use specified hook script.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"stdexcludes":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"stop":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"stopwait":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"storage":{"description":"Store resulting file to this storage.","enum":[],"extra":{"format_description":"storage ID"},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"tmpdir":{"description":"Store temporary files to specified directory.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vmid":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"zstd":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"10eeeb358e456ec9b14df2118156b90efe3322b1cf56bf46f153fdc2ca06521d","description":"Create new vzdump backup job.","extra":{},"name":"create_job","parameters":[{"definition":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"all"},{"definition":{"default":0,"description":"Limit I/O bandwidth (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"Description for the Job.","enum":[],"extra":{"typetext":""},"max_length":512,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"compress"},{"definition":{"default":"mon,tue,wed,thu,fri,sat,sun","description":"Deprecated: Use 'schedule' instead. Day of week selection. 'starttime' and 'dow' will be converted into 'schedule' if used.","enum":[],"extra":{"requires":"starttime","typetext":""},"format":"pve-day-of-week-list","optional":true,"properties":{},"type":"string"},"name":"dow"},{"definition":{"description":"Store resulting files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dumpdir"},{"definition":{"default":"1","description":"Enable or disable the job.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"exclude"},{"definition":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"exclude-path"},{"definition":{"description":"Options for backup fleecing (VM only).","enum":[],"extra":{"typetext":"[[enabled=]<1|0>] [,storage=]"},"format":"backup-fleecing","optional":true,"properties":{},"type":"string"},"name":"fleecing"},{"definition":{"description":"Job ID (will be autogenerated).","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"id"},{"definition":{"default":7,"description":"Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.","enum":[],"extra":{"typetext":" (0 - 8)"},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"ionice"},{"definition":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"lockwait"},{"definition":{"default":"always","description":"Deprecated: use notification targets/matchers instead. Specify when to send a notification mail","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mailnotification"},{"definition":{"description":"Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{"typetext":""},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"name":"mailto"},{"definition":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"Only run if executed on this node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.","enum":[],"extra":{"requires":"storage","typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"notes-template"},{"definition":{"default":"auto","description":"Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.","enum":["auto","legacy-sendmail","notification-system"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"notification-mode"},{"definition":{"description":"PBS mode used to detect file changes and switch encoding format for container backups.","enum":["legacy","data","metadata"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"pbs-change-detection-mode"},{"definition":{"description":"Other performance-related settings.","enum":[],"extra":{"typetext":"[max-workers=] [,pbs-entries-max=]"},"format":"backup-performance","optional":true,"properties":{},"type":"string"},"name":"performance"},{"definition":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"pigz"},{"definition":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"If true, mark backup(s) as protected.","enum":[],"extra":{"requires":"storage","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protected"},{"definition":{"default":"keep-all=1","description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"default":0,"description":"Be quiet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"quiet"},{"definition":{"default":1,"description":"Prune older backups according to 'prune-backups'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove"},{"definition":{"default":0,"description":"If true, the job will be run as soon as possible if it was missed while the scheduler was not running.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"repeat-missed"},{"definition":{"description":"Backup schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"Use specified hook script.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"script"},{"definition":{"description":"Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used.","enum":[],"extra":{"typetext":"HH:MM"},"optional":true,"pattern":"\\d{1,2}:\\d{1,2}","properties":{},"type":"string"},"name":"starttime"},{"definition":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stdexcludes"},{"definition":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stop"},{"definition":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"stopwait"},{"definition":{"description":"Store resulting file to this storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Store temporary files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tmpdir"},{"definition":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vmid"},{"definition":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"zstd"}],"permissions":{"description":"The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user.","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/backup"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e8fa5d6fa114f069dcf59323f56dc2636286f1d895cf328de285fd9c651a1f48","description":"Index for backup info related endpoints","extra":{},"name":"index","parameters":[],"protected":false,"returns":{"description":"Directory index.","enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"description":"API sub-directory endpoint","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/backup-info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"10072ad7bf08fad7b5214622361f9bcfe52101f6e15709fc5661262557128b24","description":"Shows all guests which are not covered by any backup job.","extra":{},"name":"get_guests_not_in_backup","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"description":"Contains the guest objects.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"name":{"description":"Name of the guest","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Type of the guest.","enum":["qemu","lxc"],"extra":{},"properties":{},"type":"string"},"vmid":{"description":"VMID of the guest.","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/backup-info/not-backed-up"},{"extra":{},"methods":[{"allow_token":true,"checksum":"361a95b88e0ef40ed125d2b05ed16ffbd2617b3de31a6809f36e88e99cb2cd3b","description":"Delete vzdump backup job definition.","extra":{},"name":"delete_job","parameters":[{"definition":{"description":"The job ID.","enum":[],"extra":{},"max_length":50,"pattern":"\\S+","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"c3e9b1f6ce33f47931a28cdbe23340b9c888fbe5312b1d0ece97d094f9fd3569","description":"Read vzdump backup job definition.","extra":{},"name":"read_job","parameters":[{"definition":{"description":"The job ID.","enum":[],"extra":{},"max_length":50,"pattern":"\\S+","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"all":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bwlimit":{"default":0,"description":"Limit I/O bandwidth (in KiB/s).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"comment":{"description":"Description for the Job.","enum":[],"extra":{},"max_length":512,"optional":true,"properties":{},"type":"string"},"compress":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"dumpdir":{"description":"Store resulting files to specified directory.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enabled":{"default":"1","description":"Enable or disable the job.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"exclude":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"exclude-path":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"fleecing":{"description":"Options for backup fleecing (VM only).","enum":[],"extra":{},"optional":true,"properties":{"enabled":{"default":0,"description":"Enable backup fleecing. Cache backup data from blocks where new guest writes happen on specified storage instead of copying them directly to the backup target. This can help guest IO performance and even prevent hangs, at the cost of requiring more storage space.","enum":[],"extra":{"default_key":1},"optional":true,"properties":{},"type":"boolean"},"storage":{"description":"Use this storage to storage fleecing images. For efficient space usage, it's best to use a local storage that supports discard and either thin provisioning or sparse files.","enum":[],"extra":{"format_description":"storage ID"},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"}},"type":"object"},"id":{"description":"The job ID.","enum":[],"extra":{},"max_length":50,"pattern":"\\S+","properties":{},"type":"string"},"ionice":{"default":7,"description":"Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.","enum":[],"extra":{},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"lockwait":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"mailnotification":{"default":"always","description":"Deprecated: use notification targets/matchers instead. Specify when to send a notification mail","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"mailto":{"description":"Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"mode":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"next-run":{"description":"UNIX timestamp when this backup job will be executed next","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"node":{"description":"Only run if executed on this node.","enum":[],"extra":{},"format":"pve-node","optional":true,"properties":{},"type":"string"},"notes-template":{"description":"Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.","enum":[],"extra":{"requires":"storage"},"max_length":1024,"optional":true,"properties":{},"type":"string"},"notification-mode":{"default":"auto","description":"Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.","enum":["auto","legacy-sendmail","notification-system"],"extra":{},"optional":true,"properties":{},"type":"string"},"pbs-change-detection-mode":{"description":"PBS mode used to detect file changes and switch encoding format for container backups.","enum":["legacy","data","metadata"],"extra":{},"optional":true,"properties":{},"type":"string"},"performance":{"description":"Other performance-related settings.","enum":[],"extra":{},"optional":true,"properties":{"max-workers":{"default":16,"description":"Applies to VMs. Allow up to this many IO workers at the same time.","enum":[],"extra":{},"maximum":256,"minimum":1,"optional":true,"properties":{},"type":"integer"},"pbs-entries-max":{"default":1048576,"description":"Applies to container backups sent to PBS. Limits the number of entries allowed in memory at a given time to avoid unintended OOM situations. Increase it to enable backups of containers with a large amount of files.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"}},"type":"object"},"pigz":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"pool":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"protected":{"description":"If true, mark backup(s) as protected.","enum":[],"extra":{"requires":"storage"},"optional":true,"properties":{},"type":"boolean"},"prune-backups":{"description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{},"optional":true,"properties":{"keep-all":{"description":"Keep all backups. Conflicts with the other options when true.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"keep-daily":{"description":"Keep backups for the last different days. If there is morethan one backup for a single day, only the latest one is kept.","enum":[],"extra":{"format_description":"N"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"keep-hourly":{"description":"Keep backups for the last different hours. If there is morethan one backup for a single hour, only the latest one is kept.","enum":[],"extra":{"format_description":"N"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"keep-last":{"description":"Keep the last backups.","enum":[],"extra":{"format_description":"N"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"keep-monthly":{"description":"Keep backups for the last different months. If there is morethan one backup for a single month, only the latest one is kept.","enum":[],"extra":{"format_description":"N"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"keep-weekly":{"description":"Keep backups for the last different weeks. If there is morethan one backup for a single week, only the latest one is kept.","enum":[],"extra":{"format_description":"N"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"keep-yearly":{"description":"Keep backups for the last different years. If there is morethan one backup for a single year, only the latest one is kept.","enum":[],"extra":{"format_description":"N"},"minimum":0,"optional":true,"properties":{},"type":"integer"}},"type":"object"},"quiet":{"default":0,"description":"Be quiet.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"remove":{"default":1,"description":"Prune older backups according to 'prune-backups'.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"repeat-missed":{"default":0,"description":"If true, the job will be run as soon as possible if it was missed while the scheduler was not running.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"schedule":{"description":"Backup schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"script":{"description":"Use specified hook script.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"stdexcludes":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"stop":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"stopwait":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"storage":{"description":"Store resulting file to this storage.","enum":[],"extra":{"format_description":"storage ID"},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"tmpdir":{"description":"Store temporary files to specified directory.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vmid":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"zstd":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"9137ecd36a4cfcf3563a3b5b1c6337b326b87b8346bbe11c7bf13db6af544233","description":"Update vzdump backup job definition.","extra":{},"name":"update_job","parameters":[{"definition":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"all"},{"definition":{"default":0,"description":"Limit I/O bandwidth (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"Description for the Job.","enum":[],"extra":{"typetext":""},"max_length":512,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"compress"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Deprecated: Use 'schedule' instead. Day of week selection. 'starttime' and 'dow' will be converted into 'schedule' if used.","enum":[],"extra":{"requires":"starttime","typetext":""},"format":"pve-day-of-week-list","optional":true,"properties":{},"type":"string"},"name":"dow"},{"definition":{"description":"Store resulting files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dumpdir"},{"definition":{"default":"1","description":"Enable or disable the job.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"exclude"},{"definition":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"exclude-path"},{"definition":{"description":"Options for backup fleecing (VM only).","enum":[],"extra":{"typetext":"[[enabled=]<1|0>] [,storage=]"},"format":"backup-fleecing","optional":true,"properties":{},"type":"string"},"name":"fleecing"},{"definition":{"description":"The job ID.","enum":[],"extra":{},"max_length":50,"pattern":"\\S+","properties":{},"type":"string"},"name":"id"},{"definition":{"default":7,"description":"Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.","enum":[],"extra":{"typetext":" (0 - 8)"},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"ionice"},{"definition":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"lockwait"},{"definition":{"default":"always","description":"Deprecated: use notification targets/matchers instead. Specify when to send a notification mail","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mailnotification"},{"definition":{"description":"Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{"typetext":""},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"name":"mailto"},{"definition":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"Only run if executed on this node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.","enum":[],"extra":{"requires":"storage","typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"notes-template"},{"definition":{"default":"auto","description":"Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.","enum":["auto","legacy-sendmail","notification-system"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"notification-mode"},{"definition":{"description":"PBS mode used to detect file changes and switch encoding format for container backups.","enum":["legacy","data","metadata"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"pbs-change-detection-mode"},{"definition":{"description":"Other performance-related settings.","enum":[],"extra":{"typetext":"[max-workers=] [,pbs-entries-max=]"},"format":"backup-performance","optional":true,"properties":{},"type":"string"},"name":"performance"},{"definition":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"pigz"},{"definition":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"If true, mark backup(s) as protected.","enum":[],"extra":{"requires":"storage","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protected"},{"definition":{"default":"keep-all=1","description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"default":0,"description":"Be quiet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"quiet"},{"definition":{"default":1,"description":"Prune older backups according to 'prune-backups'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove"},{"definition":{"default":0,"description":"If true, the job will be run as soon as possible if it was missed while the scheduler was not running.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"repeat-missed"},{"definition":{"description":"Backup schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"Use specified hook script.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"script"},{"definition":{"description":"Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used.","enum":[],"extra":{"typetext":"HH:MM"},"optional":true,"pattern":"\\d{1,2}:\\d{1,2}","properties":{},"type":"string"},"name":"starttime"},{"definition":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stdexcludes"},{"definition":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stop"},{"definition":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"stopwait"},{"definition":{"description":"Store resulting file to this storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Store temporary files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tmpdir"},{"definition":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vmid"},{"definition":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"zstd"}],"permissions":{"description":"The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user.","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/backup/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"31f6fa33dc5f9967d128553b7fa048f24df2d818f5f7f80b10687b0b6f6e2b44","description":"Returns included guests and the backup status of their disks. Optimized to be used in ExtJS tree views.","extra":{},"name":"get_volume_backup_included","parameters":[{"definition":{"description":"The job ID.","enum":[],"extra":{},"max_length":50,"pattern":"\\S+","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"description":"Root node of the tree object. Children represent guests, grandchildren represent volumes of that guest.","enum":[],"extra":{},"properties":{"children":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"children":{"description":"The volumes of the guest with the information if they will be included in backups.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"id":{"description":"Configuration key of the volume.","enum":[],"extra":{},"properties":{},"type":"string"},"included":{"description":"Whether the volume is included in the backup or not.","enum":[],"extra":{},"properties":{},"type":"boolean"},"name":{"description":"Name of the volume.","enum":[],"extra":{},"properties":{},"type":"string"},"reason":{"description":"The reason why the volume is included (or excluded).","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"id":{"description":"VMID of the guest.","enum":[],"extra":{},"properties":{},"type":"integer"},"name":{"description":"Name of the guest","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Type of the guest, VM, CT or unknown for removed but not purged guests.","enum":["qemu","lxc","unknown"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"}],"path":"/cluster/backup/{id}/included_volumes"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0bac8b13119b633102143f35502b8d4c9d90528877d41713047d1b74f4059e37","description":"List resource types.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/bulk-action"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c19cf85a89171397f346325c9dff177d900f28ea9d3485c19a9aa844f1c2e3b8","description":"Bulk action index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/bulk-action/guest"},{"extra":{},"methods":[{"allow_token":true,"checksum":"caaa2c82c2962f447933f4bcc730ae78a03104eab0d25f35f2ab7103cacc4cfb","description":"Bulk migrate all guests on the cluster.","extra":{"expose_credentials":1},"name":"migrate","parameters":[{"definition":{"default":1,"description":"Defines the maximum number of tasks running concurrently.","enum":[],"extra":{"typetext":" (1 - 64)"},"maximum":64,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max-workers"},{"definition":{"default":1,"description":"Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.","enum":[],"extra":{"typetext":" (1 - 64)"},"maximum":64,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxworkers"},{"definition":{"description":"Enable live migration for VMs and restart migration for CTs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"online"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Only consider guests from this list of VMIDs.","enum":[],"extra":{"typetext":""},"items":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"optional":true,"properties":{},"type":"array"},"name":"vms"},{"definition":{"description":"Enable live storage migration for local disk","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"with-local-disks"}],"permissions":{"description":"The 'VM.Migrate' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"description":"UPID of the worker","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/bulk-action/guest/migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"da15f94ea94b73ce62976c87fd49b0d7cd7ec684aeda5e5963dab82910096e25","description":"Bulk shutdown all guests on the cluster.","extra":{"expose_credentials":1},"name":"shutdown","parameters":[{"definition":{"default":1,"description":"Makes sure the Guest stops after the timeout.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force-stop"},{"definition":{"default":4,"description":"Defines the maximum number of tasks running concurrently.","enum":[],"extra":{"typetext":" (1 - 64)"},"maximum":64,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max-workers"},{"definition":{"default":4,"description":"Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.","enum":[],"extra":{"typetext":" (1 - 64)"},"maximum":64,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxworkers"},{"definition":{"default":180,"description":"Default shutdown timeout in seconds if none is configured for the guest.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"Only consider guests from this list of VMIDs.","enum":[],"extra":{"typetext":""},"items":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"optional":true,"properties":{},"type":"array"},"name":"vms"}],"permissions":{"description":"The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"description":"UPID of the worker","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/bulk-action/guest/shutdown"},{"extra":{},"methods":[{"allow_token":true,"checksum":"55dcf85bddd7d8bfd2cd74de88db10411a52a96684f038a8dc25ef134ec432c7","description":"Bulk start or resume all guests on the cluster.","extra":{"expose_credentials":1},"name":"start","parameters":[{"definition":{"default":4,"description":"Defines the maximum number of tasks running concurrently.","enum":[],"extra":{"typetext":" (1 - 64)"},"maximum":64,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max-workers"},{"definition":{"default":4,"description":"Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.","enum":[],"extra":{"typetext":" (1 - 64)"},"maximum":64,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxworkers"},{"definition":{"description":"Default start timeout in seconds. Only valid for VMs. (default depends on the guest configuration).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"Only consider guests from this list of VMIDs.","enum":[],"extra":{"typetext":""},"items":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"optional":true,"properties":{},"type":"array"},"name":"vms"}],"permissions":{"description":"The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"description":"UPID of the worker","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/bulk-action/guest/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e858564c5a8ceb3a92c6f4e59023a11533a9badf9e892a4264771de922d203e8","description":"Bulk suspend all guests on the cluster.","extra":{"expose_credentials":1},"name":"suspend","parameters":[{"definition":{"default":4,"description":"Defines the maximum number of tasks running concurrently.","enum":[],"extra":{"typetext":" (1 - 64)"},"maximum":64,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max-workers"},{"definition":{"default":4,"description":"Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.","enum":[],"extra":{"typetext":" (1 - 64)"},"maximum":64,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxworkers"},{"definition":{"description":"The storage for the VM state.","enum":[],"extra":{"format_description":"storage ID","requires":"to-disk","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"statestorage"},{"definition":{"default":0,"description":"If set, suspends the guests to disk. Will be resumed on next start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"to-disk"},{"definition":{"description":"Only consider guests from this list of VMIDs.","enum":[],"extra":{"typetext":""},"items":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"optional":true,"properties":{},"type":"array"},"name":"vms"}],"permissions":{"description":"The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter. Additionally, you need 'VM.Config.Disk' on the '/vms/{vmid}' path and 'Datastore.AllocateSpace' for the configured state-storage(s)","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"description":"UPID of the worker","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/bulk-action/guest/suspend"},{"extra":{},"methods":[{"allow_token":true,"checksum":"eba2ffcf3c2b12528c59e5ea186dccaf2c83608b8f244536294254186e44c927","description":"Cluster ceph index.","extra":{},"name":"cephindex","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/ceph"},{"extra":{},"methods":[{"allow_token":true,"checksum":"02afb14bbc8590601cd50857ea48b148df439fcd0eeb68ad743f81117830e050","description":"get the status of all ceph flags","extra":{},"name":"get_all_flags","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"description":{"description":"Flag description.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Flag name.","enum":["nobackfill","nodeep-scrub","nodown","noin","noout","norebalance","norecover","noscrub","notieragent","noup","pause"],"extra":{},"properties":{},"type":"string"},"value":{"description":"Flag value.","enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"2883e8b20eeb9da9ec81820bca67e725b6fdc63ef712bdf4ed1b79af040c4ef5","description":"Set/Unset multiple Ceph flags at once. Each flag is a top-level optional boolean: passing true sets the flag, false unsets it, omitting it leaves the current state untouched. Runs as a worker task; returns a UPID to follow.","extra":{},"name":"set_flags","parameters":[{"definition":{"description":"Backfilling of PGs is suspended.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nobackfill"},{"definition":{"description":"Deep Scrubbing is disabled.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nodeep-scrub"},{"definition":{"description":"OSD failure reports are being ignored, such that the monitors will not mark OSDs down.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nodown"},{"definition":{"description":"OSDs that were previously marked out will not be marked back in when they start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"noin"},{"definition":{"description":"OSDs will not automatically be marked out after the configured interval.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"noout"},{"definition":{"description":"Rebalancing of PGs is suspended.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"norebalance"},{"definition":{"description":"Recovery of PGs is suspended.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"norecover"},{"definition":{"description":"Scrubbing is disabled.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"noscrub"},{"definition":{"description":"Cache tiering activity is suspended.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"notieragent"},{"definition":{"description":"OSDs are not allowed to start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"noup"},{"definition":{"description":"Pauses read and writes.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pause"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/cluster/ceph/flags"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ec390749f9b3b558092a75a9d5b9a3a05a0f4d7caaba0587fbbc491a53147656","description":"Get the status of a specific ceph flag.","extra":{},"name":"get_flag","parameters":[{"definition":{"description":"The name of the flag name to get.","enum":["nobackfill","nodeep-scrub","nodown","noin","noout","norebalance","norecover","noscrub","notieragent","noup","pause"],"extra":{},"properties":{},"type":"string"},"name":"flag"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"verb":"GET"},{"allow_token":true,"checksum":"8f7fd293491bfcacee5cde0c3f628f7e2ab3c291785550d8debdbe8a6dee541d","description":"Set or clear (unset) a specific Ceph flag. Runs synchronously (unlike the bulk PUT /cluster/ceph/flags endpoint, which forks a worker task).","extra":{},"name":"update_flag","parameters":[{"definition":{"description":"The ceph flag to update","enum":["nobackfill","nodeep-scrub","nodown","noin","noout","norebalance","norecover","noscrub","notieragent","noup","pause"],"extra":{},"properties":{},"type":"string"},"name":"flag"},{"definition":{"description":"The new value of the flag","enum":[],"extra":{"typetext":""},"properties":{},"type":"boolean"},"name":"value"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/ceph/flags/{flag}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5b6fee02ce8e7df5c0c2d976a5e6aeaf8e02eb6830f0a46de8dfba7123c71bf9","description":"Get ceph metadata.","extra":{},"name":"metadata","parameters":[{"definition":{"default":"all","description":"Which metadata facet to return: 'all' enriches the per-daemon metadata with the PVE-side service state (presence of unit, data directory), 'versions' collects only per-node Ceph binary version data.","enum":["all","versions"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scope"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Items for each type of service containing objects for each instance.","enum":[],"extra":{},"properties":{"mds":{"description":"Metadata servers configured in the cluster and their properties, keyed by '@'.","enum":[],"extra":{"additionalProperties":{"additionalProperties":1,"description":"Useful properties are listed, but not the full list.","properties":{"addr":{"description":"Bind addresses and ports.","optional":1,"type":"string"},"ceph_release":{"description":"Ceph release codename currently used.","type":"string"},"ceph_version":{"description":"Version info currently used by the service.","type":"string"},"ceph_version_short":{"description":"Short version (numerical) info currently used by the service.","type":"string"},"hostname":{"description":"Hostname on which the service is running.","type":"string"},"mem_swap_kb":{"description":"Memory of the service currently in swap.","type":"integer"},"mem_total_kb":{"description":"Memory consumption of the service.","type":"integer"},"name":{"description":"Name of the service instance.","optional":1,"type":"string"}},"type":"object"}},"properties":{},"type":"object"},"mgr":{"description":"Managers configured in the cluster and their properties, keyed by '@'.","enum":[],"extra":{"additionalProperties":{"additionalProperties":1,"description":"Useful properties are listed, but not the full list.","properties":{"addr":{"description":"Bind address.","optional":1,"type":"string"},"ceph_release":{"description":"Ceph release codename currently used.","type":"string"},"ceph_version":{"description":"Version info currently used by the service.","type":"string"},"ceph_version_short":{"description":"Short version (numerical) info currently used by the service.","type":"string"},"hostname":{"description":"Hostname on which the service is running.","type":"string"},"mem_swap_kb":{"description":"Memory of the service currently in swap.","type":"integer"},"mem_total_kb":{"description":"Memory consumption of the service.","type":"integer"},"name":{"description":"Name of the service instance.","optional":1,"type":"string"}},"type":"object"}},"properties":{},"type":"object"},"mon":{"description":"Monitors configured in the cluster and their properties, keyed by '@'.","enum":[],"extra":{"additionalProperties":{"additionalProperties":1,"description":"Useful properties are listed, but not the full list.","properties":{"addrs":{"description":"Bind addresses and ports.","optional":1,"type":"string"},"ceph_release":{"description":"Ceph release codename currently used.","type":"string"},"ceph_version":{"description":"Version info currently used by the service.","type":"string"},"ceph_version_short":{"description":"Short version (numerical) info currently used by the service.","type":"string"},"hostname":{"description":"Hostname on which the service is running.","type":"string"},"mem_swap_kb":{"description":"Memory of the service currently in swap.","type":"integer"},"mem_total_kb":{"description":"Memory consumption of the service.","type":"integer"},"name":{"description":"Name of the service instance.","optional":1,"type":"string"}},"type":"object"}},"properties":{},"type":"object"},"node":{"description":"Ceph version installed on the nodes, keyed by node name.","enum":[],"extra":{"additionalProperties":{"additionalProperties":1,"properties":{"buildcommit":{"description":"GIT commit used for the build.","type":"string"},"version":{"description":"Version info.","properties":{"parts":{"description":"Major, minor and patch version numbers.","items":{"description":"Version-component string.","type":"string"},"type":"array"},"str":{"description":"Version as single string.","type":"string"}},"type":"object"}},"type":"object"}},"properties":{},"type":"object"},"osd":{"description":"OSDs configured in the cluster and their properties.","enum":[],"extra":{},"items":{"description":"Useful properties are listed, but not the full list.","enum":[],"extra":{},"properties":{"back_addr":{"description":"Bind addresses and ports for backend inter OSD traffic.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_release":{"description":"Ceph release codename currently used.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version":{"description":"Version info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version_short":{"description":"Short version (numerical) info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"device_ids":{"description":"Comma-joined list of device identifiers (e.g. 'sdb=,sdc=').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"device_paths":{"description":"Comma-joined list of /dev/disk/by-path entries for the underlying devices.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"devices":{"description":"Comma-joined list of underlying device names (e.g. 'sdb,sdc').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"front_addr":{"description":"Bind addresses and ports for frontend traffic to OSDs.","enum":[],"extra":{},"properties":{},"type":"string"},"hostname":{"description":"Hostname on which the service is running.","enum":[],"extra":{},"properties":{},"type":"string"},"id":{"description":"OSD ID.","enum":[],"extra":{},"properties":{},"type":"integer"},"mem_swap_kb":{"description":"Memory of the service currently in swap.","enum":[],"extra":{},"properties":{},"type":"integer"},"mem_total_kb":{"description":"Memory consumption of the service.","enum":[],"extra":{},"properties":{},"type":"integer"},"osd_data":{"description":"Path to the OSD data directory.","enum":[],"extra":{},"properties":{},"type":"string"},"osd_objectstore":{"description":"OSD objectstore type.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"}],"path":"/cluster/ceph/metadata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"409b59805f3b7f2541a2610e760ac490c3c6c53e2f4107c9149cc5870f3999ab","description":"Get ceph status.","extra":{},"name":"status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/ceph/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4e462b2d722b46bdaa5c6d40f69bc9f0fea21bf2b17f55764148409d7e6634a1","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"709ced773d6fce1312ba6ef5d9a5f695c87e8b93046dce71e960babcdfe27512","description":"Generate new cluster configuration. If no links given, default to local IP address as link0.","extra":{},"name":"create","parameters":[{"definition":{"description":"The name of the cluster.","enum":[],"extra":{"typetext":""},"format":"pve-node","max_length":15,"properties":{},"type":"string"},"name":"clustername"},{"definition":{"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)","enum":[],"extra":{"typetext":"[address=] [,priority=]"},"format":{"address":{"default_key":1,"description":"Hostname (or IP) of this corosync link address.","format":"address","format_description":"IP","type":"string"},"priority":{"default":0,"description":"The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.","maximum":255,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"link[n]"},{"definition":{"description":"Node id for this node.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"nodeid"},{"definition":{"default":125,"description":"Coefficient used to determine Corosync's token timeout. See the corosync.conf(5) manual for more details.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"token-coefficient"},{"definition":{"description":"Number of votes for this node.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"votes"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5861b788cde0b7cc8e00ed4490c40cc476724fc3e74e8d888af4e2667f4fc440","description":"Return the version of the cluster join API available on this node.","extra":{},"name":"join_api_version","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"description":"Cluster Join API version, currently 1","enum":[],"extra":{},"minimum":0,"properties":{},"type":"integer"},"verb":"GET"}],"path":"/cluster/config/apiversion"},{"extra":{},"methods":[{"allow_token":true,"checksum":"27b190ca706bbf299b7db981785dc2470fa61c40ce5577145f166e14dfa5ab80","description":"Get information needed to join this cluster over the connected node.","extra":{},"name":"join_info","parameters":[{"definition":{"default":"current connected node","description":"The node for which the joinee gets the nodeinfo. ","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"config_digest":{"enum":[],"extra":{},"properties":{},"type":"string"},"nodelist":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"name":{"description":"The cluster node name.","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"nodeid":{"description":"Node id for this node.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"pve_addr":{"enum":[],"extra":{},"format":"ip","properties":{},"type":"string"},"pve_fp":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"quorum_votes":{"enum":[],"extra":{},"minimum":0,"properties":{},"type":"integer"},"ring0_addr":{"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)","enum":[],"extra":{},"format":{"address":{"default_key":1,"description":"Hostname (or IP) of this corosync link address.","format":"address","format_description":"IP","type":"string"},"priority":{"default":0,"description":"The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.","maximum":255,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"preferred_node":{"description":"The cluster node name.","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"totem":{"enum":[],"extra":{},"properties":{},"type":"object"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"b68eacfbf66e39c59302d333b33cc64f4ff8211a81f4b5e13e745569757d2229","description":"Joins this node into an existing cluster. If no links are given, default to IP resolved by node's hostname on single link (fallback fails for clusters with multiple links).","extra":{},"name":"join","parameters":[{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"Do not throw error if node already exists.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Hostname (or IP) of an existing cluster member.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"hostname"},{"definition":{"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)","enum":[],"extra":{"typetext":"[address=] [,priority=]"},"format":{"address":{"default_key":1,"description":"Hostname (or IP) of this corosync link address.","format":"address","format_description":"IP","type":"string"},"priority":{"default":0,"description":"The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.","maximum":255,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"link[n]"},{"definition":{"description":"Node id for this node.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"nodeid"},{"definition":{"description":"Superuser (root) password of peer node.","enum":[],"extra":{"typetext":""},"max_length":128,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Number of votes for this node","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"votes"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/config/join"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1f1fa8f6c73d69a06ca87952831af1858a31d439c8ce22d6db1dc91f7ca064ba","description":"Corosync node list.","extra":{},"name":"nodes","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{node}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"node":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/config/nodes"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4ad5a311d984ff153e9e2592b537f44cdcce104ab314eadbe47ce01a97c6f77c","description":"Removes a node from the cluster configuration.","extra":{},"name":"delnode","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"2304b23018ece442ff87923324c1fd7f3616f5b677fc4dc2af779b5c3da61fd7","description":"Adds a node to the cluster configuration. This call is for internal use.","extra":{},"name":"addnode","parameters":[{"definition":{"description":"The JOIN_API_VERSION of the new node.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"apiversion"},{"definition":{"description":"Do not throw error if node already exists.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)","enum":[],"extra":{"typetext":"[address=] [,priority=]"},"format":{"address":{"default_key":1,"description":"Hostname (or IP) of this corosync link address.","format":"address","format_description":"IP","type":"string"},"priority":{"default":0,"description":"The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.","maximum":255,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"link[n]"},{"definition":{"description":"IP Address of node to add. Used as fallback if no links are given.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"new_node_ip"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Node id for this node.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"nodeid"},{"definition":{"description":"Number of votes for this node","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"votes"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{"corosync_authkey":{"enum":[],"extra":{},"properties":{},"type":"string"},"corosync_conf":{"enum":[],"extra":{},"properties":{},"type":"string"},"warnings":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"verb":"POST"}],"path":"/cluster/config/nodes/{node}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"51bd45c1bad501ab6b44ef5c67e7ca632259b91909c89431696c26607bfa79ae","description":"Get QDevice status","extra":{},"name":"status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/config/qdevice"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c99926d6eacc2ee248abe8c35c3b919d67610792d6702ff22aee72db49cc4a84","description":"Get corosync totem protocol settings.","extra":{},"name":"totem","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/config/totem"},{"extra":{},"methods":[{"allow_token":true,"checksum":"74551df8a7f69c7a92251a3cae53f3fa26e51e7232e76071c74973bbbcee0c60","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b3fce23e30c9cb681a73f749ce1dcd3c5eaa6accb7deb388baf2a9aca8bee91f","description":"List aliases","extra":{},"name":"get_aliases","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f144d7afa87a39ea6a57ac4e64d062df366af072960ccdf34d6336ac2377b7f3","description":"Create IP or Network Alias.","extra":{},"name":"create_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/aliases"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ec4a41a6b5108e1fd283289d8256ef9485bbdfeb65d8d3cfc4572042cb9a677c","description":"Remove IP or Network alias.","extra":{},"name":"remove_alias","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"31f91732baef0ccfba57dfc0c349ce762ef253d020ab23770f2a16b530eb55ed","description":"Read alias.","extra":{},"name":"read_alias","parameters":[{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"056e5969ce07a362663b71db6f255296a4bb9b19c9c6e154f03ad1090c4100d2","description":"Update IP or Network alias.","extra":{},"name":"update_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Rename an existing alias.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/aliases/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b142edd1f2967146d48335be6436ef08ede6983c38c5e107ea3fe74c8c714881","description":"List security groups.","extra":{},"name":"list_security_groups","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{group}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"group":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"5f97a9521d66f8673888e63abdcd4507d17dd7692b28de5029e2e4c16fe4e53d","description":"Create new security group.","extra":{},"name":"create_security_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Rename/update an existing security group. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing group.","enum":[],"extra":{},"max_length":18,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/groups"},{"extra":{},"methods":[{"allow_token":true,"checksum":"acdcc8bdd19b229574d5ede528b0727f932a90c3fbb9ef47222856db9f4531d9","description":"Delete security group.","extra":{},"name":"delete_security_group","parameters":[{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"c76f35259b66e69fddc9862796dc5776fa7720047891717b8a163ec19f046d54","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"action":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name","enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"description":"Descriptive comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"description":"Restrict packet destination address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"description":"Restrict TCP/UDP destination port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"description":"Flag to enable/disable a rule","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"description":"Network interface name. You have to use network configuration key names for VMs and containers","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"description":"IP version (4 or 6) - automatically determined from source/dest addresses","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"description":"Use predefined standard macro","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"description":"Rule position in the ruleset","enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"description":"Restrict packet source address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"description":"Restrict TCP/UDP source port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Rule type","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"42c0cdbaa4914a570c14a97d8e4f5d2a404dce6192f118d1f0d2241de295dba3","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/groups/{group}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6cf50307b7550a5994109ed58d36939b6fee81d72ef581b4536e22cc1f1c9fdb","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"cdebba22240bf720b1a235126627c68c4d2a32875691bd02d4ebc84b62cc23b3","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name","enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"description":"Descriptive comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"description":"Restrict packet destination address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"description":"Restrict TCP/UDP destination port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"description":"Flag to enable/disable a rule","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"description":"Network interface name. You have to use network configuration key names for VMs and containers","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"description":"IP version (4 or 6) - automatically determined from source/dest addresses","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"description":"Use predefined standard macro","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"description":"Rule position in the ruleset","enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"description":"Restrict packet source address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"description":"Restrict TCP/UDP source port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Rule type","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"c6c1eb12515b6c41f99959b8ae71473d2489301f6148eaf5920c5d013a665c4b","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/groups/{group}/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"02e10644e1474fe97e64060352d25dd832410fbc8ced9c0cd8b81bfd881e5f07","description":"List IPSets","extra":{},"name":"ipset_index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"name":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"d806f2879177e4ad4b25a3bd3bd8eefb291b03ceab3c4d94cc5e5d4eeed6097b","description":"Create new IPSet","extra":{},"name":"create_ipset","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/ipset"},{"extra":{},"methods":[{"allow_token":true,"checksum":"26a94d7acf918753aa6d8f5ec4155fb0e85f270e9366a91473ab924cb19cc9f0","description":"Delete IPSet","extra":{},"name":"delete_ipset","parameters":[{"definition":{"description":"Delete all members of the IPSet, if there are any.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"54fbdbe3ff6d8809dcf27bb78048fb8499eefeaba14c4bc371ea6de68a6b7cc5","description":"List IPSet content","extra":{},"name":"get_ipset","parameters":[{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cidr}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"nomatch":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"64742b376a8e3ee9b6b16b594db4e04c4b486e54165aa69f492fb0b952ea3225","description":"Add IP or Network to IPSet.","extra":{},"name":"create_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/ipset/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"35054ac0be461e02c18d2ec00e2e726f212564597638db31d0eeff1aab38415e","description":"Remove IP or Network from IPSet.","extra":{},"name":"remove_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"63a5cefffbd4607d42d80144ed58b521edc579d7778d60043f08271ec0332405","description":"Read IP or Network settings from IPSet.","extra":{},"name":"read_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"8650e84287c1ef48f83c92f08af9d31324d2409227c2ef65e8653c9f2cb2d686","description":"Update IP or Network settings","extra":{},"name":"update_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/ipset/{name}/{cidr}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8e98c5e0609b2624b64c801c530753f356fe8bd2682f5a27a745f43d6f986123","description":"List available macros","extra":{},"name":"get_macros","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"descr":{"description":"More verbose description (if available).","enum":[],"extra":{},"properties":{},"type":"string"},"macro":{"description":"Macro name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/firewall/macros"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a9be52a591c0602dacf003d199596b8c977657780cfe314bfcaecdce1b37a765","description":"Get Firewall options.","extra":{},"name":"get_options","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"ebtables":{"default":1,"description":"Enable ebtables rules cluster wide.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"enable":{"default":0,"description":"Enable or disable the firewall cluster wide.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"log_ratelimit":{"description":"Log ratelimiting settings","enum":[],"extra":{},"format":{"burst":{"default":5,"description":"Initial burst of packages which will always get logged before the rate is applied","minimum":0,"optional":1,"type":"integer"},"enable":{"default":"1","default_key":1,"description":"Enable or disable log rate limiting","type":"boolean"},"rate":{"default":"1/second","description":"Frequency with which the burst bucket gets refilled","format_description":"rate","optional":1,"pattern":"[1-9][0-9]*\\/(second|minute|hour|day)","type":"string"}},"optional":true,"properties":{},"type":"string"},"policy_forward":{"description":"Forward policy.","enum":["ACCEPT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"policy_in":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"policy_out":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"e184eb3cd7263f8ba8532bd41bd4bbfd8e54bd89d5748149c8badca3a34dd688","description":"Set Firewall options.","extra":{},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":1,"description":"Enable ebtables rules cluster wide.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ebtables"},{"definition":{"default":0,"description":"Enable or disable the firewall cluster wide.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Log ratelimiting settings","enum":[],"extra":{"typetext":"[enable=]<1|0> [,burst=] [,rate=]"},"format":{"burst":{"default":5,"description":"Initial burst of packages which will always get logged before the rate is applied","minimum":0,"optional":1,"type":"integer"},"enable":{"default":"1","default_key":1,"description":"Enable or disable log rate limiting","type":"boolean"},"rate":{"default":"1/second","description":"Frequency with which the burst bucket gets refilled","format_description":"rate","optional":1,"pattern":"[1-9][0-9]*\\/(second|minute|hour|day)","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"log_ratelimit"},{"definition":{"description":"Forward policy.","enum":["ACCEPT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_forward"},{"definition":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_in"},{"definition":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_out"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ca62b2e7b4ef073e676faf630d69bbcec98c09d6ac4b374c701808f9225ef43d","description":"Lists possible IPSet/Alias reference which are allowed in source/dest properties.","extra":{},"name":"refs","parameters":[{"definition":{"description":"Only list references of specified type.","enum":["alias","ipset"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"ref":{"enum":[],"extra":{},"properties":{},"type":"string"},"scope":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":["alias","ipset"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/firewall/refs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8eaf64d78fc789370d2913c4d834c2e4482066ef66a81eec156ca40825cabc3b","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"action":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name","enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"description":"Descriptive comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"description":"Restrict packet destination address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"description":"Restrict TCP/UDP destination port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"description":"Flag to enable/disable a rule","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"description":"Network interface name. You have to use network configuration key names for VMs and containers","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"description":"IP version (4 or 6) - automatically determined from source/dest addresses","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"description":"Use predefined standard macro","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"description":"Rule position in the ruleset","enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"description":"Restrict packet source address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"description":"Restrict TCP/UDP source port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Rule type","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"68d04cd0b9f6de5852d41ac7745d60b3d7b85b063ec6ed05e34ddcdd8b407159","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"abca0306da7fd9aa2e4ea5d711fb76723f0fe8f7908c76ca864abe119892e3e1","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"75aa973a6f2f0ad6c3a1fae9980b09a810fca42990a66fc1eb737f41cfff3a51","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name","enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"description":"Descriptive comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"description":"Restrict packet destination address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"description":"Restrict TCP/UDP destination port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"description":"Flag to enable/disable a rule","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"description":"Network interface name. You have to use network configuration key names for VMs and containers","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"description":"IP version (4 or 6) - automatically determined from source/dest addresses","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"description":"Use predefined standard macro","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"description":"Rule position in the ruleset","enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"description":"Restrict packet source address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"description":"Restrict TCP/UDP source port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Rule type","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"11ad59409653552ef6fc692b6e1ed87fd6ff77d55e44f022a38bf563343f39bc","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d001f6a38904cb5a8c874fb6d751e0a54ea9d1d75042d71b3c21dffb4e5c59ca","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/ha"},{"extra":{},"methods":[{"allow_token":true,"checksum":"66fee920273f5578e31b40004ed134056313bbefd12a9879c1617b575fae7e5d","description":"Get HA groups. (deprecated in favor of HA rules)","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{group}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"group":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"57af6164ad607d92bd967a6966ab314d244bcf77e8df8a37b903cce2f9437454","description":"Create a new HA group. (deprecated in favor of HA rules)","extra":{},"name":"create","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"List of cluster node names with optional priority.","enum":[],"extra":{"typetext":"[:]{,[:]}*","verbose_description":"List of cluster node members, where a priority can be given to each node. A resource will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the resources will get distributed to those nodes. The priorities have a relative meaning only. The higher the number, the higher the priority."},"format":"pve-ha-node-list","optional":false,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"default":0,"description":"The CRM tries to run services on the node with the highest priority. If a node with higher priority comes online, the CRM migrates the service to that node. Enabling nofailback prevents that behavior.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nofailback"},{"definition":{"default":0,"description":"Resources bound to restricted groups may only run on nodes defined by the group.","enum":[],"extra":{"typetext":"","verbose_description":"Resources bound to restricted groups may only run on nodes defined by the group. The resource will be placed in the stopped state if no group node member is online. Resources on unrestricted groups may run on any cluster node if all group members are offline, but they will migrate back as soon as a group member comes online. One can implement a 'preferred node' behavior using an unrestricted group with only one member."},"optional":true,"properties":{},"type":"boolean"},"name":"restricted"},{"definition":{"description":"Group type.","enum":["group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/groups"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7e86d43e2bf75b5b2684d447592efd86bebb609e86558229384e8bb8abc3f014","description":"Delete ha group configuration. (deprecated in favor of HA rules)","extra":{},"name":"delete","parameters":[{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"df72fe8c42bd00d3b2b013dc26467d6372d23328d32d2f288db28c30cf84aa7e","description":"Read ha group configuration. (deprecated in favor of HA rules)","extra":{},"name":"read","parameters":[{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{}},"verb":"GET"},{"allow_token":true,"checksum":"38e38556e60baa83f2850f74675bd277166ffd96f7baecd70caf56f044d9b915","description":"Update ha group configuration. (deprecated in favor of HA rules)","extra":{},"name":"update","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"List of cluster node names with optional priority.","enum":[],"extra":{"typetext":"[:]{,[:]}*","verbose_description":"List of cluster node members, where a priority can be given to each node. A resource will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the resources will get distributed to those nodes. The priorities have a relative meaning only. The higher the number, the higher the priority."},"format":"pve-ha-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"default":0,"description":"The CRM tries to run services on the node with the highest priority. If a node with higher priority comes online, the CRM migrates the service to that node. Enabling nofailback prevents that behavior.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nofailback"},{"definition":{"default":0,"description":"Resources bound to restricted groups may only run on nodes defined by the group.","enum":[],"extra":{"typetext":"","verbose_description":"Resources bound to restricted groups may only run on nodes defined by the group. The resource will be placed in the stopped state if no group node member is online. Resources on unrestricted groups may run on any cluster node if all group members are offline, but they will migrate back as soon as a group member comes online. One can implement a 'preferred node' behavior using an unrestricted group with only one member."},"optional":true,"properties":{},"type":"boolean"},"name":"restricted"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/ha/groups/{group}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"47984f628310d0cb88a50b127b972338f4cd63248dd3c160e5200d3e7bd0cdd1","description":"List HA resources.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list resources of specific type","enum":["ct","vm"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{sid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"sid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"7521690093e225136ee5c314beb4c956b1b7084c7061d7a139538c030cf05855","description":"Create a new HA resource.","extra":{},"name":"create","parameters":[{"definition":{"default":1,"description":"HA resource may be migrated during automatic rebalancing","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"auto-rebalance"},{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":1,"description":"Automatically migrate HA resource to the node with the highest priority according to their node affinity rules, if a node with a higher priority than the current node comes online.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"failback"},{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"group"},{"definition":{"default":1,"description":"Maximal number of resource relocate tries when a resource fails to start.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"max_relocate"},{"definition":{"default":1,"description":"Maximal number of tries to restart the resource on a node after its start failed. When reached, the HA manager will try to relocate the resource to an eligible node.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"max_restart"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"},{"definition":{"default":"started","description":"Requested resource state.","enum":["started","stopped","enabled","disabled","ignored"],"extra":{"verbose_description":"Requested resource state. The CRM reads this state and acts accordingly.\nPlease note that `enabled` is just an alias for `started`.\n\n`started`;;\n\nThe CRM tries to start the resource. Service state is\nset to `started` after successful start. On node failures, or when start\nfails, it tries to recover the resource. If everything fails, service\nstate it set to `error`.\n\n`stopped`;;\n\nThe CRM tries to keep the resource in `stopped` state, but it\nstill tries to relocate the resources on node failures.\n\n`disabled`;;\n\nThe CRM tries to put the resource in `stopped` state, but does not try\nto relocate the resources on node failures. The main purpose of this\nstate is error recovery, because it is the only way to move a resource out\nof the `error` state.\n\n`ignored`;;\n\nThe resource gets removed from the manager status and so the CRM and the LRM do\nnot touch the resource anymore. All {pve} API calls affecting this resource\nwill be executed, directly bypassing the HA stack. CRM commands will be thrown\naway while the resource is in this state. The resource will not get relocated\non node failures.\n\n"},"optional":true,"properties":{},"type":"string"},"name":"state"},{"definition":{"description":"Resource type.","enum":["ct","vm"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/resources"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e08af5ebc2354a2a8551f81f0eb1b7390f2e92a4b173c729389811e5b338fb1d","description":"Delete resource configuration.","extra":{},"name":"delete","parameters":[{"definition":{"default":1,"description":"Remove this resource from rules that reference it, deleting the rule if this resource is the only resource in the rule","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"purge"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"6de6a803432d57d3d29b52982fdd388a38da61e6980210a657ffad1f290ebc46","description":"Read resource configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"auto-rebalance":{"default":1,"description":"HA resource may be migrated during automatic rebalancing.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"comment":{"description":"Description.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Can be used to prevent concurrent modifications.","enum":[],"extra":{},"properties":{},"type":"string"},"failback":{"default":1,"description":"The HA resource is automatically migrated to the node with the highest priority according to their node affinity rule, if a node with a higher priority than the current node comes online.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"group":{"description":"The HA group identifier.","enum":[],"extra":{},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"max_relocate":{"description":"Maximal number of service relocate tries when a service fails to start.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"max_restart":{"description":"Maximal number of tries to restart the service on a node after its start failed.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"sid":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"state":{"description":"Requested resource state.","enum":["started","stopped","enabled","disabled","ignored"],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"The type of the resources.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"babd4ced0abf258629094de264847879ef32e76dd79125fe981cd3b27da42d28","description":"Update resource configuration.","extra":{},"name":"update","parameters":[{"definition":{"default":1,"description":"HA resource may be migrated during automatic rebalancing","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"auto-rebalance"},{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":1,"description":"Automatically migrate HA resource to the node with the highest priority according to their node affinity rules, if a node with a higher priority than the current node comes online.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"failback"},{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"group"},{"definition":{"default":1,"description":"Maximal number of resource relocate tries when a resource fails to start.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"max_relocate"},{"definition":{"default":1,"description":"Maximal number of tries to restart the resource on a node after its start failed. When reached, the HA manager will try to relocate the resource to an eligible node.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"max_restart"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"},{"definition":{"default":"started","description":"Requested resource state.","enum":["started","stopped","enabled","disabled","ignored"],"extra":{"verbose_description":"Requested resource state. The CRM reads this state and acts accordingly.\nPlease note that `enabled` is just an alias for `started`.\n\n`started`;;\n\nThe CRM tries to start the resource. Service state is\nset to `started` after successful start. On node failures, or when start\nfails, it tries to recover the resource. If everything fails, service\nstate it set to `error`.\n\n`stopped`;;\n\nThe CRM tries to keep the resource in `stopped` state, but it\nstill tries to relocate the resources on node failures.\n\n`disabled`;;\n\nThe CRM tries to put the resource in `stopped` state, but does not try\nto relocate the resources on node failures. The main purpose of this\nstate is error recovery, because it is the only way to move a resource out\nof the `error` state.\n\n`ignored`;;\n\nThe resource gets removed from the manager status and so the CRM and the LRM do\nnot touch the resource anymore. All {pve} API calls affecting this resource\nwill be executed, directly bypassing the HA stack. CRM commands will be thrown\naway while the resource is in this state. The resource will not get relocated\non node failures.\n\n"},"optional":true,"properties":{},"type":"string"},"name":"state"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/ha/resources/{sid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5b52966c6356529566e36e65bc90fd6d21264b76b4609b186a3a4f83796e062c","description":"Request resource migration (online) to another node.","extra":{},"name":"migrate","parameters":[{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"blocking-resources":{"description":"HA resources, which are blocking the given HA resource from being migrated to the requested target node.","enum":[],"extra":{},"items":{"description":"A blocking HA resource","enum":[],"extra":{},"properties":{"cause":{"description":"The reason why the HA resource is blocking the migration.","enum":["node-affinity","resource-affinity"],"extra":{},"properties":{},"type":"string"},"sid":{"description":"The blocking HA resource id","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"comigrated-resources":{"description":"HA resources, which are migrated to the same requested target node as the given HA resource, because these are in positive affinity with the HA resource.","enum":[],"extra":{},"optional":true,"properties":{},"type":"array"},"requested-node":{"description":"Node, which was requested to be migrated to.","enum":[],"extra":{},"optional":false,"properties":{},"type":"string"},"sid":{"description":"HA resource, which is requested to be migrated.","enum":[],"extra":{},"optional":false,"properties":{},"type":"string"}},"type":"object"},"verb":"POST"}],"path":"/cluster/ha/resources/{sid}/migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"fdba48e633b61f2e24179a7984bef7c92d252180e1df2d8516e467be9ab2468c","description":"Request resource relocation to another node. This stops the service on the old node, and restarts it on the target node.","extra":{},"name":"relocate","parameters":[{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"blocking-resources":{"description":"HA resources, which are blocking the given HA resource from being relocated to the requested target node.","enum":[],"extra":{},"items":{"description":"A blocking HA resource","enum":[],"extra":{},"properties":{"cause":{"description":"The reason why the HA resource is blocking the relocation.","enum":["node-affinity","resource-affinity"],"extra":{},"properties":{},"type":"string"},"sid":{"description":"The blocking HA resource id","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"comigrated-resources":{"description":"HA resources, which are relocated to the same requested target node as the given HA resource, because these are in positive affinity with the HA resource.","enum":[],"extra":{},"items":{"description":"A comigrated HA resource","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"requested-node":{"description":"Node, which was requested to be relocated to.","enum":[],"extra":{},"optional":false,"properties":{},"type":"string"},"sid":{"description":"HA resource, which is requested to be relocated.","enum":[],"extra":{},"optional":false,"properties":{},"type":"string"}},"type":"object"},"verb":"POST"}],"path":"/cluster/ha/resources/{sid}/relocate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c5bd90c621dc28909678a837c1ec02f43c77526a61c2a7d3ff472224aa756dcd","description":"Get HA rules.","extra":{},"name":"index","parameters":[{"definition":{"description":"Limit the returned list to rules affecting the specified resource.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"resource"},{"definition":{"description":"Limit the returned list to the specified rule type.","enum":["node-affinity","resource-affinity"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"links":[{"href":"{rule}","rel":"child"}]},"properties":{"rule":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"d685ebcacdbc5e9b0000b554516f067c3efa72060c82ce991713fecc2beb0188","description":"Create HA rule.","extra":{},"name":"create_rule","parameters":[{"definition":{"description":"Describes whether the HA resources are supposed to be kept on the same node ('positive'), or are supposed to be kept on separate nodes ('negative').","enum":["positive","negative"],"extra":{"instance-types":["resource-affinity"],"type-property":"type"},"optional":true,"properties":{},"type":"string"},"name":"affinity"},{"definition":{"description":"HA rule description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Whether the HA rule is disabled.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"List of cluster node names with optional priority.","enum":[],"extra":{"instance-types":["node-affinity"],"type-property":"type","typetext":"[:]{,[:]}*","verbose_description":"List of cluster node members, where a priority can be given to each node. A resource will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the resources will get distributed to those nodes. The priorities have a relative meaning only. The higher the number, the higher the priority."},"format":"pve-ha-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"List of HA resource IDs. This consists of a list of resource types followed by a resource specific name separated with a colon (example: vm:100,ct:101).","enum":[],"extra":{"typetext":":{,:}*"},"format":"pve-ha-resource-id-list","optional":false,"properties":{},"type":"string"},"name":"resources"},{"definition":{"description":"HA rule identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":false,"properties":{},"type":"string"},"name":"rule"},{"definition":{"default":0,"description":"Describes whether the node affinity rule is strict or non-strict.","enum":[],"extra":{"instance-types":["node-affinity"],"type-property":"type","typetext":"","verbose_description":"Describes whether the node affinity rule is strict or non-strict.\n\nA non-strict node affinity rule makes resources prefer to be on the defined nodes.\nIf none of the defined nodes are available, the resource may run on any other node.\n\nA strict node affinity rule makes resources be restricted to the defined nodes. If\nnone of the defined nodes are available, the resource will be stopped.\n"},"optional":true,"properties":{},"type":"boolean"},"name":"strict"},{"definition":{"description":"HA rule type.","enum":["node-affinity","resource-affinity"],"extra":{},"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6e312ad813692ff8b82415b9f80e43c538566652e7ad422d13dc7bdc90c60ea1","description":"Delete HA rule.","extra":{},"name":"delete_rule","parameters":[{"definition":{"description":"HA rule identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"rule"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"650fe10d7b6ec90dca6d6856111e0102fe97bf8dd0f8663cf2eb4a27063b16f7","description":"Read HA rule.","extra":{},"name":"read_rule","parameters":[{"definition":{"description":"HA rule identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"rule"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"rule":{"description":"HA rule identifier.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"type":{"description":"HA rule type.","enum":["node-affinity","resource-affinity"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"c6ad992e8888941fa56333a02b0fac8bb1b323a20dd350c5e8d43ee6664674ea","description":"Update HA rule.","extra":{},"name":"update_rule","parameters":[{"definition":{"description":"Describes whether the HA resources are supposed to be kept on the same node ('positive'), or are supposed to be kept on separate nodes ('negative').","enum":["positive","negative"],"extra":{"instance-types":["resource-affinity"],"type-property":"type"},"optional":true,"properties":{},"type":"string"},"name":"affinity"},{"definition":{"description":"HA rule description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Whether the HA rule is disabled.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"List of cluster node names with optional priority.","enum":[],"extra":{"instance-types":["node-affinity"],"type-property":"type","typetext":"[:]{,[:]}*","verbose_description":"List of cluster node members, where a priority can be given to each node. A resource will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the resources will get distributed to those nodes. The priorities have a relative meaning only. The higher the number, the higher the priority."},"format":"pve-ha-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"List of HA resource IDs. This consists of a list of resource types followed by a resource specific name separated with a colon (example: vm:100,ct:101).","enum":[],"extra":{"typetext":":{,:}*"},"format":"pve-ha-resource-id-list","optional":true,"properties":{},"type":"string"},"name":"resources"},{"definition":{"description":"HA rule identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":false,"properties":{},"type":"string"},"name":"rule"},{"definition":{"default":0,"description":"Describes whether the node affinity rule is strict or non-strict.","enum":[],"extra":{"instance-types":["node-affinity"],"type-property":"type","typetext":"","verbose_description":"Describes whether the node affinity rule is strict or non-strict.\n\nA non-strict node affinity rule makes resources prefer to be on the defined nodes.\nIf none of the defined nodes are available, the resource may run on any other node.\n\nA strict node affinity rule makes resources be restricted to the defined nodes. If\nnone of the defined nodes are available, the resource will be stopped.\n"},"optional":true,"properties":{},"type":"boolean"},"name":"strict"},{"definition":{"description":"HA rule type.","enum":["node-affinity","resource-affinity"],"extra":{},"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/ha/rules/{rule}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"74551df8a7f69c7a92251a3cae53f3fa26e51e7232e76071c74973bbbcee0c60","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/ha/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8016b71a303b3da572da8cc21ed53084f7148787620fcbfa79ec26fac682832b","description":"Request re-arming the HA stack after it was disarmed.","extra":{},"name":"arm-ha","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/status/arm-ha"},{"extra":{},"methods":[{"allow_token":true,"checksum":"42a3886c7442c40633ef463961415d0ba9a8fbc839f0950aa6754293f03b38b1","description":"Get HA manager status.","extra":{},"name":"status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"armed-state":{"description":"For type 'fencing'. Whether HA is armed, on standby, disarming or disarmed.","enum":["armed","standby","disarming","disarmed"],"extra":{},"optional":true,"properties":{},"type":"string"},"auto-rebalance":{"default":1,"description":"HA resource may be migrated during automatic rebalancing.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"crm_state":{"description":"For type 'service'. Service state as seen by the CRM.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"failback":{"default":1,"description":"The HA resource is automatically migrated to the node with the highest priority according to their node affinity rule, if a node with a higher priority than the current node comes online.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"id":{"description":"Status entry ID (quorum, master, lrm:, service:).","enum":[],"extra":{},"properties":{},"type":"string"},"max_relocate":{"description":"For type 'service'.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"max_restart":{"description":"For type 'service'.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"node":{"description":"Node associated to status entry.","enum":[],"extra":{},"properties":{},"type":"string"},"quorate":{"description":"For type 'quorum'. Whether the cluster is quorate or not.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"request_state":{"description":"For type 'service'. Requested service state.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"resource_mode":{"description":"For type 'fencing'. How resources are handled while disarmed.","enum":["freeze","ignore"],"extra":{},"optional":true,"properties":{},"type":"string"},"sid":{"description":"For type 'service'. Service ID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"state":{"description":"For type 'service'. Verbose service state.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"status":{"description":"Status of the entry (value depends on type).","enum":[],"extra":{},"properties":{},"type":"string"},"timestamp":{"description":"For type 'lrm','master'. Timestamp of the status information.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"type":{"description":"Type of status entry.","enum":["quorum","master","lrm","service","fencing"],"extra":{},"properties":{}}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/ha/status/current"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e0f9c6139c174804c94d89e6fd8a359654d1ec9c2c957243d4f7b81f5206676b","description":"Request disarming the HA stack, releasing all watchdogs cluster-wide.","extra":{},"name":"disarm-ha","parameters":[{"definition":{"description":"Controls how HA managed resources are handled while disarmed. The current state of resources is not affected. 'freeze': new commands and state changes are not applied. 'ignore': resources are removed from HA tracking and can be managed as if they were not HA managed.","enum":["freeze","ignore"],"extra":{},"properties":{},"type":"string"},"name":"resource-mode"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/status/disarm-ha"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6d72b7328e56705e3356e02859c184a582500b1140000b623c7f315785d6116c","description":"Get full HA manager status, including LRM status.","extra":{},"name":"manager_status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/ha/status/manager_status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e7fd541dc6bd5ac3934f5af8ff6c623fb4c63ac8f34778331904648f4ef034d9","description":"Index for jobs related endpoints.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"Directory index.","enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"description":"API sub-directory endpoint","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/jobs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6991afc8308cf7cc227211c547afaf3b3fc68d864ba698563c797f95c96f4d9d","description":"List configured realm-sync-jobs.","extra":{},"name":"syncjob_index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"A comment for the job.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enabled":{"description":"If the job is enabled or not.","enum":[],"extra":{},"properties":{},"type":"boolean"},"id":{"description":"The ID of the entry.","enum":[],"extra":{},"properties":{},"type":"string"},"last-run":{"description":"Last execution time of the job in seconds since the beginning of the UNIX epoch","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"next-run":{"description":"Next planned execution time of the job in seconds since the beginning of the UNIX epoch.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"realm":{"description":"Authentication domain ID","enum":[],"extra":{},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"remove-vanished":{"default":"none","description":"A semicolon-separated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).","enum":[],"extra":{"typetext":"([acl];[properties];[entry])|none"},"optional":true,"pattern":"(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none","properties":{},"type":"string"},"schedule":{"description":"The configured sync schedule.","enum":[],"extra":{},"properties":{},"type":"string"},"scope":{"description":"Select what to sync.","enum":["users","groups","both"],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/jobs/realm-sync"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0db7fb7f1f7c823388db4527653724add36ac3599e2857396a11dd7a637cfb46","description":"Delete realm-sync job definition.","extra":{},"name":"delete_job","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"93a9ff8182800613ae9864a6c7cce86e190587f1a55c1b0d3671c85e983d54ad","description":"Read realm-sync job definition.","extra":{},"name":"read_job","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"8295666b385b050fa4bf7fe8ca7091e37c3f32187a1d03b98c1353ffa5e1bc37","description":"Create new realm-sync job.","extra":{},"name":"create_job","parameters":[{"definition":{"description":"Description for the Job.","enum":[],"extra":{"typetext":""},"max_length":512,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":"1","description":"Enable newly synced users immediately.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable-new"},{"definition":{"default":1,"description":"Determines if the job is enabled.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"description":"The ID of the job.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":64,"properties":{},"type":"string"},"name":"id"},{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"optional":true,"properties":{},"type":"string"},"name":"realm"},{"definition":{"default":"none","description":"A semicolon-separated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).","enum":[],"extra":{"typetext":"([acl];[properties];[entry])|none"},"optional":true,"pattern":"(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none","properties":{},"type":"string"},"name":"remove-vanished"},{"definition":{"description":"Backup schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"Select what to sync.","enum":["users","groups","both"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scope"}],"permissions":{"description":"'Realm.AllocateUser' on '/access/realm/' and 'User.Modify' permissions to '/access/groups/'.","expression":{"check":["and",["perm","/access/realm/{realm}",["Realm.AllocateUser"]],["perm","/access/groups",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"d9421200e00b819969f44163ea78a101e356d364084cc2c5a3ec086a4f0e2578","description":"Update realm-sync job definition.","extra":{},"name":"update_job","parameters":[{"definition":{"description":"Description for the Job.","enum":[],"extra":{"typetext":""},"max_length":512,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"default":"1","description":"Enable newly synced users immediately.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable-new"},{"definition":{"default":1,"description":"Determines if the job is enabled.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"description":"The ID of the job.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":64,"properties":{},"type":"string"},"name":"id"},{"definition":{"default":"none","description":"A semicolon-separated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).","enum":[],"extra":{"typetext":"([acl];[properties];[entry])|none"},"optional":true,"pattern":"(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none","properties":{},"type":"string"},"name":"remove-vanished"},{"definition":{"description":"Backup schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"Select what to sync.","enum":["users","groups","both"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scope"}],"permissions":{"description":"'Realm.AllocateUser' on '/access/realm/' and 'User.Modify' permissions to '/access/groups/'.","expression":{"check":["and",["perm","/access/realm/{realm}",["Realm.AllocateUser"]],["perm","/access/groups",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/jobs/realm-sync/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b962117d14e12c92d1e1391addc0b51843bd1d16028ebdf260180f0585f7d628","description":"Returns a list of future schedule runtimes.","extra":{},"name":"schedule-analyze","parameters":[{"definition":{"default":10,"description":"Number of event-iteration to simulate and return.","enum":[],"extra":{"typetext":" (1 - 100)"},"maximum":100,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"iterations"},{"definition":{"description":"Job schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"UNIX timestamp to start the calculation from. Defaults to the current time.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"starttime"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"An array of the next events since .","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"timestamp":{"description":"UNIX timestamp for the run.","enum":[],"extra":{},"properties":{},"type":"integer"},"utc":{"description":"UTC timestamp for the run.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/jobs/schedule-analyze"},{"extra":{},"methods":[{"allow_token":true,"checksum":"893628e6a009e59e30a211f69e789344b216b8e10d903b9b536b59a6a5549a8e","description":"Read cluster log","extra":{},"name":"log","parameters":[{"definition":{"description":"Maximum number of entries.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max"}],"permissions":{"description":"The user needs 'Sys.Syslog' on '/' in order to get all logs.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0bac8b13119b633102143f35502b8d4c9d90528877d41713047d1b74f4059e37","description":"List resource types.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/mapping"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b9abd031a5cc7aefe56acc8c3f27b7ca6671ac1672d9e5f0b1d0926c7b410c52","description":"List directory mapping","extra":{},"name":"index","parameters":[{"definition":{"description":"If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the directory to the response.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"check-node"}],"permissions":{"description":"Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/dir/'.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"checks":{"description":"A list of checks, only present if 'check-node' is set.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"message":{"description":"The message of the error","enum":[],"extra":{},"properties":{},"type":"string"},"severity":{"description":"The severity of the error","enum":["warning","error"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"description":{"description":"A description of the logical mapping.","enum":[],"extra":{},"properties":{},"type":"string"},"id":{"description":"The logical ID of the mapping.","enum":[],"extra":{},"properties":{},"type":"string"},"map":{"description":"The entries of the mapping.","enum":[],"extra":{},"items":{"description":"A mapping for a node.","enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"8602f28bd41d721fe4e38c25886caef4d60cfb07cbd243a852381f43ab066516","description":"Create a new directory mapping.","extra":{},"name":"create","parameters":[{"definition":{"description":"Description of the directory mapping","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The ID of the directory mapping","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"A list of maps for the cluster nodes.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"node":{"description":"The cluster node name.","format":"pve-node","type":"string"},"path":{"description":"Absolute directory path that should be shared with the guest.","format":"pve-storage-path-in-property-string","type":"string"}},"properties":{},"type":"string"},"optional":false,"properties":{},"type":"array"},"name":"map"}],"permissions":{"expression":{"check":["perm","/mapping/dir",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/mapping/dir"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b7e8370d0c0e50d23f2a3b14f07d1d986bd27268d83d94e0ccabaa3b4928ea0f","description":"Remove directory mapping.","extra":{},"name":"delete","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/mapping/dir",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"8029154bf67479dfbe6b979b3c4b40e3d51e907e3aed0f224c4ade000b63da15","description":"Get directory mapping.","extra":{},"name":"get","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["or",["perm","/mapping/dir/{id}",["Mapping.Use"]],["perm","/mapping/dir/{id}",["Mapping.Modify"]],["perm","/mapping/dir/{id}",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"bf13a2bf62d6a1de9f615f392d402b9918b9424259b626499953698cfb1f389f","description":"Update a directory mapping.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description of the directory mapping","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The ID of the directory mapping","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"A list of maps for the cluster nodes.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"node":{"description":"The cluster node name.","format":"pve-node","type":"string"},"path":{"description":"Absolute directory path that should be shared with the guest.","format":"pve-storage-path-in-property-string","type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"map"}],"permissions":{"expression":{"check":["perm","/mapping/dir/{id}",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/mapping/dir/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d60cfe54e64682e009138eb9e5fe070b0a922286536bf55b2685cf0682b65a82","description":"List PCI Hardware Mapping","extra":{},"name":"index","parameters":[{"definition":{"description":"If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the devices to the response.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"check-node"}],"permissions":{"description":"Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/pci/'.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"checks":{"description":"A list of checks, only present if 'check_node' is set.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"message":{"description":"The message of the error","enum":[],"extra":{},"properties":{},"type":"string"},"severity":{"description":"The severity of the error","enum":["warning","error"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"description":{"description":"A description of the logical mapping.","enum":[],"extra":{},"properties":{},"type":"string"},"id":{"description":"The logical ID of the mapping.","enum":[],"extra":{},"properties":{},"type":"string"},"map":{"description":"The entries of the mapping.","enum":[],"extra":{},"items":{"description":"A mapping for a node.","enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"c5c5f015338b370a95b24d9c6d8d1d9e026ac0e4bf6bf0d4919a7e5e17a2c7cf","description":"Create a new hardware mapping.","extra":{},"name":"create","parameters":[{"definition":{"description":"Description of the logical PCI device.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The ID of the logical PCI mapping.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"default":0,"description":"Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"live-migration-capable"},{"definition":{"description":"A list of maps for the cluster nodes.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"description":{"description":"Description of the node specific device.","maxLength":4096,"optional":1,"type":"string"},"id":{"description":"The vendor and device ID that is expected. Used for detecting hardware changes","pattern":"(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)","type":"string"},"iommugroup":{"description":"The IOMMU group in which the device is to be expected in. Used for detecting hardware changes.","optional":1,"type":"integer"},"node":{"description":"The cluster node name.","format":"pve-node","type":"string"},"path":{"description":"The path to the device. If the function is omitted, the whole device is mapped. In that case use the attributes of the first device. You can give multiple paths as a semicolon separated list, the first available will then be chosen on guest start.","pattern":"(?:[a-f0-9]{4,}:[a-f0-9]{2}:[a-f0-9]{2}(?:.[a-f0-9])?;)*[a-f0-9]{4,}:[a-f0-9]{2}:[a-f0-9]{2}(?:.[a-f0-9])?","type":"string"},"subsystem-id":{"description":"The subsystem vendor and device ID that is expected. Used for detecting hardware changes.","optional":1,"pattern":"(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)","type":"string"}},"properties":{},"type":"string"},"optional":false,"properties":{},"type":"array"},"name":"map"},{"definition":{"default":0,"description":"Marks the device(s) as being capable of providing mediated devices.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"mdev"}],"permissions":{"expression":{"check":["perm","/mapping/pci",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/mapping/pci"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1ab38a61dfbff2d3971e6e378ac608d6b661055a418645e258a62b448e91993e","description":"Remove Hardware Mapping.","extra":{},"name":"delete","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/mapping/pci",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"4aafa5a8f922bc1569ed7fdc6dea719ad4afd335133c55508c307a788d54046f","description":"Get PCI Mapping.","extra":{},"name":"get","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["or",["perm","/mapping/pci/{id}",["Mapping.Use"]],["perm","/mapping/pci/{id}",["Mapping.Modify"]],["perm","/mapping/pci/{id}",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"b50e494b046747441881936c4042f1458428eb0f8e97730d829446e62a6c1e0f","description":"Update a hardware mapping.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description of the logical PCI device.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The ID of the logical PCI mapping.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"default":0,"description":"Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"live-migration-capable"},{"definition":{"description":"A list of maps for the cluster nodes.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"description":{"description":"Description of the node specific device.","maxLength":4096,"optional":1,"type":"string"},"id":{"description":"The vendor and device ID that is expected. Used for detecting hardware changes","pattern":"(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)","type":"string"},"iommugroup":{"description":"The IOMMU group in which the device is to be expected in. Used for detecting hardware changes.","optional":1,"type":"integer"},"node":{"description":"The cluster node name.","format":"pve-node","type":"string"},"path":{"description":"The path to the device. If the function is omitted, the whole device is mapped. In that case use the attributes of the first device. You can give multiple paths as a semicolon separated list, the first available will then be chosen on guest start.","pattern":"(?:[a-f0-9]{4,}:[a-f0-9]{2}:[a-f0-9]{2}(?:.[a-f0-9])?;)*[a-f0-9]{4,}:[a-f0-9]{2}:[a-f0-9]{2}(?:.[a-f0-9])?","type":"string"},"subsystem-id":{"description":"The subsystem vendor and device ID that is expected. Used for detecting hardware changes.","optional":1,"pattern":"(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)","type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"map"},{"definition":{"default":0,"description":"Marks the device(s) as being capable of providing mediated devices.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"mdev"}],"permissions":{"expression":{"check":["perm","/mapping/pci/{id}",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/mapping/pci/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dbd7757e06f8800f3f48e4f22c1f812e07310858bad59975b8ebc2c292ce33cd","description":"List USB Hardware Mappings","extra":{},"name":"index","parameters":[{"definition":{"description":"If given, checks the configurations on the given node for correctness, and adds relevant errors to the devices.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"check-node"}],"permissions":{"description":"Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/usb/'.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"description":{"description":"A description of the logical mapping.","enum":[],"extra":{},"properties":{},"type":"string"},"error":{"description":"A list of errors when 'check_node' is given.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"message":{"description":"The message of the error","enum":[],"extra":{},"properties":{},"type":"string"},"severity":{"description":"The severity of the error","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{}},"id":{"description":"The logical ID of the mapping.","enum":[],"extra":{},"properties":{},"type":"string"},"map":{"description":"The entries of the mapping.","enum":[],"extra":{},"items":{"description":"A mapping for a node.","enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"9067775f8baa064a5401c32739777b0d4a42d769ccae853f9a4a3316d9dfa506","description":"Create a new hardware mapping.","extra":{},"name":"create","parameters":[{"definition":{"description":"Description of the logical USB device.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The ID of the logical USB mapping.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"A list of maps for the cluster nodes.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"description":{"description":"Description of the node specific device.","maxLength":4096,"optional":1,"type":"string"},"id":{"description":"The vendor and device ID that is expected. If a USB path is given, it is only used for detecting hardware changes","pattern":"(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)","type":"string"},"node":{"description":"The cluster node name.","format":"pve-node","type":"string"},"path":{"description":"The path to the usb device.","optional":1,"pattern":"(?^:^(\\d+)\\-(\\d+(\\.\\d+)*)$)","type":"string"}},"properties":{},"type":"string"},"properties":{},"type":"array"},"name":"map"}],"permissions":{"expression":{"check":["perm","/mapping/usb",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/mapping/usb"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bdc92ea0426ed15e2364503f8ef030848f16dab636466c1f2b53686d77313087","description":"Remove Hardware Mapping.","extra":{},"name":"delete","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/mapping/usb",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"41a71a202028635b8a3019b74ca4076c50be08ee860e758541e0e49fcedc88d5","description":"Get USB Mapping.","extra":{},"name":"get","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["or",["perm","/mapping/usb/{id}",["Mapping.Audit"]],["perm","/mapping/usb/{id}",["Mapping.Use"]],["perm","/mapping/usb/{id}",["Mapping.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"10c711f5a8ebbd1366a9f6c2eaaadc7132629244f3b76089f51bb581c4d8f15b","description":"Update a hardware mapping.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description of the logical USB device.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The ID of the logical USB mapping.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"A list of maps for the cluster nodes.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"description":{"description":"Description of the node specific device.","maxLength":4096,"optional":1,"type":"string"},"id":{"description":"The vendor and device ID that is expected. If a USB path is given, it is only used for detecting hardware changes","pattern":"(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)","type":"string"},"node":{"description":"The cluster node name.","format":"pve-node","type":"string"},"path":{"description":"The path to the usb device.","optional":1,"pattern":"(?^:^(\\d+)\\-(\\d+(\\.\\d+)*)$)","type":"string"}},"properties":{},"type":"string"},"properties":{},"type":"array"},"name":"map"}],"permissions":{"expression":{"check":["perm","/mapping/usb/{id}",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/mapping/usb/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"32e4e0d625a43113ca32f9e4eba0fba77b683c1450a608bddb7a54be11776ea3","description":"Metrics index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/metrics"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d5946e4d282323d0c845b4ab91baebcc5d16fd17bcf192f5de1a7156e794d30b","description":"Retrieve metrics of the cluster.","extra":{"expose_credentials":1},"name":"export","parameters":[{"definition":{"default":0,"description":"Also return historic values. Returns full available metric history unless `start-time` is also set","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"history"},{"definition":{"default":0,"description":"Only return metrics for the current node instead of the whole cluster","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"local-only"},{"definition":{"description":"Only return metrics from nodes passed as comma-separated list","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"node-list"},{"definition":{"default":0,"description":"Only include metrics with a timestamp > start-time.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"start-time"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"data":{"description":"Array of system metrics. Metrics are sorted by their timestamp.","enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":0},"properties":{"id":{"description":"Unique identifier for this metric object, for instance 'node/' or 'qemu/'.","enum":[],"extra":{},"properties":{},"type":"string"},"metric":{"description":"Name of the metric.","enum":[],"extra":{},"properties":{},"type":"string"},"timestamp":{"description":"Time at which this metric was observed","enum":[],"extra":{},"properties":{},"type":"integer"},"type":{"description":"Type of the metric.","enum":["gauge","counter","derive"],"extra":{},"properties":{},"type":"string"},"value":{"description":"Metric value.","enum":[],"extra":{},"properties":{},"type":"number"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"}],"path":"/cluster/metrics/export"},{"extra":{},"methods":[{"allow_token":true,"checksum":"27149ea7f2dd2e6d37dc5ad79fe1835f771a7232d81bc38e686157565a692fc6","description":"List configured metric servers.","extra":{},"name":"server_index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"disable":{"description":"Flag to disable the plugin.","enum":[],"extra":{},"properties":{},"type":"boolean"},"id":{"description":"The ID of the entry.","enum":[],"extra":{},"properties":{},"type":"string"},"port":{"description":"Server network port","enum":[],"extra":{},"properties":{},"type":"integer"},"server":{"description":"Server dns name or IP address","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"Plugin type.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/metrics/server"},{"extra":{},"methods":[{"allow_token":true,"checksum":"56bc7f1733b6ce3c54389c9ceed9a20983de2c44898310930261592680aa259a","description":"Remove Metric server.","extra":{},"name":"delete","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"a53d502e8ae6ee9c25effeb04789f394e23cf119b2a13a620c971ed75e925a3f","description":"Read metric server configuration.","extra":{},"name":"read","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"603e4a6e3722bdbc0045ddd7b716d7b14da4847e6e4deddd4d7a4ad94acde6e0","description":"Create a new external metric server config","extra":{},"name":"create","parameters":[{"definition":{"description":"An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"api-path-prefix"},{"definition":{"description":"The InfluxDB bucket/db. Only necessary when using the http v2 api.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"bucket"},{"definition":{"description":"Flag to disable the plugin.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"The ID of the entry.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"default":"udp","enum":["udp","http","https"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"influxdbproto"},{"definition":{"default":25000000,"description":"InfluxDB max-body-size in bytes. Requests are batched up to this size.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max-body-size"},{"definition":{"default":1500,"description":"MTU for metrics transmission over UDP","enum":[],"extra":{"typetext":" (512 - 65536)"},"maximum":65536,"minimum":512,"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"organization"},{"definition":{"default":"gzip","description":"Compression algorithm for requests","enum":["none","gzip"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"otel-compression"},{"definition":{"description":"Custom HTTP headers (JSON format, base64 encoded)","enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"otel-headers"},{"definition":{"default":10000000,"description":"Maximum request body size in bytes","enum":[],"extra":{"typetext":" (1024 - N)"},"minimum":1024,"optional":true,"properties":{},"type":"integer"},"name":"otel-max-body-size"},{"definition":{"default":"/v1/metrics","description":"OTLP endpoint path","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"otel-path"},{"definition":{"default":"https","description":"HTTP protocol","enum":["http","https"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"otel-protocol"},{"definition":{"description":"Additional resource attributes as JSON, base64 encoded","enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"otel-resource-attributes"},{"definition":{"default":5,"description":"HTTP request timeout in seconds","enum":[],"extra":{"typetext":" (1 - 10)"},"maximum":10,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"otel-timeout"},{"definition":{"default":1,"description":"Verify SSL certificates","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"otel-verify-ssl"},{"definition":{"description":"root graphite path (ex: proxmox.mycluster.mykey)","enum":[],"extra":{"typetext":""},"format":"graphite-path","optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"server network port","enum":[],"extra":{"typetext":" (1 - 65536)"},"maximum":65536,"minimum":1,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Protocol to send graphite data. TCP or UDP (default)","enum":["udp","tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"server dns name or IP address","enum":[],"extra":{"typetext":""},"format":"address","properties":{},"type":"string"},"name":"server"},{"definition":{"default":1,"description":"graphite TCP socket timeout (default=1)","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"},{"definition":{"description":"Plugin type.","enum":["graphite","influxdb","opentelemetry"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"},{"definition":{"default":1,"description":"Set to 0 to disable certificate verification for https endpoints.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify-certificate"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"b237db131f7f2127f708fd02aaa4bfcef12158e7b0d8cb11dacdc04cc05141db","description":"Update metric server configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"api-path-prefix"},{"definition":{"description":"The InfluxDB bucket/db. Only necessary when using the http v2 api.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"bucket"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Flag to disable the plugin.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"The ID of the entry.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"default":"udp","enum":["udp","http","https"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"influxdbproto"},{"definition":{"default":25000000,"description":"InfluxDB max-body-size in bytes. Requests are batched up to this size.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max-body-size"},{"definition":{"default":1500,"description":"MTU for metrics transmission over UDP","enum":[],"extra":{"typetext":" (512 - 65536)"},"maximum":65536,"minimum":512,"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"organization"},{"definition":{"default":"gzip","description":"Compression algorithm for requests","enum":["none","gzip"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"otel-compression"},{"definition":{"description":"Custom HTTP headers (JSON format, base64 encoded)","enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"otel-headers"},{"definition":{"default":10000000,"description":"Maximum request body size in bytes","enum":[],"extra":{"typetext":" (1024 - N)"},"minimum":1024,"optional":true,"properties":{},"type":"integer"},"name":"otel-max-body-size"},{"definition":{"default":"/v1/metrics","description":"OTLP endpoint path","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"otel-path"},{"definition":{"default":"https","description":"HTTP protocol","enum":["http","https"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"otel-protocol"},{"definition":{"description":"Additional resource attributes as JSON, base64 encoded","enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"otel-resource-attributes"},{"definition":{"default":5,"description":"HTTP request timeout in seconds","enum":[],"extra":{"typetext":" (1 - 10)"},"maximum":10,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"otel-timeout"},{"definition":{"default":1,"description":"Verify SSL certificates","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"otel-verify-ssl"},{"definition":{"description":"root graphite path (ex: proxmox.mycluster.mykey)","enum":[],"extra":{"typetext":""},"format":"graphite-path","optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"server network port","enum":[],"extra":{"typetext":" (1 - 65536)"},"maximum":65536,"minimum":1,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Protocol to send graphite data. TCP or UDP (default)","enum":["udp","tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"server dns name or IP address","enum":[],"extra":{"typetext":""},"format":"address","properties":{},"type":"string"},"name":"server"},{"definition":{"default":1,"description":"graphite TCP socket timeout (default=1)","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"},{"definition":{"default":1,"description":"Set to 0 to disable certificate verification for https endpoints.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify-certificate"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/metrics/server/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"aa3eb10cb83557b6fcf75697ec64cec7b678f1a4450ebb9bf8ec1a20337edfa3","description":"Get next free VMID. Pass a VMID to assert that its free (at time of check).","extra":{},"name":"nextid","parameters":[{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"The next free VMID.","enum":[],"extra":{},"properties":{},"type":"integer"},"verb":"GET"}],"path":"/cluster/nextid"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7dbcb2698d0743fdaa7af4375905eaf256dcdd8b8aab222da2a96757f655c17b","description":"Index for notification-related API endpoints.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/notifications"},{"extra":{},"methods":[{"allow_token":true,"checksum":"85590b7311db3564907025d08fe26246c4cce5921df4cb13e552320becebb7b7","description":"Index for all available endpoint types.","extra":{},"name":"endpoints_index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/notifications/endpoints"},{"extra":{},"methods":[{"allow_token":true,"checksum":"aa2279f9300ffacd9067b3caf0923954a31d175a2b35e4dd55b5cdc5d6446a2d","description":"Returns a list of all gotify endpoints","extra":{},"name":"get_gotify_endpoints","parameters":[],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this target","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"name":{"description":"The name of the endpoint.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"origin":{"description":"Show if this entry was created by a user or was built-in","enum":["user-created","builtin","modified-builtin"],"extra":{},"properties":{},"type":"string"},"server":{"description":"Server URL","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"203146b6888684db9665f1eac8ba9f7c0f8badfbc80a8fb609fd9144884639d7","description":"Create a new gotify endpoint","extra":{},"name":"create_gotify_endpoint","parameters":[{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":0,"description":"Disable this target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"The name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Server URL","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"server"},{"definition":{"description":"Secret token","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"token"}],"permissions":{"expression":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/notifications/endpoints/gotify"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a6de09b94ee57a1549718ac8d08fa550e86c4f63cc58d9b87d6d5214d09114f9","description":"Remove gotify endpoint","extra":{},"name":"delete_gotify_endpoint","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"6ab08a33c312fc583f6134d2f6350bc4a95b1105b6261389b718c5240842a66e","description":"Return a specific gotify endpoint","extra":{},"name":"get_gotify_endpoint","parameters":[{"definition":{"description":"Name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this target","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"name":{"description":"The name of the endpoint.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"server":{"description":"Server URL","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"1250dacd14b1453f9e672a43ed6ae634699ac3eb7471a93d2788fc7ae609ec2f","description":"Update existing gotify endpoint","extra":{},"name":"update_gotify_endpoint","parameters":[{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Disable this target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"The name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Server URL","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"server"},{"definition":{"description":"Secret token","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"}],"permissions":{"expression":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/notifications/endpoints/gotify/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"822b8284272a3eb5b3b6b9d20fe374ac450fd09b464760fe487e6d96ff6b4ee5","description":"Returns a list of all sendmail endpoints","extra":{},"name":"get_sendmail_endpoints","parameters":[],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"author":{"description":"Author of the mail","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this target","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"from-address":{"description":"`From` address for the mail","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mailto":{"description":"List of email recipients","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"email-or-username","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"mailto-user":{"description":"List of users","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"pve-userid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":{"description":"The name of the endpoint.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"origin":{"description":"Show if this entry was created by a user or was built-in","enum":["user-created","builtin","modified-builtin"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"ff7158b8777736c611660e4a51905e8cbc619ccb80be0d565e15704dbc69efae","description":"Create a new sendmail endpoint","extra":{},"name":"create_sendmail_endpoint","parameters":[{"definition":{"description":"Author of the mail","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"author"},{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":0,"description":"Disable this target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"`From` address for the mail","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"from-address"},{"definition":{"description":"List of email recipients","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"email-or-username","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"mailto"},{"definition":{"description":"List of users","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-userid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"mailto-user"},{"definition":{"description":"The name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/notifications/endpoints/sendmail"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8b865ef7b43ac01417a73521a23175a2921b6602407180a1c687655ec120328b","description":"Remove sendmail endpoint","extra":{},"name":"delete_sendmail_endpoint","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"939df15a8a724305cca5c2b002c6546b2808542dd462d59009565a25144cf839","description":"Return a specific sendmail endpoint","extra":{},"name":"get_sendmail_endpoint","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"author":{"description":"Author of the mail","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this target","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"from-address":{"description":"`From` address for the mail","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mailto":{"description":"List of email recipients","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"email-or-username","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"mailto-user":{"description":"List of users","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"pve-userid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":{"description":"The name of the endpoint.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"918ab4f7d8ae0b6a942395375f3ffa14ec3eadcd6d38f739095057951336f9e4","description":"Update existing sendmail endpoint","extra":{},"name":"update_sendmail_endpoint","parameters":[{"definition":{"description":"Author of the mail","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"author"},{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Disable this target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"`From` address for the mail","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"from-address"},{"definition":{"description":"List of email recipients","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"email-or-username","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"mailto"},{"definition":{"description":"List of users","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-userid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"mailto-user"},{"definition":{"description":"The name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/notifications/endpoints/sendmail/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"649b926f2615be3ee77c56a411fdd943c57605f9fc8e225e545580139f1371c6","description":"Returns a list of all smtp endpoints","extra":{},"name":"get_smtp_endpoints","parameters":[],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"author":{"description":"Author of the mail. Defaults to 'Proxmox VE'.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this target","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"from-address":{"description":"`From` address for the mail","enum":[],"extra":{},"properties":{},"type":"string"},"mailto":{"description":"List of email recipients","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"email-or-username","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"mailto-user":{"description":"List of users","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"pve-userid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"mode":{"default":"tls","description":"Determine which encryption method shall be used for the connection.","enum":["insecure","starttls","tls"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"The name of the endpoint.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"origin":{"description":"Show if this entry was created by a user or was built-in","enum":["user-created","builtin","modified-builtin"],"extra":{},"properties":{},"type":"string"},"port":{"description":"The port to be used. Defaults to 465 for TLS based connections, 587 for STARTTLS based connections and port 25 for insecure plain-text connections.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"server":{"description":"The address of the SMTP server.","enum":[],"extra":{},"properties":{},"type":"string"},"username":{"description":"Username for SMTP authentication","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"50245531f58d65906617eb64a74325d81f787bde7f35ef6ce469913dfc43ef96","description":"Create a new smtp endpoint","extra":{},"name":"create_smtp_endpoint","parameters":[{"definition":{"description":"Author of the mail. Defaults to 'Proxmox VE'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"author"},{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":0,"description":"Disable this target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"`From` address for the mail","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"from-address"},{"definition":{"description":"List of email recipients","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"email-or-username","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"mailto"},{"definition":{"description":"List of users","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-userid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"mailto-user"},{"definition":{"default":"tls","description":"Determine which encryption method shall be used for the connection.","enum":["insecure","starttls","tls"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"The name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Password for SMTP authentication","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"The port to be used. Defaults to 465 for TLS based connections, 587 for STARTTLS based connections and port 25 for insecure plain-text connections.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The address of the SMTP server.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"server"},{"definition":{"description":"Username for SMTP authentication","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username"}],"permissions":{"expression":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/notifications/endpoints/smtp"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4da9aad76213e463fd077dd2994cecc67f2749fb9a67118c3db784242d3a0803","description":"Remove smtp endpoint","extra":{},"name":"delete_smtp_endpoint","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"ff151038edcae508b780b3210438ff7d62415a1fc20b2bc7f94920e1e6bd9abf","description":"Return a specific smtp endpoint","extra":{},"name":"get_smtp_endpoint","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"author":{"description":"Author of the mail. Defaults to 'Proxmox VE'.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this target","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"from-address":{"description":"`From` address for the mail","enum":[],"extra":{},"properties":{},"type":"string"},"mailto":{"description":"List of email recipients","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"email-or-username","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"mailto-user":{"description":"List of users","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"pve-userid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"mode":{"default":"tls","description":"Determine which encryption method shall be used for the connection.","enum":["insecure","starttls","tls"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"The name of the endpoint.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"port":{"description":"The port to be used. Defaults to 465 for TLS based connections, 587 for STARTTLS based connections and port 25 for insecure plain-text connections.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"server":{"description":"The address of the SMTP server.","enum":[],"extra":{},"properties":{},"type":"string"},"username":{"description":"Username for SMTP authentication","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"1007bc9cf46b936b3527c23d140212285e41624682d3cc7cbacc86bd4a1cb434","description":"Update existing smtp endpoint","extra":{},"name":"update_smtp_endpoint","parameters":[{"definition":{"description":"Author of the mail. Defaults to 'Proxmox VE'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"author"},{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Disable this target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"`From` address for the mail","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"from-address"},{"definition":{"description":"List of email recipients","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"email-or-username","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"mailto"},{"definition":{"description":"List of users","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-userid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"mailto-user"},{"definition":{"default":"tls","description":"Determine which encryption method shall be used for the connection.","enum":["insecure","starttls","tls"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"The name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Password for SMTP authentication","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"The port to be used. Defaults to 465 for TLS based connections, 587 for STARTTLS based connections and port 25 for insecure plain-text connections.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The address of the SMTP server.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"server"},{"definition":{"description":"Username for SMTP authentication","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username"}],"permissions":{"expression":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/notifications/endpoints/smtp/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f28969a47b8037821f50ecad98382ae831e9bfe571bf0f1bcf1eae8e9fcba64e","description":"Returns a list of all webhook endpoints","extra":{},"name":"get_webhook_endpoints","parameters":[],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"body":{"description":"HTTP body, base64 encoded","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this target","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"header":{"description":"HTTP headers to set. These have to be formatted as a property string in the format name=,value=","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"method":{"description":"HTTP method","enum":["post","put","get"],"extra":{},"properties":{},"type":"string"},"name":{"description":"The name of the endpoint.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"origin":{"description":"Show if this entry was created by a user or was built-in","enum":["user-created","builtin","modified-builtin"],"extra":{},"properties":{},"type":"string"},"secret":{"description":"Secrets to set. These have to be formatted as a property string in the format name=,value=","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"url":{"description":"Server URL","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"12e06ec20708e708c716f68acf165191a46721977278b1492aee8f0a87be6c05","description":"Create a new webhook endpoint","extra":{},"name":"create_webhook_endpoint","parameters":[{"definition":{"description":"HTTP body, base64 encoded","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"body"},{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":0,"description":"Disable this target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"HTTP headers to set. These have to be formatted as a property string in the format name=,value=","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"header"},{"definition":{"description":"HTTP method","enum":["post","put","get"],"extra":{},"properties":{},"type":"string"},"name":"method"},{"definition":{"description":"The name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Secrets to set. These have to be formatted as a property string in the format name=,value=","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"secret"},{"definition":{"description":"Server URL","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/notifications/endpoints/webhook"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a69d31e16174e8eeba1c3d681999308a624de1f04bededd7e80a7aef2985d39b","description":"Remove webhook endpoint","extra":{},"name":"delete_webhook_endpoint","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"872d98a658e6bda785b39c13e32ac76bd29d2619266bb1872e760e9475be1dda","description":"Return a specific webhook endpoint","extra":{},"name":"get_webhook_endpoint","parameters":[{"definition":{"description":"Name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"body":{"description":"HTTP body, base64 encoded","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this target","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"header":{"description":"HTTP headers to set. These have to be formatted as a property string in the format name=,value=","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"method":{"description":"HTTP method","enum":["post","put","get"],"extra":{},"properties":{},"type":"string"},"name":{"description":"The name of the endpoint.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"secret":{"description":"Secrets to set. These have to be formatted as a property string in the format name=,value=","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"url":{"description":"Server URL","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"8628abb1cbc8d50543fc19a45ba95f4f388d66a7a1ea108e474231a82b53baa0","description":"Update existing webhook endpoint","extra":{},"name":"update_webhook_endpoint","parameters":[{"definition":{"description":"HTTP body, base64 encoded","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"body"},{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Disable this target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"HTTP headers to set. These have to be formatted as a property string in the format name=,value=","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"header"},{"definition":{"description":"HTTP method","enum":["post","put","get"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"method"},{"definition":{"description":"The name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Secrets to set. These have to be formatted as a property string in the format name=,value=","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"secret"},{"definition":{"description":"Server URL","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/notifications/endpoints/webhook/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"aa41d7e8d333bd62d93dd0d9961cc8cc1b34eaaecefb6945b796c49800978507","description":"Returns known notification metadata fields and their known values","extra":{},"name":"get_matcher_field_values","parameters":[],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"Additional comment for this value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"field":{"description":"Field this value belongs to.","enum":[],"extra":{},"properties":{},"type":"string"},"value":{"description":"Notification metadata value known by the system.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/notifications/matcher-field-values"},{"extra":{},"methods":[{"allow_token":true,"checksum":"03edb9a3636c55ce06fe6a6aec4bb99a02d3c320360e32bd7ad92736ddfc234b","description":"Returns known notification metadata fields","extra":{},"name":"get_matcher_fields","parameters":[],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"name":{"description":"Name of the field.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/notifications/matcher-fields"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2d81c639818313f8f1574cd4398c0c7573ad6fa37dc9179983f6dda5fa1ce84d","description":"Returns a list of all matchers","extra":{},"name":"get_matchers","parameters":[],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]],["perm","/mapping/notifications",["Mapping.Use"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this matcher","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"invert-match":{"description":"Invert match of the whole matcher","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"match-calendar":{"description":"Match notification timestamp","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"match-field":{"description":"Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"match-severity":{"description":"Notification severities to match","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"mode":{"default":"all","description":"Choose between 'all' and 'any' for when multiple properties are specified","enum":["all","any"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"Name of the matcher.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"origin":{"description":"Show if this entry was created by a user or was built-in","enum":["user-created","builtin","modified-builtin"],"extra":{},"properties":{},"type":"string"},"target":{"description":"Targets to notify on match","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"15c020aae8edfbf48f094c82e446b621be8b8c453a64fb68ef0b2f1f7a5d6c62","description":"Create a new matcher","extra":{},"name":"create_matcher","parameters":[{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":0,"description":"Disable this matcher","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"Invert match of the whole matcher","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"invert-match"},{"definition":{"description":"Match notification timestamp","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"match-calendar"},{"definition":{"description":"Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"match-field"},{"definition":{"description":"Notification severities to match","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"match-severity"},{"definition":{"default":"all","description":"Choose between 'all' and 'any' for when multiple properties are specified","enum":["all","any"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"Name of the matcher.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Targets to notify on match","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"target"}],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/notifications/matchers"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bc801324430c8d7fc2b03d29ea40064856138f33ee7db0dd54fd7e757a94986b","description":"Remove matcher","extra":{},"name":"delete_matcher","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"5e51e778bdb104dd9f86b83bdd60209c721601fb362521112e045bea4136140e","description":"Return a specific matcher","extra":{},"name":"get_matcher","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this matcher","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"invert-match":{"description":"Invert match of the whole matcher","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"match-calendar":{"description":"Match notification timestamp","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"match-field":{"description":"Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"match-severity":{"description":"Notification severities to match","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"mode":{"default":"all","description":"Choose between 'all' and 'any' for when multiple properties are specified","enum":["all","any"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"Name of the matcher.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"target":{"description":"Targets to notify on match","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"0c5c9801c81e5a52a8f5859b7253e04a23c517b90a6141e07c52e880b6be5d41","description":"Update existing matcher","extra":{},"name":"update_matcher","parameters":[{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Disable this matcher","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"Invert match of the whole matcher","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"invert-match"},{"definition":{"description":"Match notification timestamp","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"match-calendar"},{"definition":{"description":"Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"match-field"},{"definition":{"description":"Notification severities to match","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"match-severity"},{"definition":{"default":"all","description":"Choose between 'all' and 'any' for when multiple properties are specified","enum":["all","any"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"Name of the matcher.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Targets to notify on match","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"target"}],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/notifications/matchers/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6df341a23c51716542f980e768ae19f61a31ec6e92a378d86fba01c4fd3a3437","description":"Returns a list of all entities that can be used as notification targets.","extra":{},"name":"get_all_targets","parameters":[],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]],["perm","/mapping/notifications",["Mapping.Use"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Show if this target is disabled","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"name":{"description":"Name of the target.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"origin":{"description":"Show if this entry was created by a user or was built-in","enum":["user-created","builtin","modified-builtin"],"extra":{},"properties":{},"type":"string"},"type":{"description":"Type of the target.","enum":["sendmail","gotify","smtp","webhook"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/notifications/targets"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7494eacdd54979c41f1bab85951ae184cdad4ec05b2ccc76db51c7df47796558","description":"Send a test notification to a provided target.","extra":{},"name":"test_target","parameters":[{"definition":{"description":"Name of the target.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]],["perm","/mapping/notifications",["Mapping.Use"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/notifications/targets/{name}/test"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f25824d5aa61d78e9fdb1f99a5845b39d507b9c2093b786e95acd8d8e072ede3","description":"Get datacenter options. Without 'Sys.Audit' on '/' not all options are returned.","extra":{},"name":"get_options","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"e3041fb53c8951a901dc5e3c612a9deccd78d781576787c802f17fa67522c6ea","description":"Set datacenter options.","extra":{},"name":"set_options","parameters":[{"definition":{"description":"Set I/O bandwidth limit for various operations (in KiB/s).","enum":[],"extra":{"typetext":"[clone=] [,default=] [,migration=] [,move=] [,restore=]"},"format":{"clone":{"description":"bandwidth limit in KiB/s for cloning disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"default":{"description":"default bandwidth limit in KiB/s","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"migration":{"description":"bandwidth limit in KiB/s for migrating guests (including moving local disks)","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"move":{"description":"bandwidth limit in KiB/s for moving disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"restore":{"description":"bandwidth limit in KiB/s for restoring guests from backups","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"}},"optional":true,"properties":{},"type":"string"},"name":"bwlimit"},{"definition":{"description":"Consent text that is displayed before logging in.","enum":[],"extra":{"typetext":""},"max_length":65536,"optional":true,"properties":{},"type":"string"},"name":"consent-text"},{"definition":{"description":"Select the default Console viewer. You can either use the builtin java applet (VNC; deprecated and maps to html5), an external virt-viewer comtatible application (SPICE), an HTML5 based vnc viewer (noVNC), or an HTML5 based console client (xtermjs). If the selected viewer is not available (e.g. SPICE not activated for the VM), the fallback is noVNC.","enum":["applet","vv","html5","xtermjs"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"console"},{"definition":{"description":"Cluster resource scheduling settings.","enum":[],"extra":{"typetext":"[ha=] [,ha-auto-rebalance=<1|0>] [,ha-auto-rebalance-hold-duration=] [,ha-auto-rebalance-margin=] [,ha-auto-rebalance-method=] [,ha-auto-rebalance-threshold=] [,ha-rebalance-on-start=<1|0>]"},"format":{"ha":{"default":"basic","description":"Use this resource scheduler mode for HA.","enum":["basic","static","dynamic"],"optional":1,"type":"string","verbose_description":"Configures how the HA Manager should select nodes to start or recover services:\n\n- with 'basic', only the number of services is used,\n- with 'static', static CPU and memory configuration of services are considered,\n- with 'dynamic', static and dynamic CPU and memory usage of services are considered.\n"},"ha-auto-rebalance":{"default":0,"description":"Whether to use CRS for balancing HA resources automatically depending on the current node imbalance.","optional":1,"type":"boolean"},"ha-auto-rebalance-hold-duration":{"default":3,"description":"The number of HA rounds for which the cluster node imbalance threshold must be exceeded before triggering an automatic resource balancing migration.","minimum":0,"optional":1,"requires":"ha-auto-rebalance","type":"number"},"ha-auto-rebalance-margin":{"default":10,"description":"The minimum relative improvement in cluster node imbalance, in percent, to commit to a resource balancing migration.","maximum":100,"minimum":0,"optional":1,"requires":"ha-auto-rebalance","type":"number"},"ha-auto-rebalance-method":{"default":"bruteforce","description":"The method to use for the scoring of balancing migrations.","enum":["bruteforce","topsis"],"optional":1,"requires":"ha-auto-rebalance","type":"string"},"ha-auto-rebalance-threshold":{"default":30,"description":"The cluster node imbalance, in percent, which will trigger the automatic resource balancing system if exceeded.","maximum":100,"minimum":0,"optional":1,"requires":"ha-auto-rebalance","type":"number"},"ha-rebalance-on-start":{"default":0,"description":"Set to use CRS for selecting a suited node when a HA services request-state changes from stop to start.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"crs"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Datacenter description. Shown in the web-interface datacenter notes panel. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":65536,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Specify email address to send notification from (default is root@$hostname)","enum":[],"extra":{"typetext":""},"format":"email-opt","optional":true,"properties":{},"type":"string"},"name":"email_from"},{"definition":{"default":"watchdog","description":"Set the fencing mode of the HA cluster. Hardware mode needs a valid configuration of fence devices in /etc/pve/ha/fence.cfg. With both all two modes are used.\n\nWARNING: 'hardware' and 'both' are EXPERIMENTAL & WIP","enum":["watchdog","hardware","both"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"fencing"},{"definition":{"description":"Cluster wide HA settings.","enum":[],"extra":{"typetext":"shutdown_policy="},"format":{"shutdown_policy":{"default":"conditional","description":"The policy for HA services on node shutdown. 'freeze' disables auto-recovery, 'failover' ensures recovery, 'conditional' recovers on poweroff and freezes on reboot. 'migrate' will migrate running services to other nodes, if possible. With 'freeze' or 'failover', HA Services will always get stopped first on shutdown.","enum":["freeze","failover","conditional","migrate"],"type":"string","verbose_description":"Describes the policy for handling HA services on poweroff or reboot of a node. Freeze will always freeze services which are still located on the node on shutdown, those services won't be recovered by the HA manager. Failover will not mark the services as frozen and thus the services will get recovered to other nodes, if the shutdown node does not come up again quickly (< 1min). 'conditional' chooses automatically depending on the type of shutdown, i.e., on a reboot the service will be frozen but on a poweroff the service will stay as is, and thus get recovered after about 2 minutes. Migrate will try to move all running services to another node when a reboot or shutdown was triggered. The poweroff process will only continue once no running services are located on the node anymore. If the node comes up again, the service will be moved back to the previously powered-off node, at least if no other migration, reloaction or recovery took place."}},"optional":true,"properties":{},"type":"string"},"name":"ha"},{"definition":{"description":"Specify external http proxy which is used for downloads (example: 'http://username:password@host:port/')","enum":[],"extra":{},"optional":true,"pattern":"http://.*","properties":{},"type":"string"},"name":"http_proxy"},{"definition":{"description":"Default keybord layout for vnc server.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"keyboard"},{"definition":{"description":"Default GUI language.","enum":["ar","ca","da","de","en","es","eu","fa","fr","hr","he","it","ja","ka","kr","nb","nl","nn","pl","pt_BR","ru","sl","sv","tr","ukr","zh_CN","zh_TW"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"language"},{"definition":{"description":"The location of the cluster.","enum":[],"extra":{"typetext":"latitude= ,longitude= [,name=]"},"format":{"latitude":{"description":"The latitude of the nodes location in degrees.","maximum":90,"minimum":-90,"type":"number"},"longitude":{"description":"The longitude of the nodes location in degrees.","maximum":180,"minimum":-180,"type":"number"},"name":{"description":"The name of the location of this node","maxLength":128,"optional":1,"type":"string","typetext":""}},"optional":true,"properties":{},"type":"string"},"name":"location"},{"definition":{"default":"BC:24:11","description":"Prefix for the auto-generated MAC addresses of virtual guests. The default 'BC:24:11' is the OUI assigned by the IEEE to Proxmox Server Solutions GmbH for a 24-bit large MAC block. You're allowed to use this in local networks, i.e., those not directly reachable by the public (e.g., in a LAN or behind NAT).","enum":[],"extra":{"typetext":"","verbose_description":"Prefix for the auto-generated MAC addresses of virtual guests. The default `BC:24:11` is the Organizationally Unique Identifier (OUI) assigned by the IEEE to Proxmox Server Solutions GmbH for a MAC Address Block Large (MA-L). You're allowed to use this in local networks, i.e., those not directly reachable by the public (e.g., in a LAN or NAT/Masquerading).\n \nNote that when you run multiple cluster that (partially) share the networks of their virtual guests, it's highly recommended that you extend the default MAC prefix, or generate a custom (valid) one, to reduce the chance of MAC collisions. For example, add a separate extra hexadecimal to the Proxmox OUI for each cluster, like `BC:24:11:0` for the first, `BC:24:11:1` for the second, and so on.\n Alternatively, you can also separate the networks of the guests logically, e.g., by using VLANs.\n\nFor publicly accessible guests it's recommended that you get your own https://standards.ieee.org/products-programs/regauth/[OUI from the IEEE] registered or coordinate with your, or your hosting providers, network admins."},"format":"mac-prefix","optional":true,"properties":{},"type":"string"},"name":"mac_prefix"},{"definition":{"description":"Defines how many workers (per node) are maximal started on actions like 'stopall VMs' or task from the ha-manager.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max_workers"},{"definition":{"description":"For cluster wide migration settings.","enum":[],"extra":{"typetext":"[type=] [,network=]"},"format":{"network":{"description":"CIDR of the (sub) network that is used for migration. Used as a fallback for replications jobs if the replication network setting is not set","format":"CIDR","format_description":"CIDR","optional":1,"type":"string"},"type":{"default":"secure","default_key":1,"description":"Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.","enum":["secure","insecure"],"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"migration"},{"definition":{"description":"Migration is secure using SSH tunnel by default. For secure private networks you can disable it to speed up migration. Deprecated, use the 'migration' property instead!","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"migration_unsecure"},{"definition":{"description":"Control the range for the free VMID auto-selection pool.","enum":[],"extra":{"typetext":"[lower=] [,upper=]"},"format":{"lower":{"default":100,"description":"Lower, inclusive boundary for free next-id API range.","max":999999999,"min":100,"optional":1,"type":"integer"},"upper":{"default":1000000,"description":"Upper, exclusive boundary for free next-id API range.","max":1000000000,"min":100,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"next-id"},{"definition":{"description":"Cluster-wide notification settings.","enum":[],"extra":{"typetext":"[fencing=] [,package-updates=] [,replication=] [,target-fencing=] [,target-package-updates=] [,target-replication=]"},"format":{"fencing":{"description":"UNUSED - Use datacenter notification settings instead.","enum":["always","never"],"optional":1,"type":"string"},"package-updates":{"default":"auto","description":"DEPRECATED: Use datacenter notification settings instead. Control when the daily update job should send out notifications.","enum":["auto","always","never"],"optional":1,"type":"string","verbose_description":"DEPRECATED: Use datacenter notification settings instead.\nControl how often the daily update job should send out notifications:\n* 'auto' daily for systems with a valid subscription, as those are assumed to be production-ready and thus should know about pending updates.\n* 'always' every update, if there are new pending updates.\n* 'never' never send a notification for new pending updates.\n"},"replication":{"description":"UNUSED - Use datacenter notification settings instead.","enum":["always","never"],"optional":1,"type":"string"},"target-fencing":{"description":"UNUSED - Use datacenter notification settings instead.","format_description":"TARGET","optional":1,"type":"string"},"target-package-updates":{"description":"UNUSED - Use datacenter notification settings instead.","format_description":"TARGET","optional":1,"type":"string"},"target-replication":{"description":"UNUSED - Use datacenter notification settings instead.","format_description":"TARGET","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"notify"},{"definition":{"description":"A list of tags that require a `Sys.Modify` on '/' to set and delete. Tags set here that are also in 'user-tag-access' also require `Sys.Modify`.","enum":[],"extra":{"typetext":"[;...]"},"optional":true,"pattern":"(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*);)*(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*)","properties":{},"type":"string"},"name":"registered-tags"},{"definition":{"description":"For cluster wide replication settings.","enum":[],"extra":{"typetext":"[type=] [,network=]"},"format":{"network":{"description":"CIDR of the (sub) network that is used for replication jobs.","format":"CIDR","format_description":"CIDR","optional":1,"type":"string"},"type":{"default":"secure","default_key":1,"description":"Replication traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.","enum":["secure","insecure"],"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"replication"},{"definition":{"description":"Tag style options.","enum":[],"extra":{"typetext":"[case-sensitive=<1|0>] [,color-map=:[:][;=...]] [,ordering=] [,shape=]"},"format":{"case-sensitive":{"default":0,"description":"Controls if filtering for unique tags on update should check case-sensitive.","optional":1,"type":"boolean"},"color-map":{"description":"Manual color mapping for tags (semicolon separated).","optional":1,"pattern":"(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*):[0-9a-fA-F]{6}(?::[0-9a-fA-F]{6})?)(?:;(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*):[0-9a-fA-F]{6}(?::[0-9a-fA-F]{6})?))*","type":"string","typetext":":[:][;=...]"},"ordering":{"default":"alphabetical","description":"Controls the sorting of the tags in the web-interface and the API update.","enum":["config","alphabetical"],"optional":1,"type":"string"},"shape":{"default":"circle","description":"Tag shape for the web ui tree. 'full' draws the full tag. 'circle' draws only a circle with the background color. 'dense' only draws a small rectancle (useful when many tags are assigned to each guest).'none' disables showing the tags.","enum":["full","circle","dense","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"tag-style"},{"definition":{"description":"u2f","enum":[],"extra":{"typetext":"[appid=] [,origin=]"},"format":{"appid":{"description":"U2F AppId URL override. Defaults to the origin.","format_description":"APPID","optional":1,"type":"string"},"origin":{"description":"U2F Origin override. Mostly useful for single nodes with a single URL.","format_description":"URL","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"u2f"},{"definition":{"description":"Privilege options for user-settable tags","enum":[],"extra":{"typetext":"[user-allow=] [,user-allow-list=[;...]]"},"format":{"user-allow":{"default":"free","description":"Controls tag usage for users without `Sys.Modify` on `/` by either allowing `none`, a `list`, already `existing` or anything (`free`).","enum":["none","list","existing","free"],"optional":1,"type":"string","verbose_description":"Controls which tags can be set or deleted on resources a user controls (such as guests). Users with the `Sys.Modify` privilege on `/` are alwaysunrestricted.\n* 'none' no tags are usable.\n* 'list' tags from 'user-allow-list' are usable.\n* 'existing' like list, but already existing tags of resources are also usable.\n* 'free' no tag restrictions.\n"},"user-allow-list":{"description":"List of tags users are allowed to set and delete (semicolon separated) for 'user-allow' values 'list' and 'existing'.","optional":1,"pattern":"(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*)(?:;(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*))*","type":"string","typetext":"[;...]"}},"optional":true,"properties":{},"type":"string"},"name":"user-tag-access"},{"definition":{"description":"webauthn configuration","enum":[],"extra":{"typetext":"[allow-subdomains=<1|0>] [,id=] [,origin=] [,rp=]"},"format":{"allow-subdomains":{"default":1,"description":"Whether to allow the origin to be a subdomain, rather than the exact URL.","optional":1,"type":"boolean"},"id":{"description":"Relying party ID. Must be the domain name without protocol, port or location. Changing this *will* break existing credentials.","format_description":"DOMAINNAME","optional":1,"type":"string"},"origin":{"description":"Site origin. Must be a `https://` URL (or `http://localhost`). Should contain the address users type in their browsers to access the web interface. Changing this *may* break existing credentials.","format_description":"URL","optional":1,"type":"string"},"rp":{"description":"Relying party name. Any text identifier. Changing this *may* break existing credentials.","format_description":"RELYING_PARTY","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"webauthn"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"925b4340058bf3c610e19328ced80f80e01e202fe987dbf638c375b9b35d4d8e","description":"Cluster-wide QEMU index","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/qemu"},{"extra":{},"methods":[{"allow_token":true,"checksum":"76350b14e42b65357b03cee311ba434d9ff6f8b8bd305c2bad925431d443b9a5","description":"List of available CPU flags. Currently only implemented for x86_64, returns an empty list for aarch64.","extra":{},"name":"index","parameters":[{"definition":{"default":"kvm","description":"Acceleration type to check node compatibility for.","enum":["kvm","tcg"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"accel"},{"definition":{"description":"Virtual processor architecture. Defaults to the host architecture.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"}],"permissions":{"expression":{"check":["or",["perm","/nodes",["Sys.Audit"]],["perm","/mapping/cpu",["Mapping.Audit","Mapping.Use","Mapping.Modify"],"any",1]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"description":{"description":"Description of the CPU flag.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"Name of the CPU flag.","enum":[],"extra":{},"properties":{},"type":"string"},"supported-on":{"description":"List of nodes supporting the flag with the selected acceleration type (\"accel\").","enum":[],"extra":{},"items":{"description":"The cluster node name.","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/qemu/cpu-flags"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4df94d274578db57a6ca724d362dad806c3662a3a765cd459b615255e21b3a02","description":"List all custom CPU model definitions visible to the user.","extra":{},"name":"config","parameters":[],"permissions":{"description":"Only lists entries where the user has 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/cpu/'.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cputype}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cputype":{"default":"kvm64","description":"Emulated CPU type. Can be default or custom name (custom model names must be prefixed with 'custom-').","enum":[],"extra":{"default_key":1,"format_description":"string"},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"flags":{"description":"List of additional CPU flags separated by ';'. Use '+FLAG' to enable, '-FLAG' to disable a flag. There is a special 'nested-virt' shorthand which controls nested virtualization for the current CPU ('svm' for AMD and 'vmx' for Intel). Custom CPU models can specify any flag supported by QEMU/KVM, VM-specific flags must be from the following set for security reasons: aes, amd-no-ssb, amd-ssbd, hv-evmcs, hv-tlbflush, ibpb, md-clear, nested-virt, pcid, pdpe1gb, spec-ctrl, ssbd, virt-ssbd","enum":[],"extra":{"format_description":"+FLAG[;-FLAG...]"},"optional":true,"pattern":"(?^u:(?^u:([+-])([a-zA-Z0-9\\-_\\.]+))(;(?^u:([+-])([a-zA-Z0-9\\-_\\.]+)))*)","properties":{},"type":"string"},"guest-phys-bits":{"description":"Number of physical address bits available to the guest.","enum":[],"extra":{},"maximum":64,"minimum":32,"optional":true,"properties":{},"type":"integer"},"hidden":{"default":0,"description":"Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"hv-vendor-id":{"description":"The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID.","enum":[],"extra":{"format_description":"vendor-id"},"optional":true,"pattern":"(?^u:[a-zA-Z0-9]{1,12})","properties":{},"type":"string"},"level":{"description":"Maximum input value for the basic CPUID leaves the guest can query - that is the vendor (leaf 0), family/model/stepping and feature bits (leaf 1), cache and topology info (leaves 4 and B), and so on. Higher-numbered leaves are hidden. Setting '30' is a common workaround for Hyper-V boot failures on Windows guests running on recent Intel hosts. Only applies when the vCPU architecture is x86_64.","enum":[],"extra":{},"maximum":4294967295,"minimum":0,"optional":true,"properties":{},"type":"integer"},"phys-bits":{"description":"The physical memory address bits that are reported to the guest OS. Should be smaller or equal to the host's. Set to 'host' to use value from host CPU, but note that doing so will break live migration to CPUs with other values.","enum":[],"extra":{"format_description":"8-64|host"},"format":"pve-phys-bits","optional":true,"properties":{},"type":"string"},"reported-model":{"default":"kvm64","description":"CPU model and vendor to report to the guest. Must be a QEMU/KVM supported model. Only valid for custom CPU model definitions, default models will always report themselves to the guest OS.","enum":["486","a64fx","athlon","Broadwell","Broadwell-IBRS","Broadwell-noTSX","Broadwell-noTSX-IBRS","Cascadelake-Server","Cascadelake-Server-noTSX","Cascadelake-Server-v2","Cascadelake-Server-v4","Cascadelake-Server-v5","ClearwaterForest","ClearwaterForest-v2","ClearwaterForest-v3","Conroe","Cooperlake","Cooperlake-v2","core2duo","coreduo","cortex-a35","cortex-a53","cortex-a55","cortex-a57","cortex-a710","cortex-a72","cortex-a76","cortex-a78ae","DiamondRapids","EPYC","EPYC-Genoa","EPYC-Genoa-v2","EPYC-IBPB","EPYC-Milan","EPYC-Milan-v2","EPYC-Milan-v3","EPYC-Rome","EPYC-Rome-v2","EPYC-Rome-v3","EPYC-Rome-v4","EPYC-Rome-v5","EPYC-Turin","EPYC-v3","EPYC-v4","EPYC-v5","GraniteRapids","GraniteRapids-v2","GraniteRapids-v3","GraniteRapids-v4","GraniteRapids-v5","Haswell","Haswell-IBRS","Haswell-noTSX","Haswell-noTSX-IBRS","host","Icelake-Client","Icelake-Client-noTSX","Icelake-Server","Icelake-Server-noTSX","Icelake-Server-v3","Icelake-Server-v4","Icelake-Server-v5","Icelake-Server-v6","Icelake-Server-v7","IvyBridge","IvyBridge-IBRS","KnightsMill","kvm32","kvm64","max","Nehalem","Nehalem-IBRS","neoverse-n1","neoverse-n2","neoverse-v1","Opteron_G1","Opteron_G2","Opteron_G3","Opteron_G4","Opteron_G5","Penryn","pentium","pentium2","pentium3","phenom","qemu32","qemu64","SandyBridge","SandyBridge-IBRS","SapphireRapids","SapphireRapids-v2","SapphireRapids-v3","SapphireRapids-v4","SapphireRapids-v5","SapphireRapids-v6","SierraForest","SierraForest-v2","SierraForest-v3","SierraForest-v4","SierraForest-v5","Skylake-Client","Skylake-Client-IBRS","Skylake-Client-noTSX-IBRS","Skylake-Client-v4","Skylake-Server","Skylake-Server-IBRS","Skylake-Server-noTSX-IBRS","Skylake-Server-v4","Skylake-Server-v5","Westmere","Westmere-IBRS"],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"0d4a0bf2eb6f4f1b7a4165633ec0118cb68d04d97681f9432969eede93291685","description":"Add a custom CPU model definition.","extra":{},"name":"create","parameters":[{"definition":{"description":"Name for the custom CPU model. The 'custom-' prefix is optional.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"cputype"},{"definition":{"description":"List of additional CPU flags separated by ';'. Use '+FLAG' to enable, '-FLAG' to disable a flag. There is a special 'nested-virt' shorthand which controls nested virtualization for the current CPU ('svm' for AMD and 'vmx' for Intel). Custom CPU models can specify any flag supported by QEMU/KVM, VM-specific flags must be from the following set for security reasons: aes, amd-no-ssb, amd-ssbd, hv-evmcs, hv-tlbflush, ibpb, md-clear, nested-virt, pcid, pdpe1gb, spec-ctrl, ssbd, virt-ssbd","enum":[],"extra":{"format_description":"+FLAG[;-FLAG...]"},"optional":true,"pattern":"(?^u:(?^u:([+-])([a-zA-Z0-9\\-_\\.]+))(;(?^u:([+-])([a-zA-Z0-9\\-_\\.]+)))*)","properties":{},"type":"string"},"name":"flags"},{"definition":{"description":"Number of physical address bits available to the guest.","enum":[],"extra":{"typetext":" (32 - 64)"},"maximum":64,"minimum":32,"optional":true,"properties":{},"type":"integer"},"name":"guest-phys-bits"},{"definition":{"default":0,"description":"Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"hidden"},{"definition":{"description":"The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID.","enum":[],"extra":{"format_description":"vendor-id"},"optional":true,"pattern":"(?^u:[a-zA-Z0-9]{1,12})","properties":{},"type":"string"},"name":"hv-vendor-id"},{"definition":{"description":"Maximum input value for the basic CPUID leaves the guest can query - that is the vendor (leaf 0), family/model/stepping and feature bits (leaf 1), cache and topology info (leaves 4 and B), and so on. Higher-numbered leaves are hidden. Setting '30' is a common workaround for Hyper-V boot failures on Windows guests running on recent Intel hosts. Only applies when the vCPU architecture is x86_64.","enum":[],"extra":{"typetext":" (0 - 4294967295)"},"maximum":4294967295,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"level"},{"definition":{"description":"The physical memory address bits that are reported to the guest OS. Should be smaller or equal to the host's. Set to 'host' to use value from host CPU, but note that doing so will break live migration to CPUs with other values.","enum":[],"extra":{"format_description":"8-64|host","typetext":"<8-64|host>"},"format":"pve-phys-bits","optional":true,"properties":{},"type":"string"},"name":"phys-bits"},{"definition":{"default":"kvm64","description":"CPU model and vendor to report to the guest. Must be a QEMU/KVM supported model. Only valid for custom CPU model definitions, default models will always report themselves to the guest OS.","enum":["486","a64fx","athlon","Broadwell","Broadwell-IBRS","Broadwell-noTSX","Broadwell-noTSX-IBRS","Cascadelake-Server","Cascadelake-Server-noTSX","Cascadelake-Server-v2","Cascadelake-Server-v4","Cascadelake-Server-v5","ClearwaterForest","ClearwaterForest-v2","ClearwaterForest-v3","Conroe","Cooperlake","Cooperlake-v2","core2duo","coreduo","cortex-a35","cortex-a53","cortex-a55","cortex-a57","cortex-a710","cortex-a72","cortex-a76","cortex-a78ae","DiamondRapids","EPYC","EPYC-Genoa","EPYC-Genoa-v2","EPYC-IBPB","EPYC-Milan","EPYC-Milan-v2","EPYC-Milan-v3","EPYC-Rome","EPYC-Rome-v2","EPYC-Rome-v3","EPYC-Rome-v4","EPYC-Rome-v5","EPYC-Turin","EPYC-v3","EPYC-v4","EPYC-v5","GraniteRapids","GraniteRapids-v2","GraniteRapids-v3","GraniteRapids-v4","GraniteRapids-v5","Haswell","Haswell-IBRS","Haswell-noTSX","Haswell-noTSX-IBRS","host","Icelake-Client","Icelake-Client-noTSX","Icelake-Server","Icelake-Server-noTSX","Icelake-Server-v3","Icelake-Server-v4","Icelake-Server-v5","Icelake-Server-v6","Icelake-Server-v7","IvyBridge","IvyBridge-IBRS","KnightsMill","kvm32","kvm64","max","Nehalem","Nehalem-IBRS","neoverse-n1","neoverse-n2","neoverse-v1","Opteron_G1","Opteron_G2","Opteron_G3","Opteron_G4","Opteron_G5","Penryn","pentium","pentium2","pentium3","phenom","qemu32","qemu64","SandyBridge","SandyBridge-IBRS","SapphireRapids","SapphireRapids-v2","SapphireRapids-v3","SapphireRapids-v4","SapphireRapids-v5","SapphireRapids-v6","SierraForest","SierraForest-v2","SierraForest-v3","SierraForest-v4","SierraForest-v5","Skylake-Client","Skylake-Client-IBRS","Skylake-Client-noTSX-IBRS","Skylake-Client-v4","Skylake-Server","Skylake-Server-IBRS","Skylake-Server-noTSX-IBRS","Skylake-Server-v4","Skylake-Server-v5","Westmere","Westmere-IBRS"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"reported-model"}],"permissions":{"expression":{"check":["perm","/mapping/cpu",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/qemu/custom-cpu-models"},{"extra":{},"methods":[{"allow_token":true,"checksum":"592ae7fce9cb920c3d1ca518e752b07861a44391a1b197acfdc2f9dab9fec1e7","description":"Delete a custom CPU model definition.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The custom model to delete. The 'custom-' prefix is optional.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"cputype"}],"permissions":{"expression":{"check":["perm","/mapping/cpu/{cputype}",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"07ede1de12f108a83d27a4c5399b55dd3d9c06d93c5e33339187fc4032255ff5","description":"Retrieve details about a specific custom CPU model.","extra":{},"name":"info","parameters":[{"definition":{"description":"Name of the CPU model to query. The 'custom-' prefix is optional.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"cputype"}],"permissions":{"expression":{"check":["or",["perm","/mapping/cpu/{cputype}",["Mapping.Audit"]],["perm","/mapping/cpu/{cputype}",["Mapping.Use"]],["perm","/mapping/cpu/{cputype}",["Mapping.Modify"]]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"cputype":{"default":"kvm64","description":"Emulated CPU type. Can be default or custom name (custom model names must be prefixed with 'custom-').","enum":[],"extra":{"default_key":1,"format_description":"string"},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"flags":{"description":"List of additional CPU flags separated by ';'. Use '+FLAG' to enable, '-FLAG' to disable a flag. There is a special 'nested-virt' shorthand which controls nested virtualization for the current CPU ('svm' for AMD and 'vmx' for Intel). Custom CPU models can specify any flag supported by QEMU/KVM, VM-specific flags must be from the following set for security reasons: aes, amd-no-ssb, amd-ssbd, hv-evmcs, hv-tlbflush, ibpb, md-clear, nested-virt, pcid, pdpe1gb, spec-ctrl, ssbd, virt-ssbd","enum":[],"extra":{"format_description":"+FLAG[;-FLAG...]"},"optional":true,"pattern":"(?^u:(?^u:([+-])([a-zA-Z0-9\\-_\\.]+))(;(?^u:([+-])([a-zA-Z0-9\\-_\\.]+)))*)","properties":{},"type":"string"},"guest-phys-bits":{"description":"Number of physical address bits available to the guest.","enum":[],"extra":{},"maximum":64,"minimum":32,"optional":true,"properties":{},"type":"integer"},"hidden":{"default":0,"description":"Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"hv-vendor-id":{"description":"The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID.","enum":[],"extra":{"format_description":"vendor-id"},"optional":true,"pattern":"(?^u:[a-zA-Z0-9]{1,12})","properties":{},"type":"string"},"level":{"description":"Maximum input value for the basic CPUID leaves the guest can query - that is the vendor (leaf 0), family/model/stepping and feature bits (leaf 1), cache and topology info (leaves 4 and B), and so on. Higher-numbered leaves are hidden. Setting '30' is a common workaround for Hyper-V boot failures on Windows guests running on recent Intel hosts. Only applies when the vCPU architecture is x86_64.","enum":[],"extra":{},"maximum":4294967295,"minimum":0,"optional":true,"properties":{},"type":"integer"},"phys-bits":{"description":"The physical memory address bits that are reported to the guest OS. Should be smaller or equal to the host's. Set to 'host' to use value from host CPU, but note that doing so will break live migration to CPUs with other values.","enum":[],"extra":{"format_description":"8-64|host"},"format":"pve-phys-bits","optional":true,"properties":{},"type":"string"},"reported-model":{"default":"kvm64","description":"CPU model and vendor to report to the guest. Must be a QEMU/KVM supported model. Only valid for custom CPU model definitions, default models will always report themselves to the guest OS.","enum":["486","a64fx","athlon","Broadwell","Broadwell-IBRS","Broadwell-noTSX","Broadwell-noTSX-IBRS","Cascadelake-Server","Cascadelake-Server-noTSX","Cascadelake-Server-v2","Cascadelake-Server-v4","Cascadelake-Server-v5","ClearwaterForest","ClearwaterForest-v2","ClearwaterForest-v3","Conroe","Cooperlake","Cooperlake-v2","core2duo","coreduo","cortex-a35","cortex-a53","cortex-a55","cortex-a57","cortex-a710","cortex-a72","cortex-a76","cortex-a78ae","DiamondRapids","EPYC","EPYC-Genoa","EPYC-Genoa-v2","EPYC-IBPB","EPYC-Milan","EPYC-Milan-v2","EPYC-Milan-v3","EPYC-Rome","EPYC-Rome-v2","EPYC-Rome-v3","EPYC-Rome-v4","EPYC-Rome-v5","EPYC-Turin","EPYC-v3","EPYC-v4","EPYC-v5","GraniteRapids","GraniteRapids-v2","GraniteRapids-v3","GraniteRapids-v4","GraniteRapids-v5","Haswell","Haswell-IBRS","Haswell-noTSX","Haswell-noTSX-IBRS","host","Icelake-Client","Icelake-Client-noTSX","Icelake-Server","Icelake-Server-noTSX","Icelake-Server-v3","Icelake-Server-v4","Icelake-Server-v5","Icelake-Server-v6","Icelake-Server-v7","IvyBridge","IvyBridge-IBRS","KnightsMill","kvm32","kvm64","max","Nehalem","Nehalem-IBRS","neoverse-n1","neoverse-n2","neoverse-v1","Opteron_G1","Opteron_G2","Opteron_G3","Opteron_G4","Opteron_G5","Penryn","pentium","pentium2","pentium3","phenom","qemu32","qemu64","SandyBridge","SandyBridge-IBRS","SapphireRapids","SapphireRapids-v2","SapphireRapids-v3","SapphireRapids-v4","SapphireRapids-v5","SapphireRapids-v6","SierraForest","SierraForest-v2","SierraForest-v3","SierraForest-v4","SierraForest-v5","Skylake-Client","Skylake-Client-IBRS","Skylake-Client-noTSX-IBRS","Skylake-Client-v4","Skylake-Server","Skylake-Server-IBRS","Skylake-Server-noTSX-IBRS","Skylake-Server-v4","Skylake-Server-v5","Westmere","Westmere-IBRS"],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"a5ea71be68918ebe821538f532287a17b375ff9f9404b26fbdd55165a9693e33","description":"Update a custom CPU model definition.","extra":{},"name":"update","parameters":[{"definition":{"description":"Name for the custom CPU model. The 'custom-' prefix is optional.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"cputype"},{"definition":{"description":"A list of properties to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"List of additional CPU flags separated by ';'. Use '+FLAG' to enable, '-FLAG' to disable a flag. There is a special 'nested-virt' shorthand which controls nested virtualization for the current CPU ('svm' for AMD and 'vmx' for Intel). Custom CPU models can specify any flag supported by QEMU/KVM, VM-specific flags must be from the following set for security reasons: aes, amd-no-ssb, amd-ssbd, hv-evmcs, hv-tlbflush, ibpb, md-clear, nested-virt, pcid, pdpe1gb, spec-ctrl, ssbd, virt-ssbd","enum":[],"extra":{"format_description":"+FLAG[;-FLAG...]"},"optional":true,"pattern":"(?^u:(?^u:([+-])([a-zA-Z0-9\\-_\\.]+))(;(?^u:([+-])([a-zA-Z0-9\\-_\\.]+)))*)","properties":{},"type":"string"},"name":"flags"},{"definition":{"description":"Number of physical address bits available to the guest.","enum":[],"extra":{"typetext":" (32 - 64)"},"maximum":64,"minimum":32,"optional":true,"properties":{},"type":"integer"},"name":"guest-phys-bits"},{"definition":{"default":0,"description":"Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"hidden"},{"definition":{"description":"The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID.","enum":[],"extra":{"format_description":"vendor-id"},"optional":true,"pattern":"(?^u:[a-zA-Z0-9]{1,12})","properties":{},"type":"string"},"name":"hv-vendor-id"},{"definition":{"description":"Maximum input value for the basic CPUID leaves the guest can query - that is the vendor (leaf 0), family/model/stepping and feature bits (leaf 1), cache and topology info (leaves 4 and B), and so on. Higher-numbered leaves are hidden. Setting '30' is a common workaround for Hyper-V boot failures on Windows guests running on recent Intel hosts. Only applies when the vCPU architecture is x86_64.","enum":[],"extra":{"typetext":" (0 - 4294967295)"},"maximum":4294967295,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"level"},{"definition":{"description":"The physical memory address bits that are reported to the guest OS. Should be smaller or equal to the host's. Set to 'host' to use value from host CPU, but note that doing so will break live migration to CPUs with other values.","enum":[],"extra":{"format_description":"8-64|host","typetext":"<8-64|host>"},"format":"pve-phys-bits","optional":true,"properties":{},"type":"string"},"name":"phys-bits"},{"definition":{"default":"kvm64","description":"CPU model and vendor to report to the guest. Must be a QEMU/KVM supported model. Only valid for custom CPU model definitions, default models will always report themselves to the guest OS.","enum":["486","a64fx","athlon","Broadwell","Broadwell-IBRS","Broadwell-noTSX","Broadwell-noTSX-IBRS","Cascadelake-Server","Cascadelake-Server-noTSX","Cascadelake-Server-v2","Cascadelake-Server-v4","Cascadelake-Server-v5","ClearwaterForest","ClearwaterForest-v2","ClearwaterForest-v3","Conroe","Cooperlake","Cooperlake-v2","core2duo","coreduo","cortex-a35","cortex-a53","cortex-a55","cortex-a57","cortex-a710","cortex-a72","cortex-a76","cortex-a78ae","DiamondRapids","EPYC","EPYC-Genoa","EPYC-Genoa-v2","EPYC-IBPB","EPYC-Milan","EPYC-Milan-v2","EPYC-Milan-v3","EPYC-Rome","EPYC-Rome-v2","EPYC-Rome-v3","EPYC-Rome-v4","EPYC-Rome-v5","EPYC-Turin","EPYC-v3","EPYC-v4","EPYC-v5","GraniteRapids","GraniteRapids-v2","GraniteRapids-v3","GraniteRapids-v4","GraniteRapids-v5","Haswell","Haswell-IBRS","Haswell-noTSX","Haswell-noTSX-IBRS","host","Icelake-Client","Icelake-Client-noTSX","Icelake-Server","Icelake-Server-noTSX","Icelake-Server-v3","Icelake-Server-v4","Icelake-Server-v5","Icelake-Server-v6","Icelake-Server-v7","IvyBridge","IvyBridge-IBRS","KnightsMill","kvm32","kvm64","max","Nehalem","Nehalem-IBRS","neoverse-n1","neoverse-n2","neoverse-v1","Opteron_G1","Opteron_G2","Opteron_G3","Opteron_G4","Opteron_G5","Penryn","pentium","pentium2","pentium3","phenom","qemu32","qemu64","SandyBridge","SandyBridge-IBRS","SapphireRapids","SapphireRapids-v2","SapphireRapids-v3","SapphireRapids-v4","SapphireRapids-v5","SapphireRapids-v6","SierraForest","SierraForest-v2","SierraForest-v3","SierraForest-v4","SierraForest-v5","Skylake-Client","Skylake-Client-IBRS","Skylake-Client-noTSX-IBRS","Skylake-Client-v4","Skylake-Server","Skylake-Server-IBRS","Skylake-Server-noTSX-IBRS","Skylake-Server-v4","Skylake-Server-v5","Westmere","Westmere-IBRS"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"reported-model"}],"permissions":{"expression":{"check":["perm","/mapping/cpu/{cputype}",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/qemu/custom-cpu-models/{cputype}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"076bc2dda60f340f3091579e729d441ffdd296de86aea80acf5068d96272dad0","description":"List replication jobs.","extra":{},"name":"index","parameters":[],"permissions":{"description":"Will only return replication jobs for which the calling user has VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"Description.","enum":[],"extra":{},"max_length":4096,"optional":true,"properties":{},"type":"string"},"disable":{"description":"Flag to disable/deactivate the entry.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"guest":{"description":"Guest ID.","enum":[],"extra":{},"properties":{},"type":"integer"},"id":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"jobnum":{"description":"Unique, sequential ID assigned to each job.","enum":[],"extra":{},"properties":{},"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"number"},"remove_job":{"description":"Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.","enum":["local","full"],"extra":{},"optional":true,"properties":{},"type":"string"},"schedule":{"default":"*/15","description":"Storage replication schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"source":{"description":"For internal use, to detect if the guest was stolen.","enum":[],"extra":{},"format":"pve-node","optional":true,"properties":{},"type":"string"},"target":{"description":"Target node.","enum":[],"extra":{},"format":"pve-node","optional":false,"properties":{},"type":"string"},"type":{"description":"Section type.","enum":["local"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"9e432563196e21cb79550d1da12b0fbcf5df9eba941dc9efa98bc0773809aad8","description":"Create a new replication job","extra":{},"name":"create","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Flag to disable/deactivate the entry.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"number"},"name":"rate"},{"definition":{"description":"Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.","enum":["local","full"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"remove_job"},{"definition":{"default":"*/15","description":"Storage replication schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"For internal use, to detect if the guest was stolen.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":false,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Section type.","enum":["local"],"extra":{},"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Requires the VM.Replicate permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/replication"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7e89c06d2829ef53470f82ac499587139047570d28007e73d590c1fa1ff88a64","description":"Mark replication job for removal.","extra":{},"name":"delete","parameters":[{"definition":{"default":0,"description":"Will remove the jobconfig entry, but will not cleanup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"default":0,"description":"Keep replicated data at target (do not remove).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keep"}],"permissions":{"description":"Requires the VM.Replicate permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"c10be12f8ffe19218fc1ba2749204d62e834058923bd8aaeba61e650a4a0bf84","description":"Read replication job configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"}],"permissions":{"description":"Requires the VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"comment":{"description":"Description.","enum":[],"extra":{},"max_length":4096,"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"disable":{"description":"Flag to disable/deactivate the entry.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"guest":{"description":"Guest ID.","enum":[],"extra":{},"properties":{},"type":"integer"},"id":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"jobnum":{"description":"Unique, sequential ID assigned to each job.","enum":[],"extra":{},"properties":{},"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"number"},"remove_job":{"description":"Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.","enum":["local","full"],"extra":{},"optional":true,"properties":{},"type":"string"},"schedule":{"default":"*/15","description":"Storage replication schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"source":{"description":"For internal use, to detect if the guest was stolen.","enum":[],"extra":{},"format":"pve-node","optional":true,"properties":{},"type":"string"},"target":{"description":"Target node.","enum":[],"extra":{},"format":"pve-node","optional":false,"properties":{},"type":"string"},"type":{"description":"Section type.","enum":["local"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"079c3b7310f65dc0cbd566ab34f95b5ca0bd303ba46d95780f165ac027f8a670","description":"Update replication job configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Flag to disable/deactivate the entry.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"number"},"name":"rate"},{"definition":{"description":"Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.","enum":["local","full"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"remove_job"},{"definition":{"default":"*/15","description":"Storage replication schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"For internal use, to detect if the guest was stolen.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"source"}],"permissions":{"description":"Requires the VM.Replicate permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/replication/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"279d56e88b77c07abe53f1c50a7e25bc058be232e6d62dbe106266c10a2049dc","description":"Resources index (cluster wide).","extra":{},"name":"resources","parameters":[{"definition":{"description":"Resource type.","enum":["vm","storage","node","sdn"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"cgroup-mode":{"description":"The cgroup mode the node operates under (for type 'node').","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"content":{"description":"Allowed storage content types (for type 'storage').","enum":[],"extra":{},"format":"pve-storage-content-list","optional":true,"properties":{},"type":"string"},"cpu":{"description":"CPU utilization (for types 'node', 'qemu' and 'lxc').","enum":[],"extra":{"renderer":"fraction_as_percentage"},"minimum":0,"optional":true,"properties":{},"type":"number"},"disk":{"description":"Used disk space in bytes (for type 'storage'), used root image space for VMs (for types 'qemu' and 'lxc').","enum":[],"extra":{"renderer":"bytes"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"diskread":{"description":"The number of bytes the guest read from its block devices since the guest was started. This info is not available for all storage types. (for types 'qemu' and 'lxc')","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"diskwrite":{"description":"The number of bytes the guest wrote to its block devices since the guest was started. This info is not available for all storage types. (for types 'qemu' and 'lxc')","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"hastate":{"description":"HA service status (for HA managed VMs).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"host-arch":{"default":"x86_64","description":"The node's CPU architecture. (for type 'node').","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"description":"Resource id.","enum":[],"extra":{},"properties":{},"type":"string"},"level":{"description":"Support level (for type 'node').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"lock":{"description":"The guest's current config lock (for types 'qemu' and 'lxc')","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxcpu":{"description":"Number of available CPUs (for types 'node', 'qemu' and 'lxc').","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"number"},"maxdisk":{"description":"Storage size in bytes (for type 'storage'), root image size for VMs (for types 'qemu' and 'lxc').","enum":[],"extra":{"renderer":"bytes"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Number of available memory in bytes (for types 'node', 'qemu' and 'lxc').","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"mem":{"description":"Used memory in bytes (for types 'node', 'qemu' and 'lxc').","enum":[],"extra":{"renderer":"bytes"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"memhost":{"description":"Used memory in bytes from the point of view of the host (for types 'qemu').","enum":[],"extra":{"renderer":"bytes"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":{"description":"Name of the resource.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"netin":{"description":"The amount of traffic in bytes that was sent to the guest over the network since it was started. (for types 'qemu' and 'lxc')","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"netout":{"description":"The amount of traffic in bytes that was sent from the guest over the network since it was started. (for types 'qemu' and 'lxc')","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"network":{"description":"The name of a Network entity (for type 'network').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"network-type":{"description":"The type of network resource (for type 'network').","enum":["fabric","zone"],"extra":{},"optional":true,"properties":{},"type":"string"},"node":{"description":"The cluster node name (for types 'node', 'storage', 'qemu', and 'lxc').","enum":[],"extra":{},"format":"pve-node","optional":true,"properties":{},"type":"string"},"plugintype":{"description":"More specific type, if available.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pool":{"description":"The pool name (for types 'pool', 'qemu' and 'lxc').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"protocol":{"description":"The protocol of a fabric (for type 'network', network-type 'fabric').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sdn":{"description":"The name of an SDN entity (for type 'sdn')","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"shared":{"description":"Determines whether the storage is shared","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"status":{"description":"Resource type dependent status.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"storage":{"description":"The storage identifier (for type 'storage').","enum":[],"extra":{"format_description":"storage ID"},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"tags":{"description":"The guest's tags (for types 'qemu' and 'lxc')","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"template":{"default":0,"description":"Determines if the guest is a template. (for types 'qemu' and 'lxc')","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"type":{"description":"Resource type.","enum":["node","storage","pool","qemu","lxc","openvz","sdn","network"],"extra":{},"properties":{},"type":"string"},"uptime":{"description":"Uptime of node or virtual guest in seconds (for types 'node', 'qemu' and 'lxc').","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The numerical vmid (for types 'qemu' and 'lxc').","enum":[],"extra":{},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"zone-type":{"description":"The type of an SDN zone (for type 'sdn').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/resources"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e55fa302d4424ac9e45c59566aeab35b6fd2029e23076095e6a3fc7845483050","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/sdn",["SDN.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"11960045172b324afe33248e873c0c9fbcc5d3e2a61d4bbe51dc4c2634d049ec","description":"Apply sdn controller changes && reload.","extra":{},"name":"reload","parameters":[{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"default":1,"description":"When lock-token has been provided and configuration successfully committed, release the lock automatically afterwards","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"release-lock"}],"permissions":{"expression":{"check":["perm","/sdn",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/cluster/sdn"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3f0b36447466aa01a420de45dc01371ad9819a5edd9a642331e2f95a77bc725c","description":"SDN controllers index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"Only list sdn controllers of specific type","enum":["bgp","evpn","faucet","isis"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/controllers/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{controller}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"asn":{"description":"The local ASN of the controller. BGP & EVPN only.","enum":[],"extra":{},"maximum":4294967295,"minimum":0,"optional":true,"properties":{},"type":"integer"},"bgp-mode":{"default":"auto","description":"Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP.","enum":["auto","external","internal"],"extra":{},"optional":true,"properties":{},"type":"string"},"bgp-multipath-as-relax":{"description":"Consider different AS paths of equal length for multipath computation. BGP only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"controller":{"description":"Name of the controller.","enum":[],"extra":{},"properties":{},"type":"string"},"digest":{"description":"Digest of the controller section.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ebgp":{"description":"Enable eBGP (remote-as external). BGP only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ebgp-multihop":{"description":"Set maximum amount of hops for eBGP peers. Needs ebgp set to 1. BGP only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"isis-domain":{"description":"Name of the IS-IS domain. IS-IS only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"isis-ifaces":{"description":"Comma-separated list of interfaces where IS-IS should be active. IS-IS only.","enum":[],"extra":{},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"isis-net":{"description":"Network Entity title for this node in the IS-IS network. IS-IS only.","enum":[],"extra":{},"format":"pve-sdn-isis-net","optional":true,"properties":{},"type":"string"},"loopback":{"description":"Name of the loopback/dummy interface that provides the Router-IP. BGP only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"node":{"description":"Node(s) where this controller is active.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"nodes":{"description":"List of cluster node names.","enum":[],"extra":{},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"peer-group-name":{"description":"Name of the peer group for this EVPN controller","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"peers":{"description":"Comma-separated list of the peers IP addresses.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pending":{"description":"Changes that have not yet been applied to the running configuration.","enum":[],"extra":{},"optional":true,"properties":{"asn":{"description":"The local ASN of the controller. BGP & EVPN only.","enum":[],"extra":{},"maximum":4294967295,"minimum":0,"optional":true,"properties":{},"type":"integer"},"bgp-mode":{"default":"auto","description":"Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP.","enum":["auto","external","internal"],"extra":{},"optional":true,"properties":{},"type":"string"},"bgp-multipath-as-relax":{"description":"Consider different AS paths of equal length for multipath computation. BGP only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ebgp":{"description":"Enable eBGP (remote-as external). BGP only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ebgp-multihop":{"description":"Set maximum amount of hops for eBGP peers. Needs ebgp set to 1. BGP only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"isis-domain":{"description":"Name of the IS-IS domain. IS-IS only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"isis-ifaces":{"description":"Comma-separated list of interfaces where IS-IS should be active. IS-IS only.","enum":[],"extra":{},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"isis-net":{"description":"Network Entity title for this node in the IS-IS network. IS-IS only.","enum":[],"extra":{},"format":"pve-sdn-isis-net","optional":true,"properties":{},"type":"string"},"loopback":{"description":"Name of the loopback/dummy interface that provides the Router-IP. BGP only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"node":{"description":"Node(s) where this controller is active.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"nodes":{"description":"List of cluster node names.","enum":[],"extra":{},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"peer-group-name":{"description":"Name of the peer group for this EVPN controller","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"peers":{"description":"Comma-separated list of the peers IP addresses.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"state":{"description":"State of the SDN configuration object.","enum":["new","changed","deleted"],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Type of the controller","enum":["bgp","evpn","faucet","isis"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"6a7b79e5e3ccda1853f2331d3e7851895a05b4b063e6c1b77c1c1c2f5b03087a","description":"Create a new sdn controller object.","extra":{},"name":"create","parameters":[{"definition":{"description":"autonomous system number","enum":[],"extra":{"typetext":" (0 - 4294967295)"},"maximum":4294967295,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"asn"},{"definition":{"default":"auto","description":"Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP.","enum":["auto","external","internal"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bgp-mode"},{"definition":{"description":"Consider different AS paths of equal length for multipath computation.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bgp-multipath-as-path-relax"},{"definition":{"description":"The SDN controller object identifier.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"Enable eBGP (remote-as external).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ebgp"},{"definition":{"description":"Set maximum amount of hops for eBGP peers.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"ebgp-multihop"},{"definition":{"description":"SDN fabric to use as underlay for this EVPN controller.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-fabric-id","optional":true,"properties":{},"type":"string"},"name":"fabric"},{"definition":{"description":"Name of the IS-IS domain.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"isis-domain"},{"definition":{"description":"Comma-separated list of interfaces where IS-IS should be active.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"isis-ifaces"},{"definition":{"description":"Network Entity title for this node in the IS-IS network.","enum":[],"extra":{},"format":"pve-sdn-isis-net","max_length":50,"min_length":20,"optional":true,"pattern":"[a-fA-F0-9]{2}(\\.[a-fA-F0-9]{4}){3,9}\\.[a-fA-F0-9]{2}","properties":{},"type":"string"},"name":"isis-net"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"description":"Name of the loopback/dummy interface that provides the Router-IP.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"loopback"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"default":"VTEP","description":"Name of the peer group for this EVPN controller","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"peer-group-name"},{"definition":{"description":"peers address list.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"peers"},{"definition":{"description":"Route Map that should be applied for incoming routes","enum":[],"extra":{"typetext":""},"format":"pve-sdn-route-map-id","optional":true,"properties":{},"type":"string"},"name":"route-map-in"},{"definition":{"description":"Route Map that should be applied for outgoing routes","enum":[],"extra":{"typetext":""},"format":"pve-sdn-route-map-id","optional":true,"properties":{},"type":"string"},"name":"route-map-out"},{"definition":{"description":"Plugin type.","enum":["bgp","evpn","faucet","isis"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/sdn/controllers",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/controllers"},{"extra":{},"methods":[{"allow_token":true,"checksum":"18aa0a3569a243319fd36951ceef450ba0dbee9098cc7a5892ad6b946c2b014c","description":"Delete sdn controller object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN controller object identifier.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"}],"permissions":{"expression":{"check":["perm","/sdn/controllers",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"68b0bc4e7de17e92b8849f075b0b3019c2a1afccdb590c736cd7c10231920ebc","description":"Read sdn controller configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The SDN controller object identifier.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"}],"permissions":{"expression":{"check":["perm","/sdn/controllers/{controller}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"asn":{"description":"The local ASN of the controller. BGP & EVPN only.","enum":[],"extra":{},"maximum":4294967295,"minimum":0,"optional":true,"properties":{},"type":"integer"},"bgp-mode":{"default":"auto","description":"Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP.","enum":["auto","external","internal"],"extra":{},"optional":true,"properties":{},"type":"string"},"bgp-multipath-as-relax":{"description":"Consider different AS paths of equal length for multipath computation. BGP only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"controller":{"description":"Name of the controller.","enum":[],"extra":{},"properties":{},"type":"string"},"digest":{"description":"Digest of the controller section.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ebgp":{"description":"Enable eBGP (remote-as external). BGP only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ebgp-multihop":{"description":"Set maximum amount of hops for eBGP peers. Needs ebgp set to 1. BGP only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"isis-domain":{"description":"Name of the IS-IS domain. IS-IS only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"isis-ifaces":{"description":"Comma-separated list of interfaces where IS-IS should be active. IS-IS only.","enum":[],"extra":{},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"isis-net":{"description":"Network Entity title for this node in the IS-IS network. IS-IS only.","enum":[],"extra":{},"format":"pve-sdn-isis-net","optional":true,"properties":{},"type":"string"},"loopback":{"description":"Name of the loopback/dummy interface that provides the Router-IP. BGP only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"node":{"description":"Node(s) where this controller is active.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"nodes":{"description":"List of cluster node names.","enum":[],"extra":{},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"peer-group-name":{"description":"Name of the peer group for this EVPN controller","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"peers":{"description":"Comma-separated list of the peers IP addresses.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pending":{"description":"Changes that have not yet been applied to the running configuration.","enum":[],"extra":{},"optional":true,"properties":{"asn":{"description":"The local ASN of the controller. BGP & EVPN only.","enum":[],"extra":{},"maximum":4294967295,"minimum":0,"optional":true,"properties":{},"type":"integer"},"bgp-mode":{"default":"auto","description":"Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP.","enum":["auto","external","internal"],"extra":{},"optional":true,"properties":{},"type":"string"},"bgp-multipath-as-relax":{"description":"Consider different AS paths of equal length for multipath computation. BGP only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ebgp":{"description":"Enable eBGP (remote-as external). BGP only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ebgp-multihop":{"description":"Set maximum amount of hops for eBGP peers. Needs ebgp set to 1. BGP only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"isis-domain":{"description":"Name of the IS-IS domain. IS-IS only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"isis-ifaces":{"description":"Comma-separated list of interfaces where IS-IS should be active. IS-IS only.","enum":[],"extra":{},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"isis-net":{"description":"Network Entity title for this node in the IS-IS network. IS-IS only.","enum":[],"extra":{},"format":"pve-sdn-isis-net","optional":true,"properties":{},"type":"string"},"loopback":{"description":"Name of the loopback/dummy interface that provides the Router-IP. BGP only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"node":{"description":"Node(s) where this controller is active.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"nodes":{"description":"List of cluster node names.","enum":[],"extra":{},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"peer-group-name":{"description":"Name of the peer group for this EVPN controller","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"peers":{"description":"Comma-separated list of the peers IP addresses.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"state":{"description":"State of the SDN configuration object.","enum":["new","changed","deleted"],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Type of the controller","enum":["bgp","evpn","faucet","isis"],"extra":{},"properties":{},"type":"string"}}},"verb":"GET"},{"allow_token":true,"checksum":"1ea743aee5962ec4b09a0687c654ef34475a08dcb3cda17f9578c27c3c29823d","description":"Update sdn controller object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"autonomous system number","enum":[],"extra":{"typetext":" (0 - 4294967295)"},"maximum":4294967295,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"asn"},{"definition":{"default":"auto","description":"Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP.","enum":["auto","external","internal"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bgp-mode"},{"definition":{"description":"Consider different AS paths of equal length for multipath computation.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bgp-multipath-as-path-relax"},{"definition":{"description":"The SDN controller object identifier.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Enable eBGP (remote-as external).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ebgp"},{"definition":{"description":"Set maximum amount of hops for eBGP peers.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"ebgp-multihop"},{"definition":{"description":"SDN fabric to use as underlay for this EVPN controller.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-fabric-id","optional":true,"properties":{},"type":"string"},"name":"fabric"},{"definition":{"description":"Name of the IS-IS domain.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"isis-domain"},{"definition":{"description":"Comma-separated list of interfaces where IS-IS should be active.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"isis-ifaces"},{"definition":{"description":"Network Entity title for this node in the IS-IS network.","enum":[],"extra":{},"format":"pve-sdn-isis-net","max_length":50,"min_length":20,"optional":true,"pattern":"[a-fA-F0-9]{2}(\\.[a-fA-F0-9]{4}){3,9}\\.[a-fA-F0-9]{2}","properties":{},"type":"string"},"name":"isis-net"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"description":"Name of the loopback/dummy interface that provides the Router-IP.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"loopback"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"default":"VTEP","description":"Name of the peer group for this EVPN controller","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"peer-group-name"},{"definition":{"description":"peers address list.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"peers"},{"definition":{"description":"Route Map that should be applied for incoming routes","enum":[],"extra":{"typetext":""},"format":"pve-sdn-route-map-id","optional":true,"properties":{},"type":"string"},"name":"route-map-in"},{"definition":{"description":"Route Map that should be applied for outgoing routes","enum":[],"extra":{"typetext":""},"format":"pve-sdn-route-map-id","optional":true,"properties":{},"type":"string"},"name":"route-map-out"}],"permissions":{"expression":{"check":["perm","/sdn/controllers",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/controllers/{controller}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"eb447be7b8deba4c48a26dec0552342de4afd2b7ed9b023f63bf59e8a899344a","description":"SDN dns index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list sdn dns of specific type","enum":["powerdns"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/dns/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{dns}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"dns":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"1604c210635447e28c41112904490638a282c9698a1526939597f9a2eb685048","description":"Create a new sdn dns object.","extra":{},"name":"create","parameters":[{"definition":{"description":"The SDN dns object identifier.","enum":[],"extra":{},"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"dns"},{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":false,"properties":{},"type":"string"},"name":"key"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"reversemaskv6"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"reversev6mask"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"ttl"},{"definition":{"description":"Plugin type.","enum":["powerdns"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":false,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["perm","/sdn/dns",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/dns"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1a40dcd9bb9d1406780021887831b98570555364892298fc9966c7d777e0208c","description":"Delete sdn dns object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN dns object identifier.","enum":[],"extra":{},"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"dns"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"}],"permissions":{"expression":{"check":["perm","/sdn/dns",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"a4f374e24198d7f8d008cddc3e7d955fd8f4ed8007df92fe9e29dda34efb69ba","description":"Read sdn dns configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The SDN dns object identifier.","enum":[],"extra":{},"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"dns"}],"permissions":{"expression":{"check":["perm","/sdn/dns/{dns}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"fd377c20ee2bb8bb3e504c6412d75aeb30c9c2e16da5aad6e61ecd81d453279a","description":"Update sdn dns object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The SDN dns object identifier.","enum":[],"extra":{},"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"dns"},{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"key"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"reversemaskv6"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"ttl"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["perm","/sdn/dns",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/dns/{dns}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"cb49728f17e4b739b6e6c7239e27d9e3aed480b25e21917e8801c2d1941cea9d","description":"Dry-run the SDN apply action and return the difference between the current configuration and the pending configuration","extra":{"proxyto":"node"},"name":"dry-run","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"frr-diff":{"description":"The difference between the current and pending FRR configuration.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"interfaces-diff":{"description":"The difference between the current and pending /etc/network/interfaces.d/sdn configuration.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/cluster/sdn/dry-run"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5ebb8ba451812df68df517f6af9783fce9ff741fa13e3c352b2d519c4c8b0ce4","description":"SDN Fabrics Index","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/sdn/fabrics",["SDN.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/sdn/fabrics"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a1270c8ad6aa9029ec9dcc9b5d6b1182d76355b73c0b7592ccaa60dc93e97ccf","description":"SDN Fabrics Index","extra":{},"name":"list_all","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"}],"permissions":{"description":"Only list fabrics where you have 'SDN.Audit' or 'SDN.Allocate' permissions on\n'/sdn/fabrics/', only list nodes where you have 'Sys.Audit' or 'Sys.Modify' on /nodes/","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"fabrics":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"area":{"description":"OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust.","enum":[],"extra":{"instance-types":["ospf"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"},"csnp_interval":{"description":"The csnp_interval property for Openfabric","enum":[],"extra":{"instance-types":["openfabric"],"type-property":"protocol"},"maximum":600,"minimum":1,"optional":true,"properties":{},"type":"number"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"hello_interval":{"description":"The hello_interval property for Openfabric","enum":[],"extra":{"instance-types":["openfabric"],"type-property":"protocol"},"maximum":600,"minimum":1,"optional":true,"properties":{},"type":"number"},"id":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"ip6_prefix":{"description":"The IP prefix for Node IPs","enum":[],"extra":{},"format":"CIDR","optional":true,"properties":{},"type":"string"},"ip_prefix":{"description":"The IP prefix for Node IPs","enum":[],"extra":{},"format":"CIDR","optional":true,"properties":{},"type":"string"},"lock-token":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"persistent_keepalive":{"description":"A seconds interval, between 1 and 65535 inclusive, of how often to send an authenticated empty packet to the peer for the purpose of keeping a stateful firewall or NAT mapping valid persistently. For example, if the interface very rarely sends traffic, but it might at anytime receive traffic from another node, and it is behind NAT, the interface might benefit from having a persistent keepalive interval of 25 seconds. If unset or set to 0, it is turned off","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"maximum":65535,"minimum":0,"optional":true,"properties":{},"type":"number"},"protocol":{"description":"Type of configuration entry in an SDN Fabric section config","enum":["openfabric","ospf","wireguard","bgp"],"extra":{},"properties":{},"type":"string"},"redistribute":{"enum":[],"extra":{"oneOf":[{"instance-types":["ospf"],"items":{"format":{"route-map":{"description":"Route map to filter or transform redistributed routes from this source.","format":"pve-sdn-route-map-id","optional":1,"type":"string"},"source":{"description":"The protocol from which to redistribute routes from.","enum":["bgp","connected","kernel","static"],"type":"string"}},"type":"string"},"optional":1,"type":"array"},{"instance-types":["bgp"],"items":{"format":{"route-map":{"description":"Route map to filter or transform redistributed routes from this source.","format":"pve-sdn-route-map-id","optional":1,"type":"string"},"source":{"description":"The protocol from which to redistribute routes from.","enum":["connected","kernel","ospf","static"],"type":"string"}},"type":"string"},"optional":1,"type":"array"}],"type-property":"protocol"},"properties":{},"type":"array"},"route_filter":{"description":"A prefix list that should be used for filtering routes that are to be installed into the kernel routing table","enum":[],"extra":{"instance-types":["ospf","openfabric"],"type-property":"protocol"},"format":"pve-sdn-prefix-list-id","optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"nodes":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"allowed_ips":{"description":"A list of IPs that are routable via this node in the WireGuard fabric.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"items":{"enum":[],"extra":{},"format":"FullRangeCIDR","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"endpoint":{"description":"The endpoint used for connecting to this node.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"},"fabric_id":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"interfaces":{"enum":[],"extra":{"oneOf":[{"description":"OpenFabric network interface","instance-types":["openfabric"],"items":{"format":{"hello_multiplier":{"description":"The hello_multiplier property of the interface","maximum":100,"minimum":2,"optional":1,"type":"integer"},"ip":{"description":"IPv4 address for this node","format":"CIDRv4","optional":1,"type":"string"},"ip6":{"description":"IPv6 address for this node","format":"CIDRv6","optional":1,"type":"string"},"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"}},"type":"string"},"optional":1,"type":"array"},{"description":"OSPF network interface","instance-types":["ospf"],"items":{"format":{"ip":{"description":"IPv4 address for this node","format":"CIDRv4","optional":1,"type":"string"},"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"},"network_type":{"description":"Network Type of the OSPF interface","enum":["broadcast","non-broadcast","point-to-multipoint","point-to-point"],"optional":1,"type":"string"}},"type":"string"},"optional":1,"type":"array"},{"description":"List of WireGuard network interfaces for this node.","instance-types":["wireguard"],"items":{"description":"WireGuard network interface","format":"pve-sdn-fabric-wireguard-interface","type":"string"},"optional":1,"type":"array"},{"description":"BGP network interface","instance-types":["bgp"],"items":{"format":{"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"}},"type":"string"},"optional":1}],"type-property":"protocol"},"properties":{},"type":"array"},"ip":{"description":"IPv4 address for this node","enum":[],"extra":{},"format":"ipv4","optional":true,"properties":{},"type":"string"},"ip6":{"description":"IPv6 address for this node","enum":[],"extra":{},"format":"ipv6","optional":true,"properties":{},"type":"string"},"lock-token":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"node_id":{"description":"Identifier for nodes in an SDN fabric","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"peers":{"enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"items":{"enum":[],"extra":{},"format":{"endpoint":{"description":"Override for the endpoint settings in the node section.","optional":1,"type":"string"},"iface":{"description":"The interface of this node that uses this peer definition.","type":"string"},"node":{"description":"The name of the referenced node section (the external node or the internal peer node).","type":"string"},"node_iface":{"description":"The interface of the other node, if it is internal","optional":1,"type":"string"},"skip_route_generation":{"default":0,"description":"Whether routes for the allowed IPs should be created in the kernel routing table.","optional":1,"type":"boolean"},"type":{"enum":["internal","external"],"type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"protocol":{"description":"Type of configuration entry in an SDN Fabric section config","enum":["openfabric","ospf","wireguard","bgp"],"extra":{},"properties":{},"type":"string"},"public_key":{"description":"The public key for the external node.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"},"role":{"description":"The role of this node in the WireGuard fabric.","enum":["internal","external"],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"}],"path":"/cluster/sdn/fabrics/all"},{"extra":{},"methods":[{"allow_token":true,"checksum":"30f3549164d14a5eea18fe861cdb9fd41e12012507216a8cdbb3080274127c0a","description":"SDN Fabrics Index","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/fabrics/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"area":{"description":"OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust.","enum":[],"extra":{"instance-types":["ospf"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"},"csnp_interval":{"description":"The csnp_interval property for Openfabric","enum":[],"extra":{"instance-types":["openfabric"],"type-property":"protocol"},"maximum":600,"minimum":1,"optional":true,"properties":{},"type":"number"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"hello_interval":{"description":"The hello_interval property for Openfabric","enum":[],"extra":{"instance-types":["openfabric"],"type-property":"protocol"},"maximum":600,"minimum":1,"optional":true,"properties":{},"type":"number"},"id":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"ip6_prefix":{"description":"The IP prefix for Node IPs","enum":[],"extra":{},"format":"CIDR","optional":true,"properties":{},"type":"string"},"ip_prefix":{"description":"The IP prefix for Node IPs","enum":[],"extra":{},"format":"CIDR","optional":true,"properties":{},"type":"string"},"lock-token":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"persistent_keepalive":{"description":"A seconds interval, between 1 and 65535 inclusive, of how often to send an authenticated empty packet to the peer for the purpose of keeping a stateful firewall or NAT mapping valid persistently. For example, if the interface very rarely sends traffic, but it might at anytime receive traffic from another node, and it is behind NAT, the interface might benefit from having a persistent keepalive interval of 25 seconds. If unset or set to 0, it is turned off","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"maximum":65535,"minimum":0,"optional":true,"properties":{},"type":"number"},"protocol":{"description":"Type of configuration entry in an SDN Fabric section config","enum":["openfabric","ospf","wireguard","bgp"],"extra":{},"properties":{},"type":"string"},"redistribute":{"enum":[],"extra":{"oneOf":[{"instance-types":["ospf"],"items":{"format":{"route-map":{"description":"Route map to filter or transform redistributed routes from this source.","format":"pve-sdn-route-map-id","optional":1,"type":"string"},"source":{"description":"The protocol from which to redistribute routes from.","enum":["bgp","connected","kernel","static"],"type":"string"}},"type":"string"},"optional":1,"type":"array"},{"instance-types":["bgp"],"items":{"format":{"route-map":{"description":"Route map to filter or transform redistributed routes from this source.","format":"pve-sdn-route-map-id","optional":1,"type":"string"},"source":{"description":"The protocol from which to redistribute routes from.","enum":["connected","kernel","ospf","static"],"type":"string"}},"type":"string"},"optional":1,"type":"array"}],"type-property":"protocol"},"properties":{},"type":"array"},"route_filter":{"description":"A prefix list that should be used for filtering routes that are to be installed into the kernel routing table","enum":[],"extra":{"instance-types":["ospf","openfabric"],"type-property":"protocol"},"format":"pve-sdn-prefix-list-id","optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"77d14c5aff062f0551a375afafa39f2a2af2a7c860c782f0addfae349301d11c","description":"Add a fabric","extra":{},"name":"add_fabric","parameters":[{"definition":{"description":"OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust.","enum":[],"extra":{"instance-types":["ospf"],"type-property":"protocol","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"area"},{"definition":{"description":"The csnp_interval property for Openfabric","enum":[],"extra":{"instance-types":["openfabric"],"type-property":"protocol","typetext":" (1 - 600)"},"maximum":600,"minimum":1,"optional":true,"properties":{},"type":"number"},"name":"csnp_interval"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The hello_interval property for Openfabric","enum":[],"extra":{"instance-types":["openfabric"],"type-property":"protocol","typetext":" (1 - 600)"},"maximum":600,"minimum":1,"optional":true,"properties":{},"type":"number"},"name":"hello_interval"},{"definition":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The IP prefix for Node IPs","enum":[],"extra":{"typetext":""},"format":"CIDR","optional":true,"properties":{},"type":"string"},"name":"ip6_prefix"},{"definition":{"description":"The IP prefix for Node IPs","enum":[],"extra":{"typetext":""},"format":"CIDR","optional":true,"properties":{},"type":"string"},"name":"ip_prefix"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"description":"A seconds interval, between 1 and 65535 inclusive, of how often to send an authenticated empty packet to the peer for the purpose of keeping a stateful firewall or NAT mapping valid persistently. For example, if the interface very rarely sends traffic, but it might at anytime receive traffic from another node, and it is behind NAT, the interface might benefit from having a persistent keepalive interval of 25 seconds. If unset or set to 0, it is turned off","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol","typetext":" (0 - 65535)"},"maximum":65535,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"persistent_keepalive"},{"definition":{"description":"Type of configuration entry in an SDN Fabric section config","enum":["openfabric","ospf","wireguard","bgp"],"extra":{},"properties":{},"type":"string"},"name":"protocol"},{"definition":{"enum":[],"extra":{"oneOf":[{"instance-types":["ospf"],"items":{"format":{"route-map":{"description":"Route map to filter or transform redistributed routes from this source.","format":"pve-sdn-route-map-id","optional":1,"type":"string"},"source":{"description":"The protocol from which to redistribute routes from.","enum":["bgp","connected","kernel","static"],"type":"string"}},"type":"string"},"optional":1,"type":"array"},{"instance-types":["bgp"],"items":{"format":{"route-map":{"description":"Route map to filter or transform redistributed routes from this source.","format":"pve-sdn-route-map-id","optional":1,"type":"string"},"source":{"description":"The protocol from which to redistribute routes from.","enum":["connected","kernel","ospf","static"],"type":"string"}},"type":"string"},"optional":1,"type":"array"}],"type-property":"protocol","typetext":""},"properties":{},"type":"array"},"name":"redistribute"},{"definition":{"description":"A prefix list that should be used for filtering routes that are to be installed into the kernel routing table","enum":[],"extra":{"instance-types":["ospf","openfabric"],"type-property":"protocol","typetext":""},"format":"pve-sdn-prefix-list-id","optional":true,"properties":{},"type":"string"},"name":"route_filter"}],"permissions":{"expression":{"check":["perm","/sdn/fabrics",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/fabrics/fabric"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2b227ff1dc31c6b14b6058403fc417ed5747f26d0b27fff8813ab72fec274bfa","description":"Add a fabric","extra":{},"name":"delete_fabric","parameters":[{"definition":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/sdn/fabrics/{id}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"a71a0af75912dc2bf37ee0a17b432646c00446b3bc7da3278e56a644655387b4","description":"Update a fabric","extra":{},"name":"get_fabric","parameters":[{"definition":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/sdn/fabrics/{id}",["SDN.Audit","SDN.Allocate"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"area":{"description":"OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust.","enum":[],"extra":{"instance-types":["ospf"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"},"csnp_interval":{"description":"The csnp_interval property for Openfabric","enum":[],"extra":{"instance-types":["openfabric"],"type-property":"protocol"},"maximum":600,"minimum":1,"optional":true,"properties":{},"type":"number"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"hello_interval":{"description":"The hello_interval property for Openfabric","enum":[],"extra":{"instance-types":["openfabric"],"type-property":"protocol"},"maximum":600,"minimum":1,"optional":true,"properties":{},"type":"number"},"id":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"ip6_prefix":{"description":"The IP prefix for Node IPs","enum":[],"extra":{},"format":"CIDR","optional":true,"properties":{},"type":"string"},"ip_prefix":{"description":"The IP prefix for Node IPs","enum":[],"extra":{},"format":"CIDR","optional":true,"properties":{},"type":"string"},"lock-token":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"persistent_keepalive":{"description":"A seconds interval, between 1 and 65535 inclusive, of how often to send an authenticated empty packet to the peer for the purpose of keeping a stateful firewall or NAT mapping valid persistently. For example, if the interface very rarely sends traffic, but it might at anytime receive traffic from another node, and it is behind NAT, the interface might benefit from having a persistent keepalive interval of 25 seconds. If unset or set to 0, it is turned off","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"maximum":65535,"minimum":0,"optional":true,"properties":{},"type":"number"},"protocol":{"description":"Type of configuration entry in an SDN Fabric section config","enum":["openfabric","ospf","wireguard","bgp"],"extra":{},"properties":{},"type":"string"},"redistribute":{"enum":[],"extra":{"oneOf":[{"instance-types":["ospf"],"items":{"format":{"route-map":{"description":"Route map to filter or transform redistributed routes from this source.","format":"pve-sdn-route-map-id","optional":1,"type":"string"},"source":{"description":"The protocol from which to redistribute routes from.","enum":["bgp","connected","kernel","static"],"type":"string"}},"type":"string"},"optional":1,"type":"array"},{"instance-types":["bgp"],"items":{"format":{"route-map":{"description":"Route map to filter or transform redistributed routes from this source.","format":"pve-sdn-route-map-id","optional":1,"type":"string"},"source":{"description":"The protocol from which to redistribute routes from.","enum":["connected","kernel","ospf","static"],"type":"string"}},"type":"string"},"optional":1,"type":"array"}],"type-property":"protocol"},"properties":{},"type":"array"},"route_filter":{"description":"A prefix list that should be used for filtering routes that are to be installed into the kernel routing table","enum":[],"extra":{"instance-types":["ospf","openfabric"],"type-property":"protocol"},"format":"pve-sdn-prefix-list-id","optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"e5bae96a2bddf6a8a2075444fcababd804c4524ace78074f7013566ab260ff89","description":"Update a fabric","extra":{},"name":"update_fabric","parameters":[{"definition":{"description":"OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust.","enum":[],"extra":{"instance-types":["ospf"],"type-property":"protocol","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"area"},{"definition":{"description":"The csnp_interval property for Openfabric","enum":[],"extra":{"instance-types":["openfabric"],"type-property":"protocol","typetext":" (1 - 600)"},"maximum":600,"minimum":1,"optional":true,"properties":{},"type":"number"},"name":"csnp_interval"},{"definition":{"enum":[],"extra":{"oneOf":[{"instance-types":["openfabric"],"items":{"enum":["ip_prefix","ip6_prefix","hello_interval","csnp_interval","route_filter"],"type":"string"},"optional":1,"type":"array"},{"instance-types":["bgp"],"items":{"enum":["ip_prefix","ip6_prefix","redistribute","route_filter","route_map_in","route_map_out"],"type":"string"},"optional":1,"type":"array"},{"instance-types":["ospf"],"items":{"enum":["area","redistribute","route_filter"],"type":"string"},"optional":1,"type":"array"},{"instance-types":["wireguard"],"items":{"enum":["persistent_keepalive"],"type":"string"},"optional":1,"type":"array"}],"type-property":"protocol","typetext":""},"properties":{},"type":"array"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The hello_interval property for Openfabric","enum":[],"extra":{"instance-types":["openfabric"],"type-property":"protocol","typetext":" (1 - 600)"},"maximum":600,"minimum":1,"optional":true,"properties":{},"type":"number"},"name":"hello_interval"},{"definition":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The IP prefix for Node IPs","enum":[],"extra":{"typetext":""},"format":"CIDR","optional":true,"properties":{},"type":"string"},"name":"ip6_prefix"},{"definition":{"description":"The IP prefix for Node IPs","enum":[],"extra":{"typetext":""},"format":"CIDR","optional":true,"properties":{},"type":"string"},"name":"ip_prefix"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"description":"A seconds interval, between 1 and 65535 inclusive, of how often to send an authenticated empty packet to the peer for the purpose of keeping a stateful firewall or NAT mapping valid persistently. For example, if the interface very rarely sends traffic, but it might at anytime receive traffic from another node, and it is behind NAT, the interface might benefit from having a persistent keepalive interval of 25 seconds. If unset or set to 0, it is turned off","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol","typetext":" (0 - 65535)"},"maximum":65535,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"persistent_keepalive"},{"definition":{"description":"Type of configuration entry in an SDN Fabric section config","enum":["openfabric","ospf","wireguard","bgp"],"extra":{},"properties":{},"type":"string"},"name":"protocol"},{"definition":{"enum":[],"extra":{"oneOf":[{"instance-types":["ospf"],"items":{"format":{"route-map":{"description":"Route map to filter or transform redistributed routes from this source.","format":"pve-sdn-route-map-id","optional":1,"type":"string"},"source":{"description":"The protocol from which to redistribute routes from.","enum":["bgp","connected","kernel","static"],"type":"string"}},"type":"string"},"optional":1,"type":"array"},{"instance-types":["bgp"],"items":{"format":{"route-map":{"description":"Route map to filter or transform redistributed routes from this source.","format":"pve-sdn-route-map-id","optional":1,"type":"string"},"source":{"description":"The protocol from which to redistribute routes from.","enum":["connected","kernel","ospf","static"],"type":"string"}},"type":"string"},"optional":1,"type":"array"}],"type-property":"protocol","typetext":""},"properties":{},"type":"array"},"name":"redistribute"},{"definition":{"description":"A prefix list that should be used for filtering routes that are to be installed into the kernel routing table","enum":[],"extra":{"instance-types":["ospf","openfabric"],"type-property":"protocol","typetext":""},"format":"pve-sdn-prefix-list-id","optional":true,"properties":{},"type":"string"},"name":"route_filter"}],"permissions":{"expression":{"check":["perm","/sdn/fabrics/{id}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/fabrics/fabric/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b2cf612042d6f973e44fdd616c3b04f30b51333fab81f884c55e31b7b055663b","description":"SDN Fabrics Index","extra":{},"name":"list_nodes","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"}],"permissions":{"description":"Only list nodes where you have 'SDN.Audit' or 'SDN.Allocate' permissions on\n'/sdn/fabrics/' and 'Sys.Audit' or 'Sys.Modify' on /nodes/","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{fabric_id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"allowed_ips":{"description":"A list of IPs that are routable via this node in the WireGuard fabric.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"items":{"enum":[],"extra":{},"format":"FullRangeCIDR","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"endpoint":{"description":"The endpoint used for connecting to this node.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"},"fabric_id":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"interfaces":{"enum":[],"extra":{"oneOf":[{"description":"OpenFabric network interface","instance-types":["openfabric"],"items":{"format":{"hello_multiplier":{"description":"The hello_multiplier property of the interface","maximum":100,"minimum":2,"optional":1,"type":"integer"},"ip":{"description":"IPv4 address for this node","format":"CIDRv4","optional":1,"type":"string"},"ip6":{"description":"IPv6 address for this node","format":"CIDRv6","optional":1,"type":"string"},"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"}},"type":"string"},"optional":1,"type":"array"},{"description":"OSPF network interface","instance-types":["ospf"],"items":{"format":{"ip":{"description":"IPv4 address for this node","format":"CIDRv4","optional":1,"type":"string"},"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"},"network_type":{"description":"Network Type of the OSPF interface","enum":["broadcast","non-broadcast","point-to-multipoint","point-to-point"],"optional":1,"type":"string"}},"type":"string"},"optional":1,"type":"array"},{"description":"List of WireGuard network interfaces for this node.","instance-types":["wireguard"],"items":{"description":"WireGuard network interface","format":"pve-sdn-fabric-wireguard-interface","type":"string"},"optional":1,"type":"array"},{"description":"BGP network interface","instance-types":["bgp"],"items":{"format":{"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"}},"type":"string"},"optional":1}],"type-property":"protocol"},"properties":{},"type":"array"},"ip":{"description":"IPv4 address for this node","enum":[],"extra":{},"format":"ipv4","optional":true,"properties":{},"type":"string"},"ip6":{"description":"IPv6 address for this node","enum":[],"extra":{},"format":"ipv6","optional":true,"properties":{},"type":"string"},"lock-token":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"node_id":{"description":"Identifier for nodes in an SDN fabric","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"peers":{"enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"items":{"enum":[],"extra":{},"format":{"endpoint":{"description":"Override for the endpoint settings in the node section.","optional":1,"type":"string"},"iface":{"description":"The interface of this node that uses this peer definition.","type":"string"},"node":{"description":"The name of the referenced node section (the external node or the internal peer node).","type":"string"},"node_iface":{"description":"The interface of the other node, if it is internal","optional":1,"type":"string"},"skip_route_generation":{"default":0,"description":"Whether routes for the allowed IPs should be created in the kernel routing table.","optional":1,"type":"boolean"},"type":{"enum":["internal","external"],"type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"protocol":{"description":"Type of configuration entry in an SDN Fabric section config","enum":["openfabric","ospf","wireguard","bgp"],"extra":{},"properties":{},"type":"string"},"public_key":{"description":"The public key for the external node.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"},"role":{"description":"The role of this node in the WireGuard fabric.","enum":["internal","external"],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/sdn/fabrics/node"},{"extra":{},"methods":[{"allow_token":true,"checksum":"91a9f6f0cc0af907e4fcf542221611cb44b9ef54f9ae51ef3857bb5b1f46ae2e","description":"SDN Fabrics Index","extra":{},"name":"list_nodes_fabric","parameters":[{"definition":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"name":"fabric_id"},{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"}],"permissions":{"description":"Only returns nodes where you have 'Sys.Audit' or 'Sys.Modify' permissions.","expression":{"check":["perm","/sdn/fabrics/{fabric_id}",["SDN.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{node_id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"allowed_ips":{"description":"A list of IPs that are routable via this node in the WireGuard fabric.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"items":{"enum":[],"extra":{},"format":"FullRangeCIDR","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"endpoint":{"description":"The endpoint used for connecting to this node.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"},"fabric_id":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"interfaces":{"enum":[],"extra":{"oneOf":[{"description":"OpenFabric network interface","instance-types":["openfabric"],"items":{"format":{"hello_multiplier":{"description":"The hello_multiplier property of the interface","maximum":100,"minimum":2,"optional":1,"type":"integer"},"ip":{"description":"IPv4 address for this node","format":"CIDRv4","optional":1,"type":"string"},"ip6":{"description":"IPv6 address for this node","format":"CIDRv6","optional":1,"type":"string"},"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"}},"type":"string"},"optional":1,"type":"array"},{"description":"OSPF network interface","instance-types":["ospf"],"items":{"format":{"ip":{"description":"IPv4 address for this node","format":"CIDRv4","optional":1,"type":"string"},"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"},"network_type":{"description":"Network Type of the OSPF interface","enum":["broadcast","non-broadcast","point-to-multipoint","point-to-point"],"optional":1,"type":"string"}},"type":"string"},"optional":1,"type":"array"},{"description":"List of WireGuard network interfaces for this node.","instance-types":["wireguard"],"items":{"description":"WireGuard network interface","format":"pve-sdn-fabric-wireguard-interface","type":"string"},"optional":1,"type":"array"},{"description":"BGP network interface","instance-types":["bgp"],"items":{"format":{"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"}},"type":"string"},"optional":1}],"type-property":"protocol"},"properties":{},"type":"array"},"ip":{"description":"IPv4 address for this node","enum":[],"extra":{},"format":"ipv4","optional":true,"properties":{},"type":"string"},"ip6":{"description":"IPv6 address for this node","enum":[],"extra":{},"format":"ipv6","optional":true,"properties":{},"type":"string"},"lock-token":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"node_id":{"description":"Identifier for nodes in an SDN fabric","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"peers":{"enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"items":{"enum":[],"extra":{},"format":{"endpoint":{"description":"Override for the endpoint settings in the node section.","optional":1,"type":"string"},"iface":{"description":"The interface of this node that uses this peer definition.","type":"string"},"node":{"description":"The name of the referenced node section (the external node or the internal peer node).","type":"string"},"node_iface":{"description":"The interface of the other node, if it is internal","optional":1,"type":"string"},"skip_route_generation":{"default":0,"description":"Whether routes for the allowed IPs should be created in the kernel routing table.","optional":1,"type":"boolean"},"type":{"enum":["internal","external"],"type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"protocol":{"description":"Type of configuration entry in an SDN Fabric section config","enum":["openfabric","ospf","wireguard","bgp"],"extra":{},"properties":{},"type":"string"},"public_key":{"description":"The public key for the external node.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"},"role":{"description":"The role of this node in the WireGuard fabric.","enum":["internal","external"],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"7023fa5f0314047ddf11026a79a9563aee60d0df5d8ead61cc0d0175af77180c","description":"Add a node","extra":{},"name":"add_node","parameters":[{"definition":{"description":"A list of IPs that are routable via this node in the WireGuard fabric.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol","typetext":""},"items":{"enum":[],"extra":{},"format":"FullRangeCIDR","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"allowed_ips"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The endpoint used for connecting to this node.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"endpoint"},{"definition":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"name":"fabric_id"},{"definition":{"enum":[],"extra":{"oneOf":[{"description":"OpenFabric network interface","instance-types":["openfabric"],"items":{"format":{"hello_multiplier":{"description":"The hello_multiplier property of the interface","maximum":100,"minimum":2,"optional":1,"type":"integer"},"ip":{"description":"IPv4 address for this node","format":"CIDRv4","optional":1,"type":"string"},"ip6":{"description":"IPv6 address for this node","format":"CIDRv6","optional":1,"type":"string"},"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"}},"type":"string"},"optional":1,"type":"array"},{"description":"OSPF network interface","instance-types":["ospf"],"items":{"format":{"ip":{"description":"IPv4 address for this node","format":"CIDRv4","optional":1,"type":"string"},"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"},"network_type":{"description":"Network Type of the OSPF interface","enum":["broadcast","non-broadcast","point-to-multipoint","point-to-point"],"optional":1,"type":"string"}},"type":"string"},"optional":1,"type":"array"},{"description":"List of WireGuard network interfaces for this node.","instance-types":["wireguard"],"items":{"description":"WireGuard network interface","format":"pve-sdn-fabric-wireguard-interface","type":"string"},"optional":1,"type":"array"},{"description":"BGP network interface","instance-types":["bgp"],"items":{"format":{"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"}},"type":"string"},"optional":1}],"type-property":"protocol","typetext":""},"properties":{},"type":"array"},"name":"interfaces"},{"definition":{"description":"IPv4 address for this node","enum":[],"extra":{"typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"ip"},{"definition":{"description":"IPv6 address for this node","enum":[],"extra":{"typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"ip6"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"description":"Identifier for nodes in an SDN fabric","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node_id"},{"definition":{"enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol","typetext":""},"items":{"enum":[],"extra":{},"format":{"endpoint":{"description":"Override for the endpoint settings in the node section.","optional":1,"type":"string"},"iface":{"description":"The interface of this node that uses this peer definition.","type":"string"},"node":{"description":"The name of the referenced node section (the external node or the internal peer node).","type":"string"},"node_iface":{"description":"The interface of the other node, if it is internal","optional":1,"type":"string"},"skip_route_generation":{"default":0,"description":"Whether routes for the allowed IPs should be created in the kernel routing table.","optional":1,"type":"boolean"},"type":{"enum":["internal","external"],"type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"peers"},{"definition":{"description":"Type of configuration entry in an SDN Fabric section config","enum":["openfabric","ospf","wireguard","bgp"],"extra":{},"properties":{},"type":"string"},"name":"protocol"},{"definition":{"description":"The public key for the external node.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"public_key"},{"definition":{"description":"The role of this node in the WireGuard fabric.","enum":["internal","external"],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"},"name":"role"}],"permissions":{"expression":{"check":["and",["perm","/sdn/fabrics/{fabric_id}",["SDN.Allocate"]],["perm","/nodes/{node_id}",["Sys.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/fabrics/node/{fabric_id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"14b16261b4ed03df636a9e612cb883b21270dcf96312bef14d37eb04270a8f32","description":"Add a node","extra":{},"name":"delete_node","parameters":[{"definition":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"name":"fabric_id"},{"definition":{"description":"Identifier for nodes in an SDN fabric","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node_id"}],"permissions":{"expression":{"check":["and",["perm","/sdn/fabrics/{fabric_id}",["SDN.Allocate"]],["perm","/nodes/{node_id}",["Sys.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"8201f275a4bebff696ad4b4386fbc3eda9d89b42fe0d0701887e58277dfe6a08","description":"Get a node","extra":{},"name":"get_node","parameters":[{"definition":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"name":"fabric_id"},{"definition":{"description":"Identifier for nodes in an SDN fabric","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node_id"}],"permissions":{"expression":{"check":["and",["perm","/sdn/fabrics/{fabric_id}",["SDN.Audit","SDN.Allocate"],"any",1],["perm","/nodes/{node_id}",["Sys.Audit","Sys.Modify"],"any",1]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"allowed_ips":{"description":"A list of IPs that are routable via this node in the WireGuard fabric.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"items":{"enum":[],"extra":{},"format":"FullRangeCIDR","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"endpoint":{"description":"The endpoint used for connecting to this node.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"},"fabric_id":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"interfaces":{"enum":[],"extra":{"oneOf":[{"description":"OpenFabric network interface","instance-types":["openfabric"],"items":{"format":{"hello_multiplier":{"description":"The hello_multiplier property of the interface","maximum":100,"minimum":2,"optional":1,"type":"integer"},"ip":{"description":"IPv4 address for this node","format":"CIDRv4","optional":1,"type":"string"},"ip6":{"description":"IPv6 address for this node","format":"CIDRv6","optional":1,"type":"string"},"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"}},"type":"string"},"optional":1,"type":"array"},{"description":"OSPF network interface","instance-types":["ospf"],"items":{"format":{"ip":{"description":"IPv4 address for this node","format":"CIDRv4","optional":1,"type":"string"},"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"},"network_type":{"description":"Network Type of the OSPF interface","enum":["broadcast","non-broadcast","point-to-multipoint","point-to-point"],"optional":1,"type":"string"}},"type":"string"},"optional":1,"type":"array"},{"description":"List of WireGuard network interfaces for this node.","instance-types":["wireguard"],"items":{"description":"WireGuard network interface","format":"pve-sdn-fabric-wireguard-interface","type":"string"},"optional":1,"type":"array"},{"description":"BGP network interface","instance-types":["bgp"],"items":{"format":{"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"}},"type":"string"},"optional":1}],"type-property":"protocol"},"properties":{},"type":"array"},"ip":{"description":"IPv4 address for this node","enum":[],"extra":{},"format":"ipv4","optional":true,"properties":{},"type":"string"},"ip6":{"description":"IPv6 address for this node","enum":[],"extra":{},"format":"ipv6","optional":true,"properties":{},"type":"string"},"lock-token":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"node_id":{"description":"Identifier for nodes in an SDN fabric","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"peers":{"enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"items":{"enum":[],"extra":{},"format":{"endpoint":{"description":"Override for the endpoint settings in the node section.","optional":1,"type":"string"},"iface":{"description":"The interface of this node that uses this peer definition.","type":"string"},"node":{"description":"The name of the referenced node section (the external node or the internal peer node).","type":"string"},"node_iface":{"description":"The interface of the other node, if it is internal","optional":1,"type":"string"},"skip_route_generation":{"default":0,"description":"Whether routes for the allowed IPs should be created in the kernel routing table.","optional":1,"type":"boolean"},"type":{"enum":["internal","external"],"type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"protocol":{"description":"Type of configuration entry in an SDN Fabric section config","enum":["openfabric","ospf","wireguard","bgp"],"extra":{},"properties":{},"type":"string"},"public_key":{"description":"The public key for the external node.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"},"role":{"description":"The role of this node in the WireGuard fabric.","enum":["internal","external"],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"}}},"verb":"GET"},{"allow_token":true,"checksum":"f89575ca2453c53954fb78b65ed911ec8c431d0d4651da5226e0f56d62c49325","description":"Update a node","extra":{},"name":"update_node","parameters":[{"definition":{"description":"A list of IPs that are routable via this node in the WireGuard fabric.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol","typetext":""},"items":{"enum":[],"extra":{},"format":"FullRangeCIDR","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"allowed_ips"},{"definition":{"enum":[],"extra":{"oneOf":[{"instance-types":["bgp"],"items":{"enum":["interfaces","ip","ip6"],"type":"string"},"optional":1,"type":"array"},{"instance-types":["openfabric","ospf"],"items":{"enum":["interfaces","ip","ip6"],"type":"string"},"optional":1,"type":"array"},{"instance-types":["wireguard"],"items":{"enum":["allowed_ips","endpoint","interfaces","ip","ip6","peers"],"type":"string"},"optional":1,"type":"array"}],"type-property":"protocol","typetext":""},"properties":{},"type":"array"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The endpoint used for connecting to this node.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"endpoint"},{"definition":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"name":"fabric_id"},{"definition":{"enum":[],"extra":{"oneOf":[{"description":"OpenFabric network interface","instance-types":["openfabric"],"items":{"format":{"hello_multiplier":{"description":"The hello_multiplier property of the interface","maximum":100,"minimum":2,"optional":1,"type":"integer"},"ip":{"description":"IPv4 address for this node","format":"CIDRv4","optional":1,"type":"string"},"ip6":{"description":"IPv6 address for this node","format":"CIDRv6","optional":1,"type":"string"},"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"}},"type":"string"},"optional":1,"type":"array"},{"description":"OSPF network interface","instance-types":["ospf"],"items":{"format":{"ip":{"description":"IPv4 address for this node","format":"CIDRv4","optional":1,"type":"string"},"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"},"network_type":{"description":"Network Type of the OSPF interface","enum":["broadcast","non-broadcast","point-to-multipoint","point-to-point"],"optional":1,"type":"string"}},"type":"string"},"optional":1,"type":"array"},{"description":"List of WireGuard network interfaces for this node.","instance-types":["wireguard"],"items":{"description":"WireGuard network interface","format":"pve-sdn-fabric-wireguard-interface","type":"string"},"optional":1,"type":"array"},{"description":"BGP network interface","instance-types":["bgp"],"items":{"format":{"name":{"description":"Name of the network interface","format":"pve-iface","type":"string"}},"type":"string"},"optional":1}],"type-property":"protocol","typetext":""},"properties":{},"type":"array"},"name":"interfaces"},{"definition":{"description":"IPv4 address for this node","enum":[],"extra":{"typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"ip"},{"definition":{"description":"IPv6 address for this node","enum":[],"extra":{"typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"ip6"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"description":"Identifier for nodes in an SDN fabric","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node_id"},{"definition":{"enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol","typetext":""},"items":{"enum":[],"extra":{},"format":{"endpoint":{"description":"Override for the endpoint settings in the node section.","optional":1,"type":"string"},"iface":{"description":"The interface of this node that uses this peer definition.","type":"string"},"node":{"description":"The name of the referenced node section (the external node or the internal peer node).","type":"string"},"node_iface":{"description":"The interface of the other node, if it is internal","optional":1,"type":"string"},"skip_route_generation":{"default":0,"description":"Whether routes for the allowed IPs should be created in the kernel routing table.","optional":1,"type":"boolean"},"type":{"enum":["internal","external"],"type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"peers"},{"definition":{"description":"Type of configuration entry in an SDN Fabric section config","enum":["openfabric","ospf","wireguard","bgp"],"extra":{},"properties":{},"type":"string"},"name":"protocol"},{"definition":{"description":"The public key for the external node.","enum":[],"extra":{"instance-types":["wireguard"],"type-property":"protocol","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"public_key"},{"definition":{"description":"The role of this node in the WireGuard fabric.","enum":["internal","external"],"extra":{"instance-types":["wireguard"],"type-property":"protocol"},"optional":true,"properties":{},"type":"string"},"name":"role"}],"permissions":{"expression":{"check":["and",["perm","/sdn/fabrics/{fabric_id}",["SDN.Allocate"]],["perm","/nodes/{node_id}",["Sys.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/fabrics/node/{fabric_id}/{node_id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2082f53189334ff79a0eb8a997c9e416b23b351b06e0804f95ee35b13963c6fc","description":"SDN ipams index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list sdn ipams of specific type","enum":["netbox","phpipam","pve"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/ipams/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{ipam}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"ipam":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"0938b4b4242806f9a95eec6c5390a13e2eb1984c107725ffb7d45c835fdeec75","description":"Create a new sdn ipam object.","extra":{},"name":"create","parameters":[{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{},"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"ipam"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"section"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"},{"definition":{"description":"Plugin type.","enum":["netbox","phpipam","pve"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["perm","/sdn/ipams",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/ipams"},{"extra":{},"methods":[{"allow_token":true,"checksum":"469ea46ada6e5f42d7cc42fd7b39b64cc0e17a15f7959c855d99b668e258960d","description":"Delete sdn ipam object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{},"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"ipam"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"}],"permissions":{"expression":{"check":["perm","/sdn/ipams",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"a0fe6d7118f1e7d89b83cd3ae65f6d056c918262e09d8a55c4d5686c00b1271a","description":"Read sdn ipam configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{},"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"ipam"}],"permissions":{"expression":{"check":["perm","/sdn/ipams/{ipam}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"728e67634f87bf574356ba4cab766eafd9a34a504f67f35b572bfc6e4b5bcba3","description":"Update sdn ipam object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{},"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"ipam"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"section"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["perm","/sdn/ipams",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/ipams/{ipam}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6c021ea58ea44992683709b0bd07aa23833f4165b1f882a65f793ef55f10e404","description":"List PVE IPAM Entries","extra":{},"name":"ipamindex","parameters":[{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{},"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"ipam"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/sdn/ipams/{ipam}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a116044ef6916dcd216027b75c549ce7f5a1e9c982950cc5abaccef787a5ac15","description":"Release global lock for SDN configuration","extra":{},"name":"release_lock","parameters":[{"definition":{"default":0,"description":"if true, allow releasing lock without providing the token","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"}],"permissions":{"expression":{"check":["perm","/sdn",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"c1abb82b85411447f5d7df97a482192488f73b61d1b2050bb31354bd4a25d558","description":"Acquire global lock for SDN configuration","extra":{},"name":"lock","parameters":[{"definition":{"default":0,"description":"if true, allow acquiring lock even though there are pending changes","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"allow-pending"}],"permissions":{"expression":{"check":["perm","/sdn",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/sdn/lock"},{"extra":{},"methods":[{"allow_token":true,"checksum":"70ed4d961be5d654afd98b037a65df8eb3994e8094affdc8c7cf3823fbf758d5","description":"List Prefix Lists","extra":{},"name":"list_prefix_lists","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"If 0, only returns id - otherwise returns all properties.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verbose"}],"permissions":{"description":"Only returns prefix list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"b18e543e844e6321c165094a0fece9faa293dcb07b74daaf247516383f63221d","description":"Create Prefix List","extra":{},"name":"create_prefix_list_entry","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"action":{"enum":["permit","deny"],"optional":0,"type":"string"},"ge":{"maximum":128,"minimum":0,"optional":1,"type":"integer"},"le":{"maximum":128,"minimum":0,"optional":1,"type":"integer"},"prefix":{"format":"FullRangeCIDR","optional":0,"type":"string"},"seq":{"maximum":4294967295,"minimum":1,"optional":1,"type":"integer"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"entries"},{"definition":{"description":"The SDN prefix list identifier","enum":[],"extra":{"typetext":""},"format":"pve-sdn-prefix-list-id","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"}],"permissions":{"expression":{"check":["perm","/sdn/prefix-lists",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/prefix-lists"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ebfb45753517107ab1eda511b119202d59c0179a9411fcfea5eee30b17612cff","description":"Delete Prefix List","extra":{},"name":"delete_prefix_list","parameters":[{"definition":{"description":"The SDN prefix list identifier","enum":[],"extra":{"typetext":""},"format":"pve-sdn-prefix-list-id","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"}],"permissions":{"expression":{"check":["perm","/sdn/prefix-lists/{id}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f82f972201fd33ac4d9390fd4340b1fbe14d219dcdd61dab84d71bd6b1dd4643","description":"Get Prefix List","extra":{},"name":"get_prefix_list","parameters":[{"definition":{"description":"The SDN prefix list identifier","enum":[],"extra":{"typetext":""},"format":"pve-sdn-prefix-list-id","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/sdn/prefix-lists/{id}",["SDN.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"7cb2df303408ff33103ef1397bea317c08068b9fcc683887d7434b88e9639f5f","description":"Update Prefix List","extra":{},"name":"update_prefix_list","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"items":{"enum":["entries"],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"action":{"enum":["permit","deny"],"optional":1,"type":"string"},"ge":{"maximum":128,"minimum":0,"optional":1,"type":"integer"},"le":{"maximum":128,"minimum":0,"optional":1,"type":"integer"},"prefix":{"format":"FullRangeCIDR","optional":1,"type":"string"},"seq":{"maximum":4294967295,"minimum":1,"optional":1,"type":"integer"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"entries"},{"definition":{"description":"The SDN prefix list identifier","enum":[],"extra":{"typetext":""},"format":"pve-sdn-prefix-list-id","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"}],"permissions":{"expression":{"check":["perm","/sdn/prefix-lists/{id}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/prefix-lists/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"45508c19255c61e0e06549c25f03939a94e5aa94ff617d0443012e7dcd9bd28d","description":"List Prefix List Entries","extra":{},"name":"get_prefix_list_entries","parameters":[{"definition":{"description":"The SDN prefix list identifier","enum":[],"extra":{"typetext":""},"format":"pve-sdn-prefix-list-id","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/sdn/prefix-lists/{id}",["SDN.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{seq}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"3280959161f44a673346fb40373fe8210995ac8a9b05d8428814fd1bdeef14b2","description":"Create Prefix List Entry","extra":{},"name":"create_prefix_list_entry","parameters":[{"definition":{"enum":["permit","deny"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"action"},{"definition":{"enum":[],"extra":{"typetext":" (0 - 128)"},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"ge"},{"definition":{"description":"The SDN prefix list identifier","enum":[],"extra":{"typetext":""},"format":"pve-sdn-prefix-list-id","properties":{},"type":"string"},"name":"id"},{"definition":{"enum":[],"extra":{"typetext":" (0 - 128)"},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"le"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"FullRangeCIDR","optional":false,"properties":{},"type":"string"},"name":"prefix"},{"definition":{"enum":[],"extra":{"typetext":" (1 - 4294967295)"},"maximum":4294967295,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"seq"}],"permissions":{"expression":{"check":["perm","/sdn/prefix-lists/{id}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/prefix-lists/{id}/entries"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8c3820c85bd50e5e42e44f50330293edd1b10e435eb5b4a072cae5dcd40aa4e8","description":"Delete Prefix List Entry","extra":{},"name":"delete_prefix_list_entry","parameters":[{"definition":{"description":"The SDN prefix list identifier","enum":[],"extra":{"typetext":""},"format":"pve-sdn-prefix-list-id","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"}],"permissions":{"expression":{"check":["perm","/sdn/prefix-lists/{id}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"0dfc0094c091ade89122a81f320589d160a6f5a44872a9053eafa29ea372affc","description":"Get Prefix List Entry","extra":{},"name":"get_prefix_list_entry","parameters":[{"definition":{"description":"The SDN prefix list identifier","enum":[],"extra":{"typetext":""},"format":"pve-sdn-prefix-list-id","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/sdn/prefix-lists/{id}",["SDN.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"615607707fc75fb2ecb598511200e502219cd5dfbaf834a363d8b64501e645e0","description":"Update Prefix List Entry","extra":{},"name":"update_prefix_list_entry","parameters":[{"definition":{"enum":["permit","deny"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"action"},{"definition":{"enum":[],"extra":{"typetext":""},"items":{"enum":["le","ge","seq"],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"enum":[],"extra":{"typetext":" (0 - 128)"},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"ge"},{"definition":{"enum":[],"extra":{"typetext":" (0 - 128)"},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"le"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"FullRangeCIDR","optional":true,"properties":{},"type":"string"},"name":"prefix"},{"definition":{"enum":[],"extra":{"typetext":" (1 - 4294967295)"},"maximum":4294967295,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"seq"}],"permissions":{"expression":{"check":["perm","/sdn/prefix-lists/{id}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/prefix-lists/{id}/entries/{url_seq}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bb0058a1fc4d5b33067b59c2453f1354f5449c04551e246f90f2982c00307347","description":"Rollback pending changes to SDN configuration","extra":{},"name":"rollback","parameters":[{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"default":1,"description":"When lock-token has been provided and configuration successfully rollbacked, release the lock automatically afterwards","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"release-lock"}],"permissions":{"expression":{"check":["perm","/sdn",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/rollback"},{"extra":{},"methods":[{"allow_token":true,"checksum":"825d5d2bb4e503d467f46acd7c634919d4d4f6a2fb2211a6d250e037cd0f5394","description":"List Route Maps","extra":{},"name":"list_route_maps","parameters":[{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"}],"permissions":{"description":"Only returns route maps where you have 'SDN.Audit' or 'SDN.Allocate' permissions.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"entries/{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"description":"The SDN route map identifier","enum":[],"extra":{},"format":"pve-sdn-route-map-id","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/sdn/route-maps"},{"extra":{},"methods":[{"allow_token":true,"checksum":"13d6c54a4e04b398e1ca16eca99d41a11403eb15b68b259c53c6ce821e8276b8","description":"Lists all route map entries.","extra":{},"name":"list_route_map_entries","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"}],"permissions":{"description":"Only returns route map entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{route-map-id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"action":{"description":"Matching policy of a route map entry.","enum":["permit","deny"],"extra":{},"optional":false,"properties":{},"type":"string"},"call":{"description":"The SDN route map identifier","enum":[],"extra":{},"format":"pve-sdn-route-map-id","optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"exit-action":{"enum":[],"extra":{},"format":{"key":{"enum":["on-match-goto","on-match-next","continue"],"type":"string"},"value":{"description":"The index of this route map entry","maximum":65535,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"match":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":{"key":{"enum":["route-type","vni","ip-address-prefix-list","ip6-address-prefix-list","ip-next-hop-prefix-list","ip6-next-hop-prefix-list","ip-next-hop-address","ip6-next-hop-address","metric","local-preference","peer","tag"],"type":"string"},"value":{"description":"Value that the field should be matched on.","format_description":"","optional":1,"type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"order":{"description":"The index of this route map entry","enum":[],"extra":{},"maximum":65535,"minimum":0,"properties":{},"type":"integer"},"route-map-id":{"description":"The SDN route map identifier","enum":[],"extra":{},"format":"pve-sdn-route-map-id","properties":{},"type":"string"},"set":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":{"key":{"enum":["ip-next-hop-peer-address","ip-next-hop","ip-next-hop-unchanged","ip6-next-hop-peer-address","ip6-next-hop-prefer-global","ip6-next-hop","local-preference","tag","weight","metric","src"],"type":"string"},"value":{"description":"Value that the field should be set to.","format_description":"","optional":1,"type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"bbffce0250e630f21ca713e2de647a0e800e741e608969cb5154d4ecc2a115a3","description":"Create Route Map entry","extra":{},"name":"create_route_map_entry","parameters":[{"definition":{"description":"Matching policy of a route map entry.","enum":["permit","deny"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"action"},{"definition":{"description":"The SDN route map identifier","enum":[],"extra":{"typetext":""},"format":"pve-sdn-route-map-id","optional":true,"properties":{},"type":"string"},"name":"call"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"enum":[],"extra":{"typetext":"key= [,value=]"},"format":{"key":{"enum":["on-match-goto","on-match-next","continue"],"type":"string"},"value":{"description":"The index of this route map entry","maximum":65535,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"exit-action"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"key":{"enum":["route-type","vni","ip-address-prefix-list","ip6-address-prefix-list","ip-next-hop-prefix-list","ip6-next-hop-prefix-list","ip-next-hop-address","ip6-next-hop-address","metric","local-preference","peer","tag"],"type":"string"},"value":{"description":"Value that the field should be matched on.","format_description":"","optional":1,"type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"match"},{"definition":{"description":"The index of this route map entry","enum":[],"extra":{"typetext":" (0 - 65535)"},"maximum":65535,"minimum":0,"properties":{},"type":"integer"},"name":"order"},{"definition":{"description":"The SDN route map identifier","enum":[],"extra":{"typetext":""},"format":"pve-sdn-route-map-id","properties":{},"type":"string"},"name":"route-map-id"},{"definition":{"enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"key":{"enum":["ip-next-hop-peer-address","ip-next-hop","ip-next-hop-unchanged","ip6-next-hop-peer-address","ip6-next-hop-prefer-global","ip6-next-hop","local-preference","tag","weight","metric","src"],"type":"string"},"value":{"description":"Value that the field should be set to.","format_description":"","optional":1,"type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"set"}],"permissions":{"expression":{"check":["perm","/sdn/route-maps",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/route-maps/entries"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a9a885c3dc3a0c29b9919f8609ab0fdcc173588e4e81a586c4ca7f9a553d4dfc","description":"List all entries for a given Route Map","extra":{},"name":"list_route_map_entries_for_route_map","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"The SDN route map identifier","enum":[],"extra":{"typetext":""},"format":"pve-sdn-route-map-id","properties":{},"type":"string"},"name":"route-map-id"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"}],"permissions":{"expression":{"check":["perm","/sdn/route-maps/{route-map-id}",["SDN.Audit","SDN.Allocate"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"entry/{order}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"action":{"description":"Matching policy of a route map entry.","enum":["permit","deny"],"extra":{},"optional":false,"properties":{},"type":"string"},"call":{"description":"The SDN route map identifier","enum":[],"extra":{},"format":"pve-sdn-route-map-id","optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"exit-action":{"enum":[],"extra":{},"format":{"key":{"enum":["on-match-goto","on-match-next","continue"],"type":"string"},"value":{"description":"The index of this route map entry","maximum":65535,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"match":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":{"key":{"enum":["route-type","vni","ip-address-prefix-list","ip6-address-prefix-list","ip-next-hop-prefix-list","ip6-next-hop-prefix-list","ip-next-hop-address","ip6-next-hop-address","metric","local-preference","peer","tag"],"type":"string"},"value":{"description":"Value that the field should be matched on.","format_description":"","optional":1,"type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"order":{"description":"The index of this route map entry","enum":[],"extra":{},"maximum":65535,"minimum":0,"properties":{},"type":"integer"},"route-map-id":{"description":"The SDN route map identifier","enum":[],"extra":{},"format":"pve-sdn-route-map-id","properties":{},"type":"string"},"set":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":{"key":{"enum":["ip-next-hop-peer-address","ip-next-hop","ip-next-hop-unchanged","ip6-next-hop-peer-address","ip6-next-hop-prefer-global","ip6-next-hop","local-preference","tag","weight","metric","src"],"type":"string"},"value":{"description":"Value that the field should be set to.","format_description":"","optional":1,"type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/sdn/route-maps/entries/{route-map-id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3c7e19ce68560c5b77fe407fb73cbd4d3bf6b1f367ff3f379ab06d40967f9f65","description":"Delete Route Map Entry","extra":{},"name":"delete_route_map_entry","parameters":[{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"description":"The index of this route map entry","enum":[],"extra":{"typetext":" (0 - 65535)"},"maximum":65535,"minimum":0,"properties":{},"type":"integer"},"name":"order"},{"definition":{"description":"The SDN route map identifier","enum":[],"extra":{"typetext":""},"format":"pve-sdn-route-map-id","properties":{},"type":"string"},"name":"route-map-id"}],"permissions":{"expression":{"check":["perm","/sdn/route-maps/{route-map-id}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"96a1dc88dee43d5e752b063bf243f6abcdd933035cb01f5dc5a7e43b629b9b1f","description":"Get Route Map Entry","extra":{},"name":"get_route_map_entry","parameters":[{"definition":{"description":"The index of this route map entry","enum":[],"extra":{"typetext":" (0 - 65535)"},"maximum":65535,"minimum":0,"properties":{},"type":"integer"},"name":"order"},{"definition":{"description":"The SDN route map identifier","enum":[],"extra":{"typetext":""},"format":"pve-sdn-route-map-id","properties":{},"type":"string"},"name":"route-map-id"}],"permissions":{"expression":{"check":["perm","/sdn/route-maps/{route-map-id}",["SDN.Audit","SDN.Allocate"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"description":"Matching policy of a route map entry.","enum":["permit","deny"],"extra":{},"optional":false,"properties":{},"type":"string"},"call":{"description":"The SDN route map identifier","enum":[],"extra":{},"format":"pve-sdn-route-map-id","optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"exit-action":{"enum":[],"extra":{},"format":{"key":{"enum":["on-match-goto","on-match-next","continue"],"type":"string"},"value":{"description":"The index of this route map entry","maximum":65535,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"match":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":{"key":{"enum":["route-type","vni","ip-address-prefix-list","ip6-address-prefix-list","ip-next-hop-prefix-list","ip6-next-hop-prefix-list","ip-next-hop-address","ip6-next-hop-address","metric","local-preference","peer","tag"],"type":"string"},"value":{"description":"Value that the field should be matched on.","format_description":"","optional":1,"type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"order":{"description":"The index of this route map entry","enum":[],"extra":{},"maximum":65535,"minimum":0,"properties":{},"type":"integer"},"route-map-id":{"description":"The SDN route map identifier","enum":[],"extra":{},"format":"pve-sdn-route-map-id","properties":{},"type":"string"},"set":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":{"key":{"enum":["ip-next-hop-peer-address","ip-next-hop","ip-next-hop-unchanged","ip6-next-hop-peer-address","ip6-next-hop-prefer-global","ip6-next-hop","local-preference","tag","weight","metric","src"],"type":"string"},"value":{"description":"Value that the field should be set to.","format_description":"","optional":1,"type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"d1677ecdc71c36a9e0074db6b02e0206a28b9f47dc01ce8c1a353e7dff0bd3d6","description":"Update Route Map Entry","extra":{},"name":"update_route_map_entry","parameters":[{"definition":{"description":"Matching policy of a route map entry.","enum":["permit","deny"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"action"},{"definition":{"description":"The SDN route map identifier","enum":[],"extra":{"typetext":""},"format":"pve-sdn-route-map-id","optional":true,"properties":{},"type":"string"},"name":"call"},{"definition":{"enum":[],"extra":{"typetext":""},"items":{"enum":["set","match","call","exit-action"],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"enum":[],"extra":{"typetext":"key= [,value=]"},"format":{"key":{"enum":["on-match-goto","on-match-next","continue"],"type":"string"},"value":{"description":"The index of this route map entry","maximum":65535,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"exit-action"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"key":{"enum":["route-type","vni","ip-address-prefix-list","ip6-address-prefix-list","ip-next-hop-prefix-list","ip6-next-hop-prefix-list","ip-next-hop-address","ip6-next-hop-address","metric","local-preference","peer","tag"],"type":"string"},"value":{"description":"Value that the field should be matched on.","format_description":"","optional":1,"type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"match"},{"definition":{"description":"The index of this route map entry","enum":[],"extra":{"typetext":" (0 - 65535)"},"maximum":65535,"minimum":0,"properties":{},"type":"integer"},"name":"order"},{"definition":{"description":"The SDN route map identifier","enum":[],"extra":{"typetext":""},"format":"pve-sdn-route-map-id","properties":{},"type":"string"},"name":"route-map-id"},{"definition":{"enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"key":{"enum":["ip-next-hop-peer-address","ip-next-hop","ip-next-hop-unchanged","ip6-next-hop-peer-address","ip6-next-hop-prefer-global","ip6-next-hop","local-preference","tag","weight","metric","src"],"type":"string"},"value":{"description":"Value that the field should be set to.","format_description":"","optional":1,"type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"set"}],"permissions":{"expression":{"check":["perm","/sdn/route-maps/{route-map-id}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8e338c91cb28cd827cb9b8a0daf6935b23a7ed03bb1eb1cde0439afe98902744","description":"SDN vnets index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{vnet}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"alias":{"description":"Alias name of the VNet.","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})","properties":{},"type":"string"},"digest":{"description":"Digest of the VNet section.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"isolate-ports":{"description":"If true, sets the isolated property for all interfaces on the bridge of this VNet.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"pending":{"description":"Changes that have not yet been applied to the running configuration.","enum":[],"extra":{},"optional":true,"properties":{"alias":{"description":"Alias name of the VNet.","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})","properties":{},"type":"string"},"isolate-ports":{"description":"If true, sets the isolated property for all interfaces on the bridge of this VNet.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"tag":{"description":"VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).","enum":[],"extra":{},"maximum":16777215,"minimum":1,"optional":true,"properties":{},"type":"integer"},"vlanaware":{"description":"Allow VLANs to pass through this VNet.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"zone":{"description":"Name of the zone this VNet belongs to.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"state":{"description":"State of the SDN configuration object.","enum":["new","changed","deleted"],"extra":{},"optional":true,"properties":{},"type":"string"},"tag":{"description":"VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).","enum":[],"extra":{},"maximum":16777215,"minimum":1,"optional":true,"properties":{},"type":"integer"},"type":{"description":"Type of the VNet.","enum":["vnet"],"extra":{},"optional":false,"properties":{},"type":"string"},"vlanaware":{"description":"Allow VLANs to pass through this VNet.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"vnet":{"description":"Name of the VNet.","enum":[],"extra":{},"optional":false,"properties":{},"type":"string"},"zone":{"description":"Name of the zone this VNet belongs to.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"a370eb9cad0b774b0d82c19fa8d54a7fe7870c1e3269863f4d36a1e674331099","description":"Create a new sdn vnet object.","extra":{},"name":"create","parameters":[{"definition":{"description":"Alias name of the VNet.","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})","properties":{},"type":"string"},"name":"alias"},{"definition":{"description":"If true, sets the isolated property for all interfaces on the bridge of this VNet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"isolate-ports"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"description":"VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).","enum":[],"extra":{"typetext":" (1 - 16777215)"},"maximum":16777215,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"tag"},{"definition":{"description":"Type of the VNet.","enum":["vnet"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"Allow VLANs to pass through this vnet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"vlanaware"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"},{"definition":{"description":"Name of the zone this VNet belongs to.","enum":[],"extra":{"typetext":""},"optional":false,"properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/vnets"},{"extra":{},"methods":[{"allow_token":true,"checksum":"371fb97826c9c1dc1a11de1e6d8e13c15958c29cf1fd8df100e4a74b94f72e6f","description":"Delete sdn vnet object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Require 'SDN.Allocate' permission on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f2fe9e1973ef29eeeb2908f2bf99444765ed8a2fdceca60a51622f740f10f746","description":"Read sdn vnet configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"alias":{"description":"Alias name of the VNet.","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})","properties":{},"type":"string"},"digest":{"description":"Digest of the VNet section.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"isolate-ports":{"description":"If true, sets the isolated property for all interfaces on the bridge of this VNet.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"pending":{"description":"Changes that have not yet been applied to the running configuration.","enum":[],"extra":{},"optional":true,"properties":{"alias":{"description":"Alias name of the VNet.","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})","properties":{},"type":"string"},"isolate-ports":{"description":"If true, sets the isolated property for all interfaces on the bridge of this VNet.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"tag":{"description":"VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).","enum":[],"extra":{},"maximum":16777215,"minimum":1,"optional":true,"properties":{},"type":"integer"},"vlanaware":{"description":"Allow VLANs to pass through this VNet.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"zone":{"description":"Name of the zone this VNet belongs to.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"state":{"description":"State of the SDN configuration object.","enum":["new","changed","deleted"],"extra":{},"optional":true,"properties":{},"type":"string"},"tag":{"description":"VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).","enum":[],"extra":{},"maximum":16777215,"minimum":1,"optional":true,"properties":{},"type":"integer"},"type":{"description":"Type of the VNet.","enum":["vnet"],"extra":{},"optional":false,"properties":{},"type":"string"},"vlanaware":{"description":"Allow VLANs to pass through this VNet.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"vnet":{"description":"Name of the VNet.","enum":[],"extra":{},"optional":false,"properties":{},"type":"string"},"zone":{"description":"Name of the zone this VNet belongs to.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}}},"verb":"GET"},{"allow_token":true,"checksum":"a3007a5f6823a1734397fe11ef242bf51d9d45d123ce114fc869226cc7494512","description":"Update sdn vnet object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"Alias name of the VNet.","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})","properties":{},"type":"string"},"name":"alias"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"If true, sets the isolated property for all interfaces on the bridge of this VNet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"isolate-ports"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"description":"VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).","enum":[],"extra":{"typetext":" (1 - 16777215)"},"maximum":16777215,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"tag"},{"definition":{"description":"Allow VLANs to pass through this vnet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"vlanaware"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"},{"definition":{"description":"Name of the zone this VNet belongs to.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"zone"}],"permissions":{"description":"Require 'SDN.Allocate' permission on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/vnets/{vnet}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"74ff7287f8d0878f5c670e8a7d21103a0a98f4c590f00ced0fa708b9b9723d73","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"}],"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/sdn/vnets/{vnet}/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"59adc44ffe9a486a678006847459f0390cac590af89d8b4d5d0c3e9514ac68f9","description":"Get vnet firewall options.","extra":{},"name":"get_options","parameters":[{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"enable":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"log_level_forward":{"description":"Log level for forwarded traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"policy_forward":{"description":"Forward policy.","enum":["ACCEPT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"2aecfaeba2b92bea7e1972a0a7c2643df1a706c0866974e84495ac79f7e8916f","description":"Set Firewall options.","extra":{},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Log level for forwarded traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_forward"},{"definition":{"description":"Forward policy.","enum":["ACCEPT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_forward"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Needs SDN.Allocate permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/vnets/{vnet}/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"031efaa673cc122608c67fbe806bbd2ba2f8ef813ed44a4d2d7580972971a99e","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"action":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name","enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"description":"Descriptive comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"description":"Restrict packet destination address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"description":"Restrict TCP/UDP destination port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"description":"Flag to enable/disable a rule","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"description":"Network interface name. You have to use network configuration key names for VMs and containers","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"description":"IP version (4 or 6) - automatically determined from source/dest addresses","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"description":"Use predefined standard macro","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"description":"Rule position in the ruleset","enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"description":"Restrict packet source address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"description":"Restrict TCP/UDP source port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Rule type","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"48e89a056a0691d5e8ab352b6f0e7653bc6ae74f340dc35222fbb3eab85aab9b","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Needs SDN.Allocate permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/vnets/{vnet}/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"eb55fdd3b558e38416b7f39bffb7a61d25c262ae4e22c1dc0c0a24172be73345","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Needs SDN.Allocate permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"e17a437f7912130deaf7432afa6c0c6918eb58bc5997af6c065c503ec078960c","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name","enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"description":"Descriptive comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"description":"Restrict packet destination address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"description":"Restrict TCP/UDP destination port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"description":"Flag to enable/disable a rule","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"description":"Network interface name. You have to use network configuration key names for VMs and containers","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"description":"IP version (4 or 6) - automatically determined from source/dest addresses","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"description":"Use predefined standard macro","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"description":"Rule position in the ruleset","enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"description":"Restrict packet source address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"description":"Restrict TCP/UDP source port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Rule type","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"dbfe2bcb4515e6b2f8c858b72d840e1398ab8c0946b390c08058a36a72b4126a","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Needs SDN.Allocate permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6ed136778d933dc973892ce1047fe3764b5776b3ddec5dabdf6fffc77b5c2abb","description":"Delete IP Mappings in a VNet","extra":{},"name":"ipdelete","parameters":[{"definition":{"description":"The IP address to delete","enum":[],"extra":{"typetext":""},"format":"ip","properties":{},"type":"string"},"name":"ip"},{"definition":{"description":"Unicast MAC address.","enum":[],"extra":{"format_description":"XX:XX:XX:XX:XX:XX","typetext":"","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"format":"mac-addr","optional":true,"properties":{},"type":"string"},"name":"mac"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}/{vnet}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"e57c4a84f28a8ce4ef800477c1c59e71c723b71f2e5845e641314820293ff031","description":"Create IP Mapping in a VNet","extra":{},"name":"ipcreate","parameters":[{"definition":{"description":"The IP address to associate with the given MAC address","enum":[],"extra":{"typetext":""},"format":"ip","properties":{},"type":"string"},"name":"ip"},{"definition":{"description":"Unicast MAC address.","enum":[],"extra":{"format_description":"XX:XX:XX:XX:XX:XX","typetext":"","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"format":"mac-addr","optional":true,"properties":{},"type":"string"},"name":"mac"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}/{vnet}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"6a9d82ef367e3cbb79df0cf3f761ccb61e3f9f09518dfa59c0f0542c30f9e906","description":"Update IP Mapping in a VNet","extra":{},"name":"ipupdate","parameters":[{"definition":{"description":"The IP address to associate with the given MAC address","enum":[],"extra":{"typetext":""},"format":"ip","properties":{},"type":"string"},"name":"ip"},{"definition":{"description":"Unicast MAC address.","enum":[],"extra":{"format_description":"XX:XX:XX:XX:XX:XX","typetext":"","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"format":"mac-addr","optional":true,"properties":{},"type":"string"},"name":"mac"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}/{vnet}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/vnets/{vnet}/ips"},{"extra":{},"methods":[{"allow_token":true,"checksum":"62816000f7d0f98c42b59f41685b1f79cdeea4c06ed7d538c33ec3ae26e0c361","description":"SDN subnets index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subnet}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"e5e57ab6633347d6e7efe08c2033ff98700da9a769ae72a6505f16169a107383","description":"Create a new sdn subnet object.","extra":{},"name":"create","parameters":[{"definition":{"description":"IP address for the DNS server","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"dhcp-dns-server"},{"definition":{"description":"A list of DHCP ranges for this subnet","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-sdn-dhcp-range","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"dhcp-range"},{"definition":{"description":"dns domain zone prefix ex: 'adm' -> .adm.mydomain.com","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"dnszoneprefix"},{"definition":{"description":"Subnet Gateway: Will be assign on vnet for layer3 zones","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"gateway"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"description":"enable masquerade for this subnet if pve-firewall","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"snat"},{"definition":{"description":"The SDN subnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-subnet-id","properties":{},"type":"string"},"name":"subnet"},{"definition":{"enum":["subnet"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"associated vnet","enum":[],"extra":{"typetext":""},"optional":false,"properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Require 'SDN.Allocate' permission on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/vnets/{vnet}/subnets"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dd98d45d9c5f0bf9fe5c3e7bfa6c08a8eb894e12d180fb568257de189a48d630","description":"Delete sdn subnet object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"description":"The SDN subnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-subnet-id","properties":{},"type":"string"},"name":"subnet"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Require 'SDN.Allocate' permission on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"1105dce5623e03e8ce47ea836eb3d0c8fb4d9da65f83c5382637ae38e718084e","description":"Read sdn subnet configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"The SDN subnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-subnet-id","properties":{},"type":"string"},"name":"subnet"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"52554619f9775fd36769a2346d588ca21f0d044b604393c6de1545ad92474cbf","description":"Update sdn subnet object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"IP address for the DNS server","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"dhcp-dns-server"},{"definition":{"description":"A list of DHCP ranges for this subnet","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-sdn-dhcp-range","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"dhcp-range"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"dns domain zone prefix ex: 'adm' -> .adm.mydomain.com","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"dnszoneprefix"},{"definition":{"description":"Subnet Gateway: Will be assign on vnet for layer3 zones","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"gateway"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"description":"enable masquerade for this subnet if pve-firewall","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"snat"},{"definition":{"description":"The SDN subnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-subnet-id","properties":{},"type":"string"},"name":"subnet"},{"definition":{"description":"associated vnet","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Require 'SDN.Allocate' permission on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/vnets/{vnet}/subnets/{subnet}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4275d5445579fe89c56f0e553f17dc053022893c398b9fb3197898b57614a72e","description":"SDN zones index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"Only list SDN zones of specific type","enum":["evpn","faucet","qinq","simple","vlan","vxlan"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{zone}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"advertise-subnets":{"description":"Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes). EVPN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bridge":{"description":"the bridge for which VLANs should be managed. VLAN & QinQ zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"bridge-disable-mac-learning":{"description":"Disable auto mac learning. VLAN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"controller":{"description":"ID of the controller for this zone. EVPN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dhcp":{"description":"Name of DHCP server backend for this zone.","enum":["dnsmasq"],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Digest of the controller section.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"disable-arp-nd-suppression":{"description":"Suppress IPv4 ARP && IPv6 Neighbour Discovery messages. EVPN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"dns":{"description":"ID of the DNS server for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dnszone":{"description":"Domain name for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"exitnodes":{"description":"List of PVE Nodes that should act as exit node for this zone. EVPN zone only.","enum":[],"extra":{},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"exitnodes-local-routing":{"description":"Create routes on the exit nodes, so they can connect to EVPN guests. EVPN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"exitnodes-primary":{"description":"Force traffic through this exitnode first. EVPN zone only.","enum":[],"extra":{},"format":"pve-node","optional":true,"properties":{},"type":"string"},"ipam":{"description":"ID of the IPAM for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mac":{"description":"MAC address of the anycast router for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mtu":{"description":"MTU of the zone, will be used for the created VNet bridges.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"nodes":{"description":"Nodes where this zone should be created.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"peers":{"description":"Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes. VXLAN zone only.","enum":[],"extra":{},"format":"ip-list","optional":true,"properties":{},"type":"string"},"pending":{"description":"Changes that have not yet been applied to the running configuration.","enum":[],"extra":{},"optional":true,"properties":{"advertise-subnets":{"description":"Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes). EVPN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bridge":{"description":"the bridge for which VLANs should be managed. VLAN & QinQ zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"bridge-disable-mac-learning":{"description":"Disable auto mac learning. VLAN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"controller":{"description":"ID of the controller for this zone. EVPN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dhcp":{"description":"Name of DHCP server backend for this zone.","enum":["dnsmasq"],"extra":{},"optional":true,"properties":{},"type":"string"},"disable-arp-nd-suppression":{"description":"Suppress IPv4 ARP && IPv6 Neighbour Discovery messages. EVPN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"dns":{"description":"ID of the DNS server for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dnszone":{"description":"Domain name for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"exitnodes":{"description":"List of PVE Nodes that should act as exit node for this zone. EVPN zone only.","enum":[],"extra":{},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"exitnodes-local-routing":{"description":"Create routes on the exit nodes, so they can connect to EVPN guests. EVPN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"exitnodes-primary":{"description":"Force traffic through this exitnode first. EVPN zone only.","enum":[],"extra":{},"format":"pve-node","optional":true,"properties":{},"type":"string"},"ipam":{"description":"ID of the IPAM for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mac":{"description":"MAC address of the anycast router for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mtu":{"description":"MTU of the zone, will be used for the created VNet bridges.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"nodes":{"description":"Nodes where this zone should be created.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"peers":{"description":"Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes. VXLAN zone only.","enum":[],"extra":{},"format":"ip-list","optional":true,"properties":{},"type":"string"},"reversedns":{"description":"ID of the reverse DNS server for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"rt-import":{"description":"Route-Targets that should be imported into the VRF of this zone via BGP. EVPN zone only.","enum":[],"extra":{},"format":"pve-sdn-bgp-rt-list","optional":true,"properties":{},"type":"string"},"secondary-controllers":{"description":"Additional controllers.","enum":[],"extra":{},"items":{"description":"Controller ID.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"tag":{"description":"Service-VLAN Tag (outer VLAN). QinQ zone only","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"vlan-protocol":{"default":"802.1q","description":"VLAN protocol for the creation of the QinQ zone. QinQ zone only.","enum":["802.1q","802.1ad"],"extra":{},"optional":true,"properties":{},"type":"string"},"vrf-vxlan":{"description":"VNI for the zone VRF. EVPN zone only.","enum":[],"extra":{},"maximum":16777215,"minimum":1,"optional":true,"properties":{},"type":"integer"},"vxlan-port":{"default":4789,"description":"UDP port that should be used for the VXLAN tunnel (default 4789). VXLAN zone only.","enum":[],"extra":{},"maximum":65536,"minimum":1,"optional":true,"properties":{},"type":"integer"}},"type":"object"},"reversedns":{"description":"ID of the reverse DNS server for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"rt-import":{"description":"Route-Targets that should be imported into the VRF of this zone via BGP. EVPN zone only.","enum":[],"extra":{},"format":"pve-sdn-bgp-rt-list","optional":true,"properties":{},"type":"string"},"secondary-controllers":{"description":"Additional controllers.","enum":[],"extra":{},"items":{"description":"Controller ID.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"state":{"description":"State of the SDN configuration object.","enum":["new","changed","deleted"],"extra":{},"optional":true,"properties":{},"type":"string"},"tag":{"description":"Service-VLAN Tag (outer VLAN). QinQ zone only","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"type":{"description":"Type of the zone.","enum":["evpn","faucet","qinq","simple","vlan","vxlan"],"extra":{},"properties":{},"type":"string"},"vlan-protocol":{"default":"802.1q","description":"VLAN protocol for the creation of the QinQ zone. QinQ zone only.","enum":["802.1q","802.1ad"],"extra":{},"optional":true,"properties":{},"type":"string"},"vrf-vxlan":{"description":"VNI for the zone VRF. EVPN zone only.","enum":[],"extra":{},"maximum":16777215,"minimum":1,"optional":true,"properties":{},"type":"integer"},"vxlan-port":{"default":4789,"description":"UDP port that should be used for the VXLAN tunnel (default 4789). VXLAN zone only.","enum":[],"extra":{},"maximum":65536,"minimum":1,"optional":true,"properties":{},"type":"integer"},"zone":{"description":"Name of the zone.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"a9296bfcb081bf33cd789da93adbf2ff32d59f0611b524a65e8cb49a5ead6bea","description":"Create a new sdn zone object.","extra":{},"name":"create","parameters":[{"definition":{"description":"Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"advertise-subnets"},{"definition":{"description":"The bridge for which VLANs should be managed.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"bridge"},{"definition":{"description":"Disable auto mac learning.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bridge-disable-mac-learning"},{"definition":{"description":"Controller for this zone.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"Type of the DHCP backend for this zone","enum":["dnsmasq"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"dhcp"},{"definition":{"description":"Suppress IPv4 ARP && IPv6 Neighbour Discovery messages.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable-arp-nd-suppression"},{"definition":{"description":"dns api server","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dns"},{"definition":{"description":"dns domain zone ex: mydomain.com","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"dnszone"},{"definition":{"description":"Faucet dataplane id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"dp-id"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"exitnodes"},{"definition":{"description":"Allow exitnodes to connect to EVPN guests.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"exitnodes-local-routing"},{"definition":{"description":"Force traffic through this exitnode first.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"exitnodes-primary"},{"definition":{"description":"SDN fabric to use as underlay for this VXLAN zone.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-fabric-id","optional":true,"properties":{},"type":"string"},"name":"fabric"},{"definition":{"description":"use a specific ipam","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ipam"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"description":"Anycast logical router mac address.","enum":[],"extra":{"typetext":""},"format":"mac-addr","optional":true,"properties":{},"type":"string"},"name":"mac"},{"definition":{"description":"MTU of the zone, will be used for the created VNet bridges.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"peers"},{"definition":{"description":"reverse dns api server","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"reversedns"},{"definition":{"description":"List of Route Targets that should be imported into the VRF of the zone.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-bgp-rt-list","optional":true,"properties":{},"type":"string"},"name":"rt-import"},{"definition":{"description":"Additional controllers.","enum":[],"extra":{"typetext":""},"items":{"description":"Controller ID.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"secondary-controllers"},{"definition":{"description":"Service-VLAN Tag (outer VLAN)","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"tag"},{"definition":{"description":"Plugin type.","enum":["evpn","faucet","qinq","simple","vlan","vxlan"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"},{"definition":{"default":"802.1q","description":"Which VLAN protocol should be used for the creation of the QinQ zone.","enum":["802.1q","802.1ad"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"vlan-protocol"},{"definition":{"description":"VNI for the zone VRF.","enum":[],"extra":{"typetext":" (1 - 16777215)"},"maximum":16777215,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vrf-vxlan"},{"definition":{"default":4789,"description":"UDP port that should be used for the VXLAN tunnel (default 4789).","enum":[],"extra":{"typetext":" (1 - 65536)"},"maximum":65536,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vxlan-port"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/zones"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6695e62470f23eff31e43d77ae3f71c6e13aa042e689683acb07c85ad024f125","description":"Delete sdn zone object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f29d7c10d9bbce6245b6a8fa85e2d8edda6a4c3463861d58f5f7cd04bf42591c","description":"Read sdn zone configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"advertise-subnets":{"description":"Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes). EVPN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bridge":{"description":"the bridge for which VLANs should be managed. VLAN & QinQ zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"bridge-disable-mac-learning":{"description":"Disable auto mac learning. VLAN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"controller":{"description":"ID of the controller for this zone. EVPN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dhcp":{"description":"Name of DHCP server backend for this zone.","enum":["dnsmasq"],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Digest of the controller section.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"disable-arp-nd-suppression":{"description":"Suppress IPv4 ARP && IPv6 Neighbour Discovery messages. EVPN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"dns":{"description":"ID of the DNS server for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dnszone":{"description":"Domain name for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"exitnodes":{"description":"List of PVE Nodes that should act as exit node for this zone. EVPN zone only.","enum":[],"extra":{},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"exitnodes-local-routing":{"description":"Create routes on the exit nodes, so they can connect to EVPN guests. EVPN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"exitnodes-primary":{"description":"Force traffic through this exitnode first. EVPN zone only.","enum":[],"extra":{},"format":"pve-node","optional":true,"properties":{},"type":"string"},"ipam":{"description":"ID of the IPAM for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mac":{"description":"MAC address of the anycast router for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mtu":{"description":"MTU of the zone, will be used for the created VNet bridges.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"nodes":{"description":"Nodes where this zone should be created.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"peers":{"description":"Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes. VXLAN zone only.","enum":[],"extra":{},"format":"ip-list","optional":true,"properties":{},"type":"string"},"pending":{"description":"Changes that have not yet been applied to the running configuration.","enum":[],"extra":{},"optional":true,"properties":{"advertise-subnets":{"description":"Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes). EVPN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bridge":{"description":"the bridge for which VLANs should be managed. VLAN & QinQ zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"bridge-disable-mac-learning":{"description":"Disable auto mac learning. VLAN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"controller":{"description":"ID of the controller for this zone. EVPN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dhcp":{"description":"Name of DHCP server backend for this zone.","enum":["dnsmasq"],"extra":{},"optional":true,"properties":{},"type":"string"},"disable-arp-nd-suppression":{"description":"Suppress IPv4 ARP && IPv6 Neighbour Discovery messages. EVPN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"dns":{"description":"ID of the DNS server for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dnszone":{"description":"Domain name for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"exitnodes":{"description":"List of PVE Nodes that should act as exit node for this zone. EVPN zone only.","enum":[],"extra":{},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"exitnodes-local-routing":{"description":"Create routes on the exit nodes, so they can connect to EVPN guests. EVPN zone only.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"exitnodes-primary":{"description":"Force traffic through this exitnode first. EVPN zone only.","enum":[],"extra":{},"format":"pve-node","optional":true,"properties":{},"type":"string"},"ipam":{"description":"ID of the IPAM for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mac":{"description":"MAC address of the anycast router for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mtu":{"description":"MTU of the zone, will be used for the created VNet bridges.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"nodes":{"description":"Nodes where this zone should be created.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"peers":{"description":"Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes. VXLAN zone only.","enum":[],"extra":{},"format":"ip-list","optional":true,"properties":{},"type":"string"},"reversedns":{"description":"ID of the reverse DNS server for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"rt-import":{"description":"Route-Targets that should be imported into the VRF of this zone via BGP. EVPN zone only.","enum":[],"extra":{},"format":"pve-sdn-bgp-rt-list","optional":true,"properties":{},"type":"string"},"secondary-controllers":{"description":"Additional controllers.","enum":[],"extra":{},"items":{"description":"Controller ID.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"tag":{"description":"Service-VLAN Tag (outer VLAN). QinQ zone only","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"vlan-protocol":{"default":"802.1q","description":"VLAN protocol for the creation of the QinQ zone. QinQ zone only.","enum":["802.1q","802.1ad"],"extra":{},"optional":true,"properties":{},"type":"string"},"vrf-vxlan":{"description":"VNI for the zone VRF. EVPN zone only.","enum":[],"extra":{},"maximum":16777215,"minimum":1,"optional":true,"properties":{},"type":"integer"},"vxlan-port":{"default":4789,"description":"UDP port that should be used for the VXLAN tunnel (default 4789). VXLAN zone only.","enum":[],"extra":{},"maximum":65536,"minimum":1,"optional":true,"properties":{},"type":"integer"}},"type":"object"},"reversedns":{"description":"ID of the reverse DNS server for this zone.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"rt-import":{"description":"Route-Targets that should be imported into the VRF of this zone via BGP. EVPN zone only.","enum":[],"extra":{},"format":"pve-sdn-bgp-rt-list","optional":true,"properties":{},"type":"string"},"secondary-controllers":{"description":"Additional controllers.","enum":[],"extra":{},"items":{"description":"Controller ID.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"state":{"description":"State of the SDN configuration object.","enum":["new","changed","deleted"],"extra":{},"optional":true,"properties":{},"type":"string"},"tag":{"description":"Service-VLAN Tag (outer VLAN). QinQ zone only","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"type":{"description":"Type of the zone.","enum":["evpn","faucet","qinq","simple","vlan","vxlan"],"extra":{},"properties":{},"type":"string"},"vlan-protocol":{"default":"802.1q","description":"VLAN protocol for the creation of the QinQ zone. QinQ zone only.","enum":["802.1q","802.1ad"],"extra":{},"optional":true,"properties":{},"type":"string"},"vrf-vxlan":{"description":"VNI for the zone VRF. EVPN zone only.","enum":[],"extra":{},"maximum":16777215,"minimum":1,"optional":true,"properties":{},"type":"integer"},"vxlan-port":{"default":4789,"description":"UDP port that should be used for the VXLAN tunnel (default 4789). VXLAN zone only.","enum":[],"extra":{},"maximum":65536,"minimum":1,"optional":true,"properties":{},"type":"integer"},"zone":{"description":"Name of the zone.","enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"GET"},{"allow_token":true,"checksum":"69d837c36d9ffbcb64c9d714ee4c48cac854aafb3a1bb785b2235d8bc47db2e4","description":"Update sdn zone object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"advertise-subnets"},{"definition":{"description":"The bridge for which VLANs should be managed.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"bridge"},{"definition":{"description":"Disable auto mac learning.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bridge-disable-mac-learning"},{"definition":{"description":"Controller for this zone.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Type of the DHCP backend for this zone","enum":["dnsmasq"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"dhcp"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Suppress IPv4 ARP && IPv6 Neighbour Discovery messages.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable-arp-nd-suppression"},{"definition":{"description":"dns api server","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dns"},{"definition":{"description":"dns domain zone ex: mydomain.com","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"dnszone"},{"definition":{"description":"Faucet dataplane id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"dp-id"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"exitnodes"},{"definition":{"description":"Allow exitnodes to connect to EVPN guests.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"exitnodes-local-routing"},{"definition":{"description":"Force traffic through this exitnode first.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"exitnodes-primary"},{"definition":{"description":"SDN fabric to use as underlay for this VXLAN zone.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-fabric-id","optional":true,"properties":{},"type":"string"},"name":"fabric"},{"definition":{"description":"use a specific ipam","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ipam"},{"definition":{"description":"the token for unlocking the global SDN configuration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lock-token"},{"definition":{"description":"Anycast logical router mac address.","enum":[],"extra":{"typetext":""},"format":"mac-addr","optional":true,"properties":{},"type":"string"},"name":"mac"},{"definition":{"description":"MTU of the zone, will be used for the created VNet bridges.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"peers"},{"definition":{"description":"reverse dns api server","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"reversedns"},{"definition":{"description":"List of Route Targets that should be imported into the VRF of the zone.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-bgp-rt-list","optional":true,"properties":{},"type":"string"},"name":"rt-import"},{"definition":{"description":"Additional controllers.","enum":[],"extra":{"typetext":""},"items":{"description":"Controller ID.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9_-]*[a-zA-Z0-9]","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"secondary-controllers"},{"definition":{"description":"Service-VLAN Tag (outer VLAN)","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"tag"},{"definition":{"default":"802.1q","description":"Which VLAN protocol should be used for the creation of the QinQ zone.","enum":["802.1q","802.1ad"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"vlan-protocol"},{"definition":{"description":"VNI for the zone VRF.","enum":[],"extra":{"typetext":" (1 - 16777215)"},"maximum":16777215,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vrf-vxlan"},{"definition":{"default":4789,"description":"UDP port that should be used for the VXLAN tunnel (default 4789).","enum":[],"extra":{"typetext":" (1 - 65536)"},"maximum":65536,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vxlan-port"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/zones/{zone}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5a589a6f8ca9ac2030fd4d33ef13a80e575465992929b29725526face0399cc5","description":"Get cluster status information.","extra":{},"name":"get_status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"ip":{"description":"[node] IP of the resolved nodename.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"level":{"description":"[node] Proxmox VE Subscription level, indicates if eligible for enterprise support as well as access to the stable Proxmox VE Enterprise Repository.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"local":{"description":"[node] Indicates if this is the responding node.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"nodeid":{"description":"[node] ID of the node from the corosync configuration.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"nodes":{"description":"[cluster] Nodes count, including offline nodes.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"online":{"description":"[node] Indicates if the node is online or offline.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"quorate":{"description":"[cluster] Indicates if there is a majority of nodes online to make decisions","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"type":{"description":"Indicates the type, either cluster or node. The type defines the object properties e.g. quorate available for type cluster.","enum":["cluster","node"],"extra":{},"properties":{},"type":"string"},"version":{"description":"[cluster] Current version of the corosync configuration file.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d04c3b849a0aa5e5920867f414fba45c484719be08796bcbeaf8832f5833fe88","description":"List recent tasks (cluster wide).","extra":{},"name":"tasks","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"upid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/tasks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"31b002c17296ec68232ef7ac7414c584f56baeeefffa7dc7edd05d8ce5e5f183","description":"Cluster node index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{node}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cpu":{"description":"CPU utilization.","enum":[],"extra":{"renderer":"fraction_as_percentage"},"optional":true,"properties":{},"type":"number"},"level":{"description":"Support level.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxcpu":{"description":"Number of available CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Number of available memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"mem":{"description":"Used memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"node":{"description":"The cluster node name.","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"ssl_fingerprint":{"description":"The SSL fingerprint for the node certificate.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"status":{"description":"Node status.","enum":["unknown","online","offline"],"extra":{},"properties":{},"type":"string"},"uptime":{"description":"Node uptime in seconds.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes"},{"extra":{},"methods":[{"allow_token":true,"checksum":"407b3d66a300b7bc4f15ce81eadffc3e3ff161e7940cd646fc925a219be029f3","description":"Node index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"35b8e469447bd0b2011a8dfbb2d764cd4c5d26a960c23bfb523d2b8c078bbaf0","description":"Get list of appliances.","extra":{"proxyto":"node"},"name":"aplinfo","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"00f31028c241d16f472be5f801c7ca88ff829df797400ed826b4eb2177807889","description":"Download appliance templates.","extra":{"proxyto":"node"},"name":"apl_download","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage where the template will be stored","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"The template which will downloaded","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"template"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.AllocateTemplate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/aplinfo"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9fba10841493cc0c3608fd5b429677bf1e44b64bc3298479603a5da713b6c7e6","description":"Directory index for apt (Advanced Package Tool).","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/apt"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f097afd72a9ccd228b09acf28b1519c7411ef32f76e54287af6aa3347a716758","description":"Get package changelogs.","extra":{"proxyto":"node"},"name":"changelog","parameters":[{"definition":{"description":"Package name.","enum":[],"extra":{},"pattern":"(?^:[a-z0-9][-+.a-z0-9:]+)","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Package version.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"version"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/apt/changelog"},{"extra":{},"methods":[{"allow_token":true,"checksum":"31afb6060270acc12e023a6b7f2e929996e408352872438f6456b06ca9790cd0","description":"Get APT repository information.","extra":{"proxyto":"node"},"name":"repositories","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"description":"Result from parsing the APT repository files in /etc/apt/.","enum":[],"extra":{},"properties":{"digest":{"description":"Common digest of all files.","enum":[],"extra":{},"properties":{},"type":"string"},"errors":{"description":"List of problematic repository files.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"error":{"description":"The error message","enum":[],"extra":{},"properties":{},"type":"string"},"path":{"description":"Path to the problematic file.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"files":{"description":"List of parsed repository files.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"digest":{"description":"Digest of the file as bytes.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"integer"},"properties":{},"type":"array"},"file-type":{"description":"Format of the file.","enum":["list","sources"],"extra":{},"properties":{},"type":"string"},"path":{"description":"Path to the problematic file.","enum":[],"extra":{},"properties":{},"type":"string"},"repositories":{"description":"The parsed repositories.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"Comment":{"description":"Associated comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"Components":{"description":"List of repository components","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"Enabled":{"description":"Whether the repository is enabled or not","enum":[],"extra":{},"properties":{},"type":"boolean"},"FileType":{"description":"Format of the defining file.","enum":["list","sources"],"extra":{},"properties":{},"type":"string"},"Options":{"description":"Additional options","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"Key":{"enum":[],"extra":{},"properties":{},"type":"string"},"Values":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"Suites":{"description":"List of package distribuitions","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"Types":{"description":"List of package types.","enum":[],"extra":{},"items":{"enum":["deb","deb-src"],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"URIs":{"description":"List of repository URIs.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"},"infos":{"description":"Additional information/warnings for APT repositories.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"index":{"description":"Index of the associated repository within the file.","enum":[],"extra":{},"properties":{},"type":"string"},"kind":{"description":"Kind of the information (e.g. warning).","enum":[],"extra":{},"properties":{},"type":"string"},"message":{"description":"Information message.","enum":[],"extra":{},"properties":{},"type":"string"},"path":{"description":"Path to the associated file.","enum":[],"extra":{},"properties":{},"type":"string"},"property":{"description":"Property from which the info originates.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"standard-repos":{"description":"List of standard repositories and their configuration status","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"handle":{"description":"Handle to identify the repository.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Full name of the repository.","enum":[],"extra":{},"properties":{},"type":"string"},"status":{"description":"Indicating enabled/disabled status, if the repository is configured.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"2e6c839d6bc3336bbd44277a870b0c9286a191be1f0ab21bc059a03be572b892","description":"Change the properties of a repository. Currently only allows enabling/disabling.","extra":{"proxyto":"node"},"name":"change_repository","parameters":[{"definition":{"description":"Digest to detect modifications.","enum":[],"extra":{"typetext":""},"max_length":80,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Whether the repository should be enabled or not.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"description":"Index within the file (starting from 0).","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"index"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Path to the containing file.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"path"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"fe3a49714d62a93527594a310f2dafe8786e91acabd0932a1d50d07073dca22d","description":"Add a standard repository to the configuration","extra":{"proxyto":"node"},"name":"add_repository","parameters":[{"definition":{"description":"Digest to detect modifications.","enum":[],"extra":{"typetext":""},"max_length":80,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Handle that identifies a repository.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"handle"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/apt/repositories"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6d627194f49290081c35aae4d6df8c7f292fa524c84eabd091f9090b81c2b907","description":"List available updates.","extra":{"proxyto":"node"},"name":"list_updates","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"Arch":{"description":"Package Architecture.","enum":["armhf","arm64","amd64","ppc64el","risc64","s390x","all"],"extra":{},"properties":{},"type":"string"},"Description":{"description":"Package description.","enum":[],"extra":{},"properties":{},"type":"string"},"NotifyStatus":{"description":"Version for which PVE has already sent an update notification for.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"OldVersion":{"description":"Old version currently installed.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"Origin":{"description":"Package origin, e.g., 'Proxmox' or 'Debian'.","enum":[],"extra":{},"properties":{},"type":"string"},"Package":{"description":"Package name.","enum":[],"extra":{},"properties":{},"type":"string"},"Priority":{"description":"Package priority.","enum":[],"extra":{},"properties":{},"type":"string"},"Section":{"description":"Package section.","enum":[],"extra":{},"properties":{},"type":"string"},"Title":{"description":"Package title.","enum":[],"extra":{},"properties":{},"type":"string"},"Version":{"description":"New version to be updated to.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"09f04ca9f5dcb082fe70acb881878e191627a740681aa9102b533d1d2f8fc8af","description":"This is used to resynchronize the package index files from their sources (apt-get update).","extra":{"proxyto":"node"},"name":"update_database","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Send notification about new packages.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"notify"},{"definition":{"default":0,"description":"Only produces output suitable for logging, omitting progress indicators.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"quiet"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/apt/update"},{"extra":{},"methods":[{"allow_token":true,"checksum":"723afbe9bd6b6862c97010bad28e4ab5797bbab6dfaa02819e50887db1d8297e","description":"Get package information for important Proxmox packages.","extra":{"proxyto":"node"},"name":"versions","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"Arch":{"description":"Package Architecture.","enum":["armhf","arm64","amd64","ppc64el","risc64","s390x","all"],"extra":{},"properties":{},"type":"string"},"CurrentState":{"description":"Current state of the package installed on the system.","enum":["Installed","NotInstalled","UnPacked","HalfConfigured","HalfInstalled","ConfigFiles"],"extra":{},"properties":{},"type":"string"},"Description":{"description":"Package description.","enum":[],"extra":{},"properties":{},"type":"string"},"ManagerVersion":{"description":"Version of the currently running pve-manager API server.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"NotifyStatus":{"description":"Version for which PVE has already sent an update notification for.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"OldVersion":{"description":"Old version currently installed.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"Origin":{"description":"Package origin, e.g., 'Proxmox' or 'Debian'.","enum":[],"extra":{},"properties":{},"type":"string"},"Package":{"description":"Package name.","enum":[],"extra":{},"properties":{},"type":"string"},"Priority":{"description":"Package priority.","enum":[],"extra":{},"properties":{},"type":"string"},"RunningKernel":{"description":"Kernel release, only for package 'proxmox-ve'.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"Section":{"description":"Package section.","enum":[],"extra":{},"properties":{},"type":"string"},"Title":{"description":"Package title.","enum":[],"extra":{},"properties":{},"type":"string"},"Version":{"description":"New version to be updated to.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/apt/versions"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0e880e2b1468a212109760bcfe03031f46a2fe2c5a1055a27f650fb0caa212ab","description":"Node capabilities index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/capabilities"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5d4f52f8672fa0bb2c55f7490562dc12c47dd83171061655b6df0bb4d75a39c5","description":"QEMU capabilities index.","extra":{"proxyto":"node"},"name":"qemu_caps_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/capabilities/qemu"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f09f34b23570cffd167671d9dfd63d2d2bfe3e394817724eea3ca825b6cb7362","description":"List all custom and default CPU models.","extra":{},"name":"index","parameters":[{"definition":{"description":"Virtual processor architecture. Defaults to the host architecture.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Custom models are filtered to those the current user has any of Mapping.{Audit,Use,Modify} on /mapping/cpu/; Sys.Audit on /nodes continues to grant visibility of all custom models for back-compat.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"abstract":{"description":"True for PVE-internal abstract profiles like x86-64-v2, -v3, -v4. These do not correspond to a QEMU CPU type and cannot be used as a custom model's 'reported-model'.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"custom":{"description":"True if this is a custom CPU model.","enum":[],"extra":{},"properties":{},"type":"boolean"},"name":{"description":"Name of the CPU model. Identifies it for subsequent API calls. Prefixed with 'custom-' for custom models.","enum":[],"extra":{},"properties":{},"type":"string"},"vendor":{"description":"CPU vendor visible to the guest when this model is selected. Vendor of 'reported-model' in case of custom models.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/capabilities/qemu/cpu"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a299063dceb8e355ad1ed3db9be2fe16dece8877548b9f1d3608c6474d697262","description":"List of available VM-specific CPU flags. Returns an empty list for 'aarch64' as no VM-specific flags are defined for it yet.","extra":{},"name":"index","parameters":[{"definition":{"default":"kvm","description":"Acceleration type to check node compatibility for.","enum":["kvm","tcg"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"accel"},{"definition":{"description":"Virtual processor architecture. Defaults to the host architecture.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"description":{"description":"Description of the CPU flag.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"Name of the CPU flag.","enum":[],"extra":{},"properties":{},"type":"string"},"supported-on":{"description":"List of nodes supporting the CPU flag with the selected acceleration type (\"accel\").","enum":[],"extra":{},"items":{"description":"The cluster node name.","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/capabilities/qemu/cpu-flags"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1c60ed215fd6a6e98ef6f1b87a09ad6e0ff1bd22f1caf3ed35c02f2d43957958","description":"Get available QEMU/KVM machine types.","extra":{"proxyto":"node"},"name":"types","parameters":[{"definition":{"description":"Virtual processor architecture. Defaults to the host architecture.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"changes":{"description":"Notable changes of a version, currently only set for +pveX versions.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"description":"Full name of machine type and version.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The machine type.","enum":["q35","i440fx"],"extra":{},"properties":{},"type":"string"},"version":{"description":"The machine version.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/capabilities/qemu/machines"},{"extra":{},"methods":[{"allow_token":true,"checksum":"87df0906443353a213b04c84e8236231f4cdaadd4f2cee97a48daf45bb4ab362","description":"Get node-specific QEMU migration capabilities of the node. Requires the 'Sys.Audit' permission on '/nodes/'.","extra":{"proxyto":"node"},"name":"capabilities","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"has-dbus-vmstate":{"description":"Whether the host supports live-migrating additional VM state via the dbus-vmstate helper.","enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/capabilities/qemu/migration"},{"extra":{},"methods":[{"allow_token":true,"checksum":"50808c982a4bc72c9bba3f95d85803db4a5a6d9897255ac750c522b0369f4f21","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph"},{"extra":{},"methods":[{"allow_token":true,"checksum":"23dca6507cde2ae0cabadf81020c2e06e2c8878c3e19c7356ba7dbc49c506a9a","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/cfg"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ba62d42af6f0692125280e7be165a864bfaaf992750789bb9553bf3e2bb3765a","description":"Get the Ceph configuration database.","extra":{"proxyto":"node"},"name":"db","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"can_update_at_runtime":{"description":"Set if the value can be changed at runtime without restarting the affected daemons. Emitted as the integer 1/0 to match the existing PVE wire convention.","enum":[],"extra":{},"properties":{},"type":"boolean"},"level":{"description":"Config level the entry is exposed at: 'basic' for operator-visible settings, 'advanced' for tuning parameters, 'dev' for developer-only knobs.","enum":["basic","advanced","dev"],"extra":{},"properties":{},"type":"string"},"mask":{"description":"Match expression restricting the entry's scope; empty when the entry has no mask. Examples: 'host:foo', 'class:ssd'.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Config key name.","enum":[],"extra":{},"properties":{},"type":"string"},"section":{"description":"Ceph config section the entry applies to: 'global', a daemon type ('mon', 'osd', 'mgr', 'mds', 'client'), or a specific daemon (e.g. 'osd.0', 'mon.').","enum":[],"extra":{},"properties":{},"type":"string"},"value":{"description":"Configured value for the key (always serialised as a string by Ceph, regardless of the option's underlying type).","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/cfg/db"},{"extra":{},"methods":[{"allow_token":true,"checksum":"566ab98133cdf7bf8664225da85a43166f5b253cad7a29e5b5d58b8f36b11786","description":"Get the Ceph configuration file.","extra":{"proxyto":"node"},"name":"raw","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/ceph/cfg/raw"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2c3b36edb17d72b5707c24f3f84ecd33e0631292c7667875724c09d65fdfdd1d","description":"Get configured values from either ceph.conf or the mon config DB. Underscores in section and key names are normalised to hyphens in the response, regardless of how they're written in the source.","extra":{"proxyto":"node"},"name":"value","parameters":[{"definition":{"description":"List of
: items separated by semicolon, comma or space.","enum":[],"extra":{"typetext":"
:[;|,|
:]"},"max_length":4096,"pattern":"(?^:^(?:(?^i:[0-9a-z\\-_\\.]+:[0-9a-zA-Z\\-_]+))(?:[;, ](?^i:[0-9a-z\\-_\\.]+:[0-9a-zA-Z\\-_]+))*$)","properties":{},"type":"string"},"name":"config-keys"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"description":"Two-level map of {section} -> {key} -> value. Underscores in section and key names are normalised to hyphens.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/cfg/value"},{"extra":{},"methods":[{"allow_token":true,"checksum":"65dc965e9fdbdb371ee7c2c78390e21cf5c6ad46c0a43453881edd203f8e4f75","description":"Heuristical check if it is safe to perform an action.","extra":{"proxyto":"node"},"name":"cmd_safety","parameters":[{"definition":{"description":"Action to check","enum":["stop","destroy"],"extra":{},"properties":{},"type":"string"},"name":"action"},{"definition":{"description":"ID of the service","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service type","enum":["osd","mon","mds"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"safe":{"description":"True if Ceph reports the requested action is safe.","enum":[],"extra":{},"properties":{},"type":"boolean"},"status":{"description":"Human-readable status message from Ceph (typically the reason an action is not safe); absent when Ceph returned no message.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/cmd-safety"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e0322c6f07c65f5c1619204f0c7e670156521f47e8951f35563c74787459eefd","description":"Get OSD crush map","extra":{"proxyto":"node"},"name":"crush","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/ceph/crush"},{"extra":{},"methods":[{"allow_token":true,"checksum":"08ccb5f5c4117f5f6ec401452223514ac48d5b8d5c3d24e8afebff114b8d6be5","description":"Directory index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"data_pool":{"description":"Name of the filesystem's first data pool. A CephFS can have more than one data pool; consumers interested in the full set should read 'data_pools' instead. Kept for backwards compatibility.","enum":[],"extra":{},"properties":{},"type":"string"},"data_pool_ids":{"description":"Numeric ids of the data pools.","enum":[],"extra":{},"items":{"description":"Data pool id.","enum":[],"extra":{},"properties":{},"type":"integer"},"optional":true,"properties":{},"type":"array"},"data_pools":{"description":"Names of all data pools assigned to the filesystem; a CephFS can have multiple data pools (e.g. replicated metadata plus EC data, or multiple device-class-specific data pools).","enum":[],"extra":{},"items":{"description":"Data pool name.","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"metadata_pool":{"description":"Name of the metadata pool.","enum":[],"extra":{},"properties":{},"type":"string"},"metadata_pool_id":{"description":"Numeric id of the metadata pool.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"name":{"description":"The ceph filesystem name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/fs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"cee30cee112bdb825fc54c06ce57208230c99d0fd671f545d48285e53060df37","description":"Destroy a Ceph filesystem. Refuses if any PVE storage entry of type 'cephfs' still references the filesystem and is not disabled. Optionally also removes the storage entries and/or the underlying metadata and data pools.","extra":{"proxyto":"node"},"name":"destroyfs","parameters":[{"definition":{"description":"The Ceph filesystem name.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Remove the metadata and data pools used by this filesystem.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove-pools"},{"definition":{"default":0,"description":"Remove pveceph-managed storages configured for this filesystem.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove-storages"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"a5b590d7b03fcb44ed813d6baec46ceeaa5bca5046b562d1a281ac2004a7c86b","description":"Create a Ceph filesystem","extra":{"proxyto":"node"},"name":"createfs","parameters":[{"definition":{"default":0,"description":"Configure the created CephFS as storage for this cluster.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add-storage"},{"definition":{"default":"cephfs","description":"The ceph filesystem name.","enum":[],"extra":{},"optional":true,"pattern":"(?^:^[^:/\\s]+$)","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":128,"description":"Number of placement groups for the backing data pool. The metadata pool will use a quarter of this.","enum":[],"extra":{"typetext":" (8 - 32768)"},"maximum":32768,"minimum":8,"optional":true,"properties":{},"type":"integer"},"name":"pg_num"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/fs/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a8f6c186debc7bc3acfbb83bcfcff92a20ceddbe705aa40140dc8c6f56f54cd6","description":"Create the initial Ceph default configuration and set up symlinks. Idempotent on re-call: if a [global] section already exists in ceph.conf, the existing fsid / auth / pool defaults are preserved and most parameters are silently ignored.","extra":{"proxyto":"node"},"name":"init","parameters":[{"definition":{"description":"Declare a separate cluster network, OSDs will route heartbeat, object replication and recovery traffic over it","enum":[],"extra":{"requires":"network","typetext":""},"format":"CIDR","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"cluster-network"},{"definition":{"default":0,"description":"Disable cephx authentication.\n\nWARNING: cephx is a security feature protecting against man-in-the-middle attacks. Only consider disabling cephx if your network is private!","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable_cephx"},{"definition":{"default":2,"description":"Minimum number of available replicas per object to allow I/O","enum":[],"extra":{"typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"min_size"},{"definition":{"description":"Use specific network for all ceph related traffic","enum":[],"extra":{"typetext":""},"format":"CIDR","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"network"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":6,"description":"Placement group bits, used to specify the default number of placement groups.\n\nDepreacted. This setting was deprecated in recent Ceph versions.","enum":[],"extra":{"typetext":" (6 - 14)"},"maximum":14,"minimum":6,"optional":true,"properties":{},"type":"integer"},"name":"pg_bits"},{"definition":{"default":3,"description":"Targeted number of replicas per object","enum":[],"extra":{"typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"size"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/init"},{"extra":{},"methods":[{"allow_token":true,"checksum":"73e3ac4f5f588bb6f33e445d80db4176ca8f3a00e7417b118e4c1f763d2a15b1","description":"Read ceph log","extra":{"proxyto":"node"},"name":"log","parameters":[{"definition":{"description":"Maximum number of log lines to return. Defaults to the dump_logfile limit (typically 50) when omitted.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Offset of the first log line to return (0-based).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Log-file line number (1-based).","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Log line text.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"43cb821d0ff9c1e20a52ba41e275fd2d3f2d5e0e45547a960ace5bb1fb25f34c","description":"MDS directory index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"addr":{"description":"Address as advertised by the MDS; Ceph-formatted (typically 'IP:PORT/NONCE').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ceph_version":{"description":"Full Ceph version string of the MDS daemon.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ceph_version_short":{"description":"Short Ceph version string of the MDS daemon (e.g. '19.2.0').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"direxists":{"description":"Set when the MDS's data directory exists on this node.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"fs_name":{"description":"Name of the CephFS this MDS is bound to; absent or null for standby MDSes not currently serving a rank.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"host":{"description":"Host the MDS runs on.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"The name (ID) for the MDS.","enum":[],"extra":{},"properties":{},"type":"string"},"rank":{"description":"MDS rank within the file system; -1 for standby MDSes not currently bound to a rank.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"service":{"description":"Set if a ceph-mds@ systemd unit is enabled on the hosting node; absent otherwise.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"standby_replay":{"description":"If true, the standby MDS is polling the active MDS for faster recovery (hot standby).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"state":{"description":"MDS state: Ceph-reported run state (e.g. 'up:active', 'up:standby', 'up:standby-replay') for daemons known to the cluster; 'stopped' or 'unknown' for configured daemons not visible to the cluster.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/mds"},{"extra":{},"methods":[{"allow_token":true,"checksum":"95bfdf6b725d610975f2cb9b78b5c858072ceb2d7fa1e721df8554522b7ff936","description":"Destroy Ceph Metadata Server","extra":{"proxyto":"node"},"name":"destroymds","parameters":[{"definition":{"description":"The name (ID) of the mds","enum":[],"extra":{},"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"4c29e0b25e7eaae57fee369c5321f25aed81dde88d8595fc4958ef09e7c5805a","description":"Create Ceph Metadata Server (MDS)","extra":{"proxyto":"node"},"name":"createmds","parameters":[{"definition":{"default":0,"description":"Determines whether a ceph-mds daemon should poll and replay the log of an active MDS. Faster switch on MDS failure, but needs more idle resources.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"hotstandby"},{"definition":{"default":"nodename","description":"The ID for the mds, when omitted the same as the nodename","enum":[],"extra":{},"max_length":200,"optional":true,"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/mds/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d46a3e8014514bcc079772ffdf01c705de9824792b283a85c6ea3c0d155ba4c1","description":"MGR directory index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"addr":{"description":"Address as advertised by the manager; Ceph-formatted (typically 'IP:PORT/NONCE').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ceph_version":{"description":"Full Ceph version string of the manager daemon.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ceph_version_short":{"description":"Short Ceph version string of the manager daemon (e.g. '19.2.0').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"direxists":{"description":"Set when the manager's data directory exists on this node.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"host":{"description":"Host the manager runs on.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"The name (ID) for the MGR.","enum":[],"extra":{},"properties":{},"type":"string"},"service":{"description":"Set if a ceph-mgr@ systemd unit is enabled on the hosting node; absent otherwise.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"state":{"description":"Manager state: 'active' or 'standby' for daemons visible to the mgr cluster, 'stopped' or 'unknown' for configured daemons not currently visible.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/mgr"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1b6eac6b4b1058f7d0564b86f899fc1c39d08317e8482afa20115de4fd4c5f3c","description":"Destroy Ceph Manager.","extra":{"proxyto":"node"},"name":"destroymgr","parameters":[{"definition":{"description":"The ID of the manager","enum":[],"extra":{},"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"5bc258b02f9a16ff515482fdd01dfec6b99064f86abd0e8fca882cba78f0d196","description":"Create Ceph Manager","extra":{"proxyto":"node"},"name":"createmgr","parameters":[{"definition":{"default":"nodename","description":"The ID for the manager, when omitted the same as the nodename.","enum":[],"extra":{},"max_length":200,"optional":true,"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/mgr/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7b40d17f2ff612890c19928bda92dafc6432ba74627904000de9e9b9bfcbe6b2","description":"Get Ceph monitor list.","extra":{"proxyto":"node"},"name":"listmon","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"addr":{"description":"Address as advertised by the monitor; Ceph-formatted (typically 'IP:PORT/NONCE', possibly as a messenger-v2 vector depending on Ceph version and ceph.conf shape).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ceph_version":{"description":"Full Ceph version string of the monitor daemon.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ceph_version_short":{"description":"Short Ceph version string of the monitor daemon (e.g. '19.2.0').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"direxists":{"description":"Set when the monitor's data directory exists on this node.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"host":{"description":"Host the monitor runs on.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"Monitor id (typically the hostname).","enum":[],"extra":{},"properties":{},"type":"string"},"quorum":{"description":"Set when the monitor is part of the current quorum.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"rank":{"description":"Rank of the monitor within the mon map.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"service":{"description":"Set if a ceph-mon@ systemd unit is enabled on the hosting node; absent otherwise.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"state":{"description":"Run state of the monitor: 'running' (in quorum), 'stopped' (systemd unit configured but daemon not visible to the cluster), or 'unknown' (no rados access).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/mon"},{"extra":{},"methods":[{"allow_token":true,"checksum":"858e8e74854d7a15a543bc4488c600dea5b2d5df9f19b6c7bf06ed01a94559c3","description":"Destroy a Ceph Monitor. Refuses to remove the last monitor of the cluster. Does not destroy any Manager on the same node; use /nodes/{node}/ceph/mgr/{id} for that.","extra":{"proxyto":"node"},"name":"destroymon","parameters":[{"definition":{"description":"Monitor ID","enum":[],"extra":{},"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"monid"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"549272006e84e0d5c9c51bbfe2487a0e57c5a7ef5b5e85a511e1a5f011f38424","description":"Create a Ceph Monitor. Also auto-creates a Manager for the first monitor.","extra":{"proxyto":"node"},"name":"createmon","parameters":[{"definition":{"description":"Overwrites autodetected monitor IP address(es). Must be in the public network(s) of Ceph.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"mon-address"},{"definition":{"default":"nodename","description":"The ID for the monitor, when omitted the same as the nodename.","enum":[],"extra":{},"max_length":200,"optional":true,"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"monid"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/mon/{monid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"56953015460fc765c3550e673b2314ac13192b751d13667646e633a651367cc8","description":"Get Ceph osd list/tree.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":1},"properties":{"flags":{"description":"Comma-joined list of currently-set OSD flags; absent when no flags are set on the cluster.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"root":{"description":"Top-level CRUSH bucket; recursive structure with 'children' lists holding nested buckets and OSD leaves. Per-node properties (status, weight, in, usage, latencies, etc.) vary by node type and are not statically typed here.","enum":[],"extra":{"additionalProperties":1},"properties":{},"type":"object"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"3ec4db7eece1e9e6aba5972c9c30d9985d7ad675f7e5b99a617d1f44f609eb2e","description":"Create OSD","extra":{"proxyto":"node"},"name":"createosd","parameters":[{"definition":{"description":"Set the device class of the OSD in crush.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"crush-device-class"},{"definition":{"description":"Block device name for block.db.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"db_dev"},{"definition":{"description":"Size in GiB for block.db.","enum":[],"extra":{"requires":"db_dev","typetext":" (1 - N)","verbose_description":"If a block.db is requested but the size is not given, will be automatically selected by: bluestore_block_db_size from the ceph database (osd or global section) or config (osd or global section) in that order. If this is not available, it will be sized 10% of the size of the OSD device. Fails if the available size is not enough."},"minimum":1,"optional":true,"properties":{},"type":"number"},"name":"db_dev_size"},{"definition":{"description":"Block device name.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"dev"},{"definition":{"default":0,"description":"Enables encryption of the OSD.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"encrypted"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD services per physical device. Only useful for fast NVMe devices to utilize their performance better. Mutually exclusive with 'db_dev' and 'wal_dev'.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"osds-per-device"},{"definition":{"description":"Block device name for block.wal.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"wal_dev"},{"definition":{"description":"Size in GiB for block.wal.","enum":[],"extra":{"requires":"wal_dev","typetext":" (0.5 - N)","verbose_description":"If a block.wal is requested but the size is not given, will be automatically selected by: bluestore_block_wal_size from the ceph database (osd or global section) or config (osd or global section) in that order. If this is not available, it will be sized 1% of the size of the OSD device. Fails if the available size is not enough."},"minimum":0.5,"optional":true,"properties":{},"type":"number"},"name":"wal_dev_size"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/osd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5dcec2d00dff70431bc0d8d09a50d18a9ec58561ad54b336508d04545c9bbdee","description":"Destroy OSD","extra":{"proxyto":"node"},"name":"destroyosd","parameters":[{"definition":{"default":0,"description":"If set, also destroy the underlying logical volumes via 'ceph-volume lvm zap --destroy', remove the volume group's physical volume with pvremove, and wipe any journal/block.db/block.wal partitions left over from filestore OSDs. Without this flag the LVs and partitions are left intact for inspection.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"b0f0250fd1edc6d6565b0c04f6252bdec7e416f3d6f5b2209aff3559cf79b1a7","description":"OSD index.","extra":{},"name":"osdindex","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/osd/{osdid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bf7b180ff0f405fde06dc5d87505bd8ab58b5d1502106abd87441f78d23f5e26","description":"ceph osd in","extra":{"proxyto":"node"},"name":"in","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/osd/{osdid}/in"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5836bad68fa9724eac7f11cc92c5cd8dc2364d7f44ddc9a2e0e45627a167922f","description":"Get OSD volume details","extra":{"proxyto":"node"},"name":"osdvolume","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"},{"definition":{"default":"block","description":"OSD device type","enum":["block","db","wal"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"creation_time":{"description":"Creation time as reported by `lvs`.","enum":[],"extra":{},"properties":{},"type":"string"},"lv_name":{"description":"Name of the logical volume (LV).","enum":[],"extra":{},"properties":{},"type":"string"},"lv_path":{"description":"Path to the logical volume (LV).","enum":[],"extra":{},"properties":{},"type":"string"},"lv_size":{"description":"Size of the logical volume (LV).","enum":[],"extra":{},"properties":{},"type":"integer"},"lv_uuid":{"description":"UUID of the logical volume (LV).","enum":[],"extra":{},"properties":{},"type":"string"},"vg_name":{"description":"Name of the volume group (VG).","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/osd/{osdid}/lv-info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"36c7eaeb442c6ea6af0cf3de0af8ca964f155bfae1c4daf252d8af9bf9a248bf","description":"Get OSD details","extra":{"proxyto":"node"},"name":"osddetails","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"devices":{"description":"Array containing data about devices","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"dev_node":{"description":"Device node","enum":[],"extra":{},"properties":{},"type":"string"},"device":{"description":"Kind of OSD device","enum":["block","db","wal"],"extra":{},"properties":{},"type":"string"},"physical_device":{"description":"Underlying physical device(s) used by this OSD device (comma- or space-joined when multiple).","enum":[],"extra":{},"properties":{},"type":"string"},"size":{"description":"Size of the OSD device in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"support_discard":{"description":"Whether the underlying physical device supports discard/TRIM.","enum":[],"extra":{},"properties":{},"type":"boolean"},"type":{"description":"Type of device. For example, hdd or ssd","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"osd":{"description":"General information about the OSD","enum":[],"extra":{},"properties":{"back_addr":{"description":"Address and port used to talk to other OSDs.","enum":[],"extra":{},"properties":{},"type":"string"},"encrypted":{"description":"Whether the OSD is encrypted with LUKS via dm-crypt.","enum":[],"extra":{},"properties":{},"type":"boolean"},"front_addr":{"description":"Address and port used to talk to clients and monitors.","enum":[],"extra":{},"properties":{},"type":"string"},"hb_back_addr":{"description":"Heartbeat address and port for other OSDs.","enum":[],"extra":{},"properties":{},"type":"string"},"hb_front_addr":{"description":"Heartbeat address and port for clients and monitors.","enum":[],"extra":{},"properties":{},"type":"string"},"hostname":{"description":"Name of the host containing the OSD.","enum":[],"extra":{},"properties":{},"type":"string"},"id":{"description":"ID of the OSD.","enum":[],"extra":{},"properties":{},"type":"integer"},"mem_usage":{"description":"Proportional set size (PSS) memory usage of the OSD daemon process in bytes; 0 when the process is not running.","enum":[],"extra":{},"properties":{},"type":"integer"},"osd_data":{"description":"Path to the OSD's data directory.","enum":[],"extra":{},"properties":{},"type":"string"},"osd_objectstore":{"description":"The type of object store used.","enum":[],"extra":{},"properties":{},"type":"string"},"pid":{"description":"OSD process ID; absent if the systemd unit for this OSD is not currently running.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"version":{"description":"Ceph version of the OSD service.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/osd/{osdid}/metadata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"23d8222b59c8aab7050f8c7415d7e3d12494cab703c1ee49bb4be15f1b666800","description":"ceph osd out","extra":{"proxyto":"node"},"name":"out","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/osd/{osdid}/out"},{"extra":{},"methods":[{"allow_token":true,"checksum":"60019df48da0442ab7a3f116bc02cc627d89cc4c978434e73175e44fa0e2107b","description":"Instruct the OSD to scrub.","extra":{"proxyto":"node"},"name":"scrub","parameters":[{"definition":{"default":0,"description":"If set, instructs a deep scrub instead of a normal one.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"deep"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/osd/{osdid}/scrub"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2efcd4aad6156953b2a237af8ce20a4c6cfdbc2fbe35824cee3daf5525d28e7a","description":"List all pools and their settings (which are settable by the POST/PUT endpoints).","extra":{"proxyto":"node"},"name":"lspools","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{pool_name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"application_metadata":{"description":"Application tags attached to the pool (mapping of application name to its metadata object).","enum":[],"extra":{"title":"Associated Applications"},"optional":true,"properties":{},"type":"object"},"autoscale_status":{"description":"Raw pg_autoscaler status object for this pool; shape varies between Ceph releases.","enum":[],"extra":{"title":"Autoscale Status"},"optional":true,"properties":{},"type":"object"},"bytes_used":{"description":"Bytes currently used in the pool; absent if no usage statistics are reported.","enum":[],"extra":{"renderer":"bytes","title":"Used"},"optional":true,"properties":{},"type":"integer"},"crush_rule":{"description":"Numeric id of the CRUSH rule used by this pool.","enum":[],"extra":{"title":"Crush Rule"},"properties":{},"type":"integer"},"crush_rule_name":{"description":"Human-readable name of the CRUSH rule used by this pool; absent if the rule id is not in the current CRUSH map.","enum":[],"extra":{"title":"Crush Rule Name"},"optional":true,"properties":{},"type":"string"},"min_size":{"description":"Minimum number of replicas required to accept writes.","enum":[],"extra":{"title":"Min Size"},"properties":{},"type":"integer"},"percent_used":{"description":"Percentage of pool capacity currently used; absent if no usage statistics are reported.","enum":[],"extra":{"title":"%-Used"},"optional":true,"properties":{},"type":"number"},"pg_autoscale_mode":{"description":"Placement-group autoscaler mode ('on', 'warn' or 'off').","enum":[],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"pg_num":{"description":"Current placement-group count.","enum":[],"extra":{"title":"PG Num"},"properties":{},"type":"integer"},"pg_num_final":{"description":"Optimal placement-group count computed by pg_autoscaler.","enum":[],"extra":{"title":"Optimal PG Num"},"optional":true,"properties":{},"type":"integer"},"pg_num_min":{"description":"Minimum placement-group count the pg_autoscaler may choose.","enum":[],"extra":{"title":"min. PG Num"},"optional":true,"properties":{},"type":"integer"},"pool":{"description":"Numeric pool id assigned by Ceph.","enum":[],"extra":{"title":"ID"},"properties":{},"type":"integer"},"pool_name":{"description":"Operator-visible name of the pool.","enum":[],"extra":{"title":"Name"},"properties":{},"type":"string"},"size":{"description":"Replication factor (target number of object replicas).","enum":[],"extra":{"title":"Size"},"properties":{},"type":"integer"},"target_size":{"description":"Operator-supplied target size in bytes; hints the pg_autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"properties":{},"type":"integer"},"target_size_ratio":{"description":"Operator-supplied target ratio of total pool capacity; hints the pg_autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Ratio"},"optional":true,"properties":{},"type":"number"},"type":{"description":"Pool type: 'replicated' for n-way replication, 'erasure' for an erasure-coded pool, 'unknown' for types PVE does not yet map.","enum":["replicated","erasure","unknown"],"extra":{"title":"Type"},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"e0884d07f2e947848ce562e910f2275e2fd9d0900ee1fb95b205742e041156b5","description":"Create Ceph pool","extra":{"proxyto":"node"},"name":"createpool","parameters":[{"definition":{"default":0,"description":"Configure VM and CT storage using the new pool. Defaults to false for replicated pools and to true for erasure-coded pools (since EC pools are typically only useful when wired up to storage).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storages"},{"definition":{"default":"rbd","description":"The application of the pool.","enum":["rbd","cephfs","rgw"],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"string"},"name":"application"},{"definition":{"description":"The rule to use for mapping object placement in the cluster.","enum":[],"extra":{"title":"Crush Rule Name","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"crush_rule"},{"definition":{"description":"Create an erasure coded pool for RBD with an accompaning replicated pool for metadata storage. With EC, the common ceph options 'size', 'min_size' and 'crush_rule' parameters will be applied to the metadata pool.","enum":[],"extra":{"typetext":"k= ,m= [,device-class=] [,failure-domain=] [,profile=]"},"format":{"device-class":{"description":"CRUSH device class. Will create an erasure coded pool plus a replicated pool for metadata.","format_description":"class","optional":1,"type":"string"},"failure-domain":{"default":"host","description":"CRUSH failure domain. Default is 'host'. Will create an erasure coded pool plus a replicated pool for metadata.","format_description":"domain","optional":1,"type":"string"},"k":{"description":"Number of data chunks. Will create an erasure coded pool plus a replicated pool for metadata.","minimum":2,"type":"integer"},"m":{"description":"Number of coding chunks. Will create an erasure coded pool plus a replicated pool for metadata.","minimum":1,"type":"integer"},"profile":{"description":"Override the erasure code (EC) profile to use. Will create an erasure coded pool plus a replicated pool for metadata.","format_description":"profile","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"erasure-coding"},{"definition":{"default":2,"description":"Minimum number of replicas per object","enum":[],"extra":{"title":"Min Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"min_size"},{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"title":"Name"},"pattern":"(?^:^[^:/\\s]+$)","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"warn","description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"name":"pg_autoscale_mode"},{"definition":{"default":128,"description":"Number of placement groups.","enum":[],"extra":{"title":"PG Num","typetext":" (1 - 32768)"},"maximum":32768,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"pg_num"},{"definition":{"description":"Minimal number of placement groups.","enum":[],"extra":{"title":"min. PG Num","typetext":" (-N - 32768)"},"maximum":32768,"optional":true,"properties":{},"type":"integer"},"name":"pg_num_min"},{"definition":{"default":3,"description":"Number of replicas per object","enum":[],"extra":{"title":"Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"size"},{"definition":{"description":"The estimated target size of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"pattern":"^(\\d+(\\.\\d+)?)([KMGT])?$","properties":{},"type":"string"},"name":"target_size"},{"definition":{"description":"The estimated target ratio of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Ratio","typetext":""},"optional":true,"properties":{},"type":"number"},"name":"target_size_ratio"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/pool"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8708fe36bb2d3f3abbf03cb27e6db8fd1c5baaf58225e6095a69a2ea6b3217c6","description":"Destroy pool","extra":{"proxyto":"node"},"name":"destroypool","parameters":[{"definition":{"default":0,"description":"If true, destroys pool even if in use","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":1,"description":"Remove the erasure code profile. Defaults to true, if applicable.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove_ecprofile"},{"definition":{"default":0,"description":"Remove all pveceph-managed storages configured for this pool","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove_storages"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"aa0616ec83924fa46a149a0e35dedaf66156879c4aed761d93bd66aaa00aa242","description":"Pool index.","extra":{},"name":"poolindex","parameters":[{"definition":{"description":"The name of the pool.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"4165ab074ab90f0d5e5eb8b7bcc2a0e7fce8ec275cff5623c6e243ba402f574a","description":"Change POOL settings","extra":{"proxyto":"node"},"name":"setpool","parameters":[{"definition":{"description":"The application of the pool.","enum":["rbd","cephfs","rgw"],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"string"},"name":"application"},{"definition":{"description":"The rule to use for mapping object placement in the cluster.","enum":[],"extra":{"title":"Crush Rule Name","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"crush_rule"},{"definition":{"description":"Minimum number of replicas per object","enum":[],"extra":{"title":"Min Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"min_size"},{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"title":"Name"},"pattern":"(?^:^[^:/\\s]+$)","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"name":"pg_autoscale_mode"},{"definition":{"description":"Number of placement groups.","enum":[],"extra":{"title":"PG Num","typetext":" (1 - 32768)"},"maximum":32768,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"pg_num"},{"definition":{"description":"Minimal number of placement groups.","enum":[],"extra":{"title":"min. PG Num","typetext":" (-N - 32768)"},"maximum":32768,"optional":true,"properties":{},"type":"integer"},"name":"pg_num_min"},{"definition":{"description":"Number of replicas per object","enum":[],"extra":{"title":"Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"size"},{"definition":{"description":"The estimated target size of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"pattern":"^(\\d+(\\.\\d+)?)([KMGT])?$","properties":{},"type":"string"},"name":"target_size"},{"definition":{"description":"The estimated target ratio of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Ratio","typetext":""},"optional":true,"properties":{},"type":"number"},"name":"target_size_ratio"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/ceph/pool/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"49d4defba9305cf8ed5c151f01561e96c8e8f5c896cb8403794219f38c65749f","description":"Show the current pool status.","extra":{"proxyto":"node"},"name":"getpool","parameters":[{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"If enabled, will display additional data(eg. statistics).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verbose"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"application":{"default":"rbd","description":"The application of the pool.","enum":["rbd","cephfs","rgw"],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"string"},"application_list":{"description":"Names of applications currently associated with the pool.","enum":[],"extra":{"title":"Application"},"items":{"description":"Application name (e.g. 'rbd', 'cephfs', 'rgw').","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"autoscale_status":{"description":"Raw pg_autoscaler status object for this pool; shape varies between Ceph releases.","enum":[],"extra":{"title":"Autoscale Status"},"optional":true,"properties":{},"type":"object"},"crush_rule":{"description":"The rule to use for mapping object placement in the cluster.","enum":[],"extra":{"title":"Crush Rule Name"},"optional":true,"properties":{},"type":"string"},"fast_read":{"description":"Set if the pool uses fast-read for erasure-coded reads.","enum":[],"extra":{"title":"Fast Read"},"properties":{},"type":"boolean"},"hashpspool":{"description":"Set if the pool hashes pool id into its CRUSH placement-seed.","enum":[],"extra":{"title":"hashpspool"},"properties":{},"type":"boolean"},"id":{"description":"Numeric pool id assigned by Ceph.","enum":[],"extra":{"title":"ID"},"properties":{},"type":"integer"},"min_size":{"default":2,"description":"Minimum number of replicas per object","enum":[],"extra":{"title":"Min Size"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"title":"Name"},"pattern":"(?^:^[^:/\\s]+$)","properties":{},"type":"string"},"nodeep-scrub":{"description":"Set if deep-scrubbing is disabled for this pool.","enum":[],"extra":{"title":"nodeep-scrub"},"properties":{},"type":"boolean"},"nodelete":{"description":"Set if pool delete is blocked.","enum":[],"extra":{"title":"nodelete"},"properties":{},"type":"boolean"},"nopgchange":{"description":"Set if changing the placement-group count is blocked.","enum":[],"extra":{"title":"nopgchange"},"properties":{},"type":"boolean"},"noscrub":{"description":"Set if scrubbing is disabled for this pool.","enum":[],"extra":{"title":"noscrub"},"properties":{},"type":"boolean"},"nosizechange":{"description":"Set if changing the replication size is blocked.","enum":[],"extra":{"title":"nosizechange"},"properties":{},"type":"boolean"},"pg_autoscale_mode":{"default":"warn","description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"pg_num":{"default":128,"description":"Number of placement groups.","enum":[],"extra":{"title":"PG Num"},"maximum":32768,"minimum":1,"optional":true,"properties":{},"type":"integer"},"pg_num_min":{"description":"Minimal number of placement groups.","enum":[],"extra":{"title":"min. PG Num"},"maximum":32768,"optional":true,"properties":{},"type":"integer"},"pgp_num":{"description":"Placement-group-for-placement count.","enum":[],"extra":{"title":"PGP num"},"properties":{},"type":"integer"},"size":{"default":3,"description":"Number of replicas per object","enum":[],"extra":{"title":"Size"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"statistics":{"description":"Optional pool usage and IO statistics (only present when verbose=1 is requested).","enum":[],"extra":{"title":"Statistics"},"optional":true,"properties":{},"type":"object"},"target_size":{"description":"The estimated target size of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"pattern":"^(\\d+(\\.\\d+)?)([KMGT])?$","properties":{},"type":"string"},"target_size_ratio":{"description":"The estimated target ratio of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Ratio"},"optional":true,"properties":{},"type":"number"},"use_gmt_hitset":{"description":"Set if hitsets use GMT timestamps (for cache-tier pools).","enum":[],"extra":{"title":"use_gmt_hitset"},"properties":{},"type":"boolean"},"write_fadvise_dontneed":{"description":"Set if the pool sets the FADV_DONTNEED hint on writes.","enum":[],"extra":{"title":"write_fadvise_dontneed"},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/pool/{name}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"66470aac293499be1d9f13fbde93bcd92a5186719612a4adf79b3466af814c69","description":"Restart ceph services.","extra":{"proxyto":"node"},"name":"restart","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"ceph.target","description":"Ceph service name.","enum":[],"extra":{},"optional":true,"pattern":"(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?","properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/restart"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d1d564dc8fb769d538a36abe333e96421609c5e6a7fb99fd92be6a90fedf4f44","description":"List ceph rules.","extra":{"proxyto":"node"},"name":"rules","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"name":{"description":"Name of the CRUSH rule.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ecb354e68cb5aeaa1e4b8b63c176ff7410fa0fed35f792c2891964ab6662d962","description":"Start ceph services.","extra":{"proxyto":"node"},"name":"start","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"ceph.target","description":"Ceph service name.","enum":[],"extra":{},"optional":true,"pattern":"(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?","properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2008abd1f8fed57a2b194073f827580233fd366124dc276938527f2b35351bc0","description":"Get the Ceph cluster status (raw 'ceph status' output). The response is cluster-wide and identical to /cluster/ceph/status; this node-level alias exists for operator convenience.","extra":{"proxyto":"node"},"name":"status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2844e52262806ae8703017f4b336a790d3c54cd9c0ad3ae772ed9fe138def456","description":"Stop ceph services.","extra":{"proxyto":"node"},"name":"stop","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"ceph.target","description":"Ceph service name.","enum":[],"extra":{},"optional":true,"pattern":"(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?","properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/stop"},{"extra":{},"methods":[{"allow_token":true,"checksum":"407b3d66a300b7bc4f15ce81eadffc3e3ff161e7940cd646fc925a219be029f3","description":"Node index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/certificates"},{"extra":{},"methods":[{"allow_token":true,"checksum":"93b19d6ea7cca4a3a682a7c06117351418c9725fb782f6ed86050c0ac92f4bd4","description":"ACME index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/certificates/acme"},{"extra":{},"methods":[{"allow_token":true,"checksum":"79bd82498d21a1c5d90f053e1aaec400ad82efd3983c8cf0559fe0c47b5b293c","description":"Revoke existing certificate from CA.","extra":{"proxyto":"node"},"name":"revoke_certificate","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"eb094550eb00e663dca797ef8c9dc07865542e546832f3d913080f5638f81c3a","description":"Order a new certificate from ACME-compatible CA.","extra":{"proxyto":"node"},"name":"new_certificate","parameters":[{"definition":{"default":0,"description":"Overwrite existing custom certificate.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"},{"allow_token":true,"checksum":"f8eea8445722cd9588417a2079abe85620556ba298b502dd0717e3876aa1abc5","description":"Renew existing certificate from CA.","extra":{"proxyto":"node"},"name":"renew_certificate","parameters":[{"definition":{"default":0,"description":"Force renewal even if expiry is more than 30 days away.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/certificates/acme/certificate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"929493029f5253253302d24f7a1e2c0046bf726108c3d37ed8c86801ddc3384a","description":"DELETE custom certificate chain and key.","extra":{"proxyto":"node"},"name":"remove_custom_cert","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Restart pveproxy.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restart"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"604d77053bdcded86a50810bad7ad1b20c14ff8887d4068b001db73771908654","description":"Upload or update custom certificate chain and key.","extra":{"proxyto":"node"},"name":"upload_custom_cert","parameters":[{"definition":{"description":"PEM encoded certificate (chain).","enum":[],"extra":{"typetext":""},"format":"pem-certificate-chain","properties":{},"type":"string"},"name":"certificates"},{"definition":{"default":0,"description":"Overwrite existing custom or ACME certificate files.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"PEM encoded private key.","enum":[],"extra":{"typetext":""},"format":"pem-string","optional":true,"properties":{},"type":"string"},"name":"key"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Restart pveproxy.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restart"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"fingerprint":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"issuer":{"description":"Certificate issuer name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"notafter":{"description":"Certificate's notAfter timestamp (UNIX epoch).","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"notbefore":{"description":"Certificate's notBefore timestamp (UNIX epoch).","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"pem":{"description":"Certificate in PEM format","enum":[],"extra":{},"format":"pem-certificate","optional":true,"properties":{},"type":"string"},"public-key-bits":{"description":"Certificate's public key size","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"public-key-type":{"description":"Certificate's public key algorithm","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"san":{"description":"List of Certificate's SubjectAlternativeName entries.","enum":[],"extra":{"renderer":"yaml"},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"subject":{"description":"Certificate subject name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/certificates/custom"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2a9b8f5b1a046e68e76e42747bf6de9bb776652ea56f1797a0b8f6bd32e2d21b","description":"Get information about node's certificates.","extra":{"proxyto":"node"},"name":"info","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"fingerprint":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"issuer":{"description":"Certificate issuer name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"notafter":{"description":"Certificate's notAfter timestamp (UNIX epoch).","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"notbefore":{"description":"Certificate's notBefore timestamp (UNIX epoch).","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"pem":{"description":"Certificate in PEM format","enum":[],"extra":{},"format":"pem-certificate","optional":true,"properties":{},"type":"string"},"public-key-bits":{"description":"Certificate's public key size","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"public-key-type":{"description":"Certificate's public key algorithm","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"san":{"description":"List of Certificate's SubjectAlternativeName entries.","enum":[],"extra":{"renderer":"yaml"},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"subject":{"description":"Certificate subject name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/certificates/info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3f9919ebfb1307b11392af45044473f8605084ab9d78eaa1514078b40c79c670","description":"Get node configuration options.","extra":{"proxyto":"node"},"name":"get_config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"all","description":"Return only a specific property from the node configuration.","enum":["acme","acmedomain0","acmedomain1","acmedomain2","acmedomain3","acmedomain4","acmedomain5","ballooning-target","description","location","startall-onboot-delay","wakeonlan"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"property"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"acme":{"description":"Node specific ACME settings.","enum":[],"extra":{},"format":{"account":{"default":"default","description":"ACME account config file name.","format":"pve-configid","format_description":"name","optional":1,"type":"string"},"domains":{"description":"List of domains for this node's ACME certificate","format":"pve-acme-domain-list","format_description":"domain[;domain;...]","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"acmedomain[n]":{"description":"ACME domain and validation plugin","enum":[],"extra":{},"format":{"alias":{"description":"Alias for the Domain to verify ACME Challenge over DNS","format":"pve-acme-alias","format_description":"domain","optional":1,"type":"string"},"domain":{"default_key":1,"description":"domain for this node's ACME certificate","format":"pve-acme-domain","format_description":"domain","type":"string"},"plugin":{"default":"standalone","description":"The ACME plugin ID","format":"pve-configid","format_description":"name of the plugin configuration","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"ballooning-target":{"default":80,"description":"RAM usage target for ballooning (in percent of total memory)","enum":[],"extra":{},"maximum":100,"minimum":0,"optional":true,"properties":{},"type":"integer"},"description":{"description":"Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.","enum":[],"extra":{},"max_length":65536,"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":true,"properties":{},"type":"string"},"location":{"description":"The location of the node. Overrides the default from the datacenter config.","enum":[],"extra":{},"format":{"latitude":{"description":"The latitude of the nodes location in degrees.","maximum":90,"minimum":-90,"type":"number"},"longitude":{"description":"The longitude of the nodes location in degrees.","maximum":180,"minimum":-180,"type":"number"},"name":{"description":"The name of the location of this node","maxLength":128,"optional":1,"type":"string","typetext":""}},"optional":true,"properties":{},"type":"string"},"startall-onboot-delay":{"default":0,"description":"Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.","enum":[],"extra":{},"maximum":300,"minimum":0,"optional":true,"properties":{},"type":"integer"},"wakeonlan":{"description":"Node specific wake on LAN settings.","enum":[],"extra":{},"format":{"bind-interface":{"default":"The interface carrying the default route","description":"Bind to this interface when sending wake on LAN packet","format":"pve-iface","format_description":"bind interface","optional":1,"type":"string"},"broadcast-address":{"default":"255.255.255.255","description":"IPv4 broadcast address to use when sending wake on LAN packet","format":"ipv4","format_description":"IPv4 broadcast address","optional":1,"type":"string"},"mac":{"default_key":1,"description":"MAC address for wake on LAN","format":"mac-addr","format_description":"MAC address","type":"string"}},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"4b928e3bc1c11f222f85e0cc44f3358b65073d1fbad749555c793c887245bd89","description":"Set node configuration options.","extra":{"proxyto":"node"},"name":"set_options","parameters":[{"definition":{"description":"Node specific ACME settings.","enum":[],"extra":{"typetext":"[account=] [,domains=]"},"format":{"account":{"default":"default","description":"ACME account config file name.","format":"pve-configid","format_description":"name","optional":1,"type":"string"},"domains":{"description":"List of domains for this node's ACME certificate","format":"pve-acme-domain-list","format_description":"domain[;domain;...]","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"acme"},{"definition":{"description":"ACME domain and validation plugin","enum":[],"extra":{"typetext":"[domain=] [,alias=] [,plugin=]"},"format":{"alias":{"description":"Alias for the Domain to verify ACME Challenge over DNS","format":"pve-acme-alias","format_description":"domain","optional":1,"type":"string"},"domain":{"default_key":1,"description":"domain for this node's ACME certificate","format":"pve-acme-domain","format_description":"domain","type":"string"},"plugin":{"default":"standalone","description":"The ACME plugin ID","format":"pve-configid","format_description":"name of the plugin configuration","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"acmedomain[n]"},{"definition":{"default":80,"description":"RAM usage target for ballooning (in percent of total memory)","enum":[],"extra":{"typetext":" (0 - 100)"},"maximum":100,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"ballooning-target"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":65536,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The location of the node. Overrides the default from the datacenter config.","enum":[],"extra":{"typetext":"latitude= ,longitude= [,name=]"},"format":{"latitude":{"description":"The latitude of the nodes location in degrees.","maximum":90,"minimum":-90,"type":"number"},"longitude":{"description":"The longitude of the nodes location in degrees.","maximum":180,"minimum":-180,"type":"number"},"name":{"description":"The name of the location of this node","maxLength":128,"optional":1,"type":"string","typetext":""}},"optional":true,"properties":{},"type":"string"},"name":"location"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.","enum":[],"extra":{"typetext":" (0 - 300)"},"maximum":300,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"startall-onboot-delay"},{"definition":{"description":"Node specific wake on LAN settings.","enum":[],"extra":{"typetext":"[mac=] [,bind-interface=] [,broadcast-address=]"},"format":{"bind-interface":{"default":"The interface carrying the default route","description":"Bind to this interface when sending wake on LAN packet","format":"pve-iface","format_description":"bind interface","optional":1,"type":"string"},"broadcast-address":{"default":"255.255.255.255","description":"IPv4 broadcast address to use when sending wake on LAN packet","format":"ipv4","format_description":"IPv4 broadcast address","optional":1,"type":"string"},"mac":{"default_key":1,"description":"MAC address for wake on LAN","format":"mac-addr","format_description":"MAC address","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"wakeonlan"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c852718145641f2177102cbfc0fd436f6aeef81be29c2faedeed85f289314d9f","description":"Node index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/disks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2b0b603e80bb49e4f94508459ac35fb463fc1cb96dd525ab36ee550b228e5929","description":"PVE Managed Directory storages.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"device":{"description":"The mounted device.","enum":[],"extra":{},"properties":{},"type":"string"},"options":{"description":"The mount options.","enum":[],"extra":{},"properties":{},"type":"string"},"path":{"description":"The mount path.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The filesystem type.","enum":[],"extra":{},"properties":{},"type":"string"},"unitfile":{"description":"The path of the mount unit.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"52ce612ca7baab2bdd57b06bcfceb08779ce1d2ac530d8130aff7e3c6dec9477","description":"Create a Filesystem on an unused disk. Will be mounted under '/mnt/pve/NAME'.","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"default":0,"description":"Configure storage using the directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storage"},{"definition":{"description":"The block device you want to create the filesystem on.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"device"},{"definition":{"default":"ext4","description":"The desired filesystem.","enum":["ext4","xfs"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"filesystem"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/directory"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f0fe4d0df791ab5bd40314e73c8c366417f843c3bae376bb3b8010c65009fb34","description":"Unmounts the storage and removes the mount unit.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"default":0,"description":"Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-config"},{"definition":{"default":0,"description":"Also wipe disk so it can be repurposed afterwards.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-disks"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"}],"path":"/nodes/{node}/disks/directory/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e07569915888aa6baceeffec53ed6c431ea006c760c7620558ca0980ba012061","description":"Initialize Disk with GPT","extra":{"proxyto":"node"},"name":"initgpt","parameters":[{"definition":{"description":"Block device name","enum":[],"extra":{},"pattern":"^/dev/[a-zA-Z0-9\\/]+$","properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"UUID for the GPT table","enum":[],"extra":{},"max_length":36,"optional":true,"pattern":"[a-fA-F0-9\\-]+","properties":{},"type":"string"},"name":"uuid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/initgpt"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b19c44d4db67e33f6c20913d198f5366ed3c97ec021c2a54670041eaef285702","description":"List local disks.","extra":{"proxyto":"node"},"name":"list","parameters":[{"definition":{"default":0,"description":"Also include partitions.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"include-partitions"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Skip smart checks.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skipsmart"},{"definition":{"description":"Only list specific types of disks.","enum":["unused","journal_disks"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["or",["perm","/",["Sys.Audit"]],["perm","/nodes/{node}",["Sys.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"devpath":{"description":"The device path","enum":[],"extra":{},"properties":{},"type":"string"},"gpt":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"health":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"model":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mounted":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"osdid":{"enum":[],"extra":{},"properties":{},"type":"integer"},"osdid-list":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"integer"},"properties":{},"type":"array"},"parent":{"description":"For partitions only. The device path of the disk the partition resides on.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"size":{"enum":[],"extra":{},"properties":{},"type":"integer"},"used":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vendor":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"wwn":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/disks/list"},{"extra":{},"methods":[{"allow_token":true,"checksum":"547375dd65648a9398230df72264cdc019782638796d54756ac0b8145c21975f","description":"List LVM Volume Groups","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"children":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"children":{"description":"The underlying physical volumes","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"free":{"description":"The free bytes in the physical volume","enum":[],"extra":{},"properties":{},"type":"integer"},"leaf":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"name":{"description":"The name of the physical volume","enum":[],"extra":{},"properties":{},"type":"string"},"size":{"description":"The size of the physical volume in bytes","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"free":{"description":"The free bytes in the volume group","enum":[],"extra":{},"properties":{},"type":"integer"},"leaf":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"name":{"description":"The name of the volume group","enum":[],"extra":{},"properties":{},"type":"string"},"size":{"description":"The size of the volume group in bytes","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"leaf":{"enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"465ee8af4bac2a64832eeb82709a6ff666335ab27be88058f40175b94d5f4542","description":"Create an LVM Volume Group","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"default":0,"description":"Configure storage using the Volume Group","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storage"},{"definition":{"description":"The block device you want to create the volume group on","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"device"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/lvm"},{"extra":{},"methods":[{"allow_token":true,"checksum":"41be5d70ce8afdbc0cffdf60aba42159045297f9274a49064625dfc79884f9cb","description":"Remove an LVM Volume Group.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"default":0,"description":"Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-config"},{"definition":{"default":0,"description":"Also wipe disks so they can be repurposed afterwards.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-disks"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"}],"path":"/nodes/{node}/disks/lvm/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9d0210c30eeba102cd5491e7f961792286b4fbf7dcbaed83b1cac181115b29ee","description":"List LVM thinpools","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"lv":{"description":"The name of the thinpool.","enum":[],"extra":{},"properties":{},"type":"string"},"lv_size":{"description":"The size of the thinpool in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"metadata_size":{"description":"The size of the metadata lv in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"metadata_used":{"description":"The used bytes of the metadata lv.","enum":[],"extra":{},"properties":{},"type":"integer"},"used":{"description":"The used bytes of the thinpool.","enum":[],"extra":{},"properties":{},"type":"integer"},"vg":{"description":"The associated volume group.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"58432b26fb6a7729315b2a98c47db27b32ce10f5be1d69a6fe7132e7cf066560","description":"Create an LVM thinpool","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"default":0,"description":"Configure storage using the thinpool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storage"},{"definition":{"description":"The block device you want to create the thinpool on.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"device"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/lvmthin"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0dfc32202fa94d5574b4220343f91f097aae08e39de39e8d4153139686567f9b","description":"Remove an LVM thin pool.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"default":0,"description":"Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-config"},{"definition":{"default":0,"description":"Also wipe disks so they can be repurposed afterwards.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-disks"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"volume-group"}],"permissions":{"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"}],"path":"/nodes/{node}/disks/lvmthin/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b8be9774a5c882925ed844f0a84b0c893019315e9d99d5707940856e370cf778","description":"Get SMART Health of a disk.","extra":{"proxyto":"node"},"name":"smart","parameters":[{"definition":{"description":"Block device name","enum":[],"extra":{},"pattern":"^/dev/[a-zA-Z0-9\\/]+$","properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"If true returns only the health status","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"healthonly"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"attributes":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"array"},"health":{"enum":[],"extra":{},"properties":{},"type":"string"},"text":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/disks/smart"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5863de4fd64b709cb09f59e5ed64aa977df1243471343673fedafcc9441196d4","description":"Wipe a disk or partition.","extra":{"proxyto":"node"},"name":"wipe_disk","parameters":[{"definition":{"description":"Block device name","enum":[],"extra":{},"pattern":"^/dev/[a-zA-Z0-9\\/]+$","properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/disks/wipedisk"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d32343b2f2aa7b3ebb677e824c108e9a394940d90ed272b780889c094e876172","description":"List Zpools.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"alloc":{"description":"","enum":[],"extra":{},"properties":{},"type":"integer"},"dedup":{"description":"","enum":[],"extra":{},"properties":{},"type":"number"},"frag":{"description":"","enum":[],"extra":{},"properties":{},"type":"integer"},"free":{"description":"","enum":[],"extra":{},"properties":{},"type":"integer"},"health":{"description":"","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"","enum":[],"extra":{},"properties":{},"type":"string"},"size":{"description":"","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"9307314b98ab891eff85b9312ae22dd45789e5eec022d70ce026f3142435d1b8","description":"Create a ZFS pool.","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"default":0,"description":"Configure storage using the zpool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storage"},{"definition":{"default":12,"description":"Pool sector size exponent.","enum":[],"extra":{"typetext":" (9 - 16)"},"maximum":16,"minimum":9,"optional":true,"properties":{},"type":"integer"},"name":"ashift"},{"definition":{"default":"on","description":"The compression algorithm to use.","enum":["on","off","gzip","lz4","lzjb","zle","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"compression"},{"definition":{"description":"The block devices you want to create the zpool on.","enum":[],"extra":{"typetext":""},"format":"string-list","properties":{},"type":"string"},"name":"devices"},{"definition":{"enum":[],"extra":{"typetext":"data= ,spares="},"format":{"data":{"description":"The number of data devices per redundancy group. (dRAID)","minimum":1,"type":"integer"},"spares":{"description":"Number of dRAID spares.","minimum":0,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"draid-config"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The RAID level to use.","enum":["single","mirror","raid10","raidz","raidz2","raidz3","draid","draid2","draid3"],"extra":{},"properties":{},"type":"string"},"name":"raidlevel"}],"permissions":{"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/zfs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"29aa5ca8b0d31811a6ede028c5b0db8458f3816460f152e4471328fb4e1632f0","description":"Destroy a ZFS pool.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"default":0,"description":"Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-config"},{"definition":{"default":0,"description":"Also wipe disks so they can be repurposed afterwards.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-disks"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"7557098c2bcfb870e8e6beb40292b42f3205d3ab8ac1e80b3bd1fbaf0240f93a","description":"Get details about a zpool.","extra":{"proxyto":"node"},"name":"detail","parameters":[{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"action":{"description":"Information about the recommended action to fix the state.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"children":{"description":"The pool configuration information, including the vdevs for each section (e.g. spares, cache), may be nested.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"cksum":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"msg":{"description":"An optional message about the vdev.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"The name of the vdev or section.","enum":[],"extra":{},"properties":{},"type":"string"},"read":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"state":{"description":"The state of the vdev.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"write":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"number"}},"type":"object"},"properties":{},"type":"array"},"errors":{"description":"Information about the errors on the zpool.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"The name of the zpool.","enum":[],"extra":{},"properties":{},"type":"string"},"scan":{"description":"Information about the last/current scrub.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"state":{"description":"The state of the zpool.","enum":[],"extra":{},"properties":{},"type":"string"},"status":{"description":"Information about the state of the zpool.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/disks/zfs/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a2a9840bc5b5f6fedb64fc871e0f30293e36589bef2b2cca3b75b167641bd3ad","description":"Read DNS settings.","extra":{"proxyto":"node"},"name":"dns","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"dns1":{"description":"First name server IP address.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dns2":{"description":"Second name server IP address.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dns3":{"description":"Third name server IP address.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"search":{"description":"Search domain for host-name lookup.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"aa3976a9e9313d0108087afc577aaef882c6caa542300b9aa580823664733034","description":"Write DNS settings.","extra":{"proxyto":"node"},"name":"update_dns","parameters":[{"definition":{"description":"First name server IP address.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"dns1"},{"definition":{"description":"Second name server IP address.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"dns2"},{"definition":{"description":"Third name server IP address.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"dns3"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Search domain for host-name lookup.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"search"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/dns"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b9b5ae5cee9408c0f7067b2093039c75ae790b13b2a78ff993842ae9f2694a77","description":"Execute multiple commands in order, root only.","extra":{"proxyto":"node"},"name":"execute","parameters":[{"definition":{"description":"JSON encoded array of commands.","enum":[],"extra":{"typetext":"","verbose_description":"JSON encoded array of commands, where each command is an object with the following properties:\n args: \n\t A set of parameter names and their values.\n\n method: (GET|POST|PUT|DELETE)\n\t A method related to the API endpoint (GET, POST etc.).\n\n path: \n\t A relative path to an API endpoint on this node.\n\n"},"format":"pve-command-batch","properties":{},"type":"string"},"name":"commands"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"POST"}],"path":"/nodes/{node}/execute"},{"extra":{},"methods":[{"allow_token":true,"checksum":"23dca6507cde2ae0cabadf81020c2e06e2c8878c3e19c7356ba7dbc49c506a9a","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0bf35a80d104d2faaf32511debedeee1423c276df3c2eeba6d83b3e7ee589cd3","description":"Read firewall log","extra":{"proxyto":"node"},"name":"log","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Display log since this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"since"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"Display log until this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"until"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/firewall/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"77ab8158f4d58b98250649aac4fc97b84bc7f5b7aa5b165dbe40211211aac06d","description":"Get host firewall options.","extra":{"proxyto":"node"},"name":"get_options","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"enable":{"default":1,"description":"Enable host firewall rules.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"log_level_forward":{"description":"Log level for forwarded traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_level_in":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_level_out":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_nf_conntrack":{"default":0,"description":"Enable logging of conntrack information.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ndp":{"default":1,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"nf_conntrack_allow_invalid":{"default":0,"description":"Allow invalid packets on connection tracking.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"nf_conntrack_helpers":{"default":"","description":"Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp","enum":[],"extra":{},"format":"pve-fw-conntrack-helper","optional":true,"properties":{},"type":"string"},"nf_conntrack_max":{"default":262144,"description":"Maximum number of tracked connections.","enum":[],"extra":{},"minimum":32768,"optional":true,"properties":{},"type":"integer"},"nf_conntrack_tcp_timeout_established":{"default":432000,"description":"Conntrack established timeout.","enum":[],"extra":{},"minimum":7875,"optional":true,"properties":{},"type":"integer"},"nf_conntrack_tcp_timeout_syn_recv":{"default":60,"description":"Conntrack syn recv timeout.","enum":[],"extra":{},"maximum":60,"minimum":30,"optional":true,"properties":{},"type":"integer"},"nftables":{"default":0,"description":"Enable nftables based firewall (tech preview)","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"nosmurfs":{"description":"Enable SMURFS filter.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"protection_synflood":{"default":0,"description":"Enable synflood protection","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"protection_synflood_burst":{"default":1000,"description":"Synflood protection rate burst by ip src.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"protection_synflood_rate":{"default":200,"description":"Synflood protection rate syn/sec by ip src.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"smurf_log_level":{"description":"Log level for SMURFS filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"tcp_flags_log_level":{"description":"Log level for illegal tcp flags filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"tcpflags":{"default":0,"description":"Filter illegal combinations of TCP flags.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"28ee2143b75ba18faede617dc09dd3c13cb35f585fc27faf73702327b5af1d31","description":"Set Firewall options.","extra":{"proxyto":"node"},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":1,"description":"Enable host firewall rules.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Log level for forwarded traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_forward"},{"definition":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_in"},{"definition":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_out"},{"definition":{"default":0,"description":"Enable logging of conntrack information.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"log_nf_conntrack"},{"definition":{"default":1,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ndp"},{"definition":{"default":0,"description":"Allow invalid packets on connection tracking.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nf_conntrack_allow_invalid"},{"definition":{"default":"","description":"Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp","enum":[],"extra":{"typetext":""},"format":"pve-fw-conntrack-helper","optional":true,"properties":{},"type":"string"},"name":"nf_conntrack_helpers"},{"definition":{"default":262144,"description":"Maximum number of tracked connections.","enum":[],"extra":{"typetext":" (32768 - N)"},"minimum":32768,"optional":true,"properties":{},"type":"integer"},"name":"nf_conntrack_max"},{"definition":{"default":432000,"description":"Conntrack established timeout.","enum":[],"extra":{"typetext":" (7875 - N)"},"minimum":7875,"optional":true,"properties":{},"type":"integer"},"name":"nf_conntrack_tcp_timeout_established"},{"definition":{"default":60,"description":"Conntrack syn recv timeout.","enum":[],"extra":{"typetext":" (30 - 60)"},"maximum":60,"minimum":30,"optional":true,"properties":{},"type":"integer"},"name":"nf_conntrack_tcp_timeout_syn_recv"},{"definition":{"default":0,"description":"Enable nftables based firewall (tech preview)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nftables"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Enable SMURFS filter.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nosmurfs"},{"definition":{"default":0,"description":"Enable synflood protection","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection_synflood"},{"definition":{"default":1000,"description":"Synflood protection rate burst by ip src.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"protection_synflood_burst"},{"definition":{"default":200,"description":"Synflood protection rate syn/sec by ip src.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"protection_synflood_rate"},{"definition":{"description":"Log level for SMURFS filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"smurf_log_level"},{"definition":{"description":"Log level for illegal tcp flags filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"tcp_flags_log_level"},{"definition":{"default":0,"description":"Filter illegal combinations of TCP flags.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tcpflags"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3211780150b2cbf90639e19ebc9bdb9a0e7043436a20152279ffa62a79192a04","description":"List rules.","extra":{"proxyto":"node"},"name":"get_rules","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"action":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name","enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"description":"Descriptive comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"description":"Restrict packet destination address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"description":"Restrict TCP/UDP destination port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"description":"Flag to enable/disable a rule","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"description":"Network interface name. You have to use network configuration key names for VMs and containers","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"description":"IP version (4 or 6) - automatically determined from source/dest addresses","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"description":"Use predefined standard macro","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"description":"Rule position in the ruleset","enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"description":"Restrict packet source address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"description":"Restrict TCP/UDP source port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Rule type","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"52ed479494817bbd7348903edb0529f7d685ac0089933fad256eb2481b39031b","description":"Create new rule.","extra":{"proxyto":"node"},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9a8cd16dbdfb0ed78c0435f1e63da94e3c4fb81b5581e4ec361bbe2f9e3b8727","description":"Delete rule.","extra":{"proxyto":"node"},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"b73996fd40ff7c76835e6ca9cc28c9f14dc11cf66ef4709623970ee7ffa1ab29","description":"Get single rule data.","extra":{"proxyto":"node"},"name":"get_rule","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name","enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"description":"Descriptive comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"description":"Restrict packet destination address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"description":"Restrict TCP/UDP destination port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"description":"Flag to enable/disable a rule","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"description":"Network interface name. You have to use network configuration key names for VMs and containers","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"description":"IP version (4 or 6) - automatically determined from source/dest addresses","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"description":"Use predefined standard macro","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"description":"Rule position in the ruleset","enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"description":"Restrict packet source address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"description":"Restrict TCP/UDP source port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Rule type","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"34b4eb319950ecb2eeac91ba686ad2a44444fa1b7c330a00799252e0509bb563","description":"Modify rule data.","extra":{"proxyto":"node"},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a942affba5edd9876d3a47c7aaed97b5c3eeca8b6a2748dbb6cfd04b87ec4985","description":"Index of hardware types","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{type}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1556e034fd144677c2e86bdb15422d235a60e2b5a68ce93c6f43253902d897e5","description":"List local PCI devices.","extra":{"proxyto":"node"},"name":"pci_scan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"05;06;0b","description":"A list of blacklisted PCI classes, which will not be returned. Following are filtered by default: Memory Controller (05), Bridge (06) and Processor (0b).","enum":[],"extra":{"typetext":""},"format":"string-list","optional":true,"properties":{},"type":"string"},"name":"pci-class-blacklist"},{"definition":{"default":1,"description":"If disabled, does only print the PCI IDs. Otherwise, additional information like vendor and device will be returned.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verbose"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Sys.Modify"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"class":{"description":"The PCI Class of the device.","enum":[],"extra":{},"properties":{},"type":"string"},"device":{"description":"The Device ID.","enum":[],"extra":{},"properties":{},"type":"string"},"device_name":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"description":"The PCI ID.","enum":[],"extra":{},"properties":{},"type":"string"},"iommugroup":{"description":"The IOMMU group in which the device is in. If no IOMMU group is detected, it is set to -1.","enum":[],"extra":{},"properties":{},"type":"integer"},"mdev":{"description":"If set, marks that the device is capable of creating mediated devices.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"subsystem_device":{"description":"The Subsystem Device ID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"subsystem_device_name":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"subsystem_vendor":{"description":"The Subsystem Vendor ID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"subsystem_vendor_name":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vendor":{"description":"The Vendor ID.","enum":[],"extra":{},"properties":{},"type":"string"},"vendor_name":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware/pci"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0380005f39419bdbf9fbd8e0605704890700d45925bdc7e09289d01a1584b88a","description":"Index of available pci methods","extra":{},"name":"pci_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{},"pattern":"(?:(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\\.[0-9a-fA-F])|([a-zA-Z][a-zA-Z0-9_-]+)","properties":{},"type":"string"},"name":"pci-id-or-mapping"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{method}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"method":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware/pci/{pci-id-or-mapping}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f3f42c8ccc4e915864049b845055cc72a2e753e5310db9fd846b53248f69ca69","description":"List mediated device types for given PCI device.","extra":{"proxyto":"node"},"name":"mdevscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The PCI ID or mapping to list the mdev types for.","enum":[],"extra":{},"pattern":"(?:(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\\.[0-9a-fA-F])|([a-zA-Z][a-zA-Z0-9_-]+)","properties":{},"type":"string"},"name":"pci-id-or-mapping"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Sys.Modify"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"available":{"description":"The number of still available instances of this type.","enum":[],"extra":{},"properties":{},"type":"integer"},"description":{"description":"Additional description of the type.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"A human readable name for the type.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"The name of the mdev type.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c34730e00f0d40259fe27fa8d10c86ca51d09c55d88e56c0a58a874dcf7bff9c","description":"List local USB devices.","extra":{"proxyto":"node"},"name":"usbscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"busnum":{"enum":[],"extra":{},"properties":{},"type":"integer"},"class":{"enum":[],"extra":{},"properties":{},"type":"integer"},"devnum":{"enum":[],"extra":{},"properties":{},"type":"integer"},"level":{"enum":[],"extra":{},"properties":{},"type":"integer"},"manufacturer":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"prodid":{"enum":[],"extra":{},"properties":{},"type":"string"},"product":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"speed":{"enum":[],"extra":{},"properties":{},"type":"string"},"usbpath":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vendid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware/usb"},{"extra":{},"methods":[{"allow_token":true,"checksum":"245aea500b630299322623884169fd5c6b7817f39702ab7e27adcf12ffacd5d3","description":"Get the content of /etc/hosts.","extra":{"proxyto":"node"},"name":"get_etc_hosts","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"data":{"description":"The content of /etc/hosts.","enum":[],"extra":{},"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"37ce9f4f98771127e217c1cae8f1c5cee8ce3cefba81cc528f7c6ca1619d4752","description":"Write /etc/hosts.","extra":{"proxyto":"node"},"name":"write_etc_hosts","parameters":[{"definition":{"description":"The target content of /etc/hosts.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"data"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/hosts"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f19983c07943897ef9b485d0ec8107565a6488638328628e2704475ab4457b32","description":"Read Journal","extra":{"download_allowed":1,"proxyto":"node"},"name":"journal","parameters":[{"definition":{"description":"End before the given Cursor. Conflicts with 'until'","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"endcursor"},{"definition":{"description":"Limit to the last X lines. Conflicts with a range.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"lastentries"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Display all log since this UNIX epoch. Conflicts with 'startcursor'.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"since"},{"definition":{"description":"Start after the given Cursor. Conflicts with 'since'","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"startcursor"},{"definition":{"description":"Display all log until this UNIX epoch. Conflicts with 'endcursor'.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"until"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/journal"},{"extra":{},"methods":[{"allow_token":true,"checksum":"71b5d311f9b4141bf62dcdcee0b9220e5307484ebb7518753edc0a644c8cbd98","description":"LXC container index (per node).","extra":{"proxyto":"node"},"name":"vmlist","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Only list CTs where you have VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{vmid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cpu":{"description":"Current CPU usage.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"cpus":{"description":"Maximum usable CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"disk":{"description":"Root disk image space-usage in bytes.","enum":[],"extra":{"renderer":"bytes"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"diskread":{"description":"The amount of bytes the guest read from it's block devices since the guest was started. (Note: This info is not available for all storage types.)","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"diskwrite":{"description":"The amount of bytes the guest wrote from it's block devices since the guest was started. (Note: This info is not available for all storage types.)","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"lock":{"description":"The current config lock, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxdisk":{"description":"Root disk image size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Maximum memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxswap":{"description":"Maximum SWAP memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"mem":{"description":"Currently used memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"name":{"description":"Container name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"netin":{"description":"The amount of traffic in bytes that was sent to the guest over the network since it was started.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"netout":{"description":"The amount of traffic in bytes that was sent from the guest over the network since it was started.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"pressurecpusome":{"description":"CPU Some pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressureiofull":{"description":"IO Full pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressureiosome":{"description":"IO Some pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressurememoryfull":{"description":"Memory Full pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressurememorysome":{"description":"Memory Some pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"status":{"description":"LXC Container status.","enum":["stopped","running"],"extra":{},"properties":{},"type":"string"},"tags":{"description":"The current configured tags, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"template":{"default":0,"description":"Determines if the guest is a template.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"uptime":{"description":"Uptime in seconds.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"0ae9c475217d7999244dc8fd208085a721468eac45ee6fd0c1d4226a9a44484e","description":"Create or restore a container.","extra":{"proxyto":"node"},"name":"create_vm","parameters":[{"definition":{"default":"amd64","description":"OS architecture type.","enum":["amd64","i386","arm64","armhf","riscv32","riscv64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"default":"restore limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"default":"tty","description":"Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).","enum":["shell","console","tty"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmode"},{"definition":{"default":1,"description":"Attach a console device (/dev/console) to the container.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"console"},{"definition":{"description":"The number of cores assigned to the container. A container can use all available cores by default.","enum":[],"extra":{"typetext":" (1 - 8192)"},"maximum":8192,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"default":0,"description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.","enum":[],"extra":{"typetext":" (0 - 8192)"},"maximum":8192,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"typetext":" (0 - 500000)","verbose_description":"CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests."},"maximum":500000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"default":0,"description":"Try to be more verbose. For now this only enables debug log-level on start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"debug"},{"definition":{"description":"Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":8192,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Device to pass through to the container","enum":[],"extra":{"typetext":"[[path=]] [,deny-write=<1|0>] [,gid=] [,mode=] [,uid=]"},"format":{"deny-write":{"default":0,"description":"Deny the container to write to the device","optional":1,"type":"boolean"},"gid":{"description":"Group ID to be assigned to the device node","minimum":0,"optional":1,"type":"integer"},"mode":{"description":"Access mode to be set on the device node","format_description":"Octal access mode","optional":1,"pattern":"0[0-7]{3}","type":"string"},"path":{"default_key":1,"description":"Device to pass through to the container","format":"pve-lxc-dev-string","format_description":"Path","optional":1,"type":"string","verbose_description":"Path to the device to pass through to the container"},"uid":{"description":"User ID to be assigned to the device node","minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"dev[n]"},{"definition":{"default":"/sbin/init","description":"Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH.","enum":[],"extra":{},"optional":true,"pattern":"(?^:[^\\x00-\\x08\\x0a-\\x1F\\x7F]+)","properties":{},"type":"string"},"name":"entrypoint"},{"definition":{"description":"The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config.","enum":[],"extra":{},"optional":true,"pattern":"(?^:(?:\\w+=[^\\x00-\\x08\\x0a-\\x1F\\x7F]*)(?:\\0\\w+=[^\\x00-\\x08\\x0a-\\x1F\\x7F]*)*)","properties":{},"type":"string"},"name":"env"},{"definition":{"description":"Allow containers access to advanced features.","enum":[],"extra":{"typetext":"[force_rw_sys=<1|0>] [,fuse=<1|0>] [,keyctl=<1|0>] [,mknod=<1|0>] [,mount=] [,nesting=<1|0>]"},"format":{"force_rw_sys":{"default":0,"description":"Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.","optional":1,"type":"boolean"},"fuse":{"default":0,"description":"Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.","optional":1,"type":"boolean"},"keyctl":{"default":0,"description":"For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.","optional":1,"type":"boolean"},"mknod":{"default":0,"description":"Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.","optional":1,"type":"boolean"},"mount":{"description":"Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.","format_description":"fstype;fstype;...","optional":1,"pattern":"(?^:[a-zA-Z0-9_; ]+)","type":"string"},"nesting":{"default":0,"description":"Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest. This is also required by systemd to isolate services.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"features"},{"definition":{"description":"Allow to overwrite existing container.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"default":0,"description":"Add the CT as a HA resource after it was created.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ha-managed"},{"definition":{"description":"Script that will be executed during various steps in the containers lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Set a host name for the container.","enum":[],"extra":{"typetext":""},"format":"dns-name","max_length":255,"optional":true,"properties":{},"type":"string"},"name":"hostname"},{"definition":{"description":"Ignore errors when extracting the template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ignore-unpack-errors"},{"definition":{"description":"Lock/unlock the container.","enum":["backup","create","destroyed","disk","fstrim","migrate","mounted","rollback","snapshot","snapshot-delete"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"default":512,"description":"Amount of RAM for the container in MB.","enum":[],"extra":{"typetext":" (16 - N)"},"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"memory"},{"definition":{"description":"Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[volume=] ,mp= [,acl=<1|0>] [,backup=<1|0>] [,idmap=] [,keepattrs=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]"},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"backup":{"description":"Whether to include the mount point in backups.","optional":1,"type":"boolean","verbose_description":"Whether to include the mount point in backups (only used for volume mount points)."},"idmap":{"description":"Map specific container UIDs/GIDs to underlying disk UIDs/GIDs for this mount point","format_description":"type:container:disk:range-size[;type:container:disk:range-size;...]","optional":1,"pattern":"(?^:^(?:passthrough|[ug]:[0-9]+:[0-9]+:[1-9][0-9]*(?:;[ug]:[0-9]+:[0-9]+:[1-9][0-9]*)*)$)","type":"string","verbose_description":"Customize UID/GID mappings that override the container's `lxc.idmap` for this mount point. Accepts a semicolon-separated list of `type:container:disk:range-size` entries.\n\n`type` is `u` for UID or `g` for GID.\n\n`container` is the first ID as seen inside the container.\n\n`disk` is the first corresponding ID on the underlying filesystem.\n\n`range-size` is the number of consecutive IDs to map.\n\nUnmapped IDs fall back to the container's `lxc.idmap`.\n\nExample 1: `u:123:456:1` maps UID 123 in the container to UID 456 on the disk. Files owned by UID 456 on the disk will appear as UID 123 inside the container.\n\nExample 2: `g:100:50:5` maps 5 consecutive GIDs, such that GIDs 100-104 in the container are mapped to GIDs 50-54 on the disk.\n\nExample 3: `passthrough` identity-maps all UIDs and GIDs, meaning IDs inside the container will match the IDs on the disk."},"keepattrs":{"default":0,"description":"Inherit ownership and permissions from the mount point directory.","optional":1,"type":"boolean","verbose_description":"Inherit UID, GID and access mode from the mount point directory, if it exists already."},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)","type":"string"},"mp":{"description":"Path to the mount point as seen from inside the container (must not contain symlinks).","format":"pve-lxc-mp-string","format_description":"Path","type":"string","verbose_description":"Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons."},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"mp[n]"},{"definition":{"description":"Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{"typetext":""},"format":"lxc-ip-with-ll-iface-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specifies network interfaces for the container.","enum":[],"extra":{"typetext":"name= [,bridge=] [,firewall=<1|0>] [,gw=] [,gw6=] [,host-managed=<1|0>] [,hwaddr=] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=<(IPv6/CIDR|auto|dhcp|manual)>] [,link_down=<1|0>] [,mtu=] [,rate=] [,tag=] [,trunks=] [,type=]"},"format":{"bridge":{"description":"Bridge to attach the network device to.","format_description":"bridge","optional":1,"pattern":"[-_.\\w\\d]+","type":"string"},"firewall":{"description":"Controls whether this interface's firewall rules should be used.","optional":1,"type":"boolean"},"gw":{"description":"Default gateway for IPv4 traffic.","format":"ipv4","format_description":"GatewayIPv4","optional":1,"type":"string"},"gw6":{"description":"Default gateway for IPv6 traffic.","format":"ipv6","format_description":"GatewayIPv6","optional":1,"type":"string"},"host-managed":{"description":"Whether this interface's IP configuration should be managed by the host. When enabled, the host (rather than the container) is responsible for the interface's IP configuration. The container should not run its own DHCP client or network manager on this interface. This is useful for containers that lack an internal network management stack, like many application containers.","optional":1,"type":"boolean"},"hwaddr":{"description":"The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"ip":{"description":"IPv4 address in CIDR format.","format":"pve-ipv4-config","format_description":"(IPv4/CIDR|dhcp|manual)","optional":1,"type":"string"},"ip6":{"description":"IPv6 address in CIDR format.","format":"pve-ipv6-config","format_description":"(IPv6/CIDR|auto|dhcp|manual)","optional":1,"type":"string"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"mtu":{"description":"Maximum transfer unit of the interface. (lxc.network.mtu)","maximum":65535,"minimum":64,"optional":1,"type":"integer"},"name":{"description":"Name of the network device as seen from inside the container. (lxc.network.name)","format_description":"string","pattern":"[-_.\\w\\d]+","type":"string"},"rate":{"description":"Apply rate limiting to the interface","format_description":"mbps","optional":1,"type":"number"},"tag":{"description":"VLAN tag for this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN ids to pass through the interface","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:;\\d+)*)","type":"string"},"type":{"description":"Network interface type.","enum":["veth"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Specifies whether a container will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"The OS template or backup file.","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"ostemplate"},{"definition":{"description":"OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.","enum":["debian","devuan","ubuntu","centos","fedora","opensuse","archlinux","alpine","gentoo","nixos","unmanaged"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"description":"Sets root password inside container.","enum":[],"extra":{"typetext":""},"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Add the VM to the specified pool.","enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"default":0,"description":"Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"description":"Mark this as restore task.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restore"},{"definition":{"description":"Use volume as container root.","enum":[],"extra":{"typetext":"[volume=] [,acl=<1|0>] [,idmap=] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]"},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"idmap":{"description":"Map specific container UIDs/GIDs to underlying disk UIDs/GIDs for this mount point","format_description":"type:container:disk:range-size[;type:container:disk:range-size;...]","optional":1,"pattern":"(?^:^(?:passthrough|[ug]:[0-9]+:[0-9]+:[1-9][0-9]*(?:;[ug]:[0-9]+:[0-9]+:[1-9][0-9]*)*)$)","type":"string","verbose_description":"Customize UID/GID mappings that override the container's `lxc.idmap` for this mount point. Accepts a semicolon-separated list of `type:container:disk:range-size` entries.\n\n`type` is `u` for UID or `g` for GID.\n\n`container` is the first ID as seen inside the container.\n\n`disk` is the first corresponding ID on the underlying filesystem.\n\n`range-size` is the number of consecutive IDs to map.\n\nUnmapped IDs fall back to the container's `lxc.idmap`.\n\nExample 1: `u:123:456:1` maps UID 123 in the container to UID 456 on the disk. Files owned by UID 456 on the disk will appear as UID 123 inside the container.\n\nExample 2: `g:100:50:5` maps 5 consecutive GIDs, such that GIDs 100-104 in the container are mapped to GIDs 50-54 on the disk.\n\nExample 3: `passthrough` identity-maps all UIDs and GIDs, meaning IDs inside the container will match the IDs on the disk."},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)","type":"string"},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"rootfs"},{"definition":{"description":"Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{"typetext":""},"format":"dns-name-list","optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ssh-public-keys"},{"definition":{"default":0,"description":"Start the CT after its creation finished successfully.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"start"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"default":"local","description":"Default Storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"default":512,"description":"Amount of SWAP for the container in MB.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"swap"},{"definition":{"description":"Tags of the Container. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab","enum":[],"extra":{"typetext":""},"format":"pve-ct-timezone","optional":true,"properties":{},"type":"string"},"name":"timezone"},{"definition":{"default":2,"description":"Specify the number of tty available to the container","enum":[],"extra":{"typetext":" (0 - 6)"},"maximum":6,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"tty"},{"definition":{"description":"Assign a unique random ethernet address.","enum":[],"extra":{"requires":"restore","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"unique"},{"definition":{"default":0,"description":"Makes the container run as unprivileged user. For creation, the default is 1. For restore, the default is the value from the backup. (Should not be modified manually.)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"unprivileged"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[volume=]"},"format":{"volume":{"default_key":1,"description":"The volume that is not used currently.","format":"pve-volume-id","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permission on /vms/{vmid} or on the VM pool /pool/{pool}. For restore, it is enough if the user has 'VM.Backup' permission and the VM already exists. You also need 'Datastore.AllocateSpace' permissions on the storage. For privileged containers, 'Sys.Modify' permissions on '/' are required.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c19475ddef11337e048bb0acd1838036c83e7f6c9e9087b79f44af4db7ddaa96","description":"Destroy the container (also delete all uses files).","extra":{"proxyto":"node"},"name":"destroy_vm","parameters":[{"definition":{"description":"If set, destroy additionally all disks with the VMID from all enabled storages which are not referenced in the config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"destroy-unreferenced-disks"},{"definition":{"default":0,"description":"Force destroy, even if running.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Remove container from all related configurations. For example, backup jobs, replication jobs or HA. Related ACLs and Firewall entries will *always* be removed.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"purge"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"9e36c28967bab606c23a50ff07fa5524991078437cdd75bba7697aac8a894802","description":"Directory index","extra":{"proxyto":"node"},"name":"vmdiridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4bbb53382d608d5df0acb24c45061badb77671649b3feb996359f7d9b1b671ae","description":"Create a container clone/copy","extra":{"proxyto":"node"},"name":"clone_vm","parameters":[{"definition":{"default":"clone limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"description":"Description for the new CT.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Create a full copy of all disks. This is always done when you clone a normal CT. For CT templates, we try to create a linked clone by default.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"},{"definition":{"description":"Set a hostname for the new CT.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"hostname"},{"definition":{"description":"VMID for the clone.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"newid"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Add the new CT to the specified pool.","enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"Target storage for full clone.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Target node. Only allowed if the original VM is on shared storage.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions on /vms/{newid} (or on the VM pool /pool/{pool}). You also need 'Datastore.AllocateSpace' on any used storage, and 'SDN.Use' on any bridge.","expression":{"check":["and",["perm","/vms/{vmid}",["VM.Clone"]],["or",["perm","/vms/{newid}",["VM.Allocate"]],["perm","/pool/{pool}",["VM.Allocate"],"require_param","pool"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/clone"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4b0b6b976eb98d95d36220a90d0b2b4f467a2b73c3bb1de2a981a6041afc74bb","description":"Get container configuration.","extra":{"proxyto":"node"},"name":"vm_config","parameters":[{"definition":{"default":0,"description":"Get current values (instead of pending values).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"current"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Fetch config values from given snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapshot"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"arch":{"default":"amd64","description":"OS architecture type.","enum":["amd64","i386","arm64","armhf","riscv32","riscv64"],"extra":{},"optional":true,"properties":{},"type":"string"},"cmode":{"default":"tty","description":"Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).","enum":["shell","console","tty"],"extra":{},"optional":true,"properties":{},"type":"string"},"console":{"default":1,"description":"Attach a console device (/dev/console) to the container.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"cores":{"description":"The number of cores assigned to the container. A container can use all available cores by default.","enum":[],"extra":{},"maximum":8192,"minimum":1,"optional":true,"properties":{},"type":"integer"},"cpulimit":{"default":0,"description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.","enum":[],"extra":{},"maximum":8192,"minimum":0,"optional":true,"properties":{},"type":"number"},"cpuunits":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"verbose_description":"CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests."},"maximum":500000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"debug":{"default":0,"description":"Try to be more verbose. For now this only enables debug log-level on start.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"description":{"description":"Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{},"max_length":8192,"optional":true,"properties":{},"type":"string"},"dev[n]":{"description":"Device to pass through to the container","enum":[],"extra":{},"format":{"deny-write":{"default":0,"description":"Deny the container to write to the device","optional":1,"type":"boolean"},"gid":{"description":"Group ID to be assigned to the device node","minimum":0,"optional":1,"type":"integer"},"mode":{"description":"Access mode to be set on the device node","format_description":"Octal access mode","optional":1,"pattern":"0[0-7]{3}","type":"string"},"path":{"default_key":1,"description":"Device to pass through to the container","format":"pve-lxc-dev-string","format_description":"Path","optional":1,"type":"string","verbose_description":"Path to the device to pass through to the container"},"uid":{"description":"User ID to be assigned to the device node","minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"digest":{"description":"SHA1 digest of configuration file. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"properties":{},"type":"string"},"entrypoint":{"default":"/sbin/init","description":"Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH.","enum":[],"extra":{},"optional":true,"pattern":"(?^:[^\\x00-\\x08\\x0a-\\x1F\\x7F]+)","properties":{},"type":"string"},"env":{"description":"The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config.","enum":[],"extra":{},"optional":true,"pattern":"(?^:(?:\\w+=[^\\x00-\\x08\\x0a-\\x1F\\x7F]*)(?:\\0\\w+=[^\\x00-\\x08\\x0a-\\x1F\\x7F]*)*)","properties":{},"type":"string"},"features":{"description":"Allow containers access to advanced features.","enum":[],"extra":{},"format":{"force_rw_sys":{"default":0,"description":"Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.","optional":1,"type":"boolean"},"fuse":{"default":0,"description":"Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.","optional":1,"type":"boolean"},"keyctl":{"default":0,"description":"For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.","optional":1,"type":"boolean"},"mknod":{"default":0,"description":"Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.","optional":1,"type":"boolean"},"mount":{"description":"Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.","format_description":"fstype;fstype;...","optional":1,"pattern":"(?^:[a-zA-Z0-9_; ]+)","type":"string"},"nesting":{"default":0,"description":"Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest. This is also required by systemd to isolate services.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"hookscript":{"description":"Script that will be executed during various steps in the containers lifetime.","enum":[],"extra":{},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"hostname":{"description":"Set a host name for the container.","enum":[],"extra":{},"format":"dns-name","max_length":255,"optional":true,"properties":{},"type":"string"},"lock":{"description":"Lock/unlock the container.","enum":["backup","create","destroyed","disk","fstrim","migrate","mounted","rollback","snapshot","snapshot-delete"],"extra":{},"optional":true,"properties":{},"type":"string"},"lxc":{"description":"Array of lxc low-level configurations ([[key1, value1], [key2, value2] ...]).","enum":[],"extra":{},"items":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"optional":true,"properties":{},"type":"array"},"memory":{"default":512,"description":"Amount of RAM for the container in MB.","enum":[],"extra":{},"minimum":16,"optional":true,"properties":{},"type":"integer"},"mp[n]":{"description":"Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"backup":{"description":"Whether to include the mount point in backups.","optional":1,"type":"boolean","verbose_description":"Whether to include the mount point in backups (only used for volume mount points)."},"idmap":{"description":"Map specific container UIDs/GIDs to underlying disk UIDs/GIDs for this mount point","format_description":"type:container:disk:range-size[;type:container:disk:range-size;...]","optional":1,"pattern":"(?^:^(?:passthrough|[ug]:[0-9]+:[0-9]+:[1-9][0-9]*(?:;[ug]:[0-9]+:[0-9]+:[1-9][0-9]*)*)$)","type":"string","verbose_description":"Customize UID/GID mappings that override the container's `lxc.idmap` for this mount point. Accepts a semicolon-separated list of `type:container:disk:range-size` entries.\n\n`type` is `u` for UID or `g` for GID.\n\n`container` is the first ID as seen inside the container.\n\n`disk` is the first corresponding ID on the underlying filesystem.\n\n`range-size` is the number of consecutive IDs to map.\n\nUnmapped IDs fall back to the container's `lxc.idmap`.\n\nExample 1: `u:123:456:1` maps UID 123 in the container to UID 456 on the disk. Files owned by UID 456 on the disk will appear as UID 123 inside the container.\n\nExample 2: `g:100:50:5` maps 5 consecutive GIDs, such that GIDs 100-104 in the container are mapped to GIDs 50-54 on the disk.\n\nExample 3: `passthrough` identity-maps all UIDs and GIDs, meaning IDs inside the container will match the IDs on the disk."},"keepattrs":{"default":0,"description":"Inherit ownership and permissions from the mount point directory.","optional":1,"type":"boolean","verbose_description":"Inherit UID, GID and access mode from the mount point directory, if it exists already."},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)","type":"string"},"mp":{"description":"Path to the mount point as seen from inside the container (must not contain symlinks).","format":"pve-lxc-mp-string","format_description":"Path","type":"string","verbose_description":"Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons."},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"nameserver":{"description":"Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{},"format":"lxc-ip-with-ll-iface-list","optional":true,"properties":{},"type":"string"},"net[n]":{"description":"Specifies network interfaces for the container.","enum":[],"extra":{},"format":{"bridge":{"description":"Bridge to attach the network device to.","format_description":"bridge","optional":1,"pattern":"[-_.\\w\\d]+","type":"string"},"firewall":{"description":"Controls whether this interface's firewall rules should be used.","optional":1,"type":"boolean"},"gw":{"description":"Default gateway for IPv4 traffic.","format":"ipv4","format_description":"GatewayIPv4","optional":1,"type":"string"},"gw6":{"description":"Default gateway for IPv6 traffic.","format":"ipv6","format_description":"GatewayIPv6","optional":1,"type":"string"},"host-managed":{"description":"Whether this interface's IP configuration should be managed by the host. When enabled, the host (rather than the container) is responsible for the interface's IP configuration. The container should not run its own DHCP client or network manager on this interface. This is useful for containers that lack an internal network management stack, like many application containers.","optional":1,"type":"boolean"},"hwaddr":{"description":"The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"ip":{"description":"IPv4 address in CIDR format.","format":"pve-ipv4-config","format_description":"(IPv4/CIDR|dhcp|manual)","optional":1,"type":"string"},"ip6":{"description":"IPv6 address in CIDR format.","format":"pve-ipv6-config","format_description":"(IPv6/CIDR|auto|dhcp|manual)","optional":1,"type":"string"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"mtu":{"description":"Maximum transfer unit of the interface. (lxc.network.mtu)","maximum":65535,"minimum":64,"optional":1,"type":"integer"},"name":{"description":"Name of the network device as seen from inside the container. (lxc.network.name)","format_description":"string","pattern":"[-_.\\w\\d]+","type":"string"},"rate":{"description":"Apply rate limiting to the interface","format_description":"mbps","optional":1,"type":"number"},"tag":{"description":"VLAN tag for this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN ids to pass through the interface","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:;\\d+)*)","type":"string"},"type":{"description":"Network interface type.","enum":["veth"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"onboot":{"default":0,"description":"Specifies whether a container will be started during system bootup.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ostype":{"description":"OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.","enum":["debian","devuan","ubuntu","centos","fedora","opensuse","archlinux","alpine","gentoo","nixos","unmanaged"],"extra":{},"optional":true,"properties":{},"type":"string"},"protection":{"default":0,"description":"Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"rootfs":{"description":"Use volume as container root.","enum":[],"extra":{},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"idmap":{"description":"Map specific container UIDs/GIDs to underlying disk UIDs/GIDs for this mount point","format_description":"type:container:disk:range-size[;type:container:disk:range-size;...]","optional":1,"pattern":"(?^:^(?:passthrough|[ug]:[0-9]+:[0-9]+:[1-9][0-9]*(?:;[ug]:[0-9]+:[0-9]+:[1-9][0-9]*)*)$)","type":"string","verbose_description":"Customize UID/GID mappings that override the container's `lxc.idmap` for this mount point. Accepts a semicolon-separated list of `type:container:disk:range-size` entries.\n\n`type` is `u` for UID or `g` for GID.\n\n`container` is the first ID as seen inside the container.\n\n`disk` is the first corresponding ID on the underlying filesystem.\n\n`range-size` is the number of consecutive IDs to map.\n\nUnmapped IDs fall back to the container's `lxc.idmap`.\n\nExample 1: `u:123:456:1` maps UID 123 in the container to UID 456 on the disk. Files owned by UID 456 on the disk will appear as UID 123 inside the container.\n\nExample 2: `g:100:50:5` maps 5 consecutive GIDs, such that GIDs 100-104 in the container are mapped to GIDs 50-54 on the disk.\n\nExample 3: `passthrough` identity-maps all UIDs and GIDs, meaning IDs inside the container will match the IDs on the disk."},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)","type":"string"},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"searchdomain":{"description":"Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{},"format":"dns-name-list","optional":true,"properties":{},"type":"string"},"startup":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"swap":{"default":512,"description":"Amount of SWAP for the container in MB.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"tags":{"description":"Tags of the Container. This is only meta information.","enum":[],"extra":{},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"template":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"timezone":{"description":"Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab","enum":[],"extra":{},"format":"pve-ct-timezone","optional":true,"properties":{},"type":"string"},"tty":{"default":2,"description":"Specify the number of tty available to the container","enum":[],"extra":{},"maximum":6,"minimum":0,"optional":true,"properties":{},"type":"integer"},"unprivileged":{"default":0,"description":"Makes the container run as unprivileged user. For creation, the default is 1. For restore, the default is the value from the backup. (Should not be modified manually.)","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"unused[n]":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{},"format":{"volume":{"default_key":1,"description":"The volume that is not used currently.","format":"pve-volume-id","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"cbd5e8c8afa91edb2e6c4b09f2951aaf82131f4bdbda4160e0fb1a9d753ace00","description":"Set container options.","extra":{"proxyto":"node"},"name":"update_vm","parameters":[{"definition":{"default":"amd64","description":"OS architecture type.","enum":["amd64","i386","arm64","armhf","riscv32","riscv64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"default":"tty","description":"Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).","enum":["shell","console","tty"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmode"},{"definition":{"default":1,"description":"Attach a console device (/dev/console) to the container.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"console"},{"definition":{"description":"The number of cores assigned to the container. A container can use all available cores by default.","enum":[],"extra":{"typetext":" (1 - 8192)"},"maximum":8192,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"default":0,"description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.","enum":[],"extra":{"typetext":" (0 - 8192)"},"maximum":8192,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"typetext":" (0 - 500000)","verbose_description":"CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests."},"maximum":500000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"default":0,"description":"Try to be more verbose. For now this only enables debug log-level on start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"debug"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":8192,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Device to pass through to the container","enum":[],"extra":{"typetext":"[[path=]] [,deny-write=<1|0>] [,gid=] [,mode=] [,uid=]"},"format":{"deny-write":{"default":0,"description":"Deny the container to write to the device","optional":1,"type":"boolean"},"gid":{"description":"Group ID to be assigned to the device node","minimum":0,"optional":1,"type":"integer"},"mode":{"description":"Access mode to be set on the device node","format_description":"Octal access mode","optional":1,"pattern":"0[0-7]{3}","type":"string"},"path":{"default_key":1,"description":"Device to pass through to the container","format":"pve-lxc-dev-string","format_description":"Path","optional":1,"type":"string","verbose_description":"Path to the device to pass through to the container"},"uid":{"description":"User ID to be assigned to the device node","minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"dev[n]"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":"/sbin/init","description":"Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH.","enum":[],"extra":{},"optional":true,"pattern":"(?^:[^\\x00-\\x08\\x0a-\\x1F\\x7F]+)","properties":{},"type":"string"},"name":"entrypoint"},{"definition":{"description":"The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config.","enum":[],"extra":{},"optional":true,"pattern":"(?^:(?:\\w+=[^\\x00-\\x08\\x0a-\\x1F\\x7F]*)(?:\\0\\w+=[^\\x00-\\x08\\x0a-\\x1F\\x7F]*)*)","properties":{},"type":"string"},"name":"env"},{"definition":{"description":"Allow containers access to advanced features.","enum":[],"extra":{"typetext":"[force_rw_sys=<1|0>] [,fuse=<1|0>] [,keyctl=<1|0>] [,mknod=<1|0>] [,mount=] [,nesting=<1|0>]"},"format":{"force_rw_sys":{"default":0,"description":"Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.","optional":1,"type":"boolean"},"fuse":{"default":0,"description":"Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.","optional":1,"type":"boolean"},"keyctl":{"default":0,"description":"For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.","optional":1,"type":"boolean"},"mknod":{"default":0,"description":"Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.","optional":1,"type":"boolean"},"mount":{"description":"Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.","format_description":"fstype;fstype;...","optional":1,"pattern":"(?^:[a-zA-Z0-9_; ]+)","type":"string"},"nesting":{"default":0,"description":"Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest. This is also required by systemd to isolate services.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"features"},{"definition":{"description":"Script that will be executed during various steps in the containers lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Set a host name for the container.","enum":[],"extra":{"typetext":""},"format":"dns-name","max_length":255,"optional":true,"properties":{},"type":"string"},"name":"hostname"},{"definition":{"description":"Lock/unlock the container.","enum":["backup","create","destroyed","disk","fstrim","migrate","mounted","rollback","snapshot","snapshot-delete"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"default":512,"description":"Amount of RAM for the container in MB.","enum":[],"extra":{"typetext":" (16 - N)"},"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"memory"},{"definition":{"description":"Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[volume=] ,mp= [,acl=<1|0>] [,backup=<1|0>] [,idmap=] [,keepattrs=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]"},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"backup":{"description":"Whether to include the mount point in backups.","optional":1,"type":"boolean","verbose_description":"Whether to include the mount point in backups (only used for volume mount points)."},"idmap":{"description":"Map specific container UIDs/GIDs to underlying disk UIDs/GIDs for this mount point","format_description":"type:container:disk:range-size[;type:container:disk:range-size;...]","optional":1,"pattern":"(?^:^(?:passthrough|[ug]:[0-9]+:[0-9]+:[1-9][0-9]*(?:;[ug]:[0-9]+:[0-9]+:[1-9][0-9]*)*)$)","type":"string","verbose_description":"Customize UID/GID mappings that override the container's `lxc.idmap` for this mount point. Accepts a semicolon-separated list of `type:container:disk:range-size` entries.\n\n`type` is `u` for UID or `g` for GID.\n\n`container` is the first ID as seen inside the container.\n\n`disk` is the first corresponding ID on the underlying filesystem.\n\n`range-size` is the number of consecutive IDs to map.\n\nUnmapped IDs fall back to the container's `lxc.idmap`.\n\nExample 1: `u:123:456:1` maps UID 123 in the container to UID 456 on the disk. Files owned by UID 456 on the disk will appear as UID 123 inside the container.\n\nExample 2: `g:100:50:5` maps 5 consecutive GIDs, such that GIDs 100-104 in the container are mapped to GIDs 50-54 on the disk.\n\nExample 3: `passthrough` identity-maps all UIDs and GIDs, meaning IDs inside the container will match the IDs on the disk."},"keepattrs":{"default":0,"description":"Inherit ownership and permissions from the mount point directory.","optional":1,"type":"boolean","verbose_description":"Inherit UID, GID and access mode from the mount point directory, if it exists already."},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)","type":"string"},"mp":{"description":"Path to the mount point as seen from inside the container (must not contain symlinks).","format":"pve-lxc-mp-string","format_description":"Path","type":"string","verbose_description":"Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons."},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"mp[n]"},{"definition":{"description":"Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{"typetext":""},"format":"lxc-ip-with-ll-iface-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specifies network interfaces for the container.","enum":[],"extra":{"typetext":"name= [,bridge=] [,firewall=<1|0>] [,gw=] [,gw6=] [,host-managed=<1|0>] [,hwaddr=] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=<(IPv6/CIDR|auto|dhcp|manual)>] [,link_down=<1|0>] [,mtu=] [,rate=] [,tag=] [,trunks=] [,type=]"},"format":{"bridge":{"description":"Bridge to attach the network device to.","format_description":"bridge","optional":1,"pattern":"[-_.\\w\\d]+","type":"string"},"firewall":{"description":"Controls whether this interface's firewall rules should be used.","optional":1,"type":"boolean"},"gw":{"description":"Default gateway for IPv4 traffic.","format":"ipv4","format_description":"GatewayIPv4","optional":1,"type":"string"},"gw6":{"description":"Default gateway for IPv6 traffic.","format":"ipv6","format_description":"GatewayIPv6","optional":1,"type":"string"},"host-managed":{"description":"Whether this interface's IP configuration should be managed by the host. When enabled, the host (rather than the container) is responsible for the interface's IP configuration. The container should not run its own DHCP client or network manager on this interface. This is useful for containers that lack an internal network management stack, like many application containers.","optional":1,"type":"boolean"},"hwaddr":{"description":"The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"ip":{"description":"IPv4 address in CIDR format.","format":"pve-ipv4-config","format_description":"(IPv4/CIDR|dhcp|manual)","optional":1,"type":"string"},"ip6":{"description":"IPv6 address in CIDR format.","format":"pve-ipv6-config","format_description":"(IPv6/CIDR|auto|dhcp|manual)","optional":1,"type":"string"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"mtu":{"description":"Maximum transfer unit of the interface. (lxc.network.mtu)","maximum":65535,"minimum":64,"optional":1,"type":"integer"},"name":{"description":"Name of the network device as seen from inside the container. (lxc.network.name)","format_description":"string","pattern":"[-_.\\w\\d]+","type":"string"},"rate":{"description":"Apply rate limiting to the interface","format_description":"mbps","optional":1,"type":"number"},"tag":{"description":"VLAN tag for this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN ids to pass through the interface","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:;\\d+)*)","type":"string"},"type":{"description":"Network interface type.","enum":["veth"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Specifies whether a container will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.","enum":["debian","devuan","ubuntu","centos","fedora","opensuse","archlinux","alpine","gentoo","nixos","unmanaged"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"default":0,"description":"Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"description":"Revert a pending change.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"revert"},{"definition":{"description":"Use volume as container root.","enum":[],"extra":{"typetext":"[volume=] [,acl=<1|0>] [,idmap=] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]"},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"idmap":{"description":"Map specific container UIDs/GIDs to underlying disk UIDs/GIDs for this mount point","format_description":"type:container:disk:range-size[;type:container:disk:range-size;...]","optional":1,"pattern":"(?^:^(?:passthrough|[ug]:[0-9]+:[0-9]+:[1-9][0-9]*(?:;[ug]:[0-9]+:[0-9]+:[1-9][0-9]*)*)$)","type":"string","verbose_description":"Customize UID/GID mappings that override the container's `lxc.idmap` for this mount point. Accepts a semicolon-separated list of `type:container:disk:range-size` entries.\n\n`type` is `u` for UID or `g` for GID.\n\n`container` is the first ID as seen inside the container.\n\n`disk` is the first corresponding ID on the underlying filesystem.\n\n`range-size` is the number of consecutive IDs to map.\n\nUnmapped IDs fall back to the container's `lxc.idmap`.\n\nExample 1: `u:123:456:1` maps UID 123 in the container to UID 456 on the disk. Files owned by UID 456 on the disk will appear as UID 123 inside the container.\n\nExample 2: `g:100:50:5` maps 5 consecutive GIDs, such that GIDs 100-104 in the container are mapped to GIDs 50-54 on the disk.\n\nExample 3: `passthrough` identity-maps all UIDs and GIDs, meaning IDs inside the container will match the IDs on the disk."},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)","type":"string"},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"rootfs"},{"definition":{"description":"Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{"typetext":""},"format":"dns-name-list","optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"default":512,"description":"Amount of SWAP for the container in MB.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"swap"},{"definition":{"description":"Tags of the Container. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab","enum":[],"extra":{"typetext":""},"format":"pve-ct-timezone","optional":true,"properties":{},"type":"string"},"name":"timezone"},{"definition":{"default":2,"description":"Specify the number of tty available to the container","enum":[],"extra":{"typetext":" (0 - 6)"},"maximum":6,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"tty"},{"definition":{"default":0,"description":"Makes the container run as unprivileged user. For creation, the default is 1. For restore, the default is the value from the backup. (Should not be modified manually.)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"unprivileged"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[volume=]"},"format":{"volume":{"default_key":1,"description":"The volume that is not used currently.","format":"pve-volume-id","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"non-volume mount points in rootfs and mp[n] are restricted to root@pam","expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk","VM.Config.CPU","VM.Config.Memory","VM.Config.Network","VM.Config.Options"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1cca28754546ef80b178a942204d1b34b746054d684c6e37c44488c2d6a58e2d","description":"Check if feature for virtual machine is available.","extra":{"proxyto":"node"},"name":"vm_feature","parameters":[{"definition":{"description":"Feature to check.","enum":["snapshot","clone","copy"],"extra":{},"properties":{},"type":"string"},"name":"feature"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"hasFeature":{"enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/feature"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7ee5be237c4406d406b763db7b1c3deb794543cfa9e5376476821ff4ad174512","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0e240eee88d783388fa7fd5c605d1946866c6de040a5072e91675a7d06594943","description":"List aliases","extra":{},"name":"get_aliases","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"24f08f4001bb83fb2a6d7e9a6a5d0c3692949ea94751c543f2ce056e43beeacb","description":"Create IP or Network Alias.","extra":{},"name":"create_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/aliases"},{"extra":{},"methods":[{"allow_token":true,"checksum":"547018a4e77e1f19d15e71017e8e7e7bdb3f893052f3a61c4ac77fe1a23a7524","description":"Remove IP or Network alias.","extra":{},"name":"remove_alias","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f5bce1f868d6f087fc556f605b8dba1dadf850207fb04bbddc999079cd9486b7","description":"Read alias.","extra":{},"name":"read_alias","parameters":[{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"1e344b0d51e8e531d0d525f26ebe09c01f6c4cf270e92c36ebe11eca2779dcee","description":"Update IP or Network alias.","extra":{},"name":"update_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Rename an existing alias.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"406378d5359b09bbd6589c105f8df2f99aeef8a54b526302377c06fe5401770e","description":"List IPSets","extra":{},"name":"ipset_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"name":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f4bb41ff25f7d50144a81944017055185c7a72e313a861f8a0406de6bf34ecf2","description":"Create new IPSet","extra":{},"name":"create_ipset","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/ipset"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a40e1badd168974a686fc466a2e06598ef9762be5b279a8f1fa0eca53f7d4880","description":"Delete IPSet","extra":{},"name":"delete_ipset","parameters":[{"definition":{"description":"Delete all members of the IPSet, if there are any.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"5fc76313da1679fa4a2631d95ce58eb8b267a2dd67a0c1a8ac5a55a0ab34b13c","description":"List IPSet content","extra":{},"name":"get_ipset","parameters":[{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cidr}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"nomatch":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"a3ace74f6557fc643406d7775bd8e6eb21c0200d079174ee43ee5a0fd24506c9","description":"Add IP or Network to IPSet.","extra":{},"name":"create_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5f612a84aecce1fd03bb87a7e7c15c6786474a3e211f958a0281c55c835eeebc","description":"Remove IP or Network from IPSet.","extra":{},"name":"remove_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"cae0afef06b37e0a88847c53e617e5a4def2d669bf4da3f4d541cdf1811046a4","description":"Read IP or Network settings from IPSet.","extra":{},"name":"read_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"bb0b6ded1cf4736fae405e8af7ccf92e10623473112c4bb7a73992fdb81b4a2f","description":"Update IP or Network settings","extra":{},"name":"update_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d6b7e9154ddc56bd6b0b9af8378442e873109fc13d420483930da8dafe5fad5c","description":"Read firewall log","extra":{"proxyto":"node"},"name":"log","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Display log since this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"since"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"Display log until this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"until"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"af723360b2a8cdd037ee749b5446fc9d46829aa3972c986d79b9db3fc63f81a7","description":"Get VM firewall options.","extra":{"proxyto":"node"},"name":"get_options","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"dhcp":{"default":0,"description":"Enable DHCP.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"enable":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ipfilter":{"description":"Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"log_level_in":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_level_out":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macfilter":{"default":1,"description":"Enable/disable MAC address filter.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ndp":{"default":1,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"policy_in":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"policy_out":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"radv":{"description":"Allow sending Router Advertisement.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"672ed666236dff83d18a26757f88e1de445eab5d3fa527aaab95ab786b18d2bc","description":"Set Firewall options.","extra":{"proxyto":"node"},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"default":0,"description":"Enable DHCP.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"dhcp"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ipfilter"},{"definition":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_in"},{"definition":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_out"},{"definition":{"default":1,"description":"Enable/disable MAC address filter.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"macfilter"},{"definition":{"default":1,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ndp"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_in"},{"definition":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_out"},{"definition":{"description":"Allow sending Router Advertisement.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"radv"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4d9b684dc2793a1badcd82adfe45cf304ab1efec63d4b53ff4ea0402242531d3","description":"Lists possible IPSet/Alias reference which are allowed in source/dest properties.","extra":{},"name":"refs","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list references of specified type.","enum":["alias","ipset"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"ref":{"enum":[],"extra":{},"properties":{},"type":"string"},"scope":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":["alias","ipset"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/refs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"15e058c129609079ad1251f5545083d4b251f67ce893b3a079ab5702eb86f2d1","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"action":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name","enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"description":"Descriptive comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"description":"Restrict packet destination address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"description":"Restrict TCP/UDP destination port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"description":"Flag to enable/disable a rule","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"description":"Network interface name. You have to use network configuration key names for VMs and containers","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"description":"IP version (4 or 6) - automatically determined from source/dest addresses","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"description":"Use predefined standard macro","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"description":"Rule position in the ruleset","enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"description":"Restrict packet source address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"description":"Restrict TCP/UDP source port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Rule type","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"8031675c54c1cfbf59734cd14ad9735f26d24b9a3960fb0a9e8420731f3d5e51","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"464d07111ad5ee01829e46153bd86a7a820949db1b9fb33ddc3144037e35f734","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"2b90c544e2fc6e225b3d30ed8334b496699e3c3c2ec9fe71215c8f912819ade8","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name","enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"description":"Descriptive comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"description":"Restrict packet destination address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"description":"Restrict TCP/UDP destination port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"description":"Flag to enable/disable a rule","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"description":"Network interface name. You have to use network configuration key names for VMs and containers","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"description":"IP version (4 or 6) - automatically determined from source/dest addresses","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"description":"Use predefined standard macro","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"description":"Rule position in the ruleset","enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"description":"Restrict packet source address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"description":"Restrict TCP/UDP source port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Rule type","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"7f95e71affdc035175864e9fdc728419b98b26887f2b75d4e04ab52c8db841e4","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"db50c406622b6a6be675d45be4eabf8616f10a670120c8bfe9daee0e3bca0365","description":"Get IP addresses of the specified container interface.","extra":{"proxyto":"node"},"name":"ip","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"hardware-address":{"description":"The MAC address of the interface","enum":[],"extra":{},"optional":false,"properties":{},"type":"string"},"hwaddr":{"description":"The MAC address of the interface","enum":[],"extra":{},"optional":false,"properties":{},"type":"string"},"inet":{"description":"The IPv4 address of the interface","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"inet6":{"description":"The IPv6 address of the interface","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ip-addresses":{"description":"The addresses of the interface","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"ip-address":{"description":"IP-Address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ip-address-type":{"description":"IP-Family","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"prefix":{"description":"IP-Prefix","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"optional":false,"properties":{},"type":"array"},"name":{"description":"The name of the interface","enum":[],"extra":{},"optional":false,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/interfaces"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2da3c2b1a5db277caf3a0a7b17f7db7506a35eac16001739a5be2fb92d99b0a1","description":"Get preconditions for migration.","extra":{"proxyto":"node"},"name":"migrate_vm_precondition","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"allowed-nodes":{"description":"List of nodes allowed for migration.","enum":[],"extra":{},"items":{"description":"An allowed node","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"dependent-ha-resources":{"description":"HA resources, which will be migrated to the same target node as the VM, because these are in positive affinity with the VM.","enum":[],"extra":{},"items":{"description":"The ':' resource IDs of a HA resource with a positive affinity rule to this CT.","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"not-allowed-nodes":{"description":"List of not allowed nodes with additional information.","enum":[],"extra":{},"optional":true,"properties":{"blocking-ha-resources":{"description":"HA resources, which are blocking the container from being migrated to the node.","enum":[],"extra":{},"items":{"description":"A blocking HA resource","enum":[],"extra":{},"properties":{"cause":{"description":"The reason why the HA resource is blocking the migration.","enum":["node-affinity","resource-affinity"],"extra":{},"properties":{},"type":"string"},"sid":{"description":"The blocking HA resource id","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"running":{"description":"Determines if the container is running.","enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"2e51013f613ed89d385f9e2be74bbdbdb760cc082b7a89d4264699ea2d8fb201","description":"Migrate the container to another node. Creates a new migration task.","extra":{"proxyto":"node"},"name":"migrate_vm","parameters":[{"definition":{"default":"migrate limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use online/live migration.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"online"},{"definition":{"description":"Use restart migration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restart"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storage-pair-list","optional":true,"properties":{},"type":"string"},"name":"target-storage"},{"definition":{"default":180,"description":"Timeout in seconds for shutdown for restart migration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5dc2e0078cc64480a11331ee212a52548608d8e15a628540354b59057841d366","description":"Move a rootfs-/mp-volume to a different storage or to a different container.","extra":{"proxyto":"node"},"name":"move_volume","parameters":[{"definition":{"default":"clone limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"default":0,"description":"Delete the original volume after successful copy. By default the original is kept as an unused volume entry.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 \" .\n\t\t \"digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target Storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Prevent changes if current configuration file of the target \" .\n\t\t \"container has a different SHA1 digest. This can be used to prevent \" .\n\t\t \"concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"target-digest"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"target-vmid"},{"definition":{"description":"The config key the volume will be moved to. Default is the source volume key.","enum":["rootfs","mp0","mp1","mp2","mp3","mp4","mp5","mp6","mp7","mp8","mp9","mp10","mp11","mp12","mp13","mp14","mp15","mp16","mp17","mp18","mp19","mp20","mp21","mp22","mp23","mp24","mp25","mp26","mp27","mp28","mp29","mp30","mp31","mp32","mp33","mp34","mp35","mp36","mp37","mp38","mp39","mp40","mp41","mp42","mp43","mp44","mp45","mp46","mp47","mp48","mp49","mp50","mp51","mp52","mp53","mp54","mp55","mp56","mp57","mp58","mp59","mp60","mp61","mp62","mp63","mp64","mp65","mp66","mp67","mp68","mp69","mp70","mp71","mp72","mp73","mp74","mp75","mp76","mp77","mp78","mp79","mp80","mp81","mp82","mp83","mp84","mp85","mp86","mp87","mp88","mp89","mp90","mp91","mp92","mp93","mp94","mp95","mp96","mp97","mp98","mp99","mp100","mp101","mp102","mp103","mp104","mp105","mp106","mp107","mp108","mp109","mp110","mp111","mp112","mp113","mp114","mp115","mp116","mp117","mp118","mp119","mp120","mp121","mp122","mp123","mp124","mp125","mp126","mp127","mp128","mp129","mp130","mp131","mp132","mp133","mp134","mp135","mp136","mp137","mp138","mp139","mp140","mp141","mp142","mp143","mp144","mp145","mp146","mp147","mp148","mp149","mp150","mp151","mp152","mp153","mp154","mp155","mp156","mp157","mp158","mp159","mp160","mp161","mp162","mp163","mp164","mp165","mp166","mp167","mp168","mp169","mp170","mp171","mp172","mp173","mp174","mp175","mp176","mp177","mp178","mp179","mp180","mp181","mp182","mp183","mp184","mp185","mp186","mp187","mp188","mp189","mp190","mp191","mp192","mp193","mp194","mp195","mp196","mp197","mp198","mp199","mp200","mp201","mp202","mp203","mp204","mp205","mp206","mp207","mp208","mp209","mp210","mp211","mp212","mp213","mp214","mp215","mp216","mp217","mp218","mp219","mp220","mp221","mp222","mp223","mp224","mp225","mp226","mp227","mp228","mp229","mp230","mp231","mp232","mp233","mp234","mp235","mp236","mp237","mp238","mp239","mp240","mp241","mp242","mp243","mp244","mp245","mp246","mp247","mp248","mp249","mp250","mp251","mp252","mp253","mp254","mp255","unused0","unused1","unused2","unused3","unused4","unused5","unused6","unused7","unused8","unused9","unused10","unused11","unused12","unused13","unused14","unused15","unused16","unused17","unused18","unused19","unused20","unused21","unused22","unused23","unused24","unused25","unused26","unused27","unused28","unused29","unused30","unused31","unused32","unused33","unused34","unused35","unused36","unused37","unused38","unused39","unused40","unused41","unused42","unused43","unused44","unused45","unused46","unused47","unused48","unused49","unused50","unused51","unused52","unused53","unused54","unused55","unused56","unused57","unused58","unused59","unused60","unused61","unused62","unused63","unused64","unused65","unused66","unused67","unused68","unused69","unused70","unused71","unused72","unused73","unused74","unused75","unused76","unused77","unused78","unused79","unused80","unused81","unused82","unused83","unused84","unused85","unused86","unused87","unused88","unused89","unused90","unused91","unused92","unused93","unused94","unused95","unused96","unused97","unused98","unused99","unused100","unused101","unused102","unused103","unused104","unused105","unused106","unused107","unused108","unused109","unused110","unused111","unused112","unused113","unused114","unused115","unused116","unused117","unused118","unused119","unused120","unused121","unused122","unused123","unused124","unused125","unused126","unused127","unused128","unused129","unused130","unused131","unused132","unused133","unused134","unused135","unused136","unused137","unused138","unused139","unused140","unused141","unused142","unused143","unused144","unused145","unused146","unused147","unused148","unused149","unused150","unused151","unused152","unused153","unused154","unused155","unused156","unused157","unused158","unused159","unused160","unused161","unused162","unused163","unused164","unused165","unused166","unused167","unused168","unused169","unused170","unused171","unused172","unused173","unused174","unused175","unused176","unused177","unused178","unused179","unused180","unused181","unused182","unused183","unused184","unused185","unused186","unused187","unused188","unused189","unused190","unused191","unused192","unused193","unused194","unused195","unused196","unused197","unused198","unused199","unused200","unused201","unused202","unused203","unused204","unused205","unused206","unused207","unused208","unused209","unused210","unused211","unused212","unused213","unused214","unused215","unused216","unused217","unused218","unused219","unused220","unused221","unused222","unused223","unused224","unused225","unused226","unused227","unused228","unused229","unused230","unused231","unused232","unused233","unused234","unused235","unused236","unused237","unused238","unused239","unused240","unused241","unused242","unused243","unused244","unused245","unused246","unused247","unused248","unused249","unused250","unused251","unused252","unused253","unused254","unused255"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"target-volume"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Volume which will be moved.","enum":["rootfs","mp0","mp1","mp2","mp3","mp4","mp5","mp6","mp7","mp8","mp9","mp10","mp11","mp12","mp13","mp14","mp15","mp16","mp17","mp18","mp19","mp20","mp21","mp22","mp23","mp24","mp25","mp26","mp27","mp28","mp29","mp30","mp31","mp32","mp33","mp34","mp35","mp36","mp37","mp38","mp39","mp40","mp41","mp42","mp43","mp44","mp45","mp46","mp47","mp48","mp49","mp50","mp51","mp52","mp53","mp54","mp55","mp56","mp57","mp58","mp59","mp60","mp61","mp62","mp63","mp64","mp65","mp66","mp67","mp68","mp69","mp70","mp71","mp72","mp73","mp74","mp75","mp76","mp77","mp78","mp79","mp80","mp81","mp82","mp83","mp84","mp85","mp86","mp87","mp88","mp89","mp90","mp91","mp92","mp93","mp94","mp95","mp96","mp97","mp98","mp99","mp100","mp101","mp102","mp103","mp104","mp105","mp106","mp107","mp108","mp109","mp110","mp111","mp112","mp113","mp114","mp115","mp116","mp117","mp118","mp119","mp120","mp121","mp122","mp123","mp124","mp125","mp126","mp127","mp128","mp129","mp130","mp131","mp132","mp133","mp134","mp135","mp136","mp137","mp138","mp139","mp140","mp141","mp142","mp143","mp144","mp145","mp146","mp147","mp148","mp149","mp150","mp151","mp152","mp153","mp154","mp155","mp156","mp157","mp158","mp159","mp160","mp161","mp162","mp163","mp164","mp165","mp166","mp167","mp168","mp169","mp170","mp171","mp172","mp173","mp174","mp175","mp176","mp177","mp178","mp179","mp180","mp181","mp182","mp183","mp184","mp185","mp186","mp187","mp188","mp189","mp190","mp191","mp192","mp193","mp194","mp195","mp196","mp197","mp198","mp199","mp200","mp201","mp202","mp203","mp204","mp205","mp206","mp207","mp208","mp209","mp210","mp211","mp212","mp213","mp214","mp215","mp216","mp217","mp218","mp219","mp220","mp221","mp222","mp223","mp224","mp225","mp226","mp227","mp228","mp229","mp230","mp231","mp232","mp233","mp234","mp235","mp236","mp237","mp238","mp239","mp240","mp241","mp242","mp243","mp244","mp245","mp246","mp247","mp248","mp249","mp250","mp251","mp252","mp253","mp254","mp255","unused0","unused1","unused2","unused3","unused4","unused5","unused6","unused7","unused8","unused9","unused10","unused11","unused12","unused13","unused14","unused15","unused16","unused17","unused18","unused19","unused20","unused21","unused22","unused23","unused24","unused25","unused26","unused27","unused28","unused29","unused30","unused31","unused32","unused33","unused34","unused35","unused36","unused37","unused38","unused39","unused40","unused41","unused42","unused43","unused44","unused45","unused46","unused47","unused48","unused49","unused50","unused51","unused52","unused53","unused54","unused55","unused56","unused57","unused58","unused59","unused60","unused61","unused62","unused63","unused64","unused65","unused66","unused67","unused68","unused69","unused70","unused71","unused72","unused73","unused74","unused75","unused76","unused77","unused78","unused79","unused80","unused81","unused82","unused83","unused84","unused85","unused86","unused87","unused88","unused89","unused90","unused91","unused92","unused93","unused94","unused95","unused96","unused97","unused98","unused99","unused100","unused101","unused102","unused103","unused104","unused105","unused106","unused107","unused108","unused109","unused110","unused111","unused112","unused113","unused114","unused115","unused116","unused117","unused118","unused119","unused120","unused121","unused122","unused123","unused124","unused125","unused126","unused127","unused128","unused129","unused130","unused131","unused132","unused133","unused134","unused135","unused136","unused137","unused138","unused139","unused140","unused141","unused142","unused143","unused144","unused145","unused146","unused147","unused148","unused149","unused150","unused151","unused152","unused153","unused154","unused155","unused156","unused157","unused158","unused159","unused160","unused161","unused162","unused163","unused164","unused165","unused166","unused167","unused168","unused169","unused170","unused171","unused172","unused173","unused174","unused175","unused176","unused177","unused178","unused179","unused180","unused181","unused182","unused183","unused184","unused185","unused186","unused187","unused188","unused189","unused190","unused191","unused192","unused193","unused194","unused195","unused196","unused197","unused198","unused199","unused200","unused201","unused202","unused203","unused204","unused205","unused206","unused207","unused208","unused209","unused210","unused211","unused212","unused213","unused214","unused215","unused216","unused217","unused218","unused219","unused220","unused221","unused222","unused223","unused224","unused225","unused226","unused227","unused228","unused229","unused230","unused231","unused232","unused233","unused234","unused235","unused236","unused237","unused238","unused239","unused240","unused241","unused242","unused243","unused244","unused245","unused246","unused247","unused248","unused249","unused250","unused251","unused252","unused253","unused254","unused255"],"extra":{},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need 'VM.Config.Disk' permissions on /vms/{vmid}, and 'Datastore.AllocateSpace' permissions on the storage. To move a volume to another container, you need the permissions on the target container as well.","expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/move_volume"},{"extra":{},"methods":[{"allow_token":true,"checksum":"cbc77f1f6c5524d9dd0aefcc53a4574533b00d1500dd5efdeda1c0681e466b66","description":"Migration tunnel endpoint - only for internal use by CT migration.","extra":{},"name":"mtunnel","parameters":[{"definition":{"description":"List of network bridges to check availability. Will be checked again for actually used bridges during migration.","enum":[],"extra":{"typetext":""},"format":"pve-bridge-id-list","optional":true,"properties":{},"type":"string"},"name":"bridges"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"List of storages to check permission and availability. Will be checked again for all actually used storages during migration.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id-list","optional":true,"properties":{},"type":"string"},"name":"storages"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permissions on '/vms/{vmid}' and Sys.Incoming on '/'. Further permission checks happen during the actual migration.","expression":{"check":["and",["perm","/vms/{vmid}",["VM.Allocate"]],["perm","/",["Sys.Incoming"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"socket":{"enum":[],"extra":{},"properties":{},"type":"string"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/mtunnel"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5074d114941c7d6bcff687122305de9ba6fe8456c7b40ccc88b503ae5f07dd59","description":"Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration.","extra":{},"name":"mtunnelwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"unix socket to forward to","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"socket"},{"definition":{"description":"ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"ticket"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need to pass a ticket valid for the selected socket. Tickets can be created via the mtunnel API call, which will check permissions accordingly.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"socket":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/mtunnelwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"eca2f9833cddd3132e0f155a1e906060d21aeb47b0a5e90c16f88d6c6bbc7c33","description":"Get container configuration, including pending changes.","extra":{"proxyto":"node"},"name":"vm_pending","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"delete":{"description":"Indicates a pending delete request if present and not 0.","enum":[],"extra":{},"maximum":2,"minimum":0,"optional":true,"properties":{},"type":"integer"},"key":{"description":"Configuration option name.","enum":[],"extra":{},"properties":{},"type":"string"},"pending":{"description":"Pending value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"value":{"description":"Current value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/pending"},{"extra":{},"methods":[{"allow_token":true,"checksum":"92d79d188f48c5ec8412882f2b26b10068c51108355bd54185019dee990cd19d","description":"Migrate the container to another cluster. Creates a new migration task. EXPERIMENTAL feature!","extra":{"proxyto":"node"},"name":"remote_migrate_vm","parameters":[{"definition":{"default":"migrate limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"default":0,"description":"Delete the original CT and related data after successful migration. By default the original CT is kept on the source cluster in a stopped state.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use online/live migration.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"online"},{"definition":{"description":"Use restart migration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restart"},{"definition":{"description":"Mapping from source to target bridges. Providing only a single bridge ID maps all source bridges to that bridge. Providing the special value '1' will map each source bridge to itself.","enum":[],"extra":{"typetext":""},"format":"bridge-pair-list","properties":{},"type":"string"},"name":"target-bridge"},{"definition":{"description":"Remote target endpoint","enum":[],"extra":{"typetext":"apitoken= ,host=
[,fingerprint=] [,port=]"},"format":"proxmox-remote","properties":{},"type":"string"},"name":"target-endpoint"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storage-pair-list","optional":false,"properties":{},"type":"string"},"name":"target-storage"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"target-vmid"},{"definition":{"default":180,"description":"Timeout in seconds for shutdown for restart migration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/remote_migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c9cbc740cc85254dd58f570dfe12a2adab7e0bfd14cae547490946e1fe519126","description":"Resize a container mount point.","extra":{"proxyto":"node"},"name":"resize_vm","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The disk you want to resize.","enum":["rootfs","mp0","mp1","mp2","mp3","mp4","mp5","mp6","mp7","mp8","mp9","mp10","mp11","mp12","mp13","mp14","mp15","mp16","mp17","mp18","mp19","mp20","mp21","mp22","mp23","mp24","mp25","mp26","mp27","mp28","mp29","mp30","mp31","mp32","mp33","mp34","mp35","mp36","mp37","mp38","mp39","mp40","mp41","mp42","mp43","mp44","mp45","mp46","mp47","mp48","mp49","mp50","mp51","mp52","mp53","mp54","mp55","mp56","mp57","mp58","mp59","mp60","mp61","mp62","mp63","mp64","mp65","mp66","mp67","mp68","mp69","mp70","mp71","mp72","mp73","mp74","mp75","mp76","mp77","mp78","mp79","mp80","mp81","mp82","mp83","mp84","mp85","mp86","mp87","mp88","mp89","mp90","mp91","mp92","mp93","mp94","mp95","mp96","mp97","mp98","mp99","mp100","mp101","mp102","mp103","mp104","mp105","mp106","mp107","mp108","mp109","mp110","mp111","mp112","mp113","mp114","mp115","mp116","mp117","mp118","mp119","mp120","mp121","mp122","mp123","mp124","mp125","mp126","mp127","mp128","mp129","mp130","mp131","mp132","mp133","mp134","mp135","mp136","mp137","mp138","mp139","mp140","mp141","mp142","mp143","mp144","mp145","mp146","mp147","mp148","mp149","mp150","mp151","mp152","mp153","mp154","mp155","mp156","mp157","mp158","mp159","mp160","mp161","mp162","mp163","mp164","mp165","mp166","mp167","mp168","mp169","mp170","mp171","mp172","mp173","mp174","mp175","mp176","mp177","mp178","mp179","mp180","mp181","mp182","mp183","mp184","mp185","mp186","mp187","mp188","mp189","mp190","mp191","mp192","mp193","mp194","mp195","mp196","mp197","mp198","mp199","mp200","mp201","mp202","mp203","mp204","mp205","mp206","mp207","mp208","mp209","mp210","mp211","mp212","mp213","mp214","mp215","mp216","mp217","mp218","mp219","mp220","mp221","mp222","mp223","mp224","mp225","mp226","mp227","mp228","mp229","mp230","mp231","mp232","mp233","mp234","mp235","mp236","mp237","mp238","mp239","mp240","mp241","mp242","mp243","mp244","mp245","mp246","mp247","mp248","mp249","mp250","mp251","mp252","mp253","mp254","mp255"],"extra":{},"properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The new size. With the '+' sign the value is added to the actual size of the volume and without it, the value is taken as an absolute one. Shrinking disk size is not supported.","enum":[],"extra":{},"pattern":"\\+?\\d+(\\.\\d+)?[KMGT]?","properties":{},"type":"string"},"name":"size"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/resize"},{"extra":{},"methods":[{"allow_token":true,"checksum":"76edba13c3870fdb403a8a46fd95c3033cf4aeecac012f3d822f9075a80aa729","description":"Read VM RRD statistics (returns PNG)","extra":{},"name":"rrd","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The list of datasources you want to display.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"ds"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/rrd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"708d135d9bf06d5aed00329691506df18a1ed11938257a15c87431dfc5b617f3","description":"Read VM RRD statistics","extra":{},"name":"rrddata","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/rrddata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2cc7acefd4e8a1d9cda78d17b71e9f5c952c548a739884a6da023cc7abf31ba4","description":"List all snapshots.","extra":{"proxyto":"node"},"name":"list","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"description":{"description":"Snapshot description.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Snapshot identifier. Value 'current' identifies the current VM.","enum":[],"extra":{},"properties":{},"type":"string"},"parent":{"description":"Parent snapshot identifier.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"snaptime":{"description":"Snapshot creation time","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"65b066ef336fa2e77e966ba74190bbf917f85c6286188204e9b813d78b916965","description":"Snapshot a container.","extra":{"proxyto":"node"},"name":"snapshot","parameters":[{"definition":{"description":"A textual description or comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/snapshot"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4eca683e9eded5aacd69fffdde27a647f386c5d8035a8a006ddf57c85f71ea94","description":"Delete a LXC snapshot.","extra":{"proxyto":"node"},"name":"delsnapshot","parameters":[{"definition":{"description":"For removal from config file, even if removing disk snapshots fails.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"832c5b9a025e005606202e4c83d793ce08937ecc33dfcd397a7fef121e0b5411","description":"","extra":{},"name":"snapshot_cmd_idx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cmd}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"65e5a768abb44d154e1140615379246ed5399a3dc43425f8e51baa6c7fbd75af","description":"Get snapshot configuration","extra":{"proxyto":"node"},"name":"get_snapshot_config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback","VM.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"281a4f10e550455fd4dd289251fc1fe0ecb359e2777227df294a67d67a5fa13b","description":"Update snapshot metadata.","extra":{"proxyto":"node"},"name":"update_snapshot_config","parameters":[{"definition":{"description":"A textual description or comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f3303e04d815dc43d11d0667bcb86834208728ef9405020f8603e0abf43fc883","description":"Rollback LXC state to specified snapshot.","extra":{"proxyto":"node"},"name":"rollback","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"default":0,"description":"Whether the container should get started after rolling back successfully","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"start"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a387cac0a81099ae0cfeba0168f3a8ecf4469ed365c0acfeac84de39ceb0ad90","description":"Returns a SPICE configuration to connect to the CT.","extra":{"proxyto":"node"},"name":"spiceproxy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).","enum":[],"extra":{"typetext":""},"format":"address","optional":true,"properties":{},"type":"string"},"name":"proxy"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"description":"Returned values can be directly passed to the 'remote-viewer' application.","enum":[],"extra":{"additionalProperties":1},"properties":{"host":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"enum":[],"extra":{},"properties":{},"type":"string"},"proxy":{"enum":[],"extra":{},"properties":{},"type":"string"},"tls-port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/spiceproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e0aec5f2ad5f243e5f05705856f0b3c74f1e863e35ceb571106f118e8b4027e3","description":"Directory index","extra":{"proxyto":"node"},"name":"vmcmdidx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c0261c27e4b490c08534e1df410b7757c61fd9a86753257a3472f95a98702f87","description":"Get virtual machine status.","extra":{"proxyto":"node"},"name":"vm_status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"cpu":{"description":"Current CPU usage.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"cpus":{"description":"Maximum usable CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"disk":{"description":"Root disk image space-usage in bytes.","enum":[],"extra":{"renderer":"bytes"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"diskread":{"description":"The amount of bytes the guest read from it's block devices since the guest was started. (Note: This info is not available for all storage types.)","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"diskwrite":{"description":"The amount of bytes the guest wrote from it's block devices since the guest was started. (Note: This info is not available for all storage types.)","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"ha":{"description":"HA manager service status.","enum":[],"extra":{},"properties":{},"type":"object"},"lock":{"description":"The current config lock, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxdisk":{"description":"Root disk image size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Maximum memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxswap":{"description":"Maximum SWAP memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"mem":{"description":"Currently used memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"name":{"description":"Container name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"netin":{"description":"The amount of traffic in bytes that was sent to the guest over the network since it was started.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"netout":{"description":"The amount of traffic in bytes that was sent from the guest over the network since it was started.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"pressurecpusome":{"description":"CPU Some pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressureiofull":{"description":"IO Full pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressureiosome":{"description":"IO Some pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressurememoryfull":{"description":"Memory Full pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressurememorysome":{"description":"Memory Some pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"status":{"description":"LXC Container status.","enum":["stopped","running"],"extra":{},"properties":{},"type":"string"},"tags":{"description":"The current configured tags, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"template":{"default":0,"description":"Determines if the guest is a template.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"uptime":{"description":"Uptime in seconds.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/status/current"},{"extra":{},"methods":[{"allow_token":true,"checksum":"eba2ee91fe49acdfef5a00f589c3f8d4028b9ccaceebad3cda480818a7dc8234","description":"Reboot the container by shutting it down, and starting it again. Applies pending changes.","extra":{"proxyto":"node"},"name":"vm_reboot","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Wait maximal timeout seconds for the shutdown.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/reboot"},{"extra":{},"methods":[{"allow_token":true,"checksum":"73dcd3e2f3a70ea0d5ee48b979264e5b35f89dad81101a6e7e2fb529f4121502","description":"Resume the container.","extra":{"proxyto":"node"},"name":"vm_resume","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/resume"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1215c26a5cc93e92334e4831665c2a0bd3a37c003d8e81ee3dd292ffca4d1c30","description":"Shutdown the container. This will trigger a clean shutdown of the container, see lxc-stop(1) for details.","extra":{"proxyto":"node"},"name":"vm_shutdown","parameters":[{"definition":{"default":0,"description":"Make sure the Container stops.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"forceStop"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":60,"description":"Wait maximal timeout seconds.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/shutdown"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5c0c283d714281e0b593ed3392fd653724b50b9ede5a31f1e566121fb5919d19","description":"Start the container.","extra":{"proxyto":"node"},"name":"vm_start","parameters":[{"definition":{"default":0,"description":"If set, enables very verbose debug log-level on start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"debug"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f93fd82ece83db0f42309e14023ac63a1b4e5d301e4ab8eec9c8edaed8edc97b","description":"Stop the container. This will abruptly stop all processes running in the container.","extra":{"proxyto":"node"},"name":"vm_stop","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Try to abort active 'vzshutdown' tasks before stopping.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"overrule-shutdown"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/stop"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d8606dc5363a4702091ed917fd8a9b46f24380b6c6280a5fa213df2d6655dd57","description":"Suspend the container. This is experimental.","extra":{"proxyto":"node"},"name":"vm_suspend","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/suspend"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f621cca791d32aba1c7cfe0dea4167c53ffe559863efeace03ffdec6fce06339","description":"Create a Template.","extra":{"proxyto":"node"},"name":"template","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permissions on /vms/{vmid}","expression":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/template"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6e61212a198fccaf0e72dcaab2feaa049b1fc92c26133bb1e23307444f4c4faa","description":"Creates a TCP proxy connection.","extra":{},"name":"termproxy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/termproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"865f57c4e53a89345448cebad0de2d2e414fce4f2ce129c166a51cd7c755ec32","description":"Creates a TCP VNC proxy connections.","extra":{},"name":"vncproxy","parameters":[{"definition":{"description":"sets the height of the console in pixels.","enum":[],"extra":{"typetext":" (16 - 2160)"},"maximum":2160,"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"height"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"use websocket instead of standard VNC.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"websocket"},{"definition":{"description":"sets the width of the console in pixels.","enum":[],"extra":{"typetext":" (16 - 4096)"},"maximum":4096,"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"width"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"cert":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"description":"Password used for authentication within the VNC protocol. Consists of printable ASCII characters ('!' .. '~').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/vncproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e35fae5176b1f7cdf7edfac342ebeb906e94cbc3aa934ddf26ebe4f1b595cb33","description":"Opens a websocket for VNC traffic.","extra":{},"name":"vncwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Port number returned by previous vncproxy call.","enum":[],"extra":{"typetext":" (5900 - 5999)"},"maximum":5999,"minimum":5900,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Ticket from previous call to vncproxy.","enum":[],"extra":{"typetext":""},"max_length":512,"properties":{},"type":"string"},"name":"vncticket"}],"permissions":{"description":"You also need to pass a valid ticket (vncticket).","expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/vncwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b88e5f2ab6fd9f4300a0af56b1b73cfa0b4b7631f9426013577867e90cef3430","description":"Migrate all VMs and Containers.","extra":{"proxyto":"node"},"name":"migrateall","parameters":[{"definition":{"description":"Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg. One of both must be set!","enum":[],"extra":{"typetext":" (1 - 64)"},"maximum":64,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max-workers"},{"definition":{"description":"Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg. One of both must be set!Deprecated, use 'max-workers' instead.","enum":[],"extra":{"typetext":" (1 - 64)"},"maximum":64,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxworkers"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Only consider Guests with these IDs.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"},{"definition":{"description":"Enable live storage migration for local disk","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"with-local-disks"}],"permissions":{"description":"The 'VM.Migrate' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/migrateall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c2c207a7e8a4df2370ac547d2a570d636677faa99ba285adbe6298dde17efefc","description":"Read tap/vm network device interface counters","extra":{"proxyto":"node"},"name":"netstat","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/netstat"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3de07e746f474e02ab38c834d3571d70c15aa5d66e4a80d73f9f67876bcd5bfc","description":"Revert network configuration changes.","extra":{"proxyto":"node"},"name":"revert_network_changes","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"a1a3937512f2841ea1a9815c218353f73c826880461244fb1038f32c7d87a2e9","description":"List available networks","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list specific interface types.","enum":["bridge","bond","eth","alias","vlan","fabric","OVSBridge","OVSBond","OVSPort","OVSIntPort","vnet","any_bridge","any_local_bridge","include_sdn"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{iface}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"active":{"description":"Set to true if the interface is active.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"address":{"description":"IP address.","enum":[],"extra":{"requires":"netmask"},"format":"ipv4","optional":true,"properties":{},"type":"string"},"address6":{"description":"IP address.","enum":[],"extra":{"requires":"netmask6"},"format":"ipv6","optional":true,"properties":{},"type":"string"},"autostart":{"description":"Automatically start interface on boot.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bond-primary":{"description":"Specify the primary interface for active-backup bond.","enum":[],"extra":{},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"bond_mode":{"description":"Bonding mode.","enum":["balance-rr","active-backup","balance-xor","broadcast","802.3ad","balance-tlb","balance-alb","balance-slb","lacp-balance-slb","lacp-balance-tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"bond_xmit_hash_policy":{"description":"Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.","enum":["layer2","layer2+3","layer3+4"],"extra":{},"optional":true,"properties":{},"type":"string"},"bridge-access":{"description":"The bridge port access VLAN.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"bridge-arp-nd-suppress":{"description":"Bridge port ARP/ND suppress flag.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bridge-learning":{"description":"Bridge port learning flag.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bridge-multicast-flood":{"description":"Bridge port multicast flood flag.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bridge-unicast-flood":{"description":"Bridge port unicast flood flag.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bridge_ports":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"bridge_vids":{"description":"Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.","enum":[],"extra":{},"format":"pve-vlan-id-or-range-list","optional":true,"properties":{},"type":"string"},"bridge_vlan_aware":{"description":"Enable bridge vlan support.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"cidr":{"description":"IPv4 CIDR.","enum":[],"extra":{},"format":"CIDRv4","optional":true,"properties":{},"type":"string"},"cidr6":{"description":"IPv6 CIDR.","enum":[],"extra":{},"format":"CIDRv6","optional":true,"properties":{},"type":"string"},"comments":{"description":"Comments","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"comments6":{"description":"Comments","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"exists":{"description":"Set to true if the interface physically exists.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"families":{"description":"The network families.","enum":[],"extra":{},"items":{"description":"A network family.","enum":["inet","inet6"],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"gateway":{"description":"Default gateway address.","enum":[],"extra":{},"format":"ipv4","optional":true,"properties":{},"type":"string"},"gateway6":{"description":"Default ipv6 gateway address.","enum":[],"extra":{},"format":"ipv6","optional":true,"properties":{},"type":"string"},"iface":{"description":"Network interface name.","enum":[],"extra":{},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"link-type":{"description":"The link type.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"method":{"description":"The network configuration method for IPv4.","enum":["loopback","dhcp","manual","static","auto"],"extra":{},"optional":true,"properties":{},"type":"string"},"method6":{"description":"The network configuration method for IPv6.","enum":["loopback","dhcp","manual","static","auto"],"extra":{},"optional":true,"properties":{},"type":"string"},"mtu":{"description":"MTU.","enum":[],"extra":{},"maximum":65520,"minimum":1280,"optional":true,"properties":{},"type":"integer"},"netmask":{"description":"Network mask.","enum":[],"extra":{"requires":"address"},"format":"ipv4mask","optional":true,"properties":{},"type":"string"},"netmask6":{"description":"Network mask.","enum":[],"extra":{"requires":"address6"},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"integer"},"options":{"description":"A list of additional interface options for IPv4.","enum":[],"extra":{},"items":{"description":"An interface property.","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"options6":{"description":"A list of additional interface options for IPv6.","enum":[],"extra":{},"items":{"description":"An interface property.","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"ovs_bonds":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"ovs_bridge":{"description":"The OVS bridge associated with a OVS port. This is required when you create an OVS port.","enum":[],"extra":{},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"ovs_options":{"description":"OVS interface options.","enum":[],"extra":{},"max_length":1024,"optional":true,"properties":{},"type":"string"},"ovs_ports":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"ovs_tag":{"description":"Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)","enum":[],"extra":{},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"priority":{"description":"The order of the interface.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"slaves":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"type":{"description":"Network interface type","enum":["bridge","bond","eth","alias","vlan","fabric","OVSBridge","OVSBond","OVSPort","OVSIntPort","vnet","unknown"],"extra":{},"properties":{},"type":"string"},"uplink-id":{"description":"The uplink ID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vlan-id":{"description":"vlan-id for a custom named vlan interface (ifupdown2 only).","enum":[],"extra":{},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"vlan-protocol":{"description":"The VLAN protocol.","enum":["802.1ad","802.1q"],"extra":{},"optional":true,"properties":{},"type":"string"},"vlan-raw-device":{"description":"Specify the raw interface for the vlan interface.","enum":[],"extra":{},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"vxlan-id":{"description":"The VXLAN ID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"vxlan-local-tunnelip":{"description":"The VXLAN local tunnel IP.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vxlan-physdev":{"description":"The physical device for the VXLAN tunnel.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vxlan-svcnodeip":{"description":"The VXLAN SVC node IP.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"6f473ac59664ba01af4906cccf1d1c406c04865198f6d34c087c2b7cb1b7e498","description":"Create network device configuration","extra":{"proxyto":"node"},"name":"create_network","parameters":[{"definition":{"description":"IP address.","enum":[],"extra":{"requires":"netmask","typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"address"},{"definition":{"description":"IP address.","enum":[],"extra":{"requires":"netmask6","typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"address6"},{"definition":{"description":"Automatically start interface on boot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Specify the primary interface for active-backup bond.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"bond-primary"},{"definition":{"description":"Bonding mode.","enum":["balance-rr","active-backup","balance-xor","broadcast","802.3ad","balance-tlb","balance-alb","balance-slb","lacp-balance-slb","lacp-balance-tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bond_mode"},{"definition":{"description":"Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.","enum":["layer2","layer2+3","layer3+4"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bond_xmit_hash_policy"},{"definition":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"bridge_ports"},{"definition":{"description":"Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.","enum":[],"extra":{"typetext":""},"format":"pve-vlan-id-or-range-list","optional":true,"properties":{},"type":"string"},"name":"bridge_vids"},{"definition":{"description":"Enable bridge vlan support.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bridge_vlan_aware"},{"definition":{"description":"IPv4 CIDR.","enum":[],"extra":{"typetext":""},"format":"CIDRv4","optional":true,"properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IPv6 CIDR.","enum":[],"extra":{"typetext":""},"format":"CIDRv6","optional":true,"properties":{},"type":"string"},"name":"cidr6"},{"definition":{"description":"Comments","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comments"},{"definition":{"description":"Comments","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comments6"},{"definition":{"description":"Default gateway address.","enum":[],"extra":{"typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"gateway"},{"definition":{"description":"Default ipv6 gateway address.","enum":[],"extra":{"typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"gateway6"},{"definition":{"description":"Network interface name.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"MTU.","enum":[],"extra":{"typetext":" (1280 - 65520)"},"maximum":65520,"minimum":1280,"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"Network mask.","enum":[],"extra":{"requires":"address","typetext":""},"format":"ipv4mask","optional":true,"properties":{},"type":"string"},"name":"netmask"},{"definition":{"description":"Network mask.","enum":[],"extra":{"requires":"address6","typetext":" (0 - 128)"},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"netmask6"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"ovs_bonds"},{"definition":{"description":"The OVS bridge associated with a OVS port. This is required when you create an OVS port.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"ovs_bridge"},{"definition":{"description":"OVS interface options.","enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"ovs_options"},{"definition":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"ovs_ports"},{"definition":{"description":"Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)","enum":[],"extra":{"typetext":" (1 - 4094)"},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"ovs_tag"},{"definition":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"slaves"},{"definition":{"description":"Network interface type","enum":["bridge","bond","eth","alias","vlan","fabric","OVSBridge","OVSBond","OVSPort","OVSIntPort","vnet","unknown"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"vlan-id for a custom named vlan interface (ifupdown2 only).","enum":[],"extra":{"typetext":" (1 - 4094)"},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vlan-id"},{"definition":{"description":"Specify the raw interface for the vlan interface.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"vlan-raw-device"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"85b52ee8b7923fb4c923011ac1d6278391d589c4bed76e1809351b387bed7e4b","description":"Reload network configuration","extra":{"proxyto":"node"},"name":"reload_network_config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Whether FRR config generation should get skipped or not.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"regenerate-frr"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/network"},{"extra":{},"methods":[{"allow_token":true,"checksum":"32c344b0dfe6220c53d77420aa2694e1bc65998071ee6a33024bccd2265550f3","description":"Delete network device configuration","extra":{"proxyto":"node"},"name":"delete_network","parameters":[{"definition":{"description":"Network interface name.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"91ab56660b1db09d5d12a3a1739ea872acc81e6d3a0f84993fa51ea56b78dea3","description":"Read network device configuration","extra":{"proxyto":"node"},"name":"network_config","parameters":[{"definition":{"description":"Network interface name.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"method":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"f5e55a3555da959c107cde743eaa8dbc81308a754c8eb6fe762bd00c98f5244f","description":"Update network device configuration","extra":{"proxyto":"node"},"name":"update_network","parameters":[{"definition":{"description":"IP address.","enum":[],"extra":{"requires":"netmask","typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"address"},{"definition":{"description":"IP address.","enum":[],"extra":{"requires":"netmask6","typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"address6"},{"definition":{"description":"Automatically start interface on boot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Specify the primary interface for active-backup bond.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"bond-primary"},{"definition":{"description":"Bonding mode.","enum":["balance-rr","active-backup","balance-xor","broadcast","802.3ad","balance-tlb","balance-alb","balance-slb","lacp-balance-slb","lacp-balance-tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bond_mode"},{"definition":{"description":"Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.","enum":["layer2","layer2+3","layer3+4"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bond_xmit_hash_policy"},{"definition":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"bridge_ports"},{"definition":{"description":"Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.","enum":[],"extra":{"typetext":""},"format":"pve-vlan-id-or-range-list","optional":true,"properties":{},"type":"string"},"name":"bridge_vids"},{"definition":{"description":"Enable bridge vlan support.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bridge_vlan_aware"},{"definition":{"description":"IPv4 CIDR.","enum":[],"extra":{"typetext":""},"format":"CIDRv4","optional":true,"properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IPv6 CIDR.","enum":[],"extra":{"typetext":""},"format":"CIDRv6","optional":true,"properties":{},"type":"string"},"name":"cidr6"},{"definition":{"description":"Comments","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comments"},{"definition":{"description":"Comments","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comments6"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Default gateway address.","enum":[],"extra":{"typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"gateway"},{"definition":{"description":"Default ipv6 gateway address.","enum":[],"extra":{"typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"gateway6"},{"definition":{"description":"Network interface name.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"MTU.","enum":[],"extra":{"typetext":" (1280 - 65520)"},"maximum":65520,"minimum":1280,"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"Network mask.","enum":[],"extra":{"requires":"address","typetext":""},"format":"ipv4mask","optional":true,"properties":{},"type":"string"},"name":"netmask"},{"definition":{"description":"Network mask.","enum":[],"extra":{"requires":"address6","typetext":" (0 - 128)"},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"netmask6"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"ovs_bonds"},{"definition":{"description":"The OVS bridge associated with a OVS port. This is required when you create an OVS port.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"ovs_bridge"},{"definition":{"description":"OVS interface options.","enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"ovs_options"},{"definition":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"ovs_ports"},{"definition":{"description":"Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)","enum":[],"extra":{"typetext":" (1 - 4094)"},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"ovs_tag"},{"definition":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"slaves"},{"definition":{"description":"Network interface type","enum":["bridge","bond","eth","alias","vlan","fabric","OVSBridge","OVSBond","OVSPort","OVSIntPort","vnet","unknown"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"vlan-id for a custom named vlan interface (ifupdown2 only).","enum":[],"extra":{"typetext":" (1 - 4094)"},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vlan-id"},{"definition":{"description":"Specify the raw interface for the vlan interface.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"vlan-raw-device"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/network/{iface}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0a47bf3e9c08c1f9a191af7ed8ea8f0b7d683f6c47903a09b08383d1914ef4cb","description":"Virtual machine index (per node).","extra":{"proxyto":"node"},"name":"vmlist","parameters":[{"definition":{"description":"Determine the full status of active VMs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Only list VMs where you have VM.Audit permissions on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{vmid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cpu":{"description":"Current CPU usage.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"cpus":{"description":"Maximum usable CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"diskread":{"description":"The amount of bytes the guest read from it's block devices since the guest was started. (Note: This info is not available for all storage types.)","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"diskwrite":{"description":"The amount of bytes the guest wrote from it's block devices since the guest was started. (Note: This info is not available for all storage types.)","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"lock":{"description":"The current config lock, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxdisk":{"description":"Root disk size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Maximum memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"mem":{"description":"Currently used memory in bytes. Does not take into account kernel same-page merging (KSM). Uses information from ballooning when available.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"memhost":{"description":"Current memory usage on the host. Does not take into account kernel same-page merging (KSM).","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"name":{"description":"VM (host)name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"netin":{"description":"The amount of traffic in bytes that was sent to the guest over the network since it was started.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"netout":{"description":"The amount of traffic in bytes that was sent from the guest over the network since it was started.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"pid":{"description":"PID of the QEMU process, if the VM is running.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"pressurecpufull":{"description":"CPU Full pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressurecpusome":{"description":"CPU Some pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressureiofull":{"description":"IO Full pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressureiosome":{"description":"IO Some pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressurememoryfull":{"description":"Memory Full pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressurememorysome":{"description":"Memory Some pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"qmpstatus":{"description":"VM run state from the 'query-status' QMP monitor command.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"running-machine":{"description":"The currently running machine type (if running).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"running-qemu":{"description":"The QEMU version the VM is currently using (if running).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial":{"description":"Guest has serial device configured.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"status":{"description":"QEMU process status.","enum":["stopped","running"],"extra":{},"properties":{},"type":"string"},"tags":{"description":"The current configured tags, if any","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"template":{"default":0,"description":"Determines if the guest is a template.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"uptime":{"description":"Uptime in seconds.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"5fce9577e635af3dde4815235b5c635c9f9bd8455a3a2b9a357f81ffd9c9a00b","description":"Create or restore a virtual machine.","extra":{"proxyto":"node"},"name":"create_vm","parameters":[{"definition":{"default":1,"description":"Enable/disable ACPI.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"acpi"},{"definition":{"description":"List of host cores used to execute guest processes, for example: 0,5,8-11","enum":[],"extra":{"typetext":""},"format":"pve-cpuset","optional":true,"properties":{},"type":"string"},"name":"affinity"},{"definition":{"description":"Enable/disable communication with the QEMU Guest Agent and its properties.","enum":[],"extra":{"typetext":"[enabled=]<1|0> [,freeze-fs=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]"},"format":{"enabled":{"default":0,"default_key":1,"description":"Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.","type":"boolean"},"freeze-fs":{"default":1,"description":"Freeze guest filesystems through QGA for consistent disk state on operations such as snapshots, backups, replications and clones.","optional":1,"type":"boolean","verbose_description":"Whether to issue the guest-fsfreeze-freeze and guest-fsfreeze-thaw QEMU guest agent commands. Backups in snapshot mode, clones, snapshots without RAM, importing disks from a running guest, and replications normally issue a guest-fsfreeze-freeze and a respective thaw command when the QEMU Guest agent option is enabled in the guest's configuration and the agent is running inside of the guest.\n\nThe deprecated 'freeze-fs-on-backup' setting is treated as an alias for this setting."},"freeze-fs-on-backup":{"alias":"freeze-fs"},"fstrim_cloned_disks":{"default":0,"description":"Run fstrim after moving a disk or migrating the VM.","optional":1,"type":"boolean"},"guest-fsfreeze":{"alias":"freeze-fs"},"type":{"default":"virtio","description":"Select the agent type","enum":["virtio","isa"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"agent"},{"definition":{"default":1,"description":"Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"allow-ksm"},{"definition":{"description":"Secure Encrypted Virtualization (SEV) features by AMD CPUs","enum":[],"extra":{"typetext":"[type=] [,allow-smt=<1|0>] [,kernel-hashes=<1|0>] [,no-debug=<1|0>] [,no-key-sharing=<1|0>]"},"format":"pve-qemu-sev-fmt","optional":true,"properties":{},"type":"string"},"name":"amd-sev"},{"definition":{"description":"Virtual processor architecture. Defaults to the host architecture.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"description":"The backup archive. Either the file system path to a .tar or .vma file (use '-' to pipe data from stdin) or a proxmox storage backup volume identifier.","enum":[],"extra":{"typetext":""},"max_length":255,"optional":true,"properties":{},"type":"string"},"name":"archive"},{"definition":{"description":"Arbitrary arguments passed to kvm.","enum":[],"extra":{"typetext":"","verbose_description":"Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -smbios 'type=0,vendor=FOO'\n\nNOTE: this option is for experts only.\n"},"optional":true,"properties":{},"type":"string"},"name":"args"},{"definition":{"description":"Configure a audio device, useful in combination with QXL/Spice.","enum":[],"extra":{"typetext":"device= [,driver=]"},"format":{"device":{"description":"Configure an audio device.","enum":["ich9-intel-hda","intel-hda","AC97"],"type":"string"},"driver":{"default":"spice","description":"Driver backend for the audio device.","enum":["spice","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"audio0"},{"definition":{"default":0,"description":"Automatic restart after crash (currently ignored).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Amount of target RAM for the VM in MiB. The balloon driver is enabled by default, unless it is explicitly disabled by setting the value to zero.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"balloon"},{"definition":{"default":"seabios","description":"Select BIOS implementation.","enum":["seabios","ovmf"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bios"},{"definition":{"description":"Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.","enum":[],"extra":{"typetext":"[[legacy=]<[acdn]{1,4}>] [,order=]"},"format":"pve-qm-boot","optional":true,"properties":{},"type":"string"},"name":"boot"},{"definition":{"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","enum":[],"extra":{},"format":"pve-qm-bootdisk","optional":true,"pattern":"(ide|sata|scsi|virtio)\\d+","properties":{},"type":"string"},"name":"bootdisk"},{"definition":{"default":"restore limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"This is an alias for option -ide2","enum":[],"extra":{"typetext":""},"format":"pve-qm-ide","optional":true,"properties":{},"type":"string"},"name":"cdrom"},{"definition":{"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","enum":[],"extra":{"typetext":"[meta=] [,network=] [,user=] [,vendor=]"},"format":"pve-qm-cicustom","optional":true,"properties":{},"type":"string"},"name":"cicustom"},{"definition":{"description":"cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cipassword"},{"definition":{"description":"Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.","enum":["configdrive2","nocloud","opennebula"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"citype"},{"definition":{"default":1,"description":"cloud-init: do an automatic package upgrade after the first boot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ciupgrade"},{"definition":{"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ciuser"},{"definition":{"default":1,"description":"The number of cores per socket.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"description":"Emulated CPU type.","enum":[],"extra":{"typetext":"[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,guest-phys-bits=] [,hidden=<1|0>] [,hv-vendor-id=] [,level=] [,phys-bits=<8-64|host>] [,reported-model=]"},"format":"pve-vm-cpu-conf","optional":true,"properties":{},"type":"string"},"name":"cpu"},{"definition":{"default":0,"description":"Limit of CPU usage.","enum":[],"extra":{"typetext":" (0 - 128)","verbose_description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit."},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"typetext":" (1 - 262144)","verbose_description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs."},"maximum":262144,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"description":"Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":8192,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,ms-cert=] [,pre-enrolled-keys=<1|0>] [,size=]"},"format":{"efitype":{"default":"2m","description":"Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarch64 (ARM).","enum":["2m","4m"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"ms-cert":{"default":"2011","description":"Informational marker indicating the version of the latest Microsoft UEFI certificates that have been enrolled by Proxmox VE. The value '2023k' means that the 'Microsoft UEFI CA 2023', the 'Windows UEFI CA 2023' and the 'Microsoft Corporation KEK 2K CA 2023' certificates are included. The values '2023' and '2023w' are deprecated and for compatibility only.","enum":["2011","2023","2023w","2023k"],"optional":1,"type":"string"},"pre-enrolled-keys":{"default":0,"description":"Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.","optional":1,"type":"boolean"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"efidisk0"},{"definition":{"description":"Allow to overwrite existing VM.","enum":[],"extra":{"requires":"archive","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Freeze CPU at startup (use 'c' monitor command to start execution).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"freeze"},{"definition":{"default":0,"description":"Add the VM as a HA resource after it was created.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ha-managed"},{"definition":{"description":"Script that will be executed during various steps in the vms lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Map host PCI devices into guest.","enum":[],"extra":{"typetext":"[[host=]] [,device-id=] [,driver=] [,legacy-igd=<1|0>] [,mapping=] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]","verbose_description":"Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"format":"pve-qm-hostpci","optional":true,"properties":{},"type":"string"},"name":"hostpci[n]"},{"definition":{"default":"network,disk,usb","description":"Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.","enum":[],"extra":{"typetext":""},"format":"pve-hotplug-features","optional":true,"properties":{},"type":"string"},"name":"hotplug"},{"definition":{"description":"Enables hugepages memory.\n\nSets the size of hugepages in MiB. If the value is set to 'any' then 1 GiB hugepages will be used if possible, otherwise the size will fall back to 2 MiB.","enum":["any","2","1024"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"hugepages"},{"definition":{"description":"Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"model":{"description":"The drive's reported model name, url-encoded, up to 40 bytes long.","format":"urlencoded","format_description":"model","maxLength":120,"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"ide[n]"},{"definition":{"description":"A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"import-working-storage"},{"definition":{"description":"Trusted Domain Extension (TDX) features by Intel CPUs","enum":[],"extra":{"typetext":"[type=] ,attestation=<1|0> [,vsock-cid=] [,vsock-port=]"},"format":"pve-qemu-tdx-fmt","optional":true,"properties":{},"type":"string"},"name":"intel-tdx"},{"definition":{"description":"cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n","enum":[],"extra":{"typetext":"[gw=] [,gw6=] [,ip=] [,ip6=]"},"format":"pve-qm-ipconfig","optional":true,"properties":{},"type":"string"},"name":"ipconfig[n]"},{"definition":{"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host.","enum":[],"extra":{"typetext":"size= [,name=]"},"format":{"name":{"description":"The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.","format_description":"string","optional":1,"pattern":"[a-zA-Z0-9\\-]+","type":"string"},"size":{"description":"The size of the file in MB.","minimum":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"ivshmem"},{"definition":{"default":0,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keephugepages"},{"definition":{"description":"Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"keyboard"},{"definition":{"default":1,"description":"Enable/disable KVM hardware virtualization.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"kvm"},{"definition":{"description":"Start the VM immediately while importing or restoring in the background.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"live-restore"},{"definition":{"description":"Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"localtime"},{"definition":{"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"description":"Specify the QEMU machine.","enum":[],"extra":{"typetext":"[[type=]] [,aw-bits=] [,enable-s3=<1|0>] [,enable-s4=<1|0>] [,viommu=]"},"format":{"aw-bits":{"description":"Specifies the vIOMMU address space bit width.","maximum":64,"minimum":32,"optional":1,"type":"number","verbose_description":"Specifies the vIOMMU address space bit width.\n\nIntel vIOMMU supports a bit width of either 39 or 48 bits and VirtIO vIOMMU supports any bit width between 32 and 64 bits."},"enable-s3":{"description":"Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"enable-s4":{"description":"Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"type":{"default_key":1,"description":"Specifies the QEMU machine type.","format_description":"machine type","maxLength":40,"optional":1,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","type":"string"},"viommu":{"description":"Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).","enum":["intel","virtio"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"machine"},{"definition":{"description":"Memory properties.","enum":[],"extra":{"typetext":"[current=]"},"format":{"current":{"default":512,"default_key":1,"description":"Current amount of online RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.","minimum":16,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"memory"},{"definition":{"default":0.1,"description":"Set maximum tolerated downtime (in seconds) for migrations. Should the migration not be able to converge in the very end, because too much newly dirtied RAM needs to be transferred, the limit will be increased automatically step-by-step until migration can converge. Will be capped to 2000 seconds (maximum in QEMU).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"migrate_downtime"},{"definition":{"default":0,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"migrate_speed"},{"definition":{"description":"Set a name for the VM. Only used on the configuration web interface.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"format":"address-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specify network devices.","enum":[],"extra":{"typetext":"[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]"},"format":{"bridge":{"description":"Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n","format":"pve-bridge-id","format_description":"bridge","optional":1,"type":"string"},"e1000":{"alias":"macaddr","keyAlias":"model"},"e1000-82540em":{"alias":"macaddr","keyAlias":"model"},"e1000-82544gc":{"alias":"macaddr","keyAlias":"model"},"e1000-82545em":{"alias":"macaddr","keyAlias":"model"},"e1000e":{"alias":"macaddr","keyAlias":"model"},"firewall":{"description":"Whether this interface should be protected by the firewall.","optional":1,"type":"boolean"},"i82551":{"alias":"macaddr","keyAlias":"model"},"i82557b":{"alias":"macaddr","keyAlias":"model"},"i82559er":{"alias":"macaddr","keyAlias":"model"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"macaddr":{"description":"MAC address. That address must be unique within your network. This is automatically generated if not specified.","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"model":{"default_key":1,"description":"Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.","enum":["e1000","e1000-82540em","e1000-82544gc","e1000-82545em","e1000e","i82551","i82557b","i82559er","ne2k_isa","ne2k_pci","pcnet","rtl8139","virtio","vmxnet3"],"type":"string"},"mtu":{"description":"Force MTU of network device (VirtIO only). Setting to '1' or empty will use the bridge MTU","maximum":65520,"minimum":1,"optional":1,"type":"integer"},"ne2k_isa":{"alias":"macaddr","keyAlias":"model"},"ne2k_pci":{"alias":"macaddr","keyAlias":"model"},"pcnet":{"alias":"macaddr","keyAlias":"model"},"queues":{"description":"Number of packet queues to be used on the device.","maximum":64,"minimum":0,"optional":1,"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":0,"optional":1,"type":"number"},"rtl8139":{"alias":"macaddr","keyAlias":"model"},"tag":{"description":"VLAN tag to apply to packets on this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN trunks to pass through this interface.","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"virtio":{"alias":"macaddr","keyAlias":"model"},"vmxnet3":{"alias":"macaddr","keyAlias":"model"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Enable/disable NUMA.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"numa"},{"definition":{"description":"NUMA topology.","enum":[],"extra":{"typetext":"cpus= [,hostnodes=] [,memory=] [,policy=]"},"format":{"cpus":{"description":"CPUs accessing this NUMA node.","format_description":"id[-id];...","pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"hostnodes":{"description":"Host NUMA nodes to use.","format_description":"id[-id];...","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"memory":{"description":"Amount of memory this NUMA node provides.","optional":1,"type":"number"},"policy":{"description":"NUMA allocation policy.","enum":["preferred","bind","interleave"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"numa[n]"},{"definition":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"default":"other","description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","win11","l24","l26","solaris"],"extra":{"verbose_description":"Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022/2025\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 7.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n"},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"description":"Map host parallel devices (n is 0 to 2).","enum":[],"extra":{"verbose_description":"Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"/dev/parport\\d+|/dev/usb/lp\\d+","properties":{},"type":"string"},"name":"parallel[n]"},{"definition":{"description":"Add the VM to the specified pool.","enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"default":0,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"default":1,"description":"Allow reboot. If set to '0' the VM exit on reboot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"reboot"},{"definition":{"description":"Configure a VirtIO-based Random Number Generator.","enum":[],"extra":{"typetext":"[source=] [,max_bytes=] [,period=]"},"format":"pve-qm-rng","optional":true,"properties":{},"type":"string"},"name":"rng0"},{"definition":{"description":"Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"sata[n]"},{"definition":{"description":"Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,product=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,vendor=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"product":{"description":"The drive's product name, up to 16 bytes long.","format_description":"product","optional":1,"pattern":"[A-Za-z0-9\\-_\\s]{,16}","type":"string"},"queues":{"description":"Number of queues.","minimum":2,"optional":1,"type":"integer"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"scsiblock":{"default":0,"description":"whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host","optional":1,"type":"boolean"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"vendor":{"description":"The drive's vendor name, up to 8 bytes long.","format_description":"vendor","optional":1,"pattern":"[A-Za-z0-9\\-_\\s]{,8}","type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"scsi[n]"},{"definition":{"default":"lsi","description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scsihw"},{"definition":{"description":"cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Create a serial device inside the VM (n is 0 to 3)","enum":[],"extra":{"verbose_description":"Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"(/dev/[^,]+|socket)","properties":{},"type":"string"},"name":"serial[n]"},{"definition":{"default":1000,"description":"Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.","enum":[],"extra":{"typetext":" (0 - 50000)"},"maximum":50000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"shares"},{"definition":{"description":"Specify SMBIOS type 1 fields.","enum":[],"extra":{"typetext":"[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]"},"format":"pve-qm-smbios1","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"smbios1"},{"definition":{"default":1,"description":"The number of CPUs. Please use option -sockets instead.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"smp"},{"definition":{"default":1,"description":"The number of CPU sockets.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"sockets"},{"definition":{"description":"Configure additional enhancements for SPICE.","enum":[],"extra":{"typetext":"[foldersharing=<1|0>] [,videostreaming=]"},"format":{"foldersharing":{"default":"0","description":"Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.","optional":1,"type":"boolean"},"videostreaming":{"default":"off","description":"Enable video streaming. Uses compression for detected video streams.","enum":["off","all","filter"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"spice_enhancements"},{"definition":{"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{"typetext":""},"format":"urlencoded","optional":true,"properties":{},"type":"string"},"name":"sshkeys"},{"definition":{"default":0,"description":"Start VM after it was created successfully.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"start"},{"definition":{"default":"now","description":"Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.","enum":[],"extra":{"typetext":"(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)"},"optional":true,"pattern":"(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)","properties":{},"type":"string"},"name":"startdate"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"description":"Default storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"default":1,"description":"Enable/disable the USB tablet device.","enum":[],"extra":{"typetext":"","verbose_description":"Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)."},"optional":true,"properties":{},"type":"boolean"},"name":"tablet"},{"definition":{"description":"Tags of the VM. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable time drift fix.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tdf"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,format=] [,import-from=] [,size=] [,version=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"Format of the image.","enum":["raw","qcow2","vmdk"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"version":{"default":"v1.2","description":"The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.","enum":["v1.2","v2.0"],"optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"tpmstate0"},{"definition":{"description":"Assign a unique random ethernet address.","enum":[],"extra":{"requires":"archive","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"unique"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[file=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id","format_description":"volume","type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).","enum":[],"extra":{"typetext":"[[host=]] [,mapping=] [,usb3=<1|0>]"},"format":{"host":{"default_key":1,"description":"The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadecimal numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n\nEither this or the 'mapping' key must be set.\n","format_description":"HOSTUSBDEVICE|spice","optional":1,"pattern":"(?^:(?:(?:(?^:(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})))|(?:(?^:(\\d+)\\-(\\d+(\\.\\d+)*)))|[Ss][Pp][Ii][Cc][Ee]))","type":"string"},"mapping":{"description":"The ID of a cluster wide mapping. Either this or the default-key 'host' must be set.","format":"pve-configid","format_description":"mapping-id","optional":1,"type":"string"},"usb3":{"default":0,"description":"Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"usb[n]"},{"definition":{"default":0,"description":"Number of hotplugged vcpus.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vcpus"},{"definition":{"description":"Configure the VGA hardware.","enum":[],"extra":{"typetext":"[[type=]] [,clipboard=] [,memory=]","verbose_description":"Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal."},"format":{"clipboard":{"description":"Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Live migration with a VNC clipboard is not possible with QEMU machine version < 10.1.","enum":["vnc"],"optional":1,"type":"string"},"memory":{"description":"Sets the VGA memory (in MiB). Has no effect with serial display.","maximum":512,"minimum":4,"optional":1,"type":"integer"},"type":{"default":"std","default_key":1,"description":"Select the VGA type. Using type 'cirrus' is not recommended.","enum":["cirrus","qxl","qxl2","qxl3","qxl4","none","serial0","serial1","serial2","serial3","std","virtio","virtio-gl","vmware"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"vga"},{"definition":{"description":"Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,werror=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"virtio[n]"},{"definition":{"description":"Configuration for sharing a directory between host and guest using Virtio-fs.","enum":[],"extra":{"typetext":"[dirid=] [,cache=] [,direct-io=<1|0>] [,expose-acl=<1|0>] [,expose-xattr=<1|0>]"},"format":{"cache":{"default":"auto","description":"The caching policy the file system should use (auto, always, metadata, never).","enum":["auto","always","metadata","never"],"optional":1,"type":"string"},"direct-io":{"default":0,"description":"Honor the O_DIRECT flag passed down by guest applications.","optional":1,"type":"boolean"},"dirid":{"default_key":1,"description":"Mapping identifier of the directory mapping to be shared with the guest. Also used as a mount tag inside the VM.","format":"pve-configid","format_description":"mapping-id","type":"string"},"expose-acl":{"default":0,"description":"Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.","optional":1,"type":"boolean"},"expose-xattr":{"default":0,"description":"Enable support for extended attributes for this mount.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"virtiofs[n]"},{"definition":{"default":"1 (autogenerated)","description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","enum":[],"extra":{"format_description":"UUID","verbose_description":"The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file."},"optional":true,"pattern":"(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])","properties":{},"type":"string"},"name":"vmgenid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Default storage for VM state volumes/files.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"vmstatestorage"},{"definition":{"description":"Create a virtual hardware watchdog device.","enum":[],"extra":{"typetext":"[[model=]] [,action=]","verbose_description":"Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)"},"format":"pve-qm-watchdog","optional":true,"properties":{},"type":"string"},"name":"watchdog"}],"permissions":{"description":"You need 'VM.Allocate' permissions on /vms/{vmid} or on the VM pool /pool/{pool}. For restore (option 'archive'), it is enough if the user has 'VM.Backup' permission and the VM already exists. If you create disks you need 'Datastore.AllocateSpace' on any used storage.If you use a bridge/vlan, you need 'SDN.Use' on any used bridge/vlan.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0253c629732d317131f9345a056f4d9af4c6fea99c38d29385854345b0db182b","description":"Destroy the VM and all used/owned volumes. Removes any VM specific permissions and firewall rules","extra":{"proxyto":"node"},"name":"destroy_vm","parameters":[{"definition":{"default":0,"description":"If set, destroy additionally all disks not referenced in the config but with a matching VMID from all enabled storages.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"destroy-unreferenced-disks"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Remove VMID from configurations, like backup & replication jobs and HA.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"purge"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"9e36c28967bab606c23a50ff07fa5524991078437cdd75bba7697aac8a894802","description":"Directory index","extra":{"proxyto":"node"},"name":"vmdiridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"123fba96dc634dbf1c98a76b02abda83611fd4d1163d8da2f37506d731a3990d","description":"QEMU Guest Agent command index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"Returns the list of QEMU Guest Agent commands","enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"9170372f5ca468857a5934b6879b4857aea6ee1f35120b131878c37e4f12da8f","description":"Execute QEMU Guest Agent commands.","extra":{"proxyto":"node"},"name":"agent","parameters":[{"definition":{"description":"The QGA command.","enum":["fsfreeze-freeze","fsfreeze-status","fsfreeze-thaw","fstrim","get-fsinfo","get-host-name","get-memory-block-info","get-memory-blocks","get-osinfo","get-time","get-timezone","get-users","get-vcpus","info","network-get-interfaces","ping","shutdown","suspend-disk","suspend-hybrid","suspend-ram"],"extra":{},"properties":{},"type":"string"},"name":"command"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Unrestricted","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d642907aabd594d55aec8db3328555937b72399917ff1510278e95d1cf450f02","description":"Executes the given command in the vm via the guest-agent and returns an object with the pid.","extra":{"proxyto":"node"},"name":"exec","parameters":[{"definition":{"description":"The command as a list of program + arguments.","enum":[],"extra":{"typetext":""},"items":{"description":"A single part of the program + arguments.","enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"name":"command"},{"definition":{"description":"Data to pass as 'input-data' to the guest. Usually treated as STDIN to 'command'.","enum":[],"extra":{"typetext":""},"max_length":65536,"optional":true,"properties":{},"type":"string"},"name":"input-data"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Unrestricted"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"pid":{"description":"The PID of the process started by the guest-agent.","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/exec"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8c2c413177e655786b85c3b6c224d59abde2febaf92e0f35d6d3d54cf32d07d5","description":"Gets the status of the given pid started by the guest-agent","extra":{"proxyto":"node"},"name":"exec-status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The PID to query","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"pid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Unrestricted"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"err-data":{"description":"stderr of the process","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"err-truncated":{"description":"true if stderr was not fully captured","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"exitcode":{"description":"process exit code if it was normally terminated.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"exited":{"description":"Tells if the given command has exited yet.","enum":[],"extra":{},"properties":{},"type":"boolean"},"out-data":{"description":"stdout of the process","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"out-truncated":{"description":"true if stdout was not fully captured","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"signal":{"description":"signal number or exception code if the process was abnormally terminated.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/exec-status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bfc62079dd7352f3112dfc8a3a7374e38749c31703a163f96c395374b984423d","description":"Reads the given file via guest agent. Is limited to 16777216 bytes.","extra":{"proxyto":"node"},"name":"file-read","parameters":[{"definition":{"default":"16777216","description":"Number of bytes to read.","enum":[],"extra":{"typetext":" (1 - 16777216)"},"maximum":16777216,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"count"},{"definition":{"default":1,"description":"Data received from the QEMU Guest-Agent is base64 encoded. If this is set to true, the data is decoded. Otherwise the content is forwarded with base64 encoding. Defaults to true.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"decode"},{"definition":{"description":"The path to the file","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"file"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Offset to start reading at","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"offset"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.FileRead","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a `content` property.","enum":[],"extra":{},"properties":{"content":{"description":"The content of the file, maximum 16777216","enum":[],"extra":{},"properties":{},"type":"string"},"truncated":{"description":"If set to 1, the read did not reach the end of the file.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/file-read"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9f71193125a5f573681741bb4afc181ca5a9f14f0c1c8b3b1d21ecfcec038342","description":"Writes the given file via guest agent.","extra":{"proxyto":"node"},"name":"file-write","parameters":[{"definition":{"description":"The content to write into the file.","enum":[],"extra":{"typetext":""},"max_length":61440,"properties":{},"type":"string"},"name":"content"},{"definition":{"default":1,"description":"If set, the content will be encoded as base64 (required by QEMU).Otherwise the content needs to be encoded beforehand - defaults to true.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"encode"},{"definition":{"description":"The path to the file.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"file"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.FileWrite","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/file-write"},{"extra":{},"methods":[{"allow_token":true,"checksum":"00f05b85cc5c9c94d289677a0729bac1159ac67ce3badaf600b52b69549eaa14","description":"Execute fsfreeze-freeze.","extra":{"proxyto":"node"},"name":"fsfreeze-freeze","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.FileSystemMgmt","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze"},{"extra":{},"methods":[{"allow_token":true,"checksum":"da3662fe9f80498d28df52b68b52720884ea5eba654d93cb0ecb668cc25775b9","description":"Execute fsfreeze-status.","extra":{"proxyto":"node"},"name":"fsfreeze-status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.FileSystemMgmt","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4fee39da9db940edeaef0fc557774571f29ca92ccb089f91d34a23a6957eee84","description":"Execute fsfreeze-thaw.","extra":{"proxyto":"node"},"name":"fsfreeze-thaw","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.FileSystemMgmt","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw"},{"extra":{},"methods":[{"allow_token":true,"checksum":"09d0df07e2a89fc9c16f1d5f6e51c5c609b2ae8ef56d5e4757542d055d3cabd0","description":"Execute fstrim.","extra":{"proxyto":"node"},"name":"fstrim","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.FileSystemMgmt","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/fstrim"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5879f864434a378a38436d880386e8d769259f89a9a79073f97d417da73888b8","description":"Execute get-fsinfo.","extra":{"proxyto":"node"},"name":"get-fsinfo","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-fsinfo"},{"extra":{},"methods":[{"allow_token":true,"checksum":"12df0c41d993ca0f885b69ab43bdf296e1131a009476b2b8bf9afd22511e67b4","description":"Execute get-host-name.","extra":{"proxyto":"node"},"name":"get-host-name","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-host-name"},{"extra":{},"methods":[{"allow_token":true,"checksum":"fbb23a9245fa93550e6619a827a5201dfb51f90b4f5835f878b8fcf069a6e584","description":"Execute get-memory-block-info.","extra":{"proxyto":"node"},"name":"get-memory-block-info","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8062819b828605f995bf17945216f2b3987782d35e4b2157a2484f377b377b90","description":"Execute get-memory-blocks.","extra":{"proxyto":"node"},"name":"get-memory-blocks","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"53ace970710481288f7f502cb335a56c8636727c1e1e97fc53eb9d38904f0321","description":"Execute get-osinfo.","extra":{"proxyto":"node"},"name":"get-osinfo","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-osinfo"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3fd735160c00565a270e13352639eb044530eabf46d9b22e6c3ee606d504f77d","description":"Execute get-time.","extra":{"proxyto":"node"},"name":"get-time","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-time"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a810761c444941a60d46d621f21f73eda904912a80baba0dcb8d2b258e3fdde2","description":"Execute get-timezone.","extra":{"proxyto":"node"},"name":"get-timezone","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-timezone"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f63394c465c4d62d235c485672c5ece3574f4dacfda09cfe3b27eaea1d6e170e","description":"Execute get-users.","extra":{"proxyto":"node"},"name":"get-users","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-users"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6b193521e9984f241d1d8401c29dddb08c43ed6f57fe95f00a0a8790f6759c93","description":"Execute get-vcpus.","extra":{"proxyto":"node"},"name":"get-vcpus","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-vcpus"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2a368a042c14a885fb46be95ac9a52596bce4ab3ddd3b2e15d5b8711da96edf9","description":"Execute info.","extra":{"proxyto":"node"},"name":"info","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"92398abd15887244bae2d1a6cf17c426cb934c81b13dae666c5a06b96ad053f9","description":"Execute network-get-interfaces.","extra":{"proxyto":"node"},"name":"network-get-interfaces","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a2734877492c7e13dbd606a5f90c6b06a10c499fec5318ef8a20f216e637f0c3","description":"Execute ping.","extra":{"proxyto":"node"},"name":"ping","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/ping"},{"extra":{},"methods":[{"allow_token":true,"checksum":"07553a7f7984cc94f9f84b1900c0006b5fdbc378d7b66c15e2efd79ab50b4846","description":"Sets the password for the given user to the given password","extra":{"proxyto":"node"},"name":"set-user-password","parameters":[{"definition":{"default":0,"description":"set to 1 if the password has already been passed through crypt()","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"crypted"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The new password.","enum":[],"extra":{"typetext":""},"max_length":1024,"min_length":5,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"The user to set the password for.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"username"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Unrestricted"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/set-user-password"},{"extra":{},"methods":[{"allow_token":true,"checksum":"807e10b2adf35058609f535588513cb5edf8993558a49f607bc5f913a1625f96","description":"Execute shutdown.","extra":{"proxyto":"node"},"name":"shutdown","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/shutdown"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b50284569bca39303432bd529c50361ad9d19135802001291599dbcb705df3a3","description":"Execute suspend-disk.","extra":{"proxyto":"node"},"name":"suspend-disk","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/suspend-disk"},{"extra":{},"methods":[{"allow_token":true,"checksum":"238e62f2d6f650b2babb9336007cfbf1f763ef82c49753b60c4d041dc58ce891","description":"Execute suspend-hybrid.","extra":{"proxyto":"node"},"name":"suspend-hybrid","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c5be8ccb6f510cbc7fecfcbbc3878e871ff572081e7c637c5ae132e217e9c2c9","description":"Execute suspend-ram.","extra":{"proxyto":"node"},"name":"suspend-ram","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt","VM.GuestAgent.Unrestricted"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/suspend-ram"},{"extra":{},"methods":[{"allow_token":true,"checksum":"10b4a9fb335a196b339d68a3084b9541edb26fa4f1e13b6a12d9f2e0306e0ffd","description":"Create a copy of virtual machine/template.","extra":{"proxyto":"node"},"name":"clone_vm","parameters":[{"definition":{"default":"clone limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"Description for the new VM.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Target format for file storage. Only valid for full clone.","enum":["raw","qcow2","vmdk"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"Create a full copy of all disks. This is always done when you clone a normal VM. For VM templates, we try to create a linked clone by default.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"},{"definition":{"description":"Set a name for the new VM.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"VMID for the clone.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"newid"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Add the new VM to the specified pool.","enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"Target storage for full clone.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Target node. Only allowed if the original VM is on shared storage.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions on /vms/{newid} (or on the VM pool /pool/{pool}). You also need 'Datastore.AllocateSpace' on any used storage and 'SDN.Use' on any used bridge/vnet","expression":{"check":["and",["perm","/vms/{vmid}",["VM.Clone"]],["or",["perm","/vms/{newid}",["VM.Allocate"]],["perm","/pool/{pool}",["VM.Allocate"],"require_param","pool"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/clone"},{"extra":{},"methods":[{"allow_token":true,"checksum":"536f115222144300cae0a79ff9232f285dc046f51fa00c6c287753e4b66e6381","description":"Get the cloudinit configuration with both current and pending values.","extra":{"proxyto":"node"},"name":"cloudinit_pending","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"delete":{"description":"Indicates a pending delete request if present and not 0. ","enum":[],"extra":{},"maximum":1,"minimum":0,"optional":true,"properties":{},"type":"integer"},"key":{"description":"Configuration option name.","enum":[],"extra":{},"properties":{},"type":"string"},"pending":{"description":"The new pending value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"value":{"description":"Value as it was used to generate the current cloudinit image.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"cd8eb44b3b45afbd5e723e5e6e6717db900b9ecb3bc4f8749547f0819b37d962","description":"Regenerate and change cloudinit config drive.","extra":{"proxyto":"node"},"name":"cloudinit_update","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Cloudinit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/cloudinit"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5e03b909a48d15544b7f9793fe2aaca3498b6ef2d0ea53660fa2870cb934972c","description":"Get automatically generated cloudinit config.","extra":{"proxyto":"node"},"name":"cloudinit_generated_config_dump","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Config type.","enum":["user","network","meta"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/cloudinit/dump"},{"extra":{},"methods":[{"allow_token":true,"checksum":"82d4761088617d34bfb2152cafadcffbf5317c5b3e4a4864aa7290a590461a38","description":"Get the virtual machine configuration with pending configuration changes applied. Set the 'current' parameter to get the current configuration instead.","extra":{"proxyto":"node"},"name":"vm_config","parameters":[{"definition":{"default":0,"description":"Get current values (instead of pending values).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"current"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Fetch config values from given snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapshot"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"description":"The VM configuration.","enum":[],"extra":{},"properties":{"acpi":{"default":1,"description":"Enable/disable ACPI.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"affinity":{"description":"List of host cores used to execute guest processes, for example: 0,5,8-11","enum":[],"extra":{},"format":"pve-cpuset","optional":true,"properties":{},"type":"string"},"agent":{"description":"Enable/disable communication with the QEMU Guest Agent and its properties.","enum":[],"extra":{},"format":{"enabled":{"default":0,"default_key":1,"description":"Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.","type":"boolean"},"freeze-fs":{"default":1,"description":"Freeze guest filesystems through QGA for consistent disk state on operations such as snapshots, backups, replications and clones.","optional":1,"type":"boolean","verbose_description":"Whether to issue the guest-fsfreeze-freeze and guest-fsfreeze-thaw QEMU guest agent commands. Backups in snapshot mode, clones, snapshots without RAM, importing disks from a running guest, and replications normally issue a guest-fsfreeze-freeze and a respective thaw command when the QEMU Guest agent option is enabled in the guest's configuration and the agent is running inside of the guest.\n\nThe deprecated 'freeze-fs-on-backup' setting is treated as an alias for this setting."},"freeze-fs-on-backup":{"alias":"freeze-fs"},"fstrim_cloned_disks":{"default":0,"description":"Run fstrim after moving a disk or migrating the VM.","optional":1,"type":"boolean"},"guest-fsfreeze":{"alias":"freeze-fs"},"type":{"default":"virtio","description":"Select the agent type","enum":["virtio","isa"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"allow-ksm":{"default":1,"description":"Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"amd-sev":{"description":"Secure Encrypted Virtualization (SEV) features by AMD CPUs","enum":[],"extra":{},"format":"pve-qemu-sev-fmt","optional":true,"properties":{},"type":"string"},"arch":{"description":"Virtual processor architecture. Defaults to the host architecture.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"args":{"description":"Arbitrary arguments passed to kvm.","enum":[],"extra":{"verbose_description":"Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -smbios 'type=0,vendor=FOO'\n\nNOTE: this option is for experts only.\n"},"optional":true,"properties":{},"type":"string"},"audio0":{"description":"Configure a audio device, useful in combination with QXL/Spice.","enum":[],"extra":{},"format":{"device":{"description":"Configure an audio device.","enum":["ich9-intel-hda","intel-hda","AC97"],"type":"string"},"driver":{"default":"spice","description":"Driver backend for the audio device.","enum":["spice","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"autostart":{"default":0,"description":"Automatic restart after crash (currently ignored).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"balloon":{"description":"Amount of target RAM for the VM in MiB. The balloon driver is enabled by default, unless it is explicitly disabled by setting the value to zero.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"bios":{"default":"seabios","description":"Select BIOS implementation.","enum":["seabios","ovmf"],"extra":{},"optional":true,"properties":{},"type":"string"},"boot":{"description":"Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.","enum":[],"extra":{},"format":"pve-qm-boot","optional":true,"properties":{},"type":"string"},"bootdisk":{"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","enum":[],"extra":{},"format":"pve-qm-bootdisk","optional":true,"pattern":"(ide|sata|scsi|virtio)\\d+","properties":{},"type":"string"},"cdrom":{"description":"This is an alias for option -ide2","enum":[],"extra":{"typetext":""},"format":"pve-qm-ide","optional":true,"properties":{},"type":"string"},"cicustom":{"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","enum":[],"extra":{},"format":"pve-qm-cicustom","optional":true,"properties":{},"type":"string"},"cipassword":{"description":"cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"citype":{"description":"Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.","enum":["configdrive2","nocloud","opennebula"],"extra":{},"optional":true,"properties":{},"type":"string"},"ciupgrade":{"default":1,"description":"cloud-init: do an automatic package upgrade after the first boot.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ciuser":{"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"cores":{"default":1,"description":"The number of cores per socket.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"cpu":{"description":"Emulated CPU type.","enum":[],"extra":{},"format":"pve-vm-cpu-conf","optional":true,"properties":{},"type":"string"},"cpulimit":{"default":0,"description":"Limit of CPU usage.","enum":[],"extra":{"verbose_description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit."},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"number"},"cpuunits":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"verbose_description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs."},"maximum":262144,"minimum":1,"optional":true,"properties":{},"type":"integer"},"description":{"description":"Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{},"max_length":8192,"optional":true,"properties":{},"type":"string"},"digest":{"description":"SHA1 digest of configuration file. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"properties":{},"type":"string"},"efidisk0":{"description":"Configure a disk for storing EFI vars.","enum":[],"extra":{},"format":{"efitype":{"default":"2m","description":"Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarch64 (ARM).","enum":["2m","4m"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"ms-cert":{"default":"2011","description":"Informational marker indicating the version of the latest Microsoft UEFI certificates that have been enrolled by Proxmox VE. The value '2023k' means that the 'Microsoft UEFI CA 2023', the 'Windows UEFI CA 2023' and the 'Microsoft Corporation KEK 2K CA 2023' certificates are included. The values '2023' and '2023w' are deprecated and for compatibility only.","enum":["2011","2023","2023w","2023k"],"optional":1,"type":"string"},"pre-enrolled-keys":{"default":0,"description":"Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.","optional":1,"type":"boolean"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"freeze":{"description":"Freeze CPU at startup (use 'c' monitor command to start execution).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"hookscript":{"description":"Script that will be executed during various steps in the vms lifetime.","enum":[],"extra":{},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"hostpci[n]":{"description":"Map host PCI devices into guest.","enum":[],"extra":{"verbose_description":"Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"format":"pve-qm-hostpci","optional":true,"properties":{},"type":"string"},"hotplug":{"default":"network,disk,usb","description":"Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.","enum":[],"extra":{},"format":"pve-hotplug-features","optional":true,"properties":{},"type":"string"},"hugepages":{"description":"Enables hugepages memory.\n\nSets the size of hugepages in MiB. If the value is set to 'any' then 1 GiB hugepages will be used if possible, otherwise the size will fall back to 2 MiB.","enum":["any","2","1024"],"extra":{},"optional":true,"properties":{},"type":"string"},"ide[n]":{"description":"Use volume as IDE hard disk or CD-ROM (n is 0 to 3).","enum":[],"extra":{},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"model":{"description":"The drive's reported model name, url-encoded, up to 40 bytes long.","format":"urlencoded","format_description":"model","maxLength":120,"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"intel-tdx":{"description":"Trusted Domain Extension (TDX) features by Intel CPUs","enum":[],"extra":{},"format":"pve-qemu-tdx-fmt","optional":true,"properties":{},"type":"string"},"ipconfig[n]":{"description":"cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n","enum":[],"extra":{},"format":"pve-qm-ipconfig","optional":true,"properties":{},"type":"string"},"ivshmem":{"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host.","enum":[],"extra":{},"format":{"name":{"description":"The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.","format_description":"string","optional":1,"pattern":"[a-zA-Z0-9\\-]+","type":"string"},"size":{"description":"The size of the file in MB.","minimum":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"keephugepages":{"default":0,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"keyboard":{"description":"Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"kvm":{"default":1,"description":"Enable/disable KVM hardware virtualization.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"localtime":{"description":"Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"lock":{"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"],"extra":{},"optional":true,"properties":{},"type":"string"},"machine":{"description":"Specify the QEMU machine.","enum":[],"extra":{},"format":{"aw-bits":{"description":"Specifies the vIOMMU address space bit width.","maximum":64,"minimum":32,"optional":1,"type":"number","verbose_description":"Specifies the vIOMMU address space bit width.\n\nIntel vIOMMU supports a bit width of either 39 or 48 bits and VirtIO vIOMMU supports any bit width between 32 and 64 bits."},"enable-s3":{"description":"Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"enable-s4":{"description":"Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"type":{"default_key":1,"description":"Specifies the QEMU machine type.","format_description":"machine type","maxLength":40,"optional":1,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","type":"string"},"viommu":{"description":"Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).","enum":["intel","virtio"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"memory":{"description":"Memory properties.","enum":[],"extra":{},"format":{"current":{"default":512,"default_key":1,"description":"Current amount of online RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.","minimum":16,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"meta":{"description":"Some (read-only) meta-information about this guest.","enum":[],"extra":{},"format":{"creation-qemu":{"description":"The QEMU (machine) version from the time this VM was created.","optional":1,"pattern":"\\d+(\\.\\d+)+","type":"string"},"ctime":{"description":"The guest creation timestamp as UNIX epoch time","minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"migrate_downtime":{"default":0.1,"description":"Set maximum tolerated downtime (in seconds) for migrations. Should the migration not be able to converge in the very end, because too much newly dirtied RAM needs to be transferred, the limit will be increased automatically step-by-step until migration can converge. Will be capped to 2000 seconds (maximum in QEMU).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"number"},"migrate_speed":{"default":0,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":{"description":"Set a name for the VM. Only used on the configuration web interface.","enum":[],"extra":{},"format":"dns-name","optional":true,"properties":{},"type":"string"},"nameserver":{"description":"cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{},"format":"address-list","optional":true,"properties":{},"type":"string"},"net[n]":{"description":"Specify network devices.","enum":[],"extra":{},"format":{"bridge":{"description":"Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n","format":"pve-bridge-id","format_description":"bridge","optional":1,"type":"string"},"e1000":{"alias":"macaddr","keyAlias":"model"},"e1000-82540em":{"alias":"macaddr","keyAlias":"model"},"e1000-82544gc":{"alias":"macaddr","keyAlias":"model"},"e1000-82545em":{"alias":"macaddr","keyAlias":"model"},"e1000e":{"alias":"macaddr","keyAlias":"model"},"firewall":{"description":"Whether this interface should be protected by the firewall.","optional":1,"type":"boolean"},"i82551":{"alias":"macaddr","keyAlias":"model"},"i82557b":{"alias":"macaddr","keyAlias":"model"},"i82559er":{"alias":"macaddr","keyAlias":"model"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"macaddr":{"description":"MAC address. That address must be unique within your network. This is automatically generated if not specified.","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"model":{"default_key":1,"description":"Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.","enum":["e1000","e1000-82540em","e1000-82544gc","e1000-82545em","e1000e","i82551","i82557b","i82559er","ne2k_isa","ne2k_pci","pcnet","rtl8139","virtio","vmxnet3"],"type":"string"},"mtu":{"description":"Force MTU of network device (VirtIO only). Setting to '1' or empty will use the bridge MTU","maximum":65520,"minimum":1,"optional":1,"type":"integer"},"ne2k_isa":{"alias":"macaddr","keyAlias":"model"},"ne2k_pci":{"alias":"macaddr","keyAlias":"model"},"pcnet":{"alias":"macaddr","keyAlias":"model"},"queues":{"description":"Number of packet queues to be used on the device.","maximum":64,"minimum":0,"optional":1,"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":0,"optional":1,"type":"number"},"rtl8139":{"alias":"macaddr","keyAlias":"model"},"tag":{"description":"VLAN tag to apply to packets on this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN trunks to pass through this interface.","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"virtio":{"alias":"macaddr","keyAlias":"model"},"vmxnet3":{"alias":"macaddr","keyAlias":"model"}},"optional":true,"properties":{},"type":"string"},"numa":{"default":0,"description":"Enable/disable NUMA.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"numa[n]":{"description":"NUMA topology.","enum":[],"extra":{},"format":{"cpus":{"description":"CPUs accessing this NUMA node.","format_description":"id[-id];...","pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"hostnodes":{"description":"Host NUMA nodes to use.","format_description":"id[-id];...","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"memory":{"description":"Amount of memory this NUMA node provides.","optional":1,"type":"number"},"policy":{"description":"NUMA allocation policy.","enum":["preferred","bind","interleave"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"onboot":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ostype":{"default":"other","description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","win11","l24","l26","solaris"],"extra":{"verbose_description":"Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022/2025\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 7.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n"},"optional":true,"properties":{},"type":"string"},"parallel[n]":{"description":"Map host parallel devices (n is 0 to 2).","enum":[],"extra":{"verbose_description":"Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"/dev/parport\\d+|/dev/usb/lp\\d+","properties":{},"type":"string"},"parent":{"description":"Parent snapshot name. This is used internally, and should not be modified.","enum":[],"extra":{},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"protection":{"default":0,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"reboot":{"default":1,"description":"Allow reboot. If set to '0' the VM exit on reboot.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"rng0":{"description":"Configure a VirtIO-based Random Number Generator.","enum":[],"extra":{},"format":"pve-qm-rng","optional":true,"properties":{},"type":"string"},"running-nets-host-mtu":{"description":"List of VirtIO network devices and their effective host_mtu setting. A value of 0 means that the host_mtu parameter is to be avoided for the corresponding device. This is used internally for snapshots.","enum":[],"extra":{},"optional":true,"pattern":"net\\d+=\\d+(,net\\d+=\\d+)*","properties":{},"type":"string"},"runningcpu":{"description":"Specifies the QEMU '-cpu' parameter of the running vm. This is used internally for snapshots.","enum":[],"extra":{"format_description":"QEMU -cpu parameter"},"optional":true,"pattern":"(?^u:^((?>[+-]?[\\w\\-\\._=]+,?)+)$)","properties":{},"type":"string"},"runningmachine":{"description":"Specifies the QEMU machine type of the running vm. This is used internally for snapshots.","enum":[],"extra":{},"format":{"aw-bits":{"description":"Specifies the vIOMMU address space bit width.","maximum":64,"minimum":32,"optional":1,"type":"number","verbose_description":"Specifies the vIOMMU address space bit width.\n\nIntel vIOMMU supports a bit width of either 39 or 48 bits and VirtIO vIOMMU supports any bit width between 32 and 64 bits."},"enable-s3":{"description":"Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"enable-s4":{"description":"Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"type":{"default_key":1,"description":"Specifies the QEMU machine type.","format_description":"machine type","maxLength":40,"optional":1,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","type":"string"},"viommu":{"description":"Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).","enum":["intel","virtio"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"sata[n]":{"description":"Use volume as SATA hard disk or CD-ROM (n is 0 to 5).","enum":[],"extra":{},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"scsi[n]":{"description":"Use volume as SCSI hard disk or CD-ROM (n is 0 to 30).","enum":[],"extra":{},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"product":{"description":"The drive's product name, up to 16 bytes long.","format_description":"product","optional":1,"pattern":"[A-Za-z0-9\\-_\\s]{,16}","type":"string"},"queues":{"description":"Number of queues.","minimum":2,"optional":1,"type":"integer"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"scsiblock":{"default":0,"description":"whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host","optional":1,"type":"boolean"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"vendor":{"description":"The drive's vendor name, up to 8 bytes long.","format_description":"vendor","optional":1,"pattern":"[A-Za-z0-9\\-_\\s]{,8}","type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"scsihw":{"default":"lsi","description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"extra":{},"optional":true,"properties":{},"type":"string"},"searchdomain":{"description":"cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial[n]":{"description":"Create a serial device inside the VM (n is 0 to 3)","enum":[],"extra":{"verbose_description":"Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"(/dev/[^,]+|socket)","properties":{},"type":"string"},"shares":{"default":1000,"description":"Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.","enum":[],"extra":{},"maximum":50000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"smbios1":{"description":"Specify SMBIOS type 1 fields.","enum":[],"extra":{},"format":"pve-qm-smbios1","max_length":512,"optional":true,"properties":{},"type":"string"},"smp":{"default":1,"description":"The number of CPUs. Please use option -sockets instead.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"snaptime":{"description":"Timestamp for snapshots.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"sockets":{"default":1,"description":"The number of CPU sockets.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"spice_enhancements":{"description":"Configure additional enhancements for SPICE.","enum":[],"extra":{},"format":{"foldersharing":{"default":"0","description":"Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.","optional":1,"type":"boolean"},"videostreaming":{"default":"off","description":"Enable video streaming. Uses compression for detected video streams.","enum":["off","all","filter"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"sshkeys":{"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{},"format":"urlencoded","optional":true,"properties":{},"type":"string"},"startdate":{"default":"now","description":"Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.","enum":[],"extra":{"typetext":"(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)"},"optional":true,"pattern":"(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)","properties":{},"type":"string"},"startup":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"tablet":{"default":1,"description":"Enable/disable the USB tablet device.","enum":[],"extra":{"verbose_description":"Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)."},"optional":true,"properties":{},"type":"boolean"},"tags":{"description":"Tags of the VM. This is only meta information.","enum":[],"extra":{},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"tdf":{"default":0,"description":"Enable/disable time drift fix.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"template":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"tpmstate0":{"description":"Configure a Disk for storing TPM state. The format is fixed to 'raw'.","enum":[],"extra":{},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"Format of the image.","enum":["raw","qcow2","vmdk"],"optional":1,"type":"string"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"version":{"default":"v1.2","description":"The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.","enum":["v1.2","v2.0"],"optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"unused[n]":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id","format_description":"volume","type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"usb[n]":{"description":"Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).","enum":[],"extra":{},"format":{"host":{"default_key":1,"description":"The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadecimal numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n\nEither this or the 'mapping' key must be set.\n","format_description":"HOSTUSBDEVICE|spice","optional":1,"pattern":"(?^:(?:(?:(?^:(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})))|(?:(?^:(\\d+)\\-(\\d+(\\.\\d+)*)))|[Ss][Pp][Ii][Cc][Ee]))","type":"string"},"mapping":{"description":"The ID of a cluster wide mapping. Either this or the default-key 'host' must be set.","format":"pve-configid","format_description":"mapping-id","optional":1,"type":"string"},"usb3":{"default":0,"description":"Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"vcpus":{"default":0,"description":"Number of hotplugged vcpus.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"vga":{"description":"Configure the VGA hardware.","enum":[],"extra":{"verbose_description":"Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal."},"format":{"clipboard":{"description":"Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Live migration with a VNC clipboard is not possible with QEMU machine version < 10.1.","enum":["vnc"],"optional":1,"type":"string"},"memory":{"description":"Sets the VGA memory (in MiB). Has no effect with serial display.","maximum":512,"minimum":4,"optional":1,"type":"integer"},"type":{"default":"std","default_key":1,"description":"Select the VGA type. Using type 'cirrus' is not recommended.","enum":["cirrus","qxl","qxl2","qxl3","qxl4","none","serial0","serial1","serial2","serial3","std","virtio","virtio-gl","vmware"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"virtio[n]":{"description":"Use volume as VIRTIO hard disk (n is 0 to 15).","enum":[],"extra":{},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"virtiofs[n]":{"description":"Configuration for sharing a directory between host and guest using Virtio-fs.","enum":[],"extra":{},"format":{"cache":{"default":"auto","description":"The caching policy the file system should use (auto, always, metadata, never).","enum":["auto","always","metadata","never"],"optional":1,"type":"string"},"direct-io":{"default":0,"description":"Honor the O_DIRECT flag passed down by guest applications.","optional":1,"type":"boolean"},"dirid":{"default_key":1,"description":"Mapping identifier of the directory mapping to be shared with the guest. Also used as a mount tag inside the VM.","format":"pve-configid","format_description":"mapping-id","type":"string"},"expose-acl":{"default":0,"description":"Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.","optional":1,"type":"boolean"},"expose-xattr":{"default":0,"description":"Enable support for extended attributes for this mount.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"vmgenid":{"default":"1 (autogenerated)","description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","enum":[],"extra":{"format_description":"UUID","verbose_description":"The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file."},"optional":true,"pattern":"(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])","properties":{},"type":"string"},"vmstate":{"description":"Reference to a volume which stores the VM state. This is used internally for snapshots.","enum":[],"extra":{},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"vmstatestorage":{"description":"Default storage for VM state volumes/files.","enum":[],"extra":{"format_description":"storage ID"},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"watchdog":{"description":"Create a virtual hardware watchdog device.","enum":[],"extra":{"verbose_description":"Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)"},"format":"pve-qm-watchdog","optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"11855e7aef4e9a5896b772dad19fa0740480bf79ae2c96facad977c3e146e10e","description":"Set virtual machine options (asynchronous API).","extra":{"proxyto":"node"},"name":"update_vm_async","parameters":[{"definition":{"default":1,"description":"Enable/disable ACPI.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"acpi"},{"definition":{"description":"List of host cores used to execute guest processes, for example: 0,5,8-11","enum":[],"extra":{"typetext":""},"format":"pve-cpuset","optional":true,"properties":{},"type":"string"},"name":"affinity"},{"definition":{"description":"Enable/disable communication with the QEMU Guest Agent and its properties.","enum":[],"extra":{"typetext":"[enabled=]<1|0> [,freeze-fs=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]"},"format":{"enabled":{"default":0,"default_key":1,"description":"Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.","type":"boolean"},"freeze-fs":{"default":1,"description":"Freeze guest filesystems through QGA for consistent disk state on operations such as snapshots, backups, replications and clones.","optional":1,"type":"boolean","verbose_description":"Whether to issue the guest-fsfreeze-freeze and guest-fsfreeze-thaw QEMU guest agent commands. Backups in snapshot mode, clones, snapshots without RAM, importing disks from a running guest, and replications normally issue a guest-fsfreeze-freeze and a respective thaw command when the QEMU Guest agent option is enabled in the guest's configuration and the agent is running inside of the guest.\n\nThe deprecated 'freeze-fs-on-backup' setting is treated as an alias for this setting."},"freeze-fs-on-backup":{"alias":"freeze-fs"},"fstrim_cloned_disks":{"default":0,"description":"Run fstrim after moving a disk or migrating the VM.","optional":1,"type":"boolean"},"guest-fsfreeze":{"alias":"freeze-fs"},"type":{"default":"virtio","description":"Select the agent type","enum":["virtio","isa"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"agent"},{"definition":{"default":1,"description":"Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"allow-ksm"},{"definition":{"description":"Secure Encrypted Virtualization (SEV) features by AMD CPUs","enum":[],"extra":{"typetext":"[type=] [,allow-smt=<1|0>] [,kernel-hashes=<1|0>] [,no-debug=<1|0>] [,no-key-sharing=<1|0>]"},"format":"pve-qemu-sev-fmt","optional":true,"properties":{},"type":"string"},"name":"amd-sev"},{"definition":{"description":"Virtual processor architecture. Defaults to the host architecture.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"description":"Arbitrary arguments passed to kvm.","enum":[],"extra":{"typetext":"","verbose_description":"Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -smbios 'type=0,vendor=FOO'\n\nNOTE: this option is for experts only.\n"},"optional":true,"properties":{},"type":"string"},"name":"args"},{"definition":{"description":"Configure a audio device, useful in combination with QXL/Spice.","enum":[],"extra":{"typetext":"device= [,driver=]"},"format":{"device":{"description":"Configure an audio device.","enum":["ich9-intel-hda","intel-hda","AC97"],"type":"string"},"driver":{"default":"spice","description":"Driver backend for the audio device.","enum":["spice","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"audio0"},{"definition":{"default":0,"description":"Automatic restart after crash (currently ignored).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Time to wait for the task to finish. We return 'null' if the task finish within that time.","enum":[],"extra":{"typetext":" (1 - 30)"},"maximum":30,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"background_delay"},{"definition":{"description":"Amount of target RAM for the VM in MiB. The balloon driver is enabled by default, unless it is explicitly disabled by setting the value to zero.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"balloon"},{"definition":{"default":"seabios","description":"Select BIOS implementation.","enum":["seabios","ovmf"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bios"},{"definition":{"description":"Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.","enum":[],"extra":{"typetext":"[[legacy=]<[acdn]{1,4}>] [,order=]"},"format":"pve-qm-boot","optional":true,"properties":{},"type":"string"},"name":"boot"},{"definition":{"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","enum":[],"extra":{},"format":"pve-qm-bootdisk","optional":true,"pattern":"(ide|sata|scsi|virtio)\\d+","properties":{},"type":"string"},"name":"bootdisk"},{"definition":{"description":"This is an alias for option -ide2","enum":[],"extra":{"typetext":""},"format":"pve-qm-ide","optional":true,"properties":{},"type":"string"},"name":"cdrom"},{"definition":{"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","enum":[],"extra":{"typetext":"[meta=] [,network=] [,user=] [,vendor=]"},"format":"pve-qm-cicustom","optional":true,"properties":{},"type":"string"},"name":"cicustom"},{"definition":{"description":"cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cipassword"},{"definition":{"description":"Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.","enum":["configdrive2","nocloud","opennebula"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"citype"},{"definition":{"default":1,"description":"cloud-init: do an automatic package upgrade after the first boot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ciupgrade"},{"definition":{"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ciuser"},{"definition":{"default":1,"description":"The number of cores per socket.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"description":"Emulated CPU type.","enum":[],"extra":{"typetext":"[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,guest-phys-bits=] [,hidden=<1|0>] [,hv-vendor-id=] [,level=] [,phys-bits=<8-64|host>] [,reported-model=]"},"format":"pve-vm-cpu-conf","optional":true,"properties":{},"type":"string"},"name":"cpu"},{"definition":{"default":0,"description":"Limit of CPU usage.","enum":[],"extra":{"typetext":" (0 - 128)","verbose_description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit."},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"typetext":" (1 - 262144)","verbose_description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs."},"maximum":262144,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":8192,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,ms-cert=] [,pre-enrolled-keys=<1|0>] [,size=]"},"format":{"efitype":{"default":"2m","description":"Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarch64 (ARM).","enum":["2m","4m"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"ms-cert":{"default":"2011","description":"Informational marker indicating the version of the latest Microsoft UEFI certificates that have been enrolled by Proxmox VE. The value '2023k' means that the 'Microsoft UEFI CA 2023', the 'Windows UEFI CA 2023' and the 'Microsoft Corporation KEK 2K CA 2023' certificates are included. The values '2023' and '2023w' are deprecated and for compatibility only.","enum":["2011","2023","2023w","2023k"],"optional":1,"type":"string"},"pre-enrolled-keys":{"default":0,"description":"Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.","optional":1,"type":"boolean"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"efidisk0"},{"definition":{"description":"Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.","enum":[],"extra":{"requires":"delete","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Freeze CPU at startup (use 'c' monitor command to start execution).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"freeze"},{"definition":{"description":"Script that will be executed during various steps in the vms lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Map host PCI devices into guest.","enum":[],"extra":{"typetext":"[[host=]] [,device-id=] [,driver=] [,legacy-igd=<1|0>] [,mapping=] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]","verbose_description":"Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"format":"pve-qm-hostpci","optional":true,"properties":{},"type":"string"},"name":"hostpci[n]"},{"definition":{"default":"network,disk,usb","description":"Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.","enum":[],"extra":{"typetext":""},"format":"pve-hotplug-features","optional":true,"properties":{},"type":"string"},"name":"hotplug"},{"definition":{"description":"Enables hugepages memory.\n\nSets the size of hugepages in MiB. If the value is set to 'any' then 1 GiB hugepages will be used if possible, otherwise the size will fall back to 2 MiB.","enum":["any","2","1024"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"hugepages"},{"definition":{"description":"Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"model":{"description":"The drive's reported model name, url-encoded, up to 40 bytes long.","format":"urlencoded","format_description":"model","maxLength":120,"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"ide[n]"},{"definition":{"description":"A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"import-working-storage"},{"definition":{"description":"Trusted Domain Extension (TDX) features by Intel CPUs","enum":[],"extra":{"typetext":"[type=] ,attestation=<1|0> [,vsock-cid=] [,vsock-port=]"},"format":"pve-qemu-tdx-fmt","optional":true,"properties":{},"type":"string"},"name":"intel-tdx"},{"definition":{"description":"cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n","enum":[],"extra":{"typetext":"[gw=] [,gw6=] [,ip=] [,ip6=]"},"format":"pve-qm-ipconfig","optional":true,"properties":{},"type":"string"},"name":"ipconfig[n]"},{"definition":{"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host.","enum":[],"extra":{"typetext":"size= [,name=]"},"format":{"name":{"description":"The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.","format_description":"string","optional":1,"pattern":"[a-zA-Z0-9\\-]+","type":"string"},"size":{"description":"The size of the file in MB.","minimum":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"ivshmem"},{"definition":{"default":0,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keephugepages"},{"definition":{"description":"Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"keyboard"},{"definition":{"default":1,"description":"Enable/disable KVM hardware virtualization.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"kvm"},{"definition":{"description":"Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"localtime"},{"definition":{"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"description":"Specify the QEMU machine.","enum":[],"extra":{"typetext":"[[type=]] [,aw-bits=] [,enable-s3=<1|0>] [,enable-s4=<1|0>] [,viommu=]"},"format":{"aw-bits":{"description":"Specifies the vIOMMU address space bit width.","maximum":64,"minimum":32,"optional":1,"type":"number","verbose_description":"Specifies the vIOMMU address space bit width.\n\nIntel vIOMMU supports a bit width of either 39 or 48 bits and VirtIO vIOMMU supports any bit width between 32 and 64 bits."},"enable-s3":{"description":"Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"enable-s4":{"description":"Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"type":{"default_key":1,"description":"Specifies the QEMU machine type.","format_description":"machine type","maxLength":40,"optional":1,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","type":"string"},"viommu":{"description":"Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).","enum":["intel","virtio"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"machine"},{"definition":{"description":"Memory properties.","enum":[],"extra":{"typetext":"[current=]"},"format":{"current":{"default":512,"default_key":1,"description":"Current amount of online RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.","minimum":16,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"memory"},{"definition":{"default":0.1,"description":"Set maximum tolerated downtime (in seconds) for migrations. Should the migration not be able to converge in the very end, because too much newly dirtied RAM needs to be transferred, the limit will be increased automatically step-by-step until migration can converge. Will be capped to 2000 seconds (maximum in QEMU).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"migrate_downtime"},{"definition":{"default":0,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"migrate_speed"},{"definition":{"description":"Set a name for the VM. Only used on the configuration web interface.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"format":"address-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specify network devices.","enum":[],"extra":{"typetext":"[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]"},"format":{"bridge":{"description":"Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n","format":"pve-bridge-id","format_description":"bridge","optional":1,"type":"string"},"e1000":{"alias":"macaddr","keyAlias":"model"},"e1000-82540em":{"alias":"macaddr","keyAlias":"model"},"e1000-82544gc":{"alias":"macaddr","keyAlias":"model"},"e1000-82545em":{"alias":"macaddr","keyAlias":"model"},"e1000e":{"alias":"macaddr","keyAlias":"model"},"firewall":{"description":"Whether this interface should be protected by the firewall.","optional":1,"type":"boolean"},"i82551":{"alias":"macaddr","keyAlias":"model"},"i82557b":{"alias":"macaddr","keyAlias":"model"},"i82559er":{"alias":"macaddr","keyAlias":"model"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"macaddr":{"description":"MAC address. That address must be unique within your network. This is automatically generated if not specified.","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"model":{"default_key":1,"description":"Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.","enum":["e1000","e1000-82540em","e1000-82544gc","e1000-82545em","e1000e","i82551","i82557b","i82559er","ne2k_isa","ne2k_pci","pcnet","rtl8139","virtio","vmxnet3"],"type":"string"},"mtu":{"description":"Force MTU of network device (VirtIO only). Setting to '1' or empty will use the bridge MTU","maximum":65520,"minimum":1,"optional":1,"type":"integer"},"ne2k_isa":{"alias":"macaddr","keyAlias":"model"},"ne2k_pci":{"alias":"macaddr","keyAlias":"model"},"pcnet":{"alias":"macaddr","keyAlias":"model"},"queues":{"description":"Number of packet queues to be used on the device.","maximum":64,"minimum":0,"optional":1,"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":0,"optional":1,"type":"number"},"rtl8139":{"alias":"macaddr","keyAlias":"model"},"tag":{"description":"VLAN tag to apply to packets on this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN trunks to pass through this interface.","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"virtio":{"alias":"macaddr","keyAlias":"model"},"vmxnet3":{"alias":"macaddr","keyAlias":"model"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Enable/disable NUMA.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"numa"},{"definition":{"description":"NUMA topology.","enum":[],"extra":{"typetext":"cpus= [,hostnodes=] [,memory=] [,policy=]"},"format":{"cpus":{"description":"CPUs accessing this NUMA node.","format_description":"id[-id];...","pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"hostnodes":{"description":"Host NUMA nodes to use.","format_description":"id[-id];...","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"memory":{"description":"Amount of memory this NUMA node provides.","optional":1,"type":"number"},"policy":{"description":"NUMA allocation policy.","enum":["preferred","bind","interleave"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"numa[n]"},{"definition":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"default":"other","description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","win11","l24","l26","solaris"],"extra":{"verbose_description":"Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022/2025\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 7.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n"},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"description":"Map host parallel devices (n is 0 to 2).","enum":[],"extra":{"verbose_description":"Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"/dev/parport\\d+|/dev/usb/lp\\d+","properties":{},"type":"string"},"name":"parallel[n]"},{"definition":{"default":0,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"default":1,"description":"Allow reboot. If set to '0' the VM exit on reboot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"reboot"},{"definition":{"description":"Revert a pending change.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"revert"},{"definition":{"description":"Configure a VirtIO-based Random Number Generator.","enum":[],"extra":{"typetext":"[source=] [,max_bytes=] [,period=]"},"format":"pve-qm-rng","optional":true,"properties":{},"type":"string"},"name":"rng0"},{"definition":{"description":"Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"sata[n]"},{"definition":{"description":"Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,product=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,vendor=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"product":{"description":"The drive's product name, up to 16 bytes long.","format_description":"product","optional":1,"pattern":"[A-Za-z0-9\\-_\\s]{,16}","type":"string"},"queues":{"description":"Number of queues.","minimum":2,"optional":1,"type":"integer"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"scsiblock":{"default":0,"description":"whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host","optional":1,"type":"boolean"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"vendor":{"description":"The drive's vendor name, up to 8 bytes long.","format_description":"vendor","optional":1,"pattern":"[A-Za-z0-9\\-_\\s]{,8}","type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"scsi[n]"},{"definition":{"default":"lsi","description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scsihw"},{"definition":{"description":"cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Create a serial device inside the VM (n is 0 to 3)","enum":[],"extra":{"verbose_description":"Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"(/dev/[^,]+|socket)","properties":{},"type":"string"},"name":"serial[n]"},{"definition":{"default":1000,"description":"Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.","enum":[],"extra":{"typetext":" (0 - 50000)"},"maximum":50000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"shares"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Specify SMBIOS type 1 fields.","enum":[],"extra":{"typetext":"[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]"},"format":"pve-qm-smbios1","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"smbios1"},{"definition":{"default":1,"description":"The number of CPUs. Please use option -sockets instead.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"smp"},{"definition":{"default":1,"description":"The number of CPU sockets.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"sockets"},{"definition":{"description":"Configure additional enhancements for SPICE.","enum":[],"extra":{"typetext":"[foldersharing=<1|0>] [,videostreaming=]"},"format":{"foldersharing":{"default":"0","description":"Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.","optional":1,"type":"boolean"},"videostreaming":{"default":"off","description":"Enable video streaming. Uses compression for detected video streams.","enum":["off","all","filter"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"spice_enhancements"},{"definition":{"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{"typetext":""},"format":"urlencoded","optional":true,"properties":{},"type":"string"},"name":"sshkeys"},{"definition":{"default":"now","description":"Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.","enum":[],"extra":{"typetext":"(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)"},"optional":true,"pattern":"(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)","properties":{},"type":"string"},"name":"startdate"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"default":1,"description":"Enable/disable the USB tablet device.","enum":[],"extra":{"typetext":"","verbose_description":"Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)."},"optional":true,"properties":{},"type":"boolean"},"name":"tablet"},{"definition":{"description":"Tags of the VM. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable time drift fix.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tdf"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,format=] [,import-from=] [,size=] [,version=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"Format of the image.","enum":["raw","qcow2","vmdk"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"version":{"default":"v1.2","description":"The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.","enum":["v1.2","v2.0"],"optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"tpmstate0"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[file=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id","format_description":"volume","type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).","enum":[],"extra":{"typetext":"[[host=]] [,mapping=] [,usb3=<1|0>]"},"format":{"host":{"default_key":1,"description":"The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadecimal numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n\nEither this or the 'mapping' key must be set.\n","format_description":"HOSTUSBDEVICE|spice","optional":1,"pattern":"(?^:(?:(?:(?^:(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})))|(?:(?^:(\\d+)\\-(\\d+(\\.\\d+)*)))|[Ss][Pp][Ii][Cc][Ee]))","type":"string"},"mapping":{"description":"The ID of a cluster wide mapping. Either this or the default-key 'host' must be set.","format":"pve-configid","format_description":"mapping-id","optional":1,"type":"string"},"usb3":{"default":0,"description":"Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"usb[n]"},{"definition":{"default":0,"description":"Number of hotplugged vcpus.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vcpus"},{"definition":{"description":"Configure the VGA hardware.","enum":[],"extra":{"typetext":"[[type=]] [,clipboard=] [,memory=]","verbose_description":"Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal."},"format":{"clipboard":{"description":"Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Live migration with a VNC clipboard is not possible with QEMU machine version < 10.1.","enum":["vnc"],"optional":1,"type":"string"},"memory":{"description":"Sets the VGA memory (in MiB). Has no effect with serial display.","maximum":512,"minimum":4,"optional":1,"type":"integer"},"type":{"default":"std","default_key":1,"description":"Select the VGA type. Using type 'cirrus' is not recommended.","enum":["cirrus","qxl","qxl2","qxl3","qxl4","none","serial0","serial1","serial2","serial3","std","virtio","virtio-gl","vmware"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"vga"},{"definition":{"description":"Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,werror=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"virtio[n]"},{"definition":{"description":"Configuration for sharing a directory between host and guest using Virtio-fs.","enum":[],"extra":{"typetext":"[dirid=] [,cache=] [,direct-io=<1|0>] [,expose-acl=<1|0>] [,expose-xattr=<1|0>]"},"format":{"cache":{"default":"auto","description":"The caching policy the file system should use (auto, always, metadata, never).","enum":["auto","always","metadata","never"],"optional":1,"type":"string"},"direct-io":{"default":0,"description":"Honor the O_DIRECT flag passed down by guest applications.","optional":1,"type":"boolean"},"dirid":{"default_key":1,"description":"Mapping identifier of the directory mapping to be shared with the guest. Also used as a mount tag inside the VM.","format":"pve-configid","format_description":"mapping-id","type":"string"},"expose-acl":{"default":0,"description":"Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.","optional":1,"type":"boolean"},"expose-xattr":{"default":0,"description":"Enable support for extended attributes for this mount.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"virtiofs[n]"},{"definition":{"default":"1 (autogenerated)","description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","enum":[],"extra":{"format_description":"UUID","verbose_description":"The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file."},"optional":true,"pattern":"(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])","properties":{},"type":"string"},"name":"vmgenid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Default storage for VM state volumes/files.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"vmstatestorage"},{"definition":{"description":"Create a virtual hardware watchdog device.","enum":[],"extra":{"typetext":"[[model=]] [,action=]","verbose_description":"Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)"},"format":"pve-qm-watchdog","optional":true,"properties":{},"type":"string"},"name":"watchdog"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk","VM.Config.CDROM","VM.Config.CPU","VM.Config.Memory","VM.Config.Network","VM.Config.HWType","VM.Config.Options","VM.Config.Cloudinit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"verb":"POST"},{"allow_token":true,"checksum":"abb7085fd4e2612e57bb77626965e24d2e3f63e1f7b0d3b0051308461c7cf193","description":"Set virtual machine options (synchronous API) - You should consider using the POST method instead for any actions involving hotplug or storage allocation.","extra":{"proxyto":"node"},"name":"update_vm","parameters":[{"definition":{"default":1,"description":"Enable/disable ACPI.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"acpi"},{"definition":{"description":"List of host cores used to execute guest processes, for example: 0,5,8-11","enum":[],"extra":{"typetext":""},"format":"pve-cpuset","optional":true,"properties":{},"type":"string"},"name":"affinity"},{"definition":{"description":"Enable/disable communication with the QEMU Guest Agent and its properties.","enum":[],"extra":{"typetext":"[enabled=]<1|0> [,freeze-fs=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]"},"format":{"enabled":{"default":0,"default_key":1,"description":"Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.","type":"boolean"},"freeze-fs":{"default":1,"description":"Freeze guest filesystems through QGA for consistent disk state on operations such as snapshots, backups, replications and clones.","optional":1,"type":"boolean","verbose_description":"Whether to issue the guest-fsfreeze-freeze and guest-fsfreeze-thaw QEMU guest agent commands. Backups in snapshot mode, clones, snapshots without RAM, importing disks from a running guest, and replications normally issue a guest-fsfreeze-freeze and a respective thaw command when the QEMU Guest agent option is enabled in the guest's configuration and the agent is running inside of the guest.\n\nThe deprecated 'freeze-fs-on-backup' setting is treated as an alias for this setting."},"freeze-fs-on-backup":{"alias":"freeze-fs"},"fstrim_cloned_disks":{"default":0,"description":"Run fstrim after moving a disk or migrating the VM.","optional":1,"type":"boolean"},"guest-fsfreeze":{"alias":"freeze-fs"},"type":{"default":"virtio","description":"Select the agent type","enum":["virtio","isa"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"agent"},{"definition":{"default":1,"description":"Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"allow-ksm"},{"definition":{"description":"Secure Encrypted Virtualization (SEV) features by AMD CPUs","enum":[],"extra":{"typetext":"[type=] [,allow-smt=<1|0>] [,kernel-hashes=<1|0>] [,no-debug=<1|0>] [,no-key-sharing=<1|0>]"},"format":"pve-qemu-sev-fmt","optional":true,"properties":{},"type":"string"},"name":"amd-sev"},{"definition":{"description":"Virtual processor architecture. Defaults to the host architecture.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"description":"Arbitrary arguments passed to kvm.","enum":[],"extra":{"typetext":"","verbose_description":"Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -smbios 'type=0,vendor=FOO'\n\nNOTE: this option is for experts only.\n"},"optional":true,"properties":{},"type":"string"},"name":"args"},{"definition":{"description":"Configure a audio device, useful in combination with QXL/Spice.","enum":[],"extra":{"typetext":"device= [,driver=]"},"format":{"device":{"description":"Configure an audio device.","enum":["ich9-intel-hda","intel-hda","AC97"],"type":"string"},"driver":{"default":"spice","description":"Driver backend for the audio device.","enum":["spice","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"audio0"},{"definition":{"default":0,"description":"Automatic restart after crash (currently ignored).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Amount of target RAM for the VM in MiB. The balloon driver is enabled by default, unless it is explicitly disabled by setting the value to zero.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"balloon"},{"definition":{"default":"seabios","description":"Select BIOS implementation.","enum":["seabios","ovmf"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bios"},{"definition":{"description":"Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.","enum":[],"extra":{"typetext":"[[legacy=]<[acdn]{1,4}>] [,order=]"},"format":"pve-qm-boot","optional":true,"properties":{},"type":"string"},"name":"boot"},{"definition":{"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","enum":[],"extra":{},"format":"pve-qm-bootdisk","optional":true,"pattern":"(ide|sata|scsi|virtio)\\d+","properties":{},"type":"string"},"name":"bootdisk"},{"definition":{"description":"This is an alias for option -ide2","enum":[],"extra":{"typetext":""},"format":"pve-qm-ide","optional":true,"properties":{},"type":"string"},"name":"cdrom"},{"definition":{"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","enum":[],"extra":{"typetext":"[meta=] [,network=] [,user=] [,vendor=]"},"format":"pve-qm-cicustom","optional":true,"properties":{},"type":"string"},"name":"cicustom"},{"definition":{"description":"cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cipassword"},{"definition":{"description":"Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.","enum":["configdrive2","nocloud","opennebula"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"citype"},{"definition":{"default":1,"description":"cloud-init: do an automatic package upgrade after the first boot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ciupgrade"},{"definition":{"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ciuser"},{"definition":{"default":1,"description":"The number of cores per socket.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"description":"Emulated CPU type.","enum":[],"extra":{"typetext":"[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,guest-phys-bits=] [,hidden=<1|0>] [,hv-vendor-id=] [,level=] [,phys-bits=<8-64|host>] [,reported-model=]"},"format":"pve-vm-cpu-conf","optional":true,"properties":{},"type":"string"},"name":"cpu"},{"definition":{"default":0,"description":"Limit of CPU usage.","enum":[],"extra":{"typetext":" (0 - 128)","verbose_description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit."},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"typetext":" (1 - 262144)","verbose_description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs."},"maximum":262144,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":8192,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,ms-cert=] [,pre-enrolled-keys=<1|0>] [,size=]"},"format":{"efitype":{"default":"2m","description":"Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarch64 (ARM).","enum":["2m","4m"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"ms-cert":{"default":"2011","description":"Informational marker indicating the version of the latest Microsoft UEFI certificates that have been enrolled by Proxmox VE. The value '2023k' means that the 'Microsoft UEFI CA 2023', the 'Windows UEFI CA 2023' and the 'Microsoft Corporation KEK 2K CA 2023' certificates are included. The values '2023' and '2023w' are deprecated and for compatibility only.","enum":["2011","2023","2023w","2023k"],"optional":1,"type":"string"},"pre-enrolled-keys":{"default":0,"description":"Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.","optional":1,"type":"boolean"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"efidisk0"},{"definition":{"description":"Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.","enum":[],"extra":{"requires":"delete","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Freeze CPU at startup (use 'c' monitor command to start execution).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"freeze"},{"definition":{"description":"Script that will be executed during various steps in the vms lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Map host PCI devices into guest.","enum":[],"extra":{"typetext":"[[host=]] [,device-id=] [,driver=] [,legacy-igd=<1|0>] [,mapping=] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]","verbose_description":"Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"format":"pve-qm-hostpci","optional":true,"properties":{},"type":"string"},"name":"hostpci[n]"},{"definition":{"default":"network,disk,usb","description":"Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.","enum":[],"extra":{"typetext":""},"format":"pve-hotplug-features","optional":true,"properties":{},"type":"string"},"name":"hotplug"},{"definition":{"description":"Enables hugepages memory.\n\nSets the size of hugepages in MiB. If the value is set to 'any' then 1 GiB hugepages will be used if possible, otherwise the size will fall back to 2 MiB.","enum":["any","2","1024"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"hugepages"},{"definition":{"description":"Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"model":{"description":"The drive's reported model name, url-encoded, up to 40 bytes long.","format":"urlencoded","format_description":"model","maxLength":120,"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"ide[n]"},{"definition":{"description":"Trusted Domain Extension (TDX) features by Intel CPUs","enum":[],"extra":{"typetext":"[type=] ,attestation=<1|0> [,vsock-cid=] [,vsock-port=]"},"format":"pve-qemu-tdx-fmt","optional":true,"properties":{},"type":"string"},"name":"intel-tdx"},{"definition":{"description":"cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n","enum":[],"extra":{"typetext":"[gw=] [,gw6=] [,ip=] [,ip6=]"},"format":"pve-qm-ipconfig","optional":true,"properties":{},"type":"string"},"name":"ipconfig[n]"},{"definition":{"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host.","enum":[],"extra":{"typetext":"size= [,name=]"},"format":{"name":{"description":"The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.","format_description":"string","optional":1,"pattern":"[a-zA-Z0-9\\-]+","type":"string"},"size":{"description":"The size of the file in MB.","minimum":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"ivshmem"},{"definition":{"default":0,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keephugepages"},{"definition":{"description":"Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"keyboard"},{"definition":{"default":1,"description":"Enable/disable KVM hardware virtualization.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"kvm"},{"definition":{"description":"Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"localtime"},{"definition":{"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"description":"Specify the QEMU machine.","enum":[],"extra":{"typetext":"[[type=]] [,aw-bits=] [,enable-s3=<1|0>] [,enable-s4=<1|0>] [,viommu=]"},"format":{"aw-bits":{"description":"Specifies the vIOMMU address space bit width.","maximum":64,"minimum":32,"optional":1,"type":"number","verbose_description":"Specifies the vIOMMU address space bit width.\n\nIntel vIOMMU supports a bit width of either 39 or 48 bits and VirtIO vIOMMU supports any bit width between 32 and 64 bits."},"enable-s3":{"description":"Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"enable-s4":{"description":"Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"type":{"default_key":1,"description":"Specifies the QEMU machine type.","format_description":"machine type","maxLength":40,"optional":1,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","type":"string"},"viommu":{"description":"Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).","enum":["intel","virtio"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"machine"},{"definition":{"description":"Memory properties.","enum":[],"extra":{"typetext":"[current=]"},"format":{"current":{"default":512,"default_key":1,"description":"Current amount of online RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.","minimum":16,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"memory"},{"definition":{"default":0.1,"description":"Set maximum tolerated downtime (in seconds) for migrations. Should the migration not be able to converge in the very end, because too much newly dirtied RAM needs to be transferred, the limit will be increased automatically step-by-step until migration can converge. Will be capped to 2000 seconds (maximum in QEMU).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"migrate_downtime"},{"definition":{"default":0,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"migrate_speed"},{"definition":{"description":"Set a name for the VM. Only used on the configuration web interface.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"format":"address-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specify network devices.","enum":[],"extra":{"typetext":"[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]"},"format":{"bridge":{"description":"Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n","format":"pve-bridge-id","format_description":"bridge","optional":1,"type":"string"},"e1000":{"alias":"macaddr","keyAlias":"model"},"e1000-82540em":{"alias":"macaddr","keyAlias":"model"},"e1000-82544gc":{"alias":"macaddr","keyAlias":"model"},"e1000-82545em":{"alias":"macaddr","keyAlias":"model"},"e1000e":{"alias":"macaddr","keyAlias":"model"},"firewall":{"description":"Whether this interface should be protected by the firewall.","optional":1,"type":"boolean"},"i82551":{"alias":"macaddr","keyAlias":"model"},"i82557b":{"alias":"macaddr","keyAlias":"model"},"i82559er":{"alias":"macaddr","keyAlias":"model"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"macaddr":{"description":"MAC address. That address must be unique within your network. This is automatically generated if not specified.","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"model":{"default_key":1,"description":"Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.","enum":["e1000","e1000-82540em","e1000-82544gc","e1000-82545em","e1000e","i82551","i82557b","i82559er","ne2k_isa","ne2k_pci","pcnet","rtl8139","virtio","vmxnet3"],"type":"string"},"mtu":{"description":"Force MTU of network device (VirtIO only). Setting to '1' or empty will use the bridge MTU","maximum":65520,"minimum":1,"optional":1,"type":"integer"},"ne2k_isa":{"alias":"macaddr","keyAlias":"model"},"ne2k_pci":{"alias":"macaddr","keyAlias":"model"},"pcnet":{"alias":"macaddr","keyAlias":"model"},"queues":{"description":"Number of packet queues to be used on the device.","maximum":64,"minimum":0,"optional":1,"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":0,"optional":1,"type":"number"},"rtl8139":{"alias":"macaddr","keyAlias":"model"},"tag":{"description":"VLAN tag to apply to packets on this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN trunks to pass through this interface.","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"virtio":{"alias":"macaddr","keyAlias":"model"},"vmxnet3":{"alias":"macaddr","keyAlias":"model"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Enable/disable NUMA.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"numa"},{"definition":{"description":"NUMA topology.","enum":[],"extra":{"typetext":"cpus= [,hostnodes=] [,memory=] [,policy=]"},"format":{"cpus":{"description":"CPUs accessing this NUMA node.","format_description":"id[-id];...","pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"hostnodes":{"description":"Host NUMA nodes to use.","format_description":"id[-id];...","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"memory":{"description":"Amount of memory this NUMA node provides.","optional":1,"type":"number"},"policy":{"description":"NUMA allocation policy.","enum":["preferred","bind","interleave"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"numa[n]"},{"definition":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"default":"other","description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","win11","l24","l26","solaris"],"extra":{"verbose_description":"Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022/2025\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 7.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n"},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"description":"Map host parallel devices (n is 0 to 2).","enum":[],"extra":{"verbose_description":"Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"/dev/parport\\d+|/dev/usb/lp\\d+","properties":{},"type":"string"},"name":"parallel[n]"},{"definition":{"default":0,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"default":1,"description":"Allow reboot. If set to '0' the VM exit on reboot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"reboot"},{"definition":{"description":"Revert a pending change.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"revert"},{"definition":{"description":"Configure a VirtIO-based Random Number Generator.","enum":[],"extra":{"typetext":"[source=] [,max_bytes=] [,period=]"},"format":"pve-qm-rng","optional":true,"properties":{},"type":"string"},"name":"rng0"},{"definition":{"description":"Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"sata[n]"},{"definition":{"description":"Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,product=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,vendor=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"product":{"description":"The drive's product name, up to 16 bytes long.","format_description":"product","optional":1,"pattern":"[A-Za-z0-9\\-_\\s]{,16}","type":"string"},"queues":{"description":"Number of queues.","minimum":2,"optional":1,"type":"integer"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"scsiblock":{"default":0,"description":"whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host","optional":1,"type":"boolean"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"vendor":{"description":"The drive's vendor name, up to 8 bytes long.","format_description":"vendor","optional":1,"pattern":"[A-Za-z0-9\\-_\\s]{,8}","type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"scsi[n]"},{"definition":{"default":"lsi","description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scsihw"},{"definition":{"description":"cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Create a serial device inside the VM (n is 0 to 3)","enum":[],"extra":{"verbose_description":"Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"(/dev/[^,]+|socket)","properties":{},"type":"string"},"name":"serial[n]"},{"definition":{"default":1000,"description":"Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.","enum":[],"extra":{"typetext":" (0 - 50000)"},"maximum":50000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"shares"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Specify SMBIOS type 1 fields.","enum":[],"extra":{"typetext":"[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]"},"format":"pve-qm-smbios1","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"smbios1"},{"definition":{"default":1,"description":"The number of CPUs. Please use option -sockets instead.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"smp"},{"definition":{"default":1,"description":"The number of CPU sockets.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"sockets"},{"definition":{"description":"Configure additional enhancements for SPICE.","enum":[],"extra":{"typetext":"[foldersharing=<1|0>] [,videostreaming=]"},"format":{"foldersharing":{"default":"0","description":"Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.","optional":1,"type":"boolean"},"videostreaming":{"default":"off","description":"Enable video streaming. Uses compression for detected video streams.","enum":["off","all","filter"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"spice_enhancements"},{"definition":{"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{"typetext":""},"format":"urlencoded","optional":true,"properties":{},"type":"string"},"name":"sshkeys"},{"definition":{"default":"now","description":"Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.","enum":[],"extra":{"typetext":"(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)"},"optional":true,"pattern":"(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)","properties":{},"type":"string"},"name":"startdate"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"default":1,"description":"Enable/disable the USB tablet device.","enum":[],"extra":{"typetext":"","verbose_description":"Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)."},"optional":true,"properties":{},"type":"boolean"},"name":"tablet"},{"definition":{"description":"Tags of the VM. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable time drift fix.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tdf"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,format=] [,import-from=] [,size=] [,version=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"Format of the image.","enum":["raw","qcow2","vmdk"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"version":{"default":"v1.2","description":"The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.","enum":["v1.2","v2.0"],"optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"tpmstate0"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[file=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id","format_description":"volume","type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).","enum":[],"extra":{"typetext":"[[host=]] [,mapping=] [,usb3=<1|0>]"},"format":{"host":{"default_key":1,"description":"The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadecimal numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n\nEither this or the 'mapping' key must be set.\n","format_description":"HOSTUSBDEVICE|spice","optional":1,"pattern":"(?^:(?:(?:(?^:(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})))|(?:(?^:(\\d+)\\-(\\d+(\\.\\d+)*)))|[Ss][Pp][Ii][Cc][Ee]))","type":"string"},"mapping":{"description":"The ID of a cluster wide mapping. Either this or the default-key 'host' must be set.","format":"pve-configid","format_description":"mapping-id","optional":1,"type":"string"},"usb3":{"default":0,"description":"Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"usb[n]"},{"definition":{"default":0,"description":"Number of hotplugged vcpus.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vcpus"},{"definition":{"description":"Configure the VGA hardware.","enum":[],"extra":{"typetext":"[[type=]] [,clipboard=] [,memory=]","verbose_description":"Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal."},"format":{"clipboard":{"description":"Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Live migration with a VNC clipboard is not possible with QEMU machine version < 10.1.","enum":["vnc"],"optional":1,"type":"string"},"memory":{"description":"Sets the VGA memory (in MiB). Has no effect with serial display.","maximum":512,"minimum":4,"optional":1,"type":"integer"},"type":{"default":"std","default_key":1,"description":"Select the VGA type. Using type 'cirrus' is not recommended.","enum":["cirrus","qxl","qxl2","qxl3","qxl4","none","serial0","serial1","serial2","serial3","std","virtio","virtio-gl","vmware"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"vga"},{"definition":{"description":"Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,werror=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"virtio[n]"},{"definition":{"description":"Configuration for sharing a directory between host and guest using Virtio-fs.","enum":[],"extra":{"typetext":"[dirid=] [,cache=] [,direct-io=<1|0>] [,expose-acl=<1|0>] [,expose-xattr=<1|0>]"},"format":{"cache":{"default":"auto","description":"The caching policy the file system should use (auto, always, metadata, never).","enum":["auto","always","metadata","never"],"optional":1,"type":"string"},"direct-io":{"default":0,"description":"Honor the O_DIRECT flag passed down by guest applications.","optional":1,"type":"boolean"},"dirid":{"default_key":1,"description":"Mapping identifier of the directory mapping to be shared with the guest. Also used as a mount tag inside the VM.","format":"pve-configid","format_description":"mapping-id","type":"string"},"expose-acl":{"default":0,"description":"Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.","optional":1,"type":"boolean"},"expose-xattr":{"default":0,"description":"Enable support for extended attributes for this mount.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"virtiofs[n]"},{"definition":{"default":"1 (autogenerated)","description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","enum":[],"extra":{"format_description":"UUID","verbose_description":"The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file."},"optional":true,"pattern":"(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])","properties":{},"type":"string"},"name":"vmgenid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Default storage for VM state volumes/files.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"vmstatestorage"},{"definition":{"description":"Create a virtual hardware watchdog device.","enum":[],"extra":{"typetext":"[[model=]] [,action=]","verbose_description":"Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)"},"format":"pve-qm-watchdog","optional":true,"properties":{},"type":"string"},"name":"watchdog"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk","VM.Config.CDROM","VM.Config.CPU","VM.Config.Memory","VM.Config.Network","VM.Config.HWType","VM.Config.Options","VM.Config.Cloudinit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"411c2659b7c93b4aefe6c9e9aa08dbf22b1302b90bb9b323674aef7f56460b49","description":"Control the dbus-vmstate helper for a given running VM.","extra":{"proxyto":"node"},"name":"dbus_vmstate","parameters":[{"definition":{"description":"Action to perform on the DBus VMState helper.","enum":["start","stop"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"action"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/dbus-vmstate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e46fb90f7815c5a4b54ba120dc3731ab19995905d1555869d89156ed48776592","description":"Check if feature for virtual machine is available.","extra":{"proxyto":"node"},"name":"vm_feature","parameters":[{"definition":{"description":"Feature to check.","enum":["snapshot","clone","copy"],"extra":{},"properties":{},"type":"string"},"name":"feature"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"hasFeature":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"nodes":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/feature"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7ee5be237c4406d406b763db7b1c3deb794543cfa9e5376476821ff4ad174512","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0e240eee88d783388fa7fd5c605d1946866c6de040a5072e91675a7d06594943","description":"List aliases","extra":{},"name":"get_aliases","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"24f08f4001bb83fb2a6d7e9a6a5d0c3692949ea94751c543f2ce056e43beeacb","description":"Create IP or Network Alias.","extra":{},"name":"create_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/aliases"},{"extra":{},"methods":[{"allow_token":true,"checksum":"547018a4e77e1f19d15e71017e8e7e7bdb3f893052f3a61c4ac77fe1a23a7524","description":"Remove IP or Network alias.","extra":{},"name":"remove_alias","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f5bce1f868d6f087fc556f605b8dba1dadf850207fb04bbddc999079cd9486b7","description":"Read alias.","extra":{},"name":"read_alias","parameters":[{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"1e344b0d51e8e531d0d525f26ebe09c01f6c4cf270e92c36ebe11eca2779dcee","description":"Update IP or Network alias.","extra":{},"name":"update_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Rename an existing alias.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"406378d5359b09bbd6589c105f8df2f99aeef8a54b526302377c06fe5401770e","description":"List IPSets","extra":{},"name":"ipset_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"name":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f4bb41ff25f7d50144a81944017055185c7a72e313a861f8a0406de6bf34ecf2","description":"Create new IPSet","extra":{},"name":"create_ipset","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/ipset"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a40e1badd168974a686fc466a2e06598ef9762be5b279a8f1fa0eca53f7d4880","description":"Delete IPSet","extra":{},"name":"delete_ipset","parameters":[{"definition":{"description":"Delete all members of the IPSet, if there are any.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"5fc76313da1679fa4a2631d95ce58eb8b267a2dd67a0c1a8ac5a55a0ab34b13c","description":"List IPSet content","extra":{},"name":"get_ipset","parameters":[{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cidr}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"nomatch":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"a3ace74f6557fc643406d7775bd8e6eb21c0200d079174ee43ee5a0fd24506c9","description":"Add IP or Network to IPSet.","extra":{},"name":"create_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5f612a84aecce1fd03bb87a7e7c15c6786474a3e211f958a0281c55c835eeebc","description":"Remove IP or Network from IPSet.","extra":{},"name":"remove_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"cae0afef06b37e0a88847c53e617e5a4def2d669bf4da3f4d541cdf1811046a4","description":"Read IP or Network settings from IPSet.","extra":{},"name":"read_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"bb0b6ded1cf4736fae405e8af7ccf92e10623473112c4bb7a73992fdb81b4a2f","description":"Update IP or Network settings","extra":{},"name":"update_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d6b7e9154ddc56bd6b0b9af8378442e873109fc13d420483930da8dafe5fad5c","description":"Read firewall log","extra":{"proxyto":"node"},"name":"log","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Display log since this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"since"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"Display log until this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"until"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"af723360b2a8cdd037ee749b5446fc9d46829aa3972c986d79b9db3fc63f81a7","description":"Get VM firewall options.","extra":{"proxyto":"node"},"name":"get_options","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"dhcp":{"default":0,"description":"Enable DHCP.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"enable":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ipfilter":{"description":"Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"log_level_in":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_level_out":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macfilter":{"default":1,"description":"Enable/disable MAC address filter.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ndp":{"default":1,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"policy_in":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"policy_out":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"radv":{"description":"Allow sending Router Advertisement.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"672ed666236dff83d18a26757f88e1de445eab5d3fa527aaab95ab786b18d2bc","description":"Set Firewall options.","extra":{"proxyto":"node"},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"default":0,"description":"Enable DHCP.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"dhcp"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ipfilter"},{"definition":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_in"},{"definition":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_out"},{"definition":{"default":1,"description":"Enable/disable MAC address filter.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"macfilter"},{"definition":{"default":1,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ndp"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_in"},{"definition":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_out"},{"definition":{"description":"Allow sending Router Advertisement.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"radv"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4d9b684dc2793a1badcd82adfe45cf304ab1efec63d4b53ff4ea0402242531d3","description":"Lists possible IPSet/Alias reference which are allowed in source/dest properties.","extra":{},"name":"refs","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list references of specified type.","enum":["alias","ipset"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"ref":{"enum":[],"extra":{},"properties":{},"type":"string"},"scope":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":["alias","ipset"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/refs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"15e058c129609079ad1251f5545083d4b251f67ce893b3a079ab5702eb86f2d1","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"action":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name","enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"description":"Descriptive comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"description":"Restrict packet destination address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"description":"Restrict TCP/UDP destination port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"description":"Flag to enable/disable a rule","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"description":"Network interface name. You have to use network configuration key names for VMs and containers","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"description":"IP version (4 or 6) - automatically determined from source/dest addresses","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"description":"Use predefined standard macro","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"description":"Rule position in the ruleset","enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"description":"Restrict packet source address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"description":"Restrict TCP/UDP source port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Rule type","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"8031675c54c1cfbf59734cd14ad9735f26d24b9a3960fb0a9e8420731f3d5e51","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"464d07111ad5ee01829e46153bd86a7a820949db1b9fb33ddc3144037e35f734","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"2b90c544e2fc6e225b3d30ed8334b496699e3c3c2ec9fe71215c8f912819ade8","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name","enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"description":"Descriptive comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"description":"Restrict packet destination address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"description":"Restrict TCP/UDP destination port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"description":"Flag to enable/disable a rule","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"description":"Network interface name. You have to use network configuration key names for VMs and containers","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"description":"IP version (4 or 6) - automatically determined from source/dest addresses","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"description":"Use predefined standard macro","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"description":"Rule position in the ruleset","enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"description":"Restrict packet source address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"description":"Restrict TCP/UDP source port","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Rule type","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"7f95e71affdc035175864e9fdc728419b98b26887f2b75d4e04ab52c8db841e4","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"da5b7d38d50c4003f2672376caa1655f644c2ab392c06efd24c3383ae638680b","description":"Get preconditions for migration.","extra":{"proxyto":"node"},"name":"migrate_vm_precondition","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"allowed_nodes":{"description":"List of nodes allowed for migration.","enum":[],"extra":{},"items":{"description":"An allowed node","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"dependent-ha-resources":{"description":"HA resources, which will be migrated to the same target node as the VM, because these are in positive affinity with the VM.","enum":[],"extra":{},"items":{"description":"The ':' resource IDs of a HA resource with a positive affinity rule to this VM.","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"has-dbus-vmstate":{"description":"Whether the VM host supports migrating additional VM state, such as conntrack entries.","enum":[],"extra":{},"properties":{},"type":"boolean"},"local_disks":{"description":"List local disks including CD-Rom, unused and not referenced disks","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"cdrom":{"description":"True if the disk is a cdrom.","enum":[],"extra":{},"properties":{},"type":"boolean"},"is_unused":{"description":"True if the disk is unused.","enum":[],"extra":{},"properties":{},"type":"boolean"},"size":{"description":"The size of the disk in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"volid":{"description":"The volid of the disk.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"local_resources":{"description":"List local resources (e.g. pci, usb) that block migration.","enum":[],"extra":{},"items":{"description":"A local resource","enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"mapped-resource-info":{"description":"Object of mapped resources with additional information such if they're live migratable.","enum":[],"extra":{},"properties":{},"type":"object"},"mapped-resources":{"description":"List of mapped resources e.g. pci, usb. Deprecated, use 'mapped-resource-info' instead.","enum":[],"extra":{},"items":{"description":"A mapped resource","enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"not_allowed_nodes":{"description":"List of not allowed nodes with additional information.","enum":[],"extra":{},"optional":true,"properties":{"blocking-ha-resources":{"description":"HA resources, which are blocking the VM from being migrated to the node.","enum":[],"extra":{},"items":{"description":"A blocking HA resource","enum":[],"extra":{},"properties":{"cause":{"description":"The reason why the HA resource is blocking the migration.","enum":["node-affinity","resource-affinity"],"extra":{},"properties":{},"type":"string"},"sid":{"description":"The blocking HA resource id","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"unavailable_storages":{"description":"A list of not available storages.","enum":[],"extra":{},"items":{"description":"A storage","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"running":{"description":"Determines if the VM is running.","enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"7d48d10b70f903fc5c7edb823c50d61f37d8a321392eb2f71c8fddae00f41d70","description":"Migrate virtual machine. Creates a new migration task.","extra":{"proxyto":"node"},"name":"migrate_vm","parameters":[{"definition":{"default":"migrate limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"Allow to migrate VMs which use local devices. Only root may use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"CIDR of the (sub) network that is used for migration.","enum":[],"extra":{"typetext":""},"format":"CIDR","optional":true,"properties":{},"type":"string"},"name":"migration_network"},{"definition":{"description":"Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.","enum":["secure","insecure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"migration_type"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use online/live migration if VM is running. Ignored if VM is stopped.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"online"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storage-pair-list","optional":true,"properties":{},"type":"string"},"name":"targetstorage"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"default":0,"description":"Whether to migrate conntrack entries for running VMs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"with-conntrack-state"},{"definition":{"description":"Enable live storage migration for local disk","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"with-local-disks"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9a8110d8839682696273b40716bf36be04eef63fda65084d370978052fa296e6","description":"Execute QEMU monitor commands.","extra":{"proxyto":"node"},"name":"monitor","parameters":[{"definition":{"description":"The monitor command.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"command"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"The following commands do not require any additional privilege: ?, help, info\n\nThe following commands require 'Sys.Modify': announce_self, backup_cancel, balloon, block_job_cancel, block_job_complete, block_job_pause, block_job_resume, block_job_set_speed, block_resize, block_set_io_throttle, boot_set, c, calc_dirty_rate, cancel_vcpu_dirty_limit, chardev-send-break, closefd, commit, cont, cpu, delvm, eject, exit_preconfig, expire_password, getfd, gpa2hpa, gpa2hva, gva2gpa, i, loadvm, log, migrate_cancel, migrate_continue, migrate_pause, migrate_set_capability, migrate_set_parameter, migrate_start_postcopy, mouse_button, mouse_move, mouse_set, one-insn-per-tb, p, print, q, qemu-io, qom-get, qom-list, quit, replay_break, replay_delete_break, replay_seek, ringbuf_read, ringbuf_write, s, savevm, sendkey, set_link, set_password, set_vcpu_dirty_limit, snapshot_blkdev_internal, snapshot_delete_blkdev_internal, stop, stopcapture, sum, sync-profile, system_powerdown, system_reset, system_wakeup, trace-event, x, x_colo_lost_heartbeat, xp\n\nThe following commands are root-only: backup, block_stream, change, chardev-add, chardev-change, chardev-remove, client_migrate_info, device_add, device_del, drive_add, drive_backup, drive_del, drive_mirror, dump-guest-memory, dumpdtb, gdbserver, hostfwd_add, hostfwd_remove, logfile, mce, memsave, migrate, migrate_incoming, migrate_recover, nbd_server_add, nbd_server_remove, nbd_server_start, nbd_server_stop, netdev_add, netdev_del, nmi, o, object_add, object_del, pcie_aer_inject_error, pmemsave, qom-set, savevm-end, savevm-start, screendump, snapshot_blkdev, watchdog_action, wavcapture, xen-event-inject, xen-event-list\n\nThe following commands are deprecated: stopcapture, wavcapture\n","expression":{"check":["perm","/vms/{vmid}",["Sys.Audit","Sys.Modify"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/monitor"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4a91f0d7d656d3d89604c6e683da51352f9389afa7aaaa77558586570ba5763f","description":"Move volume to different storage or to a different VM.","extra":{"proxyto":"node"},"name":"move_vm_disk","parameters":[{"definition":{"default":"move limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"default":0,"description":"Delete the original disk after successful copy. By default the original disk is kept as unused disk.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The disk you want to move.","enum":["ide0","ide1","ide2","ide3","scsi0","scsi1","scsi2","scsi3","scsi4","scsi5","scsi6","scsi7","scsi8","scsi9","scsi10","scsi11","scsi12","scsi13","scsi14","scsi15","scsi16","scsi17","scsi18","scsi19","scsi20","scsi21","scsi22","scsi23","scsi24","scsi25","scsi26","scsi27","scsi28","scsi29","scsi30","virtio0","virtio1","virtio2","virtio3","virtio4","virtio5","virtio6","virtio7","virtio8","virtio9","virtio10","virtio11","virtio12","virtio13","virtio14","virtio15","sata0","sata1","sata2","sata3","sata4","sata5","efidisk0","tpmstate0","unused0","unused1","unused2","unused3","unused4","unused5","unused6","unused7","unused8","unused9","unused10","unused11","unused12","unused13","unused14","unused15","unused16","unused17","unused18","unused19","unused20","unused21","unused22","unused23","unused24","unused25","unused26","unused27","unused28","unused29","unused30","unused31","unused32","unused33","unused34","unused35","unused36","unused37","unused38","unused39","unused40","unused41","unused42","unused43","unused44","unused45","unused46","unused47","unused48","unused49","unused50","unused51","unused52","unused53","unused54","unused55","unused56","unused57","unused58","unused59","unused60","unused61","unused62","unused63","unused64","unused65","unused66","unused67","unused68","unused69","unused70","unused71","unused72","unused73","unused74","unused75","unused76","unused77","unused78","unused79","unused80","unused81","unused82","unused83","unused84","unused85","unused86","unused87","unused88","unused89","unused90","unused91","unused92","unused93","unused94","unused95","unused96","unused97","unused98","unused99","unused100","unused101","unused102","unused103","unused104","unused105","unused106","unused107","unused108","unused109","unused110","unused111","unused112","unused113","unused114","unused115","unused116","unused117","unused118","unused119","unused120","unused121","unused122","unused123","unused124","unused125","unused126","unused127","unused128","unused129","unused130","unused131","unused132","unused133","unused134","unused135","unused136","unused137","unused138","unused139","unused140","unused141","unused142","unused143","unused144","unused145","unused146","unused147","unused148","unused149","unused150","unused151","unused152","unused153","unused154","unused155","unused156","unused157","unused158","unused159","unused160","unused161","unused162","unused163","unused164","unused165","unused166","unused167","unused168","unused169","unused170","unused171","unused172","unused173","unused174","unused175","unused176","unused177","unused178","unused179","unused180","unused181","unused182","unused183","unused184","unused185","unused186","unused187","unused188","unused189","unused190","unused191","unused192","unused193","unused194","unused195","unused196","unused197","unused198","unused199","unused200","unused201","unused202","unused203","unused204","unused205","unused206","unused207","unused208","unused209","unused210","unused211","unused212","unused213","unused214","unused215","unused216","unused217","unused218","unused219","unused220","unused221","unused222","unused223","unused224","unused225","unused226","unused227","unused228","unused229","unused230","unused231","unused232","unused233","unused234","unused235","unused236","unused237","unused238","unused239","unused240","unused241","unused242","unused243","unused244","unused245","unused246","unused247","unused248","unused249","unused250","unused251","unused252","unused253","unused254","unused255"],"extra":{},"properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"Target Format.","enum":["raw","qcow2","vmdk"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Prevent changes if the current config file of the target VM has a different SHA1 digest. This can be used to detect concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"target-digest"},{"definition":{"description":"The config key the disk will be moved to on the target VM (for example, ide0 or scsi1). Default is the source disk key.","enum":["ide0","ide1","ide2","ide3","scsi0","scsi1","scsi2","scsi3","scsi4","scsi5","scsi6","scsi7","scsi8","scsi9","scsi10","scsi11","scsi12","scsi13","scsi14","scsi15","scsi16","scsi17","scsi18","scsi19","scsi20","scsi21","scsi22","scsi23","scsi24","scsi25","scsi26","scsi27","scsi28","scsi29","scsi30","virtio0","virtio1","virtio2","virtio3","virtio4","virtio5","virtio6","virtio7","virtio8","virtio9","virtio10","virtio11","virtio12","virtio13","virtio14","virtio15","sata0","sata1","sata2","sata3","sata4","sata5","efidisk0","tpmstate0","unused0","unused1","unused2","unused3","unused4","unused5","unused6","unused7","unused8","unused9","unused10","unused11","unused12","unused13","unused14","unused15","unused16","unused17","unused18","unused19","unused20","unused21","unused22","unused23","unused24","unused25","unused26","unused27","unused28","unused29","unused30","unused31","unused32","unused33","unused34","unused35","unused36","unused37","unused38","unused39","unused40","unused41","unused42","unused43","unused44","unused45","unused46","unused47","unused48","unused49","unused50","unused51","unused52","unused53","unused54","unused55","unused56","unused57","unused58","unused59","unused60","unused61","unused62","unused63","unused64","unused65","unused66","unused67","unused68","unused69","unused70","unused71","unused72","unused73","unused74","unused75","unused76","unused77","unused78","unused79","unused80","unused81","unused82","unused83","unused84","unused85","unused86","unused87","unused88","unused89","unused90","unused91","unused92","unused93","unused94","unused95","unused96","unused97","unused98","unused99","unused100","unused101","unused102","unused103","unused104","unused105","unused106","unused107","unused108","unused109","unused110","unused111","unused112","unused113","unused114","unused115","unused116","unused117","unused118","unused119","unused120","unused121","unused122","unused123","unused124","unused125","unused126","unused127","unused128","unused129","unused130","unused131","unused132","unused133","unused134","unused135","unused136","unused137","unused138","unused139","unused140","unused141","unused142","unused143","unused144","unused145","unused146","unused147","unused148","unused149","unused150","unused151","unused152","unused153","unused154","unused155","unused156","unused157","unused158","unused159","unused160","unused161","unused162","unused163","unused164","unused165","unused166","unused167","unused168","unused169","unused170","unused171","unused172","unused173","unused174","unused175","unused176","unused177","unused178","unused179","unused180","unused181","unused182","unused183","unused184","unused185","unused186","unused187","unused188","unused189","unused190","unused191","unused192","unused193","unused194","unused195","unused196","unused197","unused198","unused199","unused200","unused201","unused202","unused203","unused204","unused205","unused206","unused207","unused208","unused209","unused210","unused211","unused212","unused213","unused214","unused215","unused216","unused217","unused218","unused219","unused220","unused221","unused222","unused223","unused224","unused225","unused226","unused227","unused228","unused229","unused230","unused231","unused232","unused233","unused234","unused235","unused236","unused237","unused238","unused239","unused240","unused241","unused242","unused243","unused244","unused245","unused246","unused247","unused248","unused249","unused250","unused251","unused252","unused253","unused254","unused255"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"target-disk"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"target-vmid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Config.Disk' permissions on /vms/{vmid}, and 'Datastore.AllocateSpace' permissions on the storage. To move a disk to another VM, you need the permissions on the target VM as well.","expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/move_disk"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1b0766e6b516ab7ddfdd5bfa201c2fbf4cb5e80b1e4da9003a00142d8b12360e","description":"Migration tunnel endpoint - only for internal use by VM migration.","extra":{},"name":"mtunnel","parameters":[{"definition":{"description":"List of network bridges to check availability. Will be checked again for actually used bridges during migration.","enum":[],"extra":{"typetext":""},"format":"pve-bridge-id-list","optional":true,"properties":{},"type":"string"},"name":"bridges"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"List of storages to check permission and availability. Will be checked again for all actually used storages during migration.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id-list","optional":true,"properties":{},"type":"string"},"name":"storages"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permissions on '/vms/{vmid}' and Sys.Incoming on '/'. Further permission checks happen during the actual migration.","expression":{"check":["and",["perm","/vms/{vmid}",["VM.Allocate"]],["perm","/",["Sys.Incoming"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"socket":{"enum":[],"extra":{},"properties":{},"type":"string"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/mtunnel"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5074d114941c7d6bcff687122305de9ba6fe8456c7b40ccc88b503ae5f07dd59","description":"Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration.","extra":{},"name":"mtunnelwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"unix socket to forward to","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"socket"},{"definition":{"description":"ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"ticket"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need to pass a ticket valid for the selected socket. Tickets can be created via the mtunnel API call, which will check permissions accordingly.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"socket":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/mtunnelwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b1d298cc9afb32d9b551dfc75531f6345ae64b9d7c9a89216a6ed693aaaff195","description":"Get the virtual machine configuration with both current and pending values.","extra":{"proxyto":"node"},"name":"vm_pending","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"delete":{"description":"Indicates a pending delete request if present and not 0. The value 2 indicates a force-delete request.","enum":[],"extra":{},"maximum":2,"minimum":0,"optional":true,"properties":{},"type":"integer"},"key":{"description":"Configuration option name.","enum":[],"extra":{},"properties":{},"type":"string"},"pending":{"description":"Pending value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"value":{"description":"Current value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/pending"},{"extra":{},"methods":[{"allow_token":true,"checksum":"07c2414abc8f0d7497305e98b12b9bcef5f5e7acd6686d51a772ff505244f535","description":"Migrate virtual machine to a remote cluster. Creates a new migration task. EXPERIMENTAL feature!","extra":{"proxyto":"node"},"name":"remote_migrate_vm","parameters":[{"definition":{"default":"migrate limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"default":0,"description":"Delete the original VM and related data after successful migration. By default the original VM is kept on the source cluster in a stopped state.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use online/live migration if VM is running. Ignored if VM is stopped.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"online"},{"definition":{"description":"Mapping from source to target bridges. Providing only a single bridge ID maps all source bridges to that bridge. Providing the special value '1' will map each source bridge to itself.","enum":[],"extra":{"typetext":""},"format":"bridge-pair-list","properties":{},"type":"string"},"name":"target-bridge"},{"definition":{"description":"Remote target endpoint","enum":[],"extra":{"typetext":"apitoken= ,host=
[,fingerprint=] [,port=]"},"format":"proxmox-remote","properties":{},"type":"string"},"name":"target-endpoint"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storage-pair-list","optional":false,"properties":{},"type":"string"},"name":"target-storage"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"target-vmid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/remote_migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"58d4860cf474784e8fbde34c0b8b950396e45b8d06b66833f07d75010d8b2f4a","description":"Extend volume size.","extra":{"proxyto":"node"},"name":"resize_vm","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The disk you want to resize.","enum":["ide0","ide1","ide2","ide3","scsi0","scsi1","scsi2","scsi3","scsi4","scsi5","scsi6","scsi7","scsi8","scsi9","scsi10","scsi11","scsi12","scsi13","scsi14","scsi15","scsi16","scsi17","scsi18","scsi19","scsi20","scsi21","scsi22","scsi23","scsi24","scsi25","scsi26","scsi27","scsi28","scsi29","scsi30","virtio0","virtio1","virtio2","virtio3","virtio4","virtio5","virtio6","virtio7","virtio8","virtio9","virtio10","virtio11","virtio12","virtio13","virtio14","virtio15","sata0","sata1","sata2","sata3","sata4","sata5","efidisk0","tpmstate0"],"extra":{},"properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The new size. With the `+` sign the value is added to the actual size of the volume and without it, the value is taken as an absolute one. Shrinking disk size is not supported.","enum":[],"extra":{},"pattern":"\\+?\\d+(\\.\\d+)?[KMGT]?","properties":{},"type":"string"},"name":"size"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/resize"},{"extra":{},"methods":[{"allow_token":true,"checksum":"76edba13c3870fdb403a8a46fd95c3033cf4aeecac012f3d822f9075a80aa729","description":"Read VM RRD statistics (returns PNG)","extra":{},"name":"rrd","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The list of datasources you want to display.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"ds"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/rrd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"708d135d9bf06d5aed00329691506df18a1ed11938257a15c87431dfc5b617f3","description":"Read VM RRD statistics","extra":{},"name":"rrddata","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/rrddata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b2f2f0cc7b858cbfe4870f1600fa6c7629a3f649f6bd9bd8a612d5d66e3e4424","description":"Send key event to virtual machine.","extra":{"proxyto":"node"},"name":"vm_sendkey","parameters":[{"definition":{"description":"The key (qemu monitor encoding).","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"key"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/sendkey"},{"extra":{},"methods":[{"allow_token":true,"checksum":"516df1fbcace02aca60a45bb75bb3ddcf9496f29f0d72107b79b93c5c4cfbd7e","description":"List all snapshots.","extra":{"proxyto":"node"},"name":"snapshot_list","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"description":{"description":"Snapshot description.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Snapshot identifier. Value 'current' identifies the current VM.","enum":[],"extra":{},"properties":{},"type":"string"},"parent":{"description":"Parent snapshot identifier.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"snaptime":{"description":"Snapshot creation time","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"vmstate":{"description":"Snapshot includes RAM.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"1b31c240c6005572df666a4955380aeea50707ff3f3d84736d7d500d82d1a847","description":"Snapshot a VM.","extra":{"proxyto":"node"},"name":"snapshot","parameters":[{"definition":{"description":"A textual description or comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Save the vmstate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"vmstate"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/snapshot"},{"extra":{},"methods":[{"allow_token":true,"checksum":"af2c83c0a994a51bc20120133f51f0e154e3b81bf203e73b5e3952f094470d67","description":"Delete a VM snapshot.","extra":{"proxyto":"node"},"name":"delsnapshot","parameters":[{"definition":{"description":"For removal from config file, even if removing disk snapshots fails.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"832c5b9a025e005606202e4c83d793ce08937ecc33dfcd397a7fef121e0b5411","description":"","extra":{},"name":"snapshot_cmd_idx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cmd}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"65e5a768abb44d154e1140615379246ed5399a3dc43425f8e51baa6c7fbd75af","description":"Get snapshot configuration","extra":{"proxyto":"node"},"name":"get_snapshot_config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback","VM.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"281a4f10e550455fd4dd289251fc1fe0ecb359e2777227df294a67d67a5fa13b","description":"Update snapshot metadata.","extra":{"proxyto":"node"},"name":"update_snapshot_config","parameters":[{"definition":{"description":"A textual description or comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c343ddb104f76a6e634b68829860eb0867ffb5ab1905319105d06052fb1da4c5","description":"Rollback VM state to specified snapshot.","extra":{"proxyto":"node"},"name":"rollback","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"default":0,"description":"Whether the VM should get started after rolling back successfully. (Note: VMs will be automatically started if the snapshot includes RAM.)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"start"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback"},{"extra":{},"methods":[{"allow_token":true,"checksum":"287de2ffbbffecf702677d7ec661948a707a380fa535c8871a4fe97b0512c131","description":"Returns a SPICE configuration to connect to the VM.","extra":{"proxyto":"node"},"name":"spiceproxy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).","enum":[],"extra":{"typetext":""},"format":"address","optional":true,"properties":{},"type":"string"},"name":"proxy"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"description":"Returned values can be directly passed to the 'remote-viewer' application.","enum":[],"extra":{"additionalProperties":1},"properties":{"host":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"enum":[],"extra":{},"properties":{},"type":"string"},"proxy":{"enum":[],"extra":{},"properties":{},"type":"string"},"tls-port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/spiceproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e0aec5f2ad5f243e5f05705856f0b3c74f1e863e35ceb571106f118e8b4027e3","description":"Directory index","extra":{"proxyto":"node"},"name":"vmcmdidx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"df3109ff688da8e3c0ed243f29fef3d8b868645658487ab6c99f6b282d679963","description":"Get virtual machine status.","extra":{"proxyto":"node"},"name":"vm_status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"agent":{"description":"QEMU Guest Agent is enabled in config.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"clipboard":{"description":"Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added.","enum":["vnc"],"extra":{},"optional":true,"properties":{},"type":"string"},"cpu":{"description":"Current CPU usage.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"cpus":{"description":"Maximum usable CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"diskread":{"description":"The amount of bytes the guest read from it's block devices since the guest was started. (Note: This info is not available for all storage types.)","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"diskwrite":{"description":"The amount of bytes the guest wrote from it's block devices since the guest was started. (Note: This info is not available for all storage types.)","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"ha":{"description":"HA manager service status.","enum":[],"extra":{},"properties":{},"type":"object"},"lock":{"description":"The current config lock, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxdisk":{"description":"Root disk size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Maximum memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"mem":{"description":"Currently used memory in bytes. Does not take into account kernel same-page merging (KSM). Uses information from ballooning when available.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"memhost":{"description":"Current memory usage on the host. Does not take into account kernel same-page merging (KSM).","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"name":{"description":"VM (host)name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"netin":{"description":"The amount of traffic in bytes that was sent to the guest over the network since it was started.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"netout":{"description":"The amount of traffic in bytes that was sent from the guest over the network since it was started.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"pid":{"description":"PID of the QEMU process, if the VM is running.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"pressurecpufull":{"description":"CPU Full pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressurecpusome":{"description":"CPU Some pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressureiofull":{"description":"IO Full pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressureiosome":{"description":"IO Some pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressurememoryfull":{"description":"Memory Full pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"pressurememorysome":{"description":"Memory Some pressure stall average over the last 10 seconds.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"qmpstatus":{"description":"VM run state from the 'query-status' QMP monitor command.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"running-machine":{"description":"The currently running machine type (if running).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"running-qemu":{"description":"The QEMU version the VM is currently using (if running).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial":{"description":"Guest has serial device configured.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"spice":{"description":"QEMU VGA configuration supports spice.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"status":{"description":"QEMU process status.","enum":["stopped","running"],"extra":{},"properties":{},"type":"string"},"tags":{"description":"The current configured tags, if any","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"template":{"default":0,"description":"Determines if the guest is a template.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"uptime":{"description":"Uptime in seconds.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/status/current"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6810bf03658282f27a25f6c7c0f1a3f13b04d943fbf948b7f786335ce6be363d","description":"Reboot the VM by shutting it down, and starting it again. Applies pending changes.","extra":{"proxyto":"node"},"name":"vm_reboot","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Wait maximal timeout seconds for the shutdown.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/reboot"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2edc46a4f88a3321618629b71a2672f7045bdf7cb3e854025b33dfc3a75d561c","description":"Reset virtual machine.","extra":{"proxyto":"node"},"name":"vm_reset","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/reset"},{"extra":{},"methods":[{"allow_token":true,"checksum":"caa58b1d1a2bf8eb0e5cf1e0b63c83966d59a011469f65748e04d233c519dc1e","description":"Resume virtual machine.","extra":{"proxyto":"node"},"name":"vm_resume","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nocheck"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/resume"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e8a90c03243834c470a30bbf05af277d953cd43a8ae2299957ed3a355f4815f7","description":"Shutdown virtual machine. This is similar to pressing the power button on a physical machine. This will send an ACPI event for the guest OS, which should then proceed to a clean shutdown.","extra":{"proxyto":"node"},"name":"vm_shutdown","parameters":[{"definition":{"default":0,"description":"Make sure the VM stops.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"forceStop"},{"definition":{"default":0,"description":"Do not deactivate storage volumes.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keepActive"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Wait maximal timeout seconds.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/shutdown"},{"extra":{},"methods":[{"allow_token":true,"checksum":"158965a49cf7c0e24f6216f47689950990217c969fe98d66073c55c89857c819","description":"Start virtual machine.","extra":{"proxyto":"node"},"name":"vm_start","parameters":[{"definition":{"description":"Override QEMU's -cpu argument with the given string.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"force-cpu"},{"definition":{"description":"Specify the QEMU machine.","enum":[],"extra":{"typetext":"[[type=]] [,aw-bits=] [,enable-s3=<1|0>] [,enable-s4=<1|0>] [,viommu=]"},"format":{"aw-bits":{"description":"Specifies the vIOMMU address space bit width.","maximum":64,"minimum":32,"optional":1,"type":"number","verbose_description":"Specifies the vIOMMU address space bit width.\n\nIntel vIOMMU supports a bit width of either 39 or 48 bits and VirtIO vIOMMU supports any bit width between 32 and 64 bits."},"enable-s3":{"description":"Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"enable-s4":{"description":"Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"type":{"default_key":1,"description":"Specifies the QEMU machine type.","format_description":"machine type","maxLength":40,"optional":1,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","type":"string"},"viommu":{"description":"Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).","enum":["intel","virtio"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"machine"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"migratedfrom"},{"definition":{"description":"CIDR of the (sub) network that is used for migration.","enum":[],"extra":{"typetext":""},"format":"CIDR","optional":true,"properties":{},"type":"string"},"name":"migration_network"},{"definition":{"description":"Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.","enum":["secure","insecure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"migration_type"},{"definition":{"description":"Used for migration compat. List of VirtIO network devices and their effective host_mtu setting according to the QEMU object model on the source side of the migration. A value of 0 means that the host_mtu parameter is to be avoided for the corresponding device.","enum":[],"extra":{},"optional":true,"pattern":"net\\d+=\\d+(,net\\d+=\\d+)*","properties":{},"type":"string"},"name":"nets-host-mtu"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Some command save/restore state from this location.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"stateuri"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storage-pair-list","optional":true,"properties":{},"type":"string"},"name":"targetstorage"},{"definition":{"default":"max(30, vm memory in GiB)","description":"Wait maximal timeout seconds.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"default":0,"description":"Whether to migrate conntrack entries for running VMs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"with-conntrack-state"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7ba56cd2614e573423e6f4004d858593872c0d9a7f06f78ce94c91ea02bcefc0","description":"Stop virtual machine. The qemu process will exit immediately. This is akin to pulling the power plug of a running computer and may damage the VM data.","extra":{"proxyto":"node"},"name":"vm_stop","parameters":[{"definition":{"default":0,"description":"Do not deactivate storage volumes.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keepActive"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"migratedfrom"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Try to abort active 'qmshutdown' tasks before stopping.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"overrule-shutdown"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Wait maximal timeout seconds.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/stop"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bfca4805bf3684736d2e2606c6653af753b62cbcafc6b400b9f040af71eb592b","description":"Suspend virtual machine.","extra":{"proxyto":"node"},"name":"vm_suspend","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The storage for the VM state","enum":[],"extra":{"format_description":"storage ID","requires":"todisk","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"statestorage"},{"definition":{"default":0,"description":"If set, suspends the VM to disk. Will be resumed on next VM start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"todisk"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.PowerMgmt' on /vms/{vmid}, and if you have set 'todisk', you need also 'VM.Config.Disk' on /vms/{vmid} and 'Datastore.AllocateSpace' on the storage for the vmstate.","expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/suspend"},{"extra":{},"methods":[{"allow_token":true,"checksum":"97358aa1702b91208eda4752b983ba9081f332b95e37c94abd786162d0a40b6d","description":"Create a Template.","extra":{"proxyto":"node"},"name":"template","parameters":[{"definition":{"description":"If you want to convert only 1 disk to base image.","enum":["ide0","ide1","ide2","ide3","scsi0","scsi1","scsi2","scsi3","scsi4","scsi5","scsi6","scsi7","scsi8","scsi9","scsi10","scsi11","scsi12","scsi13","scsi14","scsi15","scsi16","scsi17","scsi18","scsi19","scsi20","scsi21","scsi22","scsi23","scsi24","scsi25","scsi26","scsi27","scsi28","scsi29","scsi30","virtio0","virtio1","virtio2","virtio3","virtio4","virtio5","virtio6","virtio7","virtio8","virtio9","virtio10","virtio11","virtio12","virtio13","virtio14","virtio15","sata0","sata1","sata2","sata3","sata4","sata5","efidisk0","tpmstate0"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permissions on /vms/{vmid}","expression":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/template"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b80c14bb6855e37771805d1bc11b32e18b58bfd2f8ebcbf3498db55f90b15922","description":"Creates a TCP proxy connections.","extra":{},"name":"termproxy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"opens a serial terminal (defaults to display)","enum":["serial0","serial1","serial2","serial3"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"serial"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/termproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f5e5cd97555e5c8643c717a0afbc20f319f7988fec9bcee73fbb0bb4db80adce","description":"Unlink/delete disk images.","extra":{"proxyto":"node"},"name":"unlink","parameters":[{"definition":{"description":"Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"A list of disk IDs you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"idlist"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/unlink"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ffce09b65d03501bfe8678dc10029829bc64ad32197105393b76387079895de5","description":"Creates a TCP VNC proxy connections.","extra":{},"name":"vncproxy","parameters":[{"definition":{"default":0,"description":"Deprecated, do not use. Password is generated when required.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"generate-password"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Prepare for websocket upgrade (only required when using serial terminal, otherwise upgrade is always possible).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"websocket"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"cert":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"description":"Password used for authentication within the VNC protocol. Consists of printable ASCII characters ('!' .. '~').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/vncproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e35fae5176b1f7cdf7edfac342ebeb906e94cbc3aa934ddf26ebe4f1b595cb33","description":"Opens a websocket for VNC traffic.","extra":{},"name":"vncwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Port number returned by previous vncproxy call.","enum":[],"extra":{"typetext":" (5900 - 5999)"},"maximum":5999,"minimum":5900,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Ticket from previous call to vncproxy.","enum":[],"extra":{"typetext":""},"max_length":512,"properties":{},"type":"string"},"name":"vncticket"}],"permissions":{"description":"You also need to pass a valid ticket (vncticket).","expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/vncwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bb2fdf527d67d686957667796f89dff118e35b66d38df8698754ec3f4d4b5786","description":"List all tags for an OCI repository reference.","extra":{"proxyto":"node"},"name":"query_oci_repo_tags","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The reference to the repository to query tags from.","enum":[],"extra":{},"pattern":"^(?:(?:[a-zA-Z\\d]|[a-zA-Z\\d][a-zA-Z\\d-]*[a-zA-Z\\d])(?:\\.(?:[a-zA-Z\\d]|[a-zA-Z\\d][a-zA-Z\\d-]*[a-zA-Z\\d]))*(?::\\d+)?/)?[a-z\\d]+(?:(?:[._]|__|[-]*)[a-z\\d]+)*(?:/[a-z\\d]+(?:(?:[._]|__|[-]*)[a-z\\d]+)*)*$","properties":{},"type":"string"},"name":"reference"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.AccessNetwork"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/query-oci-repo-tags"},{"extra":{},"methods":[{"allow_token":true,"checksum":"538f04b05067fbe6554d199b705e5299ce19bca0fdf31783b3407037f79ccbfb","description":"Query metadata of an URL: file size, file name and mime type.","extra":{"proxyto":"node"},"name":"query_url_metadata","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The URL to query the metadata from.","enum":[],"extra":{},"pattern":"https?://.*","properties":{},"type":"string"},"name":"url"},{"definition":{"default":1,"description":"If false, no SSL/TLS certificates will be verified.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify-certificates"}],"permissions":{"expression":{"check":["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/nodes/{node}",["Sys.AccessNetwork"]]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mimetype":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"size":{"enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/query-url-metadata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"744f7304013b6bfb4e58d7da6cc6ae8a97c3a1795b3dd6b02cc2becdaf44733d","description":"List status of all replication jobs on this node.","extra":{"proxyto":"node"},"name":"status","parameters":[{"definition":{"description":"Only list replication jobs for this guest.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"guest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires the VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/replication"},{"extra":{},"methods":[{"allow_token":true,"checksum":"201ac105a0b4f70bec7ac00e32a949db054741cbd2465d2f625462367edce6f7","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/replication/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6ffc6cc2602df84fe4f8eb72ae99567ce4f7fb02dec2ca8db396ff090772cd58","description":"Read replication job log.","extra":{"proxyto":"node"},"name":"read_job_log","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"}],"permissions":{"description":"Requires the VM.Audit permission on /vms/, or 'Sys.Audit' on '/nodes/'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/replication/{id}/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bf7fa7dfb261c6681f94a6d70d89984aa09fafc3bdd4d5290234fa68df32a8a2","description":"Schedule replication job to start as soon as possible.","extra":{"proxyto":"node"},"name":"schedule_now","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires the VM.Replicate permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/replication/{id}/schedule_now"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4be58d6638ffb32fbaa33db58fac6d3964014ed3286339e84f35ca0cb6d006e1","description":"Get replication job status.","extra":{"proxyto":"node"},"name":"job_status","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires the VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/replication/{id}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0e37ddadedaa3a4ce296c24b888b12f7012e4e23b1732222e40075a4f8a9ed1f","description":"Gather various systems information about a node","extra":{"proxyto":"node"},"name":"report","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/report"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5affca591231ae3b5be5bd2582cedc4c8a20deb22a00d5b13ae69b1e6bca152a","description":"Read node RRD statistics (returns PNG)","extra":{},"name":"rrd","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The list of datasources you want to display.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"ds"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year","decade"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/rrd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7e266aaafee43f57269bf7119a0ca218785eb78c6d698a9dab9db62a5f718b33","description":"Read node RRD statistics","extra":{},"name":"rrddata","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year","decade"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/rrddata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7cca8a7c1631d17653d463ea99f96401217997b7a680967bfc57a06b99302ff1","description":"Index of available scan methods","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{method}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"method":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2ec831a4ad191d89200069d552cc1eedbbe77316334360b9e98672a3d4cf3a94","description":"Scan remote CIFS server.","extra":{"proxyto":"node"},"name":"cifsscan","parameters":[{"definition":{"description":"SMB domain (Workgroup).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"User password.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"The server address (name or IP).","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","properties":{},"type":"string"},"name":"server"},{"definition":{"description":"User name.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"description":{"description":"Descriptive text from server.","enum":[],"extra":{},"properties":{},"type":"string"},"share":{"description":"The cifs share name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/cifs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f0b69d1299f3a287b51f9e20eddd3a6c423da92c62c5263da3308104c8f9e3d8","description":"Scan remote iSCSI server.","extra":{"proxyto":"node"},"name":"iscsiscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The iSCSI portal (IP or DNS name with optional port).","enum":[],"extra":{"typetext":""},"format":"pve-storage-portal-dns","properties":{},"type":"string"},"name":"portal"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"portal":{"description":"The iSCSI portal name.","enum":[],"extra":{},"properties":{},"type":"string"},"target":{"description":"The iSCSI target name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/iscsi"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ee58724ae9c2fbdaf09f891f8286f1c4a97862a33274213f55b64ef257c82810","description":"List local LVM volume groups.","extra":{"proxyto":"node"},"name":"lvmscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"vg":{"description":"The LVM logical volume group name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/lvm"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b85f98a17a9f58549d6a53aafbaf22bfdf0e5d1665f87e90bb69fd57fad754e8","description":"List local LVM Thin Pools.","extra":{"proxyto":"node"},"name":"lvmthinscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{},"max_length":100,"pattern":"[a-zA-Z0-9\\.\\+\\_][a-zA-Z0-9\\.\\+\\_\\-]+","properties":{},"type":"string"},"name":"vg"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"lv":{"description":"The LVM Thin Pool name (LVM logical volume).","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/lvmthin"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d9ddde30d7f532fbc6f06fbe726c2833705e8d4807f2c6cd617ee8fdae18d97d","description":"Scan remote NFS server.","extra":{"proxyto":"node"},"name":"nfsscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The server address (name or IP).","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","properties":{},"type":"string"},"name":"server"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"options":{"description":"NFS export options.","enum":[],"extra":{},"properties":{},"type":"string"},"path":{"description":"The exported path.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/nfs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3ce919d002c3d125b6b1ad3b5fd0cb889318319ec14cee96f7282ff12db0bda8","description":"Scan remote Proxmox Backup Server.","extra":{"proxyto":"node"},"name":"pbsscan","parameters":[{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"User password or API token secret.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"password"},{"definition":{"default":8007,"description":"Optional port.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The server address (name or IP).","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","properties":{},"type":"string"},"name":"server"},{"definition":{"description":"User-name or API token-ID.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"username"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"Comment from server.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"store":{"description":"The datastore name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/pbs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5742df84db0fb3e83b8a85993cee8d4667b1a311b08d135a1b751e04afd1caeb","description":"Scan zfs pool list on local node.","extra":{"proxyto":"node"},"name":"zfsscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"pool":{"description":"ZFS pool name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/zfs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1e067dd0a1fab020d0aa5b223a57cec2187a2a4a2169020a18cbbee3af97b5ed","description":"SDN index.","extra":{"proxyto":"node"},"name":"sdnindex","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9bd11fa5f21c90befd7903c92c34453884c7be1bbb2da8e5b31e2def53f61dad","description":"Directory index for SDN fabric status.","extra":{},"name":"diridx","parameters":[{"definition":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"name":"fabric"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/sdn/fabrics/{fabric}",["SDN.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/fabrics/{fabric}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"445dac8ca2859cdcb42faf931f617f01c520ca20b225f9b68bf7b3f6b7868768","description":"Get all interfaces for a fabric.","extra":{"proxyto":"node"},"name":"interfaces","parameters":[{"definition":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"name":"fabric"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/sdn/fabrics/{fabric}",["SDN.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"name":{"description":"The name of the network interface.","enum":[],"extra":{},"properties":{},"type":"string"},"state":{"description":"The current state of the interface.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The type of this interface in the fabric (e.g. Point-to-Point, Broadcast, ..).","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/fabrics/{fabric}/interfaces"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5fcc5034c74d332a2e03a60c699bca3c88e312c39b23b12fce14d9a0cb7ee0d4","description":"Get all neighbors for a fabric.","extra":{"proxyto":"node"},"name":"neighbors","parameters":[{"definition":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"name":"fabric"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/sdn/fabrics/{fabric}",["SDN.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"neighbor":{"description":"The IP or hostname of the neighbor.","enum":[],"extra":{},"properties":{},"type":"string"},"status":{"description":"The status of the neighbor, as returned by FRR.","enum":[],"extra":{},"properties":{},"type":"string"},"uptime":{"description":"The uptime of this neighbor, as returned by FRR (e.g. 8h24m12s).","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/fabrics/{fabric}/neighbors"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c4f6937cdec64d0d364136e336b0ebd014c7e81c03bd01ca6ef57350c53d80d5","description":"Get all routes for a fabric.","extra":{"proxyto":"node"},"name":"routes","parameters":[{"definition":{"description":"Identifier for SDN fabrics","enum":[],"extra":{},"format":"pve-sdn-fabric-id","max_length":8,"min_length":2,"pattern":"[a-zA-Z0-9][a-zA-Z0-9-]{0,6}[a-zA-Z0-9]","properties":{},"type":"string"},"name":"fabric"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/sdn/fabrics/{fabric}",["SDN.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"route":{"description":"The CIDR block for this routing table entry.","enum":[],"extra":{},"properties":{},"type":"string"},"via":{"description":"A list of nexthops for that route.","enum":[],"extra":{},"items":{"description":"The IP address of the nexthop.","enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/fabrics/{fabric}/routes"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2c2aa9d735a06c600a1d8909cd073e6fb3eda6006213f997896953975cedf748","description":"","extra":{},"name":"diridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Require 'SDN.Audit' permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/vnets/{vnet}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6d90c39805ac9bb7646765723d5aba64260b6337eab73965d0c180079acc4d77","description":"Get the MAC VRF for a VNet in an EVPN zone.","extra":{"proxyto":"node"},"name":"mac-vrf","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Require 'SDN.Audit' permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"description":"All routes from the MAC VRF that this node self-originates or has learned via BGP.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"ip":{"description":"The IP address of the MAC VRF entry.","enum":[],"extra":{},"format":"ip","properties":{},"type":"string"},"mac":{"description":"The MAC address of the MAC VRF entry.","enum":[],"extra":{},"format":"mac-addr","properties":{},"type":"string"},"nexthop":{"description":"The IP address of the nexthop.","enum":[],"extra":{},"format":"ip","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/vnets/{vnet}/mac-vrf"},{"extra":{},"methods":[{"allow_token":true,"checksum":"78f943668954aaeb647fe17e7426525b902966fce77f64cf965c0c065a7817c5","description":"Get status for all zones.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{zone}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"status":{"description":"Status of zone","enum":["available","pending","error"],"extra":{},"properties":{},"type":"string"},"zone":{"description":"The SDN zone object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/zones"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dee435d9c9d9415c96225ed5033b2250f6f6f0e2cf043bd04759dead8ba09963","description":"Directory index for SDN zone status.","extra":{},"name":"diridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/zones/{zone}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d12f0b1bb4b1730cf29f35f636c511080f31561b8018670ec87fd41eb14c272b","description":"Get a list of all bridges (vnets) that are part of a zone, as well as the ports that are members of that bridge.","extra":{"proxyto":"node"},"name":"bridges","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"zone name or \"localnetwork\"","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"description":"List of bridges contained in the SDN zone.","enum":[],"extra":{},"properties":{"name":{"description":"Name of the bridge.","enum":[],"extra":{},"properties":{},"type":"string"},"ports":{"description":"All ports that are members of the bridge","enum":[],"extra":{},"items":{"description":"Information about bridge ports.","enum":[],"extra":{},"properties":{"index":{"description":"The index of the guests network device that this interface belongs to.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"The name of the bridge port.","enum":[],"extra":{},"properties":{},"type":"string"},"primary_vlan":{"description":"The primary VLAN configured for the port of this bridge (= PVID). Only for VLAN-aware bridges.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"vlans":{"description":"A list of VLANs and VLAN ranges that are allowed for this bridge port in addition to the primary VLAN. Only for VLAN-aware bridges.","enum":[],"extra":{},"items":{"description":"A single VLAN (123) or a VLAN range (234-435).","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"vmid":{"description":"The ID of the guest that this interface belongs to.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"}},"type":"object"},"properties":{},"type":"array"},"vlan_filtering":{"description":"Whether VLAN filtering is enabled for this bridge (= VLAN-aware).","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/zones/{zone}/bridges"},{"extra":{},"methods":[{"allow_token":true,"checksum":"98b3d04e0ee85225906ca064a5b1fbf3548e57fd310b77085403a624fb0d378d","description":"List zone content.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{},"max_length":8,"min_length":2,"pattern":"[a-zA-Z][a-zA-Z0-9]*[a-zA-Z0-9]","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{vnet}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"status":{"description":"Status.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"statusmsg":{"description":"Status details","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vnet":{"description":"Vnet identifier.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/zones/{zone}/content"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9af7b25459a1eeebeba1be07d41f7f2de8e2f07da470681fb3c686048f4289d3","description":"Get the IP VRF of an EVPN zone.","extra":{"proxyto":"node"},"name":"ip-vrf","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Name of an EVPN zone.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Audit"]]},"extra":{}},"protected":true,"returns":{"description":"All entries in the VRF table of zone {zone} of the node.This does not include /32 routes for guests on this host,since they are handled via the respective vnet bridge directly.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"ip":{"description":"The CIDR of the route table entry.","enum":[],"extra":{},"format":"CIDR","properties":{},"type":"string"},"metric":{"description":"This route's metric.","enum":[],"extra":{},"properties":{},"type":"integer"},"nexthops":{"description":"A list of nexthops for the route table entry.","enum":[],"extra":{},"items":{"description":"the interface name or ip address of the next hop","enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"protocol":{"description":"The protocol where this route was learned from (e.g. BGP).","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/zones/{zone}/ip-vrf"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3ee0af7c67192d52ca0ba38bf88476ecce871bd1f76ac074f510f4e7b44fcf23","description":"Service list.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{service}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"active-state":{"description":"Current state of the service process (systemd ActiveState).","enum":["active","inactive","failed","activating","deactivating","maintenance","reloading","refreshing","unknown"],"extra":{},"properties":{},"type":"string"},"desc":{"description":"Description of the service.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Short identifier for the service (e.g., \"pveproxy\").","enum":[],"extra":{},"properties":{},"type":"string"},"service":{"description":"Systemd unit name (e.g., pveproxy).","enum":[],"extra":{},"properties":{},"type":"string"},"state":{"description":"Execution status of the service (systemd SubState).","enum":["dead","condition","start-pre","start","start-post","running","exited","reload","reload-signal","reload-notify","mounting","stop","stop-watchdog","stop-sigterm","stop-sigkill","stop-post","final-watchdog","final-sigterm","final-sigkill","failed","dead-before-auto-restart","failed-before-auto-restart","dead-resources-pinned","auto-restart","auto-restart-queued","cleaning","unknown"],"extra":{},"properties":{},"type":"string"},"unit-state":{"description":"Whether the service is enabled (systemd UnitFileState).","enum":["enabled","enabled-runtime","linked","linked-runtime","alias","masked","masked-runtime","static","disabled","indirect","generated","transient","bad","not-found","unknown"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/services"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b47e931780c2137bcb83912c15093402968f920e5932efa253f22e2b9169a4be","description":"Directory index","extra":{},"name":"srvcmdidx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","lxcfs","postfix","proxmox-firewall","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pve-lxc-syscalld","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","qmeventd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/services/{service}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"86497860683c8825dd526d262d0047c424e589f12bc4a6ca8f9e49c3f5c8a86b","description":"Reload service. Falls back to restart if service cannot be reloaded.","extra":{"proxyto":"node"},"name":"service_reload","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","lxcfs","postfix","proxmox-firewall","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pve-lxc-syscalld","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","qmeventd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/services/{service}/reload"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b7ee00a2e34a184571d7009dcacb5ae4f36adf25a708da99c5d6805097cf8674","description":"Hard restart service. Use reload if you want to reduce interruptions.","extra":{"proxyto":"node"},"name":"service_restart","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","lxcfs","postfix","proxmox-firewall","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pve-lxc-syscalld","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","qmeventd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/services/{service}/restart"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dd514bd07365e3632ae29a0e1b3500ff822fa7542e29ea2da2bc742d4f217dc4","description":"Start service.","extra":{"proxyto":"node"},"name":"service_start","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","lxcfs","postfix","proxmox-firewall","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pve-lxc-syscalld","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","qmeventd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/services/{service}/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8e241dbc8dce6e1eb5323409ad234595a87924e7785b8b8066727d84c9b93965","description":"Read service properties","extra":{"proxyto":"node"},"name":"service_state","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","lxcfs","postfix","proxmox-firewall","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pve-lxc-syscalld","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","qmeventd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"active-state":{"description":"Current state of the service process (systemd ActiveState).","enum":["active","inactive","failed","activating","deactivating","maintenance","reloading","refreshing","unknown"],"extra":{},"properties":{},"type":"string"},"desc":{"description":"Description of the service.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Short identifier for the service (e.g., \"pveproxy\").","enum":[],"extra":{},"properties":{},"type":"string"},"service":{"description":"Systemd unit name (e.g., pveproxy).","enum":[],"extra":{},"properties":{},"type":"string"},"state":{"description":"Execution status of the service (systemd SubState).","enum":["dead","condition","start-pre","start","start-post","running","exited","reload","reload-signal","reload-notify","mounting","stop","stop-watchdog","stop-sigterm","stop-sigkill","stop-post","final-watchdog","final-sigterm","final-sigkill","failed","dead-before-auto-restart","failed-before-auto-restart","dead-resources-pinned","auto-restart","auto-restart-queued","cleaning","unknown"],"extra":{},"properties":{},"type":"string"},"unit-state":{"description":"Whether the service is enabled (systemd UnitFileState).","enum":["enabled","enabled-runtime","linked","linked-runtime","alias","masked","masked-runtime","static","disabled","indirect","generated","transient","bad","not-found","unknown"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/services/{service}/state"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7134d2215583c0019176a69c3d61bd5fe3f6c14490ddd3914b512e11486acae4","description":"Stop service.","extra":{"proxyto":"node"},"name":"service_stop","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","lxcfs","postfix","proxmox-firewall","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pve-lxc-syscalld","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","qmeventd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/services/{service}/stop"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7d618bbe1b8f0d22fd2275b2520e016db5bd09070fc41bc9b5e435b20f61e144","description":"Creates a SPICE shell.","extra":{"proxyto":"node"},"name":"spiceshell","parameters":[{"definition":{"default":"login","description":"Run specific command or default to login (requires 'root@pam')","enum":["ceph_install","login","upgrade"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmd"},{"definition":{"default":"","description":"Add parameters to a command. Encoded as null terminated strings.","enum":[],"extra":{"requires":"cmd","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cmd-opts"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).","enum":[],"extra":{"typetext":""},"format":"address","optional":true,"properties":{},"type":"string"},"name":"proxy"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"description":"Returned values can be directly passed to the 'remote-viewer' application.","enum":[],"extra":{"additionalProperties":1},"properties":{"host":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"enum":[],"extra":{},"properties":{},"type":"string"},"proxy":{"enum":[],"extra":{},"properties":{},"type":"string"},"tls-port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/spiceshell"},{"extra":{},"methods":[{"allow_token":true,"checksum":"135862acd5551c7c7c241c8517209cf32708aa937c25fc4b366b21330e52019d","description":"Start all VMs and containers located on this node (by default only those with onboot=1).","extra":{"proxyto":"node"},"name":"startall","parameters":[{"definition":{"default":"off","description":"Issue start command even if virtual guest have 'onboot' not set or set to off.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Defines the maximum number of tasks running concurrently. If not set, uses 'max_workers' from datacenter.cfg, and if that's not set, the available CPU threads, clamped to a maximum of 8, are used.","enum":[],"extra":{"typetext":" (1 - 64)"},"maximum":64,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max-workers"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only consider guests from this comma separated list of VMIDs.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"}],"permissions":{"description":"The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/startall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5710def592533e61df67f1d1a77bad45afe0df2d58db67e82d77e14a9c8bab9e","description":"Read node status","extra":{"proxyto":"node"},"name":"status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":1},"properties":{"boot-info":{"description":"Meta-information about the boot mode.","enum":[],"extra":{},"properties":{"mode":{"description":"Through which firmware the system got booted.","enum":["efi","legacy-bios"],"extra":{},"properties":{},"type":"string"},"secureboot":{"description":"System is booted in secure mode, only applicable for the \"efi\" mode.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"cpu":{"description":"The current cpu usage.","enum":[],"extra":{},"properties":{},"type":"number"},"cpuinfo":{"enum":[],"extra":{},"properties":{"cores":{"description":"The number of physical cores of the CPU.","enum":[],"extra":{},"properties":{},"type":"integer"},"cpus":{"description":"The number of logical threads of the CPU.","enum":[],"extra":{},"properties":{},"type":"integer"},"model":{"description":"The CPU model","enum":[],"extra":{},"properties":{},"type":"string"},"sockets":{"description":"The number of logical threads of the CPU.","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"current-kernel":{"description":"Meta-information about the currently booted kernel of this node.","enum":[],"extra":{},"properties":{"machine":{"description":"Hardware (architecture) type","enum":[],"extra":{},"properties":{},"type":"string"},"release":{"description":"OS kernel release (e.g., \"6.8.0\")","enum":[],"extra":{},"properties":{},"type":"string"},"sysname":{"description":"OS kernel name (e.g., \"Linux\")","enum":[],"extra":{},"properties":{},"type":"string"},"version":{"description":"OS kernel version with build info","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"loadavg":{"description":"An array of load avg for 1, 5 and 15 minutes respectively.","enum":[],"extra":{},"items":{"description":"The value of the load.","enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"memory":{"enum":[],"extra":{},"properties":{"available":{"description":"The available memory in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"free":{"description":"The free memory in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"total":{"description":"The total memory in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"used":{"description":"The used memory in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"pveversion":{"description":"The PVE version string.","enum":[],"extra":{},"properties":{},"type":"string"},"rootfs":{"enum":[],"extra":{},"properties":{"avail":{"description":"The available bytes in the root filesystem.","enum":[],"extra":{},"properties":{},"type":"integer"},"free":{"description":"The free bytes on the root filesystem.","enum":[],"extra":{},"properties":{},"type":"integer"},"total":{"description":"The total size of the root filesystem in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"used":{"description":"The used bytes in the root filesystem.","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"f11d86bf5eb63c8f7c9cd23dd0579477ea908eb3b936d39f4f8c5a20bfd0bef7","description":"Reboot or shutdown a node.","extra":{"proxyto":"node"},"name":"node_cmd","parameters":[{"definition":{"description":"Specify the command.","enum":["reboot","shutdown"],"extra":{},"properties":{},"type":"string"},"name":"command"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e85252d0599e43ed2737b4c73880b3629d745024d70d2e33043c9c5bb525794b","description":"Stop all VMs and Containers.","extra":{"proxyto":"node"},"name":"stopall","parameters":[{"definition":{"default":1,"description":"Force a hard-stop after the timeout.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force-stop"},{"definition":{"description":"Defines the maximum number of tasks running concurrently. If not set, uses 'max_workers' from datacenter.cfg, and if that's not set, the available CPU threads, clamped to a maximum of 8, are used.","enum":[],"extra":{"typetext":" (1 - 64)"},"maximum":64,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max-workers"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":180,"description":"Timeout for each guest shutdown task. Depending on `force-stop`, the shutdown gets then simply aborted or a hard-stop is forced.","enum":[],"extra":{"typetext":" (0 - 7200)"},"maximum":7200,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"Only consider Guests with these IDs.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"}],"permissions":{"description":"The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/stopall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b08cbeaba62b73fbfd2ed6e262b3a638068b1082214397a1154f54ed1f3cd575","description":"Get status for all datastores.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"Only list stores which support this content type.","enum":[],"extra":{"typetext":""},"format":"pve-storage-content-list","optional":true,"properties":{},"type":"string"},"name":"content"},{"definition":{"default":0,"description":"Only list stores which are enabled (not disabled in config).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"default":0,"description":"Include information about formats","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"format"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list status for specified storage","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"If target is different to 'node', we only lists shared storages which content is accessible on this 'node' and the specified 'target' node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"}],"permissions":{"description":"Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{storage}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"active":{"description":"Set when storage is accessible.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"avail":{"description":"Available storage space in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"content":{"description":"Allowed storage content types.","enum":[],"extra":{},"format":"pve-storage-content-list","properties":{},"type":"string"},"enabled":{"description":"Set when storage is enabled (not disabled).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"formats":{"description":"Lists the supported and default format. Use 'formats' instead. Only included if 'format' parameter is set.","enum":[],"extra":{},"optional":true,"properties":{"default":{"description":"The default format of the storage.","enum":["qcow2","raw","subvol","vmdk"],"extra":{},"properties":{},"type":"string"},"supported":{"description":"The list of supported formats","enum":[],"extra":{},"items":{"enum":["qcow2","raw","subvol","vmdk"],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"select_existing":{"description":"Instead of creating new volumes, one must select one that is already existing. Only included if 'format' parameter is set.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"shared":{"description":"Shared flag from storage configuration.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"storage":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID"},"format":"pve-storage-id","properties":{},"type":"string"},"total":{"description":"Total storage space in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"type":{"description":"Storage type.","enum":[],"extra":{},"properties":{},"type":"string"},"used":{"description":"Used storage space in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"used_fraction":{"description":"Used fraction (used/total).","enum":[],"extra":{"renderer":"fraction_as_percentage"},"optional":true,"properties":{},"type":"number"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0f34572e237a199ec9df2c4b490f1be7b4803af30d4ca82611bada9412d062b9","description":"","extra":{},"name":"diridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"aedec78e98595cf482bbe7630d6cf5bbea9b22bfb537332ed23e59cb062d0059","description":"List storage content.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"Only list content of this type.","enum":[],"extra":{"typetext":""},"format":"pve-storage-content","optional":true,"properties":{},"type":"string"},"name":"content"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Only list images for this VM","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{volid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"approximate-size":{"description":"Approximate volume size in bytes. Present instead of 'size' for storages where determining the exact size has technical limitations. Will typically be an upper bound on the actual size, but the exact semantics depend on the storage plugin.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"ctime":{"description":"Creation time (seconds since the UNIX Epoch).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"encrypted":{"description":"If whole backup is encrypted, value is the fingerprint or '1' if encrypted. Only useful for the Proxmox Backup Server storage type.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"format":{"description":"Format identifier ('raw', 'qcow2', 'subvol', 'iso', 'tgz' ...)","enum":[],"extra":{},"properties":{},"type":"string"},"notes":{"description":"Optional notes. If they contain multiple lines, only the first one is returned here.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"parent":{"description":"Volume identifier of parent (for linked cloned).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"protected":{"description":"Protection status. Currently only supported for backups.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"size":{"description":"Volume size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"used":{"description":"Used space. Please note that most storage plugins do not report anything useful here.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"verification":{"description":"Last backup verification result, only useful for PBS storages.","enum":[],"extra":{},"optional":true,"properties":{"state":{"description":"Last backup verification state.","enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"description":"Last backup verification UPID.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"vmid":{"description":"Associated Owner VMID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"volid":{"description":"Volume identifier.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"96cbd6fc8a176b7a0d5aadee14f55b99b6474880ee40613149589daff21cc06a","description":"Allocate disk images.","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"description":"The name of the file to create.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"filename"},{"definition":{"description":"Format of the image.","enum":["raw","qcow2","subvol","vmdk"],"extra":{"requires":"size"},"optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Size in kilobyte (1024 bytes). Optional suffixes 'M' (megabyte, 1024K) and 'G' (gigabyte, 1024M)","enum":[],"extra":{},"pattern":"\\d+[MG]?","properties":{},"type":"string"},"name":"size"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Specify owner VM","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.AllocateSpace"]]},"extra":{}},"protected":true,"returns":{"description":"Volume identifier","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/storage/{storage}/content"},{"extra":{},"methods":[{"allow_token":true,"checksum":"00189b956be91b24e3a41a3ea431f9e1ced9caf6170502ae77c1b796a58f9e57","description":"Delete volume","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"description":"Time to wait for the task to finish. We return 'null' if the task finish within that time.","enum":[],"extra":{"typetext":" (1 - 30)"},"maximum":30,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"delay"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need 'Datastore.Allocate' privilege on the storage (or 'Datastore.AllocateSpace' for backup volumes if you have VM.Backup privilege on the VM).","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"3baa865a5c097996d513818c079aac6d6c03cf45638cd8f3c6ee701afd7878ab","description":"Get volume attributes","extra":{"proxyto":"node"},"name":"info","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"format":{"description":"Format identifier ('raw', 'qcow2', 'subvol', 'iso', 'tgz' ...)","enum":[],"extra":{},"properties":{},"type":"string"},"notes":{"description":"Optional notes.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"path":{"description":"The Path","enum":[],"extra":{},"properties":{},"type":"string"},"protected":{"description":"Protection status. Currently only supported for backups.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"size":{"description":"Volume size in bytes.","enum":[],"extra":{"renderer":"bytes"},"properties":{},"type":"integer"},"used":{"description":"Used space. Please note that most storage plugins do not report anything useful here.","enum":[],"extra":{"renderer":"bytes"},"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"d3edd035cd3bedade91a18abce3de0cd8c13011e4a281f7a271fd98ad9858be0","description":"Copy a volume. This is experimental code - do not use.","extra":{"proxyto":"node"},"name":"copy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Target volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Target node. Default is local node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target_node"},{"definition":{"description":"Source volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"},{"allow_token":true,"checksum":"dad56b6a2a822d2722f0399472681acc089bfedac37418abf6787fa31e6370cf","description":"Update volume attributes","extra":{"proxyto":"node"},"name":"updateattributes","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The new notes.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"notes"},{"definition":{"description":"Protection status. Currently only supported for backups.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protected"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/storage/{storage}/content/{volume}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6b19c2c6757f47b20079d7dc70256c7e35b4dee7beb51cbea37a2335b838720e","description":"Download templates, ISO images, OVAs and VM images by using an URL.","extra":{"proxyto":"node"},"name":"download_url","parameters":[{"definition":{"description":"The expected checksum of the file.","enum":[],"extra":{"requires":"checksum-algorithm","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"checksum"},{"definition":{"description":"The algorithm to calculate the checksum of the file.","enum":["md5","sha1","sha224","sha256","sha384","sha512"],"extra":{"requires":"checksum"},"optional":true,"properties":{},"type":"string"},"name":"checksum-algorithm"},{"definition":{"description":"Decompress the downloaded file using the specified compression algorithm.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"compression"},{"definition":{"description":"Content type.","enum":["iso","vztmpl","import"],"extra":{},"format":"pve-storage-content","properties":{},"type":"string"},"name":"content"},{"definition":{"description":"The name of the file to create. Caution: This will be normalized!","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"filename"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"The URL to download the file from.","enum":[],"extra":{},"pattern":"https?://.*","properties":{},"type":"string"},"name":"url"},{"definition":{"default":1,"description":"If false, no SSL/TLS certificates will be verified.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify-certificates"}],"permissions":{"description":"Requires allocation access on the storage and as this allows one to probe the (local!) host network indirectly it also requires one of Sys.Modify on / (for backwards compatibility) or the newer Sys.AccessNetwork privilege on the node.","expression":{"check":["and",["perm","/storage/{storage}",["Datastore.AllocateTemplate"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/nodes/{node}",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/storage/{storage}/download-url"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f17dd8ea50a61163da50ea44dd5bb18e74f3cfe5c6d3b87eacea93f2669730a3","description":"Extract a file or directory (as zip archive) from a PBS backup.","extra":{"download_allowed":1,"proxyto":"node"},"name":"download","parameters":[{"definition":{"description":"base64-path to the directory or file to download.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"filepath"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"default":0,"description":"Download dirs as 'tar.zst' instead of 'zip'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tar"},{"definition":{"description":"Backup volume ID or name. Currently only PBS snapshots are supported.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"any"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/file-restore/download"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1f5d9f6eb8537d97c9debc4d0d83740d147c362674619cc48f0d2fa21a60ff5a","description":"List files and directories for single file restore under the given path.","extra":{"proxyto":"node"},"name":"list","parameters":[{"definition":{"description":"base64-path to the directory or file being listed, or \"/\".","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"filepath"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Backup volume ID or name. Currently only PBS snapshots are supported.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"filepath":{"description":"base64 path of the current entry","enum":[],"extra":{},"properties":{},"type":"string"},"leaf":{"description":"If this entry is a leaf in the directory graph.","enum":[],"extra":{},"properties":{},"type":"boolean"},"mtime":{"description":"Entry last-modified time (unix timestamp).","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"size":{"description":"Entry file size.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"text":{"description":"Entry display text.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"Entry type.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/file-restore/list"},{"extra":{},"methods":[{"allow_token":true,"checksum":"72d1b2d7a709524010385e69253181055e9572fe6d2f1157082d7ced390c58e7","description":"Return identity information for this storage instance.","extra":{"proxyto":"node"},"name":"identity","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"id":{"description":"Unique identifier for this storage instance. The exact format and semantics depend on the storage plugin type.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The type of the storage.","enum":["btrfs","cephfs","cifs","dir","esxi","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/identity"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7955a18eaf60f9c62ee87e38b5b2a0c438bbc8af4cd9b077138d411caa6623a7","description":"Get the base parameters for creating a guest which imports data from a foreign importable guest, like an ESXi VM","extra":{"proxyto":"node"},"name":"get_import_metadata","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Volume identifier for the guest archive/entry.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"description":"Information about how to import a guest.","enum":[],"extra":{"additionalProperties":0},"properties":{"create-args":{"description":"Parameters which can be used in a call to create a VM or container.","enum":[],"extra":{"additionalProperties":1},"properties":{},"type":"object"},"disks":{"description":"Recognised disk volumes as `$bus$id` => `$storeid:$path` map.","enum":[],"extra":{"additionalProperties":1},"optional":true,"properties":{},"type":"object"},"net":{"description":"Recognised network interfaces as `net$id` => { ...params } object.","enum":[],"extra":{"additionalProperties":1},"optional":true,"properties":{},"type":"object"},"source":{"description":"The type of the import-source of this guest volume.","enum":["esxi"],"extra":{},"properties":{},"type":"string"},"type":{"description":"The type of guest this is going to produce.","enum":["vm"],"extra":{},"properties":{},"type":"string"},"warnings":{"description":"List of known issues that can affect the import of a guest. Note that lack of warning does not imply that there cannot be any problems.","enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"key":{"description":"Related subject (config) key of warning.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"What this warning is about.","enum":["cdrom-image-ignored","efi-state-lost","guest-is-running","nvme-unsupported","ova-needs-extracting","ovmf-with-lsi-unsupported","serial-port-socket-only"],"extra":{},"properties":{},"type":"string"},"value":{"description":"Related subject (config) value of warning.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/import-metadata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"800444b773a6d18110c0dd33dd2dfc08425664e5918db7c85cbaa4b72656b767","description":"Pull an OCI image from a registry.","extra":{"proxyto":"node"},"name":"oci_registry_pull","parameters":[{"definition":{"description":"Custom destination file name of the OCI image. Caution: This will be normalized!","enum":[],"extra":{"typetext":""},"max_length":255,"min_length":1,"optional":true,"properties":{},"type":"string"},"name":"filename"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The reference to the OCI image to download.","enum":[],"extra":{},"pattern":"^(?:(?:[a-zA-Z\\d]|[a-zA-Z\\d][a-zA-Z\\d-]*[a-zA-Z\\d])(?:\\.(?:[a-zA-Z\\d]|[a-zA-Z\\d][a-zA-Z\\d-]*[a-zA-Z\\d]))*(?::\\d+)?/)?[a-z\\d]+(?:(?:[._]|__|[-]*)[a-z\\d]+)*(?:/[a-z\\d]+(?:(?:[._]|__|[-]*)[a-z\\d]+)*)*:\\w[\\w.-]{0,127}$","properties":{},"type":"string"},"name":"reference"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["and",["perm","/storage/{storage}",["Datastore.AllocateTemplate"]],["perm","/nodes/{node}",["Sys.AccessNetwork"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/storage/{storage}/oci-registry-pull"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9820bccd0c8e4fa6d9e76952af7601b655780063585e6f5ab98152fc5f6a6090","description":"Prune backups. Only those using the standard naming scheme are considered.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Either 'qemu' or 'lxc'. Only consider backups for guests of this type.","enum":["qemu","lxc"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"Only prune backups for this VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need the 'Datastore.Allocate' privilege on the storage (or if a VM ID is specified, 'Datastore.AllocateSpace' and 'VM.Backup' for the VM).","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"dc997ca715271d56e6b13c8bf092a59c488beea7395d33101289f62d0044ad0f","description":"Get prune information for backups. NOTE: this is only a preview and might not be what a subsequent prune call does if backups are removed/added in the meantime.","extra":{"proxyto":"node"},"name":"dryrun","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Either 'qemu' or 'lxc'. Only consider backups for guests of this type.","enum":["qemu","lxc"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"Only consider backups for this guest.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"ctime":{"description":"Creation time of the backup (seconds since the UNIX epoch).","enum":[],"extra":{},"properties":{},"type":"integer"},"mark":{"description":"Whether the backup would be kept or removed. Backups that are protected or don't use the standard naming scheme are not removed.","enum":["keep","remove","protected","renamed"],"extra":{},"properties":{},"type":"string"},"type":{"description":"One of 'qemu', 'lxc', 'openvz' or 'unknown'.","enum":[],"extra":{},"properties":{},"type":"string"},"vmid":{"description":"The VM the backup belongs to.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"volid":{"description":"Backup volume ID.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/prunebackups"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ef810ce3bbce11f3f3cdcc6607ae9cf7dc62b1b39282e05b40167d2acfff93de","description":"Read storage RRD statistics (returns PNG).","extra":{"proxyto":"node"},"name":"rrd","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The list of datasources you want to display.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"ds"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/rrd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7ea36673b7e9e620442b49b8b240fefdebd96b87315ed46cbe29cb6d3d943180","description":"Read storage RRD statistics.","extra":{"proxyto":"node"},"name":"rrddata","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/rrddata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2a96c29dba0a0e11da7aaa1f7c100973a7b00b9f7a7457ffd0dc02130087c295","description":"Read storage status.","extra":{"proxyto":"node"},"name":"read_status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"active":{"description":"Set when storage is accessible.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"avail":{"description":"Available storage space in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"content":{"description":"Allowed storage content types.","enum":[],"extra":{},"format":"pve-storage-content-list","properties":{},"type":"string"},"enabled":{"description":"Set when storage is enabled (not disabled).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"shared":{"description":"Shared flag from storage configuration.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"total":{"description":"Total storage space in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"type":{"description":"Storage type.","enum":[],"extra":{},"properties":{},"type":"string"},"used":{"description":"Used storage space in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3b7941d7a0a66338f7e143b5bfcd44890820f378aa6c4b1064b3c1f8affc1b62","description":"Upload templates, ISO images, OVAs and VM images.","extra":{},"name":"upload","parameters":[{"definition":{"description":"The expected checksum of the file.","enum":[],"extra":{"requires":"checksum-algorithm","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"checksum"},{"definition":{"description":"The algorithm to calculate the checksum of the file.","enum":["md5","sha1","sha224","sha256","sha384","sha512"],"extra":{"requires":"checksum"},"optional":true,"properties":{},"type":"string"},"name":"checksum-algorithm"},{"definition":{"description":"Content type.","enum":["iso","vztmpl","import"],"extra":{},"format":"pve-storage-content","properties":{},"type":"string"},"name":"content"},{"definition":{"description":"The name of the file to create. Caution: This will be normalized!","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"filename"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"The source file name. This parameter is usually set by the REST handler. You can only overwrite it when connecting to the trusted port on localhost.","enum":[],"extra":{},"optional":true,"pattern":"/var/tmp/pveupload-[0-9a-f]+","properties":{},"type":"string"},"name":"tmpfilename"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.AllocateTemplate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/storage/{storage}/upload"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f69a09923a7e070b2be36d4ccb06e891f14a3518902eee5f7f7c27f6c58e46e7","description":"Delete subscription key of this node.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"4e8dea82ae94ae036d6411f557d2895ac4a0e56b9760df6d8bac0b42d8bd109d","description":"Read subscription info.","extra":{"proxyto":"node"},"name":"get","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"checktime":{"description":"Timestamp of the last check done.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"key":{"description":"The subscription key, if set and permitted to access.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"level":{"description":"A short code for the subscription level.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"message":{"description":"A more human readable status message.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"nextduedate":{"description":"Next due date of the set subscription.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"productname":{"description":"Human readable productname of the set subscription.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"regdate":{"description":"Register date of the set subscription.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serverid":{"description":"The server ID, if permitted to access.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"signature":{"description":"Signature for offline keys","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sockets":{"description":"The number of sockets for this host.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"status":{"description":"The current subscription status.","enum":["new","notfound","active","invalid","expired","suspended"],"extra":{},"properties":{},"type":"string"},"url":{"description":"URL to the web shop.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"fd4ac8b650dd7e96bdb5021c8454a3b09b574435f893a76329e3fad2900aa892","description":"Update subscription info.","extra":{"proxyto":"node"},"name":"update","parameters":[{"definition":{"default":0,"description":"Always connect to server, even if local cache is still valid.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"36ff0176410661df4a71dff72988369e92078b7b833c101aa43f014a614dc695","description":"Set subscription key.","extra":{"proxyto":"node"},"name":"set","parameters":[{"definition":{"description":"Proxmox VE subscription key","enum":[],"extra":{},"max_length":32,"pattern":"\\s*pve([1248])([cbsp])-[0-9a-f]{10}\\s*","properties":{},"type":"string"},"name":"key"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/subscription"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e14de8ac27c4a9923b2000cc7fedc148a856455c3e47ba84ddcd6d0b17d53fd5","description":"Suspend all VMs.","extra":{"proxyto":"node"},"name":"suspendall","parameters":[{"definition":{"description":"Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg, and if that's not set the available'\n .' CPU threads, clamped to a maximum of 8, are used.","enum":[],"extra":{"typetext":" (1 - 64)"},"maximum":64,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max-workers"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only consider Guests with these IDs.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"}],"permissions":{"description":"The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter. Additionally, you need 'VM.Config.Disk' on the '/vms/{vmid}' path and 'Datastore.AllocateSpace' for the configured state-storage(s)","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/suspendall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"627733cfb797f5cb56b37117c3cd10de855d36183e4e87b8e57c0207e6238edd","description":"Read system log","extra":{"proxyto":"node"},"name":"syslog","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"service"},{"definition":{"description":"Display all log since this date-time string.","enum":[],"extra":{},"optional":true,"pattern":"^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$","properties":{},"type":"string"},"name":"since"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"Display all log until this date-time string.","enum":[],"extra":{},"optional":true,"pattern":"^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$","properties":{},"type":"string"},"name":"until"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/syslog"},{"extra":{},"methods":[{"allow_token":true,"checksum":"18f412c273134b8357a94ec36fb4b7ad9d3b5709a61dbeb0c252638c0ff9e723","description":"Read task list for one node (finished tasks).","extra":{"proxyto":"node"},"name":"node_tasks","parameters":[{"definition":{"default":0,"description":"Only list tasks with a status of ERROR.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"errors"},{"definition":{"default":50,"description":"Only list this number of tasks.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list tasks since this UNIX epoch.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"since"},{"definition":{"default":"archive","description":"List archived, active or all tasks.","enum":["archive","active","all"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"default":0,"description":"List tasks beginning from this offset.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"List of Task States that should be returned.","enum":[],"extra":{"typetext":""},"format":"pve-task-status-type-list","optional":true,"properties":{},"type":"string"},"name":"statusfilter"},{"definition":{"description":"Only list tasks of this type (e.g., vzstart, vzdump).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"typefilter"},{"definition":{"description":"Only list tasks until this UNIX epoch.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"until"},{"definition":{"description":"Only list tasks from this user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"userfilter"},{"definition":{"description":"Only list tasks for this VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"List task associated with the current user, or all task the user has 'Sys.Audit' permissions on /nodes/ (the the task runs on).","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{upid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"endtime":{"enum":[],"extra":{"renderer":"timestamp","title":"Endtime"},"optional":true,"properties":{},"type":"integer"},"id":{"enum":[],"extra":{"title":"ID"},"properties":{},"type":"string"},"node":{"enum":[],"extra":{"title":"Node"},"properties":{},"type":"string"},"pid":{"enum":[],"extra":{"title":"PID"},"properties":{},"type":"integer"},"pstart":{"enum":[],"extra":{},"properties":{},"type":"integer"},"starttime":{"enum":[],"extra":{"renderer":"timestamp","title":"Starttime"},"properties":{},"type":"integer"},"status":{"enum":[],"extra":{"title":"Status"},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{"title":"Type"},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{"title":"UPID"},"properties":{},"type":"string"},"user":{"enum":[],"extra":{"title":"User"},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/tasks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8858ff934ad9888088c08685fc89c7640b161692fc40eb48b890b6349353f5e3","description":"Stop a task.","extra":{"proxyto":"node"},"name":"stop_task","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"upid"}],"permissions":{"description":"The user needs 'Sys.Modify' permissions on '/nodes/' if they aren't the owner of the task.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"88930b3a0d6654f9ead4d8adc76725935668dd88774af0a950aa627485d41dbf","description":"","extra":{},"name":"upid_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"upid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/tasks/{upid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"97cf12e3f3800b50fec0ac7c416f87360d426eecf6b736b4dd88512b421fce39","description":"Read task log.","extra":{"download_allowed":1,"proxyto":"node"},"name":"read_task_log","parameters":[{"definition":{"description":"Whether the tasklog file should be downloaded. This parameter can't be used in conjunction with other parameters","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"download"},{"definition":{"default":50,"description":"The number of lines to read from the tasklog.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Start at this line when reading the tasklog","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"The task's unique ID.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"upid"}],"permissions":{"description":"The user needs 'Sys.Audit' permissions on '/nodes/' if they aren't the owner of the task.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/tasks/{upid}/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e5dfb923817d11920e1fbf8b6b850f93409ba0826a5758d8960edf9c3f2c3901","description":"Read task status.","extra":{"proxyto":"node"},"name":"read_task_status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The task's unique ID.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"upid"}],"permissions":{"description":"The user needs 'Sys.Audit' permissions on '/nodes/' if they are not the owner of the task.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"exitstatus":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"node":{"enum":[],"extra":{},"properties":{},"type":"string"},"pid":{"enum":[],"extra":{},"properties":{},"type":"integer"},"pstart":{"enum":[],"extra":{},"properties":{},"type":"integer"},"starttime":{"enum":[],"extra":{},"properties":{},"type":"integer"},"status":{"enum":["running","stopped"],"extra":{},"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/tasks/{upid}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b9be3d64c745d32a4edaca71c578985ac3cc434556f976e4c4d4a59e6e319e2a","description":"Creates a VNC Shell proxy.","extra":{},"name":"termproxy","parameters":[{"definition":{"default":"login","description":"Run specific command or default to login (requires 'root@pam')","enum":["ceph_install","login","upgrade"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmd"},{"definition":{"default":"","description":"Add parameters to a command. Encoded as null terminated strings.","enum":[],"extra":{"requires":"cmd","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cmd-opts"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"port":{"description":"port used to bind termproxy to.","enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"description":"VNC ticket used to verify websocket connection.","enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"description":"UPID for termproxy worker task.","enum":[],"extra":{},"properties":{},"type":"string"},"user":{"description":"user/token that generated the VNC ticket in `ticket`.","enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/termproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"15558dd947c7c5db6fd939f2882db13ec7cc1f3ed3889a21151f2ece44c27e19","description":"Read server time and time zone settings.","extra":{"proxyto":"node"},"name":"time","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"localtime":{"description":"Seconds since 1970-01-01 00:00:00 (local time)","enum":[],"extra":{"renderer":"timestamp_gmt"},"minimum":1297163644,"properties":{},"type":"integer"},"time":{"description":"Seconds since 1970-01-01 00:00:00 UTC.","enum":[],"extra":{"renderer":"timestamp"},"minimum":1297163644,"properties":{},"type":"integer"},"timezone":{"description":"Time zone","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"6e0e6c4e973322e4ff4de02a8f54fc9a9a9de171237797934f9056943f940639","description":"Set time zone.","extra":{"proxyto":"node"},"name":"set_timezone","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"timezone"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/time"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a2f20ffba970376ccb2903020b544f6ac94e79d7aaba8ea5df4a4cf3a2cfd266","description":"API version details","extra":{"proxyto":"node"},"name":"version","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"release":{"description":"The current installed Proxmox VE Release","enum":[],"extra":{},"properties":{},"type":"string"},"repoid":{"description":"The short git commit hash ID from which this version was build","enum":[],"extra":{},"properties":{},"type":"string"},"version":{"description":"The current installed pve-manager package version","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/version"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f5b2e6159a384edaf43835b6c5785811badb29eaaec7269c82eaa338f74ee1ee","description":"Creates a VNC Shell proxy.","extra":{},"name":"vncshell","parameters":[{"definition":{"default":"login","description":"Run specific command or default to login (requires 'root@pam')","enum":["ceph_install","login","upgrade"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmd"},{"definition":{"default":"","description":"Add parameters to a command. Encoded as null terminated strings.","enum":[],"extra":{"requires":"cmd","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cmd-opts"},{"definition":{"description":"sets the height of the console in pixels.","enum":[],"extra":{"typetext":" (16 - 2160)"},"maximum":2160,"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"height"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"use websocket instead of standard vnc.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"websocket"},{"definition":{"description":"sets the width of the console in pixels.","enum":[],"extra":{"typetext":" (16 - 4096)"},"maximum":4096,"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"width"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"cert":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"description":"Password used for authentication within the VNC protocol. Consists of printable ASCII characters ('!' .. '~').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/vncshell"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3e203cc8270b6e799ae07148c27e684cf432b348ff4f1b259dd73f5f6f5eb2f6","description":"Opens a websocket for VNC traffic.","extra":{},"name":"vncwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Port number returned by previous 'vncshell' call.","enum":[],"extra":{"typetext":" (5900 - 5999)"},"maximum":5999,"minimum":5900,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Ticket from previous call to 'vncshell'.","enum":[],"extra":{"typetext":""},"max_length":512,"properties":{},"type":"string"},"name":"vncticket"}],"permissions":{"description":"You also need to pass a valid ticket (vncticket).","expression":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/vncwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5a0f6500e9bded700b04a70fe8ecb9eef679b595717cc5f94dcf2df4a0b0384c","description":"Create backup.","extra":{"proxyto":"node"},"name":"vzdump","parameters":[{"definition":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"all"},{"definition":{"default":0,"description":"Limit I/O bandwidth (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"compress"},{"definition":{"description":"Store resulting files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dumpdir"},{"definition":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"exclude"},{"definition":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"exclude-path"},{"definition":{"description":"Options for backup fleecing (VM only).","enum":[],"extra":{"typetext":"[[enabled=]<1|0>] [,storage=]"},"format":"backup-fleecing","optional":true,"properties":{},"type":"string"},"name":"fleecing"},{"definition":{"default":7,"description":"Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.","enum":[],"extra":{"typetext":" (0 - 8)"},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"ionice"},{"definition":{"description":"The ID of the backup job. If set, the 'backup-job' metadata field of the backup notification will be set to this value. Only root@pam can set this parameter.","enum":[],"extra":{},"max_length":50,"optional":true,"pattern":"\\S+","properties":{},"type":"string"},"name":"job-id"},{"definition":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"lockwait"},{"definition":{"default":"always","description":"Deprecated: use notification targets/matchers instead. Specify when to send a notification mail","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mailnotification"},{"definition":{"description":"Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{"typetext":""},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"name":"mailto"},{"definition":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"Only run if executed on this node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.","enum":[],"extra":{"requires":"storage","typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"notes-template"},{"definition":{"default":"auto","description":"Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.","enum":["auto","legacy-sendmail","notification-system"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"notification-mode"},{"definition":{"description":"PBS mode used to detect file changes and switch encoding format for container backups.","enum":["legacy","data","metadata"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"pbs-change-detection-mode"},{"definition":{"description":"Other performance-related settings.","enum":[],"extra":{"typetext":"[max-workers=] [,pbs-entries-max=]"},"format":"backup-performance","optional":true,"properties":{},"type":"string"},"name":"performance"},{"definition":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"pigz"},{"definition":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"If true, mark backup(s) as protected.","enum":[],"extra":{"requires":"storage","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protected"},{"definition":{"default":"keep-all=1","description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"default":0,"description":"Be quiet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"quiet"},{"definition":{"default":1,"description":"Prune older backups according to 'prune-backups'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove"},{"definition":{"description":"Use specified hook script.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"script"},{"definition":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stdexcludes"},{"definition":{"description":"Write tar to stdout, not to a file.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stdout"},{"definition":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stop"},{"definition":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"stopwait"},{"definition":{"description":"Store resulting file to this storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Store temporary files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tmpdir"},{"definition":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vmid"},{"definition":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"zstd"}],"permissions":{"description":"The user needs 'VM.Backup' permissions on any VM, and 'Datastore.AllocateSpace' on the backup storage (and fleecing storage when fleecing is used). The 'tmpdir', 'dumpdir', 'script' and 'job-id' parameters are restricted to the 'root@pam' user. The 'prune-backups' setting requires 'Datastore.Allocate' on the backup storage. The 'bwlimit', 'performance' and 'ionice' parameters require 'Sys.Modify' on '/'.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/vzdump"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e6788eb36aeb34a8da1c315b90ea7595ba89c072bc6ddc71d3ca7add84478b64","description":"Get the currently configured vzdump defaults.","extra":{"proxyto":"node"},"name":"defaults","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"}],"permissions":{"description":"The user needs 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions for the specified storage (or default storage if none specified). Some properties are only returned when the user has 'Sys.Audit' permissions for the node.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"all":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bwlimit":{"default":0,"description":"Limit I/O bandwidth (in KiB/s).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"compress":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"dumpdir":{"description":"Store resulting files to specified directory.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"exclude":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"exclude-path":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"fleecing":{"description":"Options for backup fleecing (VM only).","enum":[],"extra":{},"format":"backup-fleecing","optional":true,"properties":{},"type":"string"},"ionice":{"default":7,"description":"Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.","enum":[],"extra":{},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"lockwait":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"mailnotification":{"default":"always","description":"Deprecated: use notification targets/matchers instead. Specify when to send a notification mail","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"mailto":{"description":"Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"mode":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"node":{"description":"Only run if executed on this node.","enum":[],"extra":{},"format":"pve-node","optional":true,"properties":{},"type":"string"},"notes-template":{"description":"Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.","enum":[],"extra":{"requires":"storage"},"max_length":1024,"optional":true,"properties":{},"type":"string"},"notification-mode":{"default":"auto","description":"Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.","enum":["auto","legacy-sendmail","notification-system"],"extra":{},"optional":true,"properties":{},"type":"string"},"pbs-change-detection-mode":{"description":"PBS mode used to detect file changes and switch encoding format for container backups.","enum":["legacy","data","metadata"],"extra":{},"optional":true,"properties":{},"type":"string"},"performance":{"description":"Other performance-related settings.","enum":[],"extra":{},"format":"backup-performance","optional":true,"properties":{},"type":"string"},"pigz":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"pool":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"protected":{"description":"If true, mark backup(s) as protected.","enum":[],"extra":{"requires":"storage"},"optional":true,"properties":{},"type":"boolean"},"prune-backups":{"default":"keep-all=1","description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"quiet":{"default":0,"description":"Be quiet.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"remove":{"default":1,"description":"Prune older backups according to 'prune-backups'.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"script":{"description":"Use specified hook script.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"stdexcludes":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"stop":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"stopwait":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"storage":{"description":"Store resulting file to this storage.","enum":[],"extra":{"format_description":"storage ID"},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"tmpdir":{"description":"Store temporary files to specified directory.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vmid":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"zstd":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/vzdump/defaults"},{"extra":{},"methods":[{"allow_token":true,"checksum":"46b5389418506fa5f7d2d85017d6a32be6b0374dbb76191ec24067f39e16e8d9","description":"Extract configuration from vzdump backup archive.","extra":{"proxyto":"node"},"name":"extractconfig","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"The user needs 'VM.Backup' permissions on the backed up guest ID, and 'Datastore.AllocateSpace' on the backup storage.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/vzdump/extractconfig"},{"extra":{},"methods":[{"allow_token":true,"checksum":"08ea4b11d331163e4a96a0c898ba2d8587d9560fda14d97304383f4248499e0e","description":"Try to wake a node via 'wake on LAN' network packet.","extra":{},"name":"wakeonlan","parameters":[{"definition":{"description":"target node for wake on LAN packet","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"description":"MAC address used to assemble the WoL magic packet.","enum":[],"extra":{},"format":"mac-addr","properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/wakeonlan"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f4566d45dc0a2a49009509edfd1756bd72eabd7f60446d1184660ea5bc43c1f7","description":"Delete pool.","extra":{},"name":"delete_pool","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"}],"permissions":{"description":"You can only delete empty pools (no members).","expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"33205b793af733e2b704df3fd61c56dee43038332e936764e59c0f5fb185823a","description":"List pools or get pool configuration.","extra":{},"name":"index","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"poolid"},{"definition":{"enum":["qemu","lxc","storage"],"extra":{"requires":"poolid"},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"List all pools where you have Pool.Audit permissions on /pool/, or the pool specific with {poolid}","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{poolid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"members":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"node":{"enum":[],"extra":{},"properties":{},"type":"string"},"storage":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":["qemu","lxc","openvz","storage"],"extra":{},"properties":{},"type":"string"},"vmid":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"poolid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"a2cb3cd45802791e51049833b8254ee8828f1f7e701c0fad2bf797ed4c4ed346","description":"Create new pool.","extra":{},"name":"create_pool","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"}],"permissions":{"expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"c211aff3cf1cda7aa8ffb37e56d69ef36e3cc19bda75c341fd6b6d9fd565ae5c","description":"Update pool.","extra":{},"name":"update_pool","parameters":[{"definition":{"default":0,"description":"Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"allow-move"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":0,"description":"Remove the passed VMIDs and/or storage IDs instead of adding them.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"},{"definition":{"description":"List of storage IDs to add or remove from this pool.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id-list","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"List of guest VMIDs to add or remove from this pool.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"}],"permissions":{"description":"You also need the right to modify permissions on any object you add/delete.","expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/pools"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b7038e5f294f100d28cfdc7123623f8b4d5f7c2151133c6b9708146818711cd0","description":"Delete pool (deprecated, no support for nested pools, use 'DELETE /pools/?poolid={poolid}').","extra":{},"name":"delete_pool_deprecated","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"}],"permissions":{"description":"You can only delete empty pools (no members).","expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"961b5c048f0d5f962830bb4c34b9f06b519c08ea28f8f115d23bd8e5c497ffdc","description":"Get pool configuration (deprecated, no support for nested pools, use 'GET /pools/?poolid={poolid}').","extra":{},"name":"read_pool","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"},{"definition":{"enum":["qemu","lxc","storage"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/pool/{poolid}",["Pool.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"members":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"node":{"enum":[],"extra":{},"properties":{},"type":"string"},"storage":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":["qemu","lxc","openvz","storage"],"extra":{},"properties":{},"type":"string"},"vmid":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"adf5ed4e8c004cb01739cd4841194fc9f1f84bd0a1dfde041a0618373ea1cb31","description":"Update pool data (deprecated, no support for nested pools - use 'PUT /pools/?poolid={poolid}' instead).","extra":{},"name":"update_pool_deprecated","parameters":[{"definition":{"default":0,"description":"Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"allow-move"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":0,"description":"Remove the passed VMIDs and/or storage IDs instead of adding them.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"},{"definition":{"description":"List of storage IDs to add or remove from this pool.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id-list","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"List of guest VMIDs to add or remove from this pool.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"}],"permissions":{"description":"You also need the right to modify permissions on any object you add/delete.","expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/pools/{poolid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4ef00604fb1871d72bff4b94656f846cebc8ae31c2e54718a717768066e01826","description":"Storage index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list storage of specific type","enum":["btrfs","cephfs","cifs","dir","esxi","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{storage}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"storage":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"6b5da59748e7b72dccc43b2e15d7ac5d59d9803c162234a041c242f97f025764","description":"Create a new storage.","extra":{},"name":"create","parameters":[{"definition":{"description":"Authsupported.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"authsupported"},{"definition":{"description":"Base volume. This volume is automatically activated.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"base"},{"definition":{"description":"ZFS block size","enum":[],"extra":{"format_description":"a power of 2 with optional k or m suffix","typetext":""},"format":"pve-storage-zfs-blocksize","optional":true,"properties":{},"type":"string"},"name":"blocksize"},{"definition":{"description":"Set I/O bandwidth limit for various operations (in KiB/s).","enum":[],"extra":{"typetext":"[clone=] [,default=] [,migration=] [,move=] [,restore=]"},"format":{"clone":{"description":"bandwidth limit in KiB/s for cloning disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"default":{"description":"default bandwidth limit in KiB/s","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"migration":{"description":"bandwidth limit in KiB/s for migrating guests (including moving local disks)","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"move":{"description":"bandwidth limit in KiB/s for moving disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"restore":{"description":"bandwidth limit in KiB/s for restoring guests from backups","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"}},"optional":true,"properties":{},"type":"string"},"name":"bwlimit"},{"definition":{"description":"host group for comstar views","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comstar_hg"},{"definition":{"description":"target group for comstar views","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comstar_tg"},{"definition":{"description":"Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n","enum":[],"extra":{"typetext":""},"format":"pve-storage-content-list","optional":true,"properties":{},"type":"string"},"name":"content"},{"definition":{"description":"Overrides for default content type directories.","enum":[],"extra":{"typetext":""},"format":"pve-dir-override-list","optional":true,"properties":{},"type":"string"},"name":"content-dirs"},{"definition":{"default":"yes","description":"Create the base directory if it doesn't exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"create-base-path"},{"definition":{"default":"yes","description":"Populate the directory with the default structure.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"create-subdirs"},{"definition":{"description":"Data Pool (for erasure coding only)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"data-pool"},{"definition":{"description":"Proxmox Backup Server datastore name.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"datastore"},{"definition":{"description":"Flag to disable the storage.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"CIFS domain.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"Encryption key. Use 'autogen' to generate one automatically without passphrase.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"encryption-key"},{"definition":{"description":"NFS export path.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"export"},{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"Default image format.","enum":["raw","qcow2","subvol","vmdk"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"The Ceph filesystem name.","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"fs-name"},{"definition":{"description":"Mount CephFS through FUSE.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"fuse"},{"definition":{"default":"no","description":"Assume the given path is an externally managed mountpoint and consider the storage offline if it is not mounted. Using a boolean (yes/no) value serves as a shortcut to using the target path in this field.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"is_mountpoint"},{"definition":{"description":"iscsi provider","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"iscsiprovider"},{"definition":{"description":"Client keyring contents (for external clusters).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"keyring"},{"definition":{"default":0,"description":"Always access rbd through krbd kernel module.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"krbd"},{"definition":{"description":"target portal group for Linux LIO targets","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lio_tpg"},{"definition":{"description":"Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"master-pubkey"},{"definition":{"default":"Unlimited for users with Datastore.Allocate privilege, 5 for other users","description":"Maximal number of protected backups per guest. Use '-1' for unlimited.","enum":[],"extra":{"typetext":" (-1 - N)"},"minimum":-1,"optional":true,"properties":{},"type":"integer"},"name":"max-protected-backups"},{"definition":{"default":"yes","description":"Create the directory if it doesn't exist and populate it with default sub-dirs. NOTE: Deprecated, use the 'create-base-path' and 'create-subdirs' options instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"mkdir"},{"definition":{"description":"IP addresses of monitors (for external clusters).","enum":[],"extra":{"typetext":""},"format":"pve-storage-portal-dns-list","optional":true,"properties":{},"type":"string"},"name":"monhost"},{"definition":{"description":"mount point","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"mountpoint"},{"definition":{"description":"Namespace.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"namespace"},{"definition":{"default":0,"description":"Set the NOCOW flag on files. Disables data checksumming and causes data errors to be unrecoverable from while allowing direct I/O. Only use this if data does not need to be any more safe than on a single ext4 formatted disk with no underlying raid system.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nocow"},{"definition":{"description":"List of nodes for which the storage configuration applies.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"disable write caching on the target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nowritecache"},{"definition":{"description":"NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')","enum":[],"extra":{"typetext":""},"format":"pve-storage-options","optional":true,"properties":{},"type":"string"},"name":"options"},{"definition":{"description":"Password for accessing the share/datastore.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"File system path.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"Pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"Use this port to connect to the storage instead of the default one (for example, with PBS or ESXi). For NFS and CIFS, use the 'options' option to configure the port via the mount options.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"iSCSI portal (IP or DNS name with optional port).","enum":[],"extra":{"typetext":""},"format":"pve-storage-portal-dns","optional":true,"properties":{},"type":"string"},"name":"portal"},{"definition":{"default":"metadata","description":"Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off.","enum":["off","metadata","falloc","full"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"preallocation"},{"definition":{"description":"The retention options with shorter intervals are processed first with --keep-last being the very first one. Each option covers a specific period of time. We say that backups within this period are covered by this option. The next option does not take care of already covered backups and only considers older backups.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"description":"Zero-out data when removing LVs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"saferemove"},{"definition":{"default":32,"description":"Wipe step size in MiB. It will be capped to the maximum supported by the storage.","enum":["1","2","4","8","16","32"],"extra":{},"optional":true,"properties":{},"type":"integer"},"name":"saferemove-stepsize"},{"definition":{"description":"Wipe throughput (cstream -t parameter value).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"saferemove_throughput"},{"definition":{"description":"Server IP or DNS name.","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","optional":true,"properties":{},"type":"string"},"name":"server"},{"definition":{"description":"CIFS share.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"share"},{"definition":{"description":"Indicate that this is a single storage with the same contents on all nodes (or all listed in the 'nodes' option). It will not make the contents of a local storage automatically accessible to other nodes, it just marks an already shared storage as such!","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"shared"},{"definition":{"default":"false","description":"Disable TLS certificate verification, only enable on fully trusted networks!","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skip-cert-verification"},{"definition":{"default":"default","description":"SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server.","enum":["default","2.0","2.1","3","3.0","3.11"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"smbversion"},{"definition":{"default":0,"description":"Enable support for creating storage-vendor agnostic snapshot through volume backing-chains.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"snapshot-as-volume-chain"},{"definition":{"description":"use sparse volumes","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"sparse"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Subdir to mount.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"subdir"},{"definition":{"description":"Only list logical volumes tagged with 'pve-vm-ID'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tagged_only"},{"definition":{"description":"iSCSI target.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"LVM thin pool LV name.","enum":[],"extra":{"typetext":""},"format":"pve-storage-vgname","optional":true,"properties":{},"type":"string"},"name":"thinpool"},{"definition":{"description":"Storage type.","enum":["btrfs","cephfs","cifs","dir","esxi","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"RBD Id.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username"},{"definition":{"description":"Volume group name.","enum":[],"extra":{"typetext":""},"format":"pve-storage-vgname","optional":true,"properties":{},"type":"string"},"name":"vgname"},{"definition":{"description":"Base path where to look for the created ZFS block devices. Set automatically during creation if not specified. Usually '/dev/zvol'.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"zfs-base-path"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"config":{"description":"Partial, possibly server generated, configuration properties.","enum":[],"extra":{"additionalProperties":1},"optional":true,"properties":{"encryption-key":{"description":"The, possibly auto-generated, encryption-key.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"storage":{"description":"The ID of the created storage.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The type of the created storage.","enum":["btrfs","cephfs","cifs","dir","esxi","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"POST"}],"path":"/storage"},{"extra":{},"methods":[{"allow_token":true,"checksum":"37429346228be0afd5c6d7e7489e2958f25d9fdf19dee4f3c724b44696c84565","description":"Delete storage configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"19316a49fd07ddbf0d58da4bf761b3bad2f3e4a5b88f990919a04589241ca0b1","description":"Read storage configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"e6745e8c74406dc644fd447f9cfba3404c4be56e5c2f8db4e6047fc7e53a617f","description":"Update storage configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"ZFS block size","enum":[],"extra":{"format_description":"a power of 2 with optional k or m suffix","typetext":""},"format":"pve-storage-zfs-blocksize","optional":true,"properties":{},"type":"string"},"name":"blocksize"},{"definition":{"description":"Set I/O bandwidth limit for various operations (in KiB/s).","enum":[],"extra":{"typetext":"[clone=] [,default=] [,migration=] [,move=] [,restore=]"},"format":{"clone":{"description":"bandwidth limit in KiB/s for cloning disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"default":{"description":"default bandwidth limit in KiB/s","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"migration":{"description":"bandwidth limit in KiB/s for migrating guests (including moving local disks)","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"move":{"description":"bandwidth limit in KiB/s for moving disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"restore":{"description":"bandwidth limit in KiB/s for restoring guests from backups","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"}},"optional":true,"properties":{},"type":"string"},"name":"bwlimit"},{"definition":{"description":"host group for comstar views","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comstar_hg"},{"definition":{"description":"target group for comstar views","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comstar_tg"},{"definition":{"description":"Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n","enum":[],"extra":{"typetext":""},"format":"pve-storage-content-list","optional":true,"properties":{},"type":"string"},"name":"content"},{"definition":{"description":"Overrides for default content type directories.","enum":[],"extra":{"typetext":""},"format":"pve-dir-override-list","optional":true,"properties":{},"type":"string"},"name":"content-dirs"},{"definition":{"default":"yes","description":"Create the base directory if it doesn't exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"create-base-path"},{"definition":{"default":"yes","description":"Populate the directory with the default structure.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"create-subdirs"},{"definition":{"description":"Data Pool (for erasure coding only)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"data-pool"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Flag to disable the storage.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"CIFS domain.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"Encryption key. Use 'autogen' to generate one automatically without passphrase.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"encryption-key"},{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"Default image format.","enum":["raw","qcow2","subvol","vmdk"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"The Ceph filesystem name.","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"fs-name"},{"definition":{"description":"Mount CephFS through FUSE.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"fuse"},{"definition":{"default":"no","description":"Assume the given path is an externally managed mountpoint and consider the storage offline if it is not mounted. Using a boolean (yes/no) value serves as a shortcut to using the target path in this field.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"is_mountpoint"},{"definition":{"description":"Client keyring contents (for external clusters).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"keyring"},{"definition":{"default":0,"description":"Always access rbd through krbd kernel module.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"krbd"},{"definition":{"description":"target portal group for Linux LIO targets","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lio_tpg"},{"definition":{"description":"Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"master-pubkey"},{"definition":{"default":"Unlimited for users with Datastore.Allocate privilege, 5 for other users","description":"Maximal number of protected backups per guest. Use '-1' for unlimited.","enum":[],"extra":{"typetext":" (-1 - N)"},"minimum":-1,"optional":true,"properties":{},"type":"integer"},"name":"max-protected-backups"},{"definition":{"default":"yes","description":"Create the directory if it doesn't exist and populate it with default sub-dirs. NOTE: Deprecated, use the 'create-base-path' and 'create-subdirs' options instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"mkdir"},{"definition":{"description":"IP addresses of monitors (for external clusters).","enum":[],"extra":{"typetext":""},"format":"pve-storage-portal-dns-list","optional":true,"properties":{},"type":"string"},"name":"monhost"},{"definition":{"description":"mount point","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"mountpoint"},{"definition":{"description":"Namespace.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"namespace"},{"definition":{"default":0,"description":"Set the NOCOW flag on files. Disables data checksumming and causes data errors to be unrecoverable from while allowing direct I/O. Only use this if data does not need to be any more safe than on a single ext4 formatted disk with no underlying raid system.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nocow"},{"definition":{"description":"List of nodes for which the storage configuration applies.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"disable write caching on the target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nowritecache"},{"definition":{"description":"NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')","enum":[],"extra":{"typetext":""},"format":"pve-storage-options","optional":true,"properties":{},"type":"string"},"name":"options"},{"definition":{"description":"Password for accessing the share/datastore.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"Use this port to connect to the storage instead of the default one (for example, with PBS or ESXi). For NFS and CIFS, use the 'options' option to configure the port via the mount options.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"default":"metadata","description":"Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off.","enum":["off","metadata","falloc","full"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"preallocation"},{"definition":{"description":"The retention options with shorter intervals are processed first with --keep-last being the very first one. Each option covers a specific period of time. We say that backups within this period are covered by this option. The next option does not take care of already covered backups and only considers older backups.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"description":"Zero-out data when removing LVs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"saferemove"},{"definition":{"default":32,"description":"Wipe step size in MiB. It will be capped to the maximum supported by the storage.","enum":["1","2","4","8","16","32"],"extra":{},"optional":true,"properties":{},"type":"integer"},"name":"saferemove-stepsize"},{"definition":{"description":"Wipe throughput (cstream -t parameter value).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"saferemove_throughput"},{"definition":{"description":"Server IP or DNS name.","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","optional":true,"properties":{},"type":"string"},"name":"server"},{"definition":{"description":"Indicate that this is a single storage with the same contents on all nodes (or all listed in the 'nodes' option). It will not make the contents of a local storage automatically accessible to other nodes, it just marks an already shared storage as such!","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"shared"},{"definition":{"default":"false","description":"Disable TLS certificate verification, only enable on fully trusted networks!","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skip-cert-verification"},{"definition":{"default":"default","description":"SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server.","enum":["default","2.0","2.1","3","3.0","3.11"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"smbversion"},{"definition":{"default":0,"description":"Enable support for creating storage-vendor agnostic snapshot through volume backing-chains.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"snapshot-as-volume-chain"},{"definition":{"description":"use sparse volumes","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"sparse"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Subdir to mount.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"subdir"},{"definition":{"description":"Only list logical volumes tagged with 'pve-vm-ID'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tagged_only"},{"definition":{"description":"RBD Id.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username"},{"definition":{"description":"Base path where to look for the created ZFS block devices. Set automatically during creation if not specified. Usually '/dev/zvol'.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"zfs-base-path"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"config":{"description":"Partial, possibly server generated, configuration properties.","enum":[],"extra":{"additionalProperties":1},"optional":true,"properties":{"encryption-key":{"description":"The, possibly auto-generated, encryption-key.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"storage":{"description":"The ID of the created storage.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The type of the created storage.","enum":["btrfs","cephfs","cifs","dir","esxi","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"PUT"}],"path":"/storage/{storage}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"45540f92dcd5801a88dc510d274bd94436e995188f217cf527e705b6b92320f8","description":"API version details, including some parts of the global datacenter config.","extra":{},"name":"version","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"console":{"description":"The default console viewer to use.","enum":["applet","vv","html5","xtermjs"],"extra":{},"optional":true,"properties":{},"type":"string"},"release":{"description":"The current Proxmox VE point release in `x.y` format.","enum":[],"extra":{},"properties":{},"type":"string"},"repoid":{"description":"The short git revision from which this version was build.","enum":[],"extra":{},"pattern":"[0-9a-fA-F]{8,64}","properties":{},"type":"string"},"version":{"description":"The full pve-manager package version of this node.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/version"}],"raw_sha256":"f2b77b57c71f3781a0993cc5062940ef31e0843fd9a6bcfdb4de4dd2001d6d9e","retrieved_at":"2026-07-12T21:18:42.527750Z","source_version":"9.2.3"} \ No newline at end of file diff --git a/contracts/fce6db0a784b3a9b447895895fc6ff4b4437c2dce82e5f3db99227af217726fa/manifest.json b/contracts/fce6db0a784b3a9b447895895fc6ff4b4437c2dce82e5f3db99227af217726fa/manifest.json new file mode 100644 index 0000000..3c314a2 --- /dev/null +++ b/contracts/fce6db0a784b3a9b447895895fc6ff4b4437c2dce82e5f3db99227af217726fa/manifest.json @@ -0,0 +1 @@ +{"method_count":605,"path_count":398,"raw_sha256":"bbe03a42c55b3f9ae77a5b5216c1a8554f4fffd0f4b266848f4af26be295946e","snapshot_sha256":"fce6db0a784b3a9b447895895fc6ff4b4437c2dce82e5f3db99227af217726fa","source_version":"8.4.5"} \ No newline at end of file diff --git a/contracts/fce6db0a784b3a9b447895895fc6ff4b4437c2dce82e5f3db99227af217726fa/raw.js b/contracts/fce6db0a784b3a9b447895895fc6ff4b4437c2dce82e5f3db99227af217726fa/raw.js new file mode 100644 index 0000000..f460bd0 --- /dev/null +++ b/contracts/fce6db0a784b3a9b447895895fc6ff4b4437c2dce82e5f3db99227af217726fa/raw.js @@ -0,0 +1,59148 @@ +const apiSchema = [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Mark replication job for removal.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "Will remove the jobconfig entry, but will not cleanup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "keep" : { + "default" : 0, + "description" : "Keep replicated data at target (do not remove).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read replication job configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/.", + "user" : "all" + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update replication job configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable/deactivate the entry.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 1, + "optional" : 1, + "type" : "number", + "typetext" : " (1 - N)" + }, + "remove_job" : { + "description" : "Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.", + "enum" : [ + "local", + "full" + ], + "optional" : 1, + "type" : "string" + }, + "schedule" : { + "default" : "*/15", + "description" : "Storage replication schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "For internal use, to detect if the guest was stolen.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/replication/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List replication jobs.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "Will only return replication jobs for which the calling user has VM.Audit permission on /vms/.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new replication job", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable/deactivate the entry.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 1, + "optional" : 1, + "type" : "number", + "typetext" : " (1 - N)" + }, + "remove_job" : { + "description" : "Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.", + "enum" : [ + "local", + "full" + ], + "optional" : 1, + "type" : "string" + }, + "schedule" : { + "default" : "*/15", + "description" : "Storage replication schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "For internal use, to detect if the guest was stolen.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Section type.", + "enum" : [ + "local" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/replication", + "text" : "replication" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove Metric server.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read metric server configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new external metric server config", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "api-path-prefix" : { + "description" : "An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bucket" : { + "description" : "The InfluxDB bucket/db. Only necessary when using the http v2 api.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the plugin.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the entry.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "influxdbproto" : { + "default" : "udp", + "enum" : [ + "udp", + "http", + "https" + ], + "optional" : 1, + "type" : "string" + }, + "max-body-size" : { + "default" : 25000000, + "description" : "InfluxDB max-body-size in bytes. Requests are batched up to this size.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mtu" : { + "default" : 1500, + "description" : "MTU for metrics transmission over UDP", + "maximum" : 65536, + "minimum" : 512, + "optional" : 1, + "type" : "integer", + "typetext" : " (512 - 65536)" + }, + "organization" : { + "description" : "The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "root graphite path (ex: proxmox.mycluster.mykey)", + "format" : "graphite-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "server network port", + "maximum" : 65536, + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - 65536)" + }, + "proto" : { + "description" : "Protocol to send graphite data. TCP or UDP (default)", + "enum" : [ + "udp", + "tcp" + ], + "optional" : 1, + "type" : "string" + }, + "server" : { + "description" : "server dns name or IP address", + "format" : "address", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 1, + "description" : "graphite TCP socket timeout (default=1)", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "token" : { + "description" : "The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "graphite", + "influxdb" + ], + "format" : "pve-configid", + "type" : "string" + }, + "verify-certificate" : { + "default" : 1, + "description" : "Set to 0 to disable certificate verification for https endpoints.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update metric server configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "api-path-prefix" : { + "description" : "An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bucket" : { + "description" : "The InfluxDB bucket/db. Only necessary when using the http v2 api.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the plugin.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the entry.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "influxdbproto" : { + "default" : "udp", + "enum" : [ + "udp", + "http", + "https" + ], + "optional" : 1, + "type" : "string" + }, + "max-body-size" : { + "default" : 25000000, + "description" : "InfluxDB max-body-size in bytes. Requests are batched up to this size.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mtu" : { + "default" : 1500, + "description" : "MTU for metrics transmission over UDP", + "maximum" : 65536, + "minimum" : 512, + "optional" : 1, + "type" : "integer", + "typetext" : " (512 - 65536)" + }, + "organization" : { + "description" : "The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "root graphite path (ex: proxmox.mycluster.mykey)", + "format" : "graphite-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "server network port", + "maximum" : 65536, + "minimum" : 1, + "type" : "integer", + "typetext" : " (1 - 65536)" + }, + "proto" : { + "description" : "Protocol to send graphite data. TCP or UDP (default)", + "enum" : [ + "udp", + "tcp" + ], + "optional" : 1, + "type" : "string" + }, + "server" : { + "description" : "server dns name or IP address", + "format" : "address", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 1, + "description" : "graphite TCP socket timeout (default=1)", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "token" : { + "description" : "The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "verify-certificate" : { + "default" : 1, + "description" : "Set to 0 to disable certificate verification for https endpoints.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/metrics/server/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List configured metric servers.", + "method" : "GET", + "name" : "server_index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "disable" : { + "description" : "Flag to disable the plugin.", + "type" : "boolean" + }, + "id" : { + "description" : "The ID of the entry.", + "type" : "string" + }, + "port" : { + "description" : "Server network port", + "type" : "integer" + }, + "server" : { + "description" : "Server dns name or IP address", + "type" : "string" + }, + "type" : { + "description" : "Plugin type.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/metrics/server", + "text" : "server" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Retrieve metrics of the cluster.", + "method" : "GET", + "name" : "export", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "history" : { + "default" : 0, + "description" : "Also return historic values. Returns full available metric history unless `start-time` is also set", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "local-only" : { + "default" : 0, + "description" : "Only return metrics for the current node instead of the whole cluster", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "start-time" : { + "default" : 0, + "description" : "Only include metrics with a timestamp > start-time.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "data" : { + "description" : "Array of system metrics. Metrics are sorted by their timestamp.", + "items" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Unique identifier for this metric object, for instance 'node/' or 'qemu/'.", + "type" : "string" + }, + "metric" : { + "description" : "Name of the metric.", + "type" : "string" + }, + "timestamp" : { + "description" : "Time at which this metric was observed", + "type" : "integer" + }, + "type" : { + "description" : "Type of the metric.", + "enum" : [ + "gauge", + "counter", + "derive" + ], + "type" : "string" + }, + "value" : { + "description" : "Metric value.", + "type" : "number" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/metrics/export", + "text" : "export" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Metrics index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/metrics", + "text" : "metrics" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns known notification metadata fields", + "method" : "GET", + "name" : "get_matcher_fields", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 0, + "returns" : { + "items" : { + "properties" : { + "name" : { + "description" : "Name of the field.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/notifications/matcher-fields", + "text" : "matcher-fields" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns known notification metadata fields and their known values", + "method" : "GET", + "name" : "get_matcher_field_values", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "Additional comment for this value.", + "optional" : 1, + "type" : "string" + }, + "field" : { + "description" : "Field this value belongs to.", + "type" : "string" + }, + "value" : { + "description" : "Notification metadata value known by the system.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/notifications/matcher-field-values", + "text" : "matcher-field-values" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove sendmail endpoint", + "method" : "DELETE", + "name" : "delete_sendmail_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Return a specific sendmail endpoint", + "method" : "GET", + "name" : "get_sendmail_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "author" : { + "description" : "Author of the mail", + "optional" : 1, + "type" : "string" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean" + }, + "from-address" : { + "description" : "`From` address for the mail", + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "List of email recipients", + "items" : { + "format" : "email-or-username", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "mailto-user" : { + "description" : "List of users", + "items" : { + "format" : "pve-userid", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update existing sendmail endpoint", + "method" : "PUT", + "name" : "update_sendmail_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "author" : { + "description" : "Author of the mail", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "from-address" : { + "description" : "`From` address for the mail", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mailto" : { + "description" : "List of email recipients", + "items" : { + "format" : "email-or-username", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mailto-user" : { + "description" : "List of users", + "items" : { + "format" : "pve-userid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/notifications/endpoints/sendmail/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns a list of all sendmail endpoints", + "method" : "GET", + "name" : "get_sendmail_endpoints", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "author" : { + "description" : "Author of the mail", + "optional" : 1, + "type" : "string" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean" + }, + "from-address" : { + "description" : "`From` address for the mail", + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "List of email recipients", + "items" : { + "format" : "email-or-username", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "mailto-user" : { + "description" : "List of users", + "items" : { + "format" : "pve-userid", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string" + }, + "origin" : { + "description" : "Show if this entry was created by a user or was built-in", + "enum" : [ + "user-created", + "builtin", + "modified-builtin" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sendmail endpoint", + "method" : "POST", + "name" : "create_sendmail_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "author" : { + "description" : "Author of the mail", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "from-address" : { + "description" : "`From` address for the mail", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mailto" : { + "description" : "List of email recipients", + "items" : { + "format" : "email-or-username", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mailto-user" : { + "description" : "List of users", + "items" : { + "format" : "pve-userid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/notifications/endpoints/sendmail", + "text" : "sendmail" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove gotify endpoint", + "method" : "DELETE", + "name" : "delete_gotify_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Return a specific gotify endpoint", + "method" : "GET", + "name" : "get_gotify_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string" + }, + "server" : { + "description" : "Server URL", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update existing gotify endpoint", + "method" : "PUT", + "name" : "update_gotify_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "Server URL", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "token" : { + "description" : "Secret token", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/notifications/endpoints/gotify/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns a list of all gotify endpoints", + "method" : "GET", + "name" : "get_gotify_endpoints", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string" + }, + "origin" : { + "description" : "Show if this entry was created by a user or was built-in", + "enum" : [ + "user-created", + "builtin", + "modified-builtin" + ], + "type" : "string" + }, + "server" : { + "description" : "Server URL", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new gotify endpoint", + "method" : "POST", + "name" : "create_gotify_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "Server URL", + "type" : "string", + "typetext" : "" + }, + "token" : { + "description" : "Secret token", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/notifications/endpoints/gotify", + "text" : "gotify" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove smtp endpoint", + "method" : "DELETE", + "name" : "delete_smtp_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Return a specific smtp endpoint", + "method" : "GET", + "name" : "get_smtp_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "author" : { + "description" : "Author of the mail. Defaults to 'Proxmox VE'.", + "optional" : 1, + "type" : "string" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean" + }, + "from-address" : { + "description" : "`From` address for the mail", + "type" : "string" + }, + "mailto" : { + "description" : "List of email recipients", + "items" : { + "format" : "email-or-username", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "mailto-user" : { + "description" : "List of users", + "items" : { + "format" : "pve-userid", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "mode" : { + "default" : "tls", + "description" : "Determine which encryption method shall be used for the connection.", + "enum" : [ + "insecure", + "starttls", + "tls" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string" + }, + "port" : { + "description" : "The port to be used. Defaults to 465 for TLS based connections, 587 for STARTTLS based connections and port 25 for insecure plain-text connections.", + "optional" : 1, + "type" : "integer" + }, + "server" : { + "description" : "The address of the SMTP server.", + "type" : "string" + }, + "username" : { + "description" : "Username for SMTP authentication", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update existing smtp endpoint", + "method" : "PUT", + "name" : "update_smtp_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "author" : { + "description" : "Author of the mail. Defaults to 'Proxmox VE'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "from-address" : { + "description" : "`From` address for the mail", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mailto" : { + "description" : "List of email recipients", + "items" : { + "format" : "email-or-username", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mailto-user" : { + "description" : "List of users", + "items" : { + "format" : "pve-userid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mode" : { + "default" : "tls", + "description" : "Determine which encryption method shall be used for the connection.", + "enum" : [ + "insecure", + "starttls", + "tls" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "Password for SMTP authentication", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "The port to be used. Defaults to 465 for TLS based connections, 587 for STARTTLS based connections and port 25 for insecure plain-text connections.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "server" : { + "description" : "The address of the SMTP server.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "Username for SMTP authentication", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/notifications/endpoints/smtp/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns a list of all smtp endpoints", + "method" : "GET", + "name" : "get_smtp_endpoints", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "author" : { + "description" : "Author of the mail. Defaults to 'Proxmox VE'.", + "optional" : 1, + "type" : "string" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean" + }, + "from-address" : { + "description" : "`From` address for the mail", + "type" : "string" + }, + "mailto" : { + "description" : "List of email recipients", + "items" : { + "format" : "email-or-username", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "mailto-user" : { + "description" : "List of users", + "items" : { + "format" : "pve-userid", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "mode" : { + "default" : "tls", + "description" : "Determine which encryption method shall be used for the connection.", + "enum" : [ + "insecure", + "starttls", + "tls" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string" + }, + "origin" : { + "description" : "Show if this entry was created by a user or was built-in", + "enum" : [ + "user-created", + "builtin", + "modified-builtin" + ], + "type" : "string" + }, + "port" : { + "description" : "The port to be used. Defaults to 465 for TLS based connections, 587 for STARTTLS based connections and port 25 for insecure plain-text connections.", + "optional" : 1, + "type" : "integer" + }, + "server" : { + "description" : "The address of the SMTP server.", + "type" : "string" + }, + "username" : { + "description" : "Username for SMTP authentication", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new smtp endpoint", + "method" : "POST", + "name" : "create_smtp_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "author" : { + "description" : "Author of the mail. Defaults to 'Proxmox VE'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "from-address" : { + "description" : "`From` address for the mail", + "type" : "string", + "typetext" : "" + }, + "mailto" : { + "description" : "List of email recipients", + "items" : { + "format" : "email-or-username", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mailto-user" : { + "description" : "List of users", + "items" : { + "format" : "pve-userid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mode" : { + "default" : "tls", + "description" : "Determine which encryption method shall be used for the connection.", + "enum" : [ + "insecure", + "starttls", + "tls" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "Password for SMTP authentication", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "The port to be used. Defaults to 465 for TLS based connections, 587 for STARTTLS based connections and port 25 for insecure plain-text connections.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "server" : { + "description" : "The address of the SMTP server.", + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "Username for SMTP authentication", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/notifications/endpoints/smtp", + "text" : "smtp" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove webhook endpoint", + "method" : "DELETE", + "name" : "delete_webhook_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Return a specific webhook endpoint", + "method" : "GET", + "name" : "get_webhook_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "body" : { + "description" : "HTTP body, base64 encoded", + "optional" : 1, + "type" : "string" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean" + }, + "header" : { + "description" : "HTTP headers to set. These have to be formatted as a property string in the format name=,value=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "method" : { + "description" : "HTTP method", + "enum" : [ + "post", + "put", + "get" + ], + "type" : "string" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string" + }, + "secret" : { + "description" : "Secrets to set. These have to be formatted as a property string in the format name=,value=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "url" : { + "description" : "Server URL", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update existing webhook endpoint", + "method" : "PUT", + "name" : "update_webhook_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "body" : { + "description" : "HTTP body, base64 encoded", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "header" : { + "description" : "HTTP headers to set. These have to be formatted as a property string in the format name=,value=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "method" : { + "description" : "HTTP method", + "enum" : [ + "post", + "put", + "get" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "secret" : { + "description" : "Secrets to set. These have to be formatted as a property string in the format name=,value=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "url" : { + "description" : "Server URL", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/notifications/endpoints/webhook/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns a list of all webhook endpoints", + "method" : "GET", + "name" : "get_webhook_endpoints", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "body" : { + "description" : "HTTP body, base64 encoded", + "optional" : 1, + "type" : "string" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean" + }, + "header" : { + "description" : "HTTP headers to set. These have to be formatted as a property string in the format name=,value=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "method" : { + "description" : "HTTP method", + "enum" : [ + "post", + "put", + "get" + ], + "type" : "string" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string" + }, + "origin" : { + "description" : "Show if this entry was created by a user or was built-in", + "enum" : [ + "user-created", + "builtin", + "modified-builtin" + ], + "type" : "string" + }, + "secret" : { + "description" : "Secrets to set. These have to be formatted as a property string in the format name=,value=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "url" : { + "description" : "Server URL", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new webhook endpoint", + "method" : "POST", + "name" : "create_webhook_endpoint", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "body" : { + "description" : "HTTP body, base64 encoded", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "header" : { + "description" : "HTTP headers to set. These have to be formatted as a property string in the format name=,value=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "method" : { + "description" : "HTTP method", + "enum" : [ + "post", + "put", + "get" + ], + "type" : "string" + }, + "name" : { + "description" : "The name of the endpoint.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "secret" : { + "description" : "Secrets to set. These have to be formatted as a property string in the format name=,value=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "url" : { + "description" : "Server URL", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/notifications/endpoints/webhook", + "text" : "webhook" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index for all available endpoint types.", + "method" : "GET", + "name" : "endpoints_index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/notifications/endpoints", + "text" : "endpoints" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Send a test notification to a provided target.", + "method" : "POST", + "name" : "test_target", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Name of the target.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Use" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/notifications/targets/{name}/test", + "text" : "test" + } + ], + "leaf" : 0, + "path" : "/cluster/notifications/targets/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns a list of all entities that can be used as notification targets.", + "method" : "GET", + "name" : "get_all_targets", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Use" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Show if this target is disabled", + "optional" : 1, + "type" : "boolean" + }, + "name" : { + "description" : "Name of the target.", + "format" : "pve-configid", + "type" : "string" + }, + "origin" : { + "description" : "Show if this entry was created by a user or was built-in", + "enum" : [ + "user-created", + "builtin", + "modified-builtin" + ], + "type" : "string" + }, + "type" : { + "description" : "Type of the target.", + "enum" : [ + "sendmail", + "gotify", + "smtp", + "webhook" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/notifications/targets", + "text" : "targets" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove matcher", + "method" : "DELETE", + "name" : "delete_matcher", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Return a specific matcher", + "method" : "GET", + "name" : "get_matcher", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this matcher", + "optional" : 1, + "type" : "boolean" + }, + "invert-match" : { + "description" : "Invert match of the whole matcher", + "optional" : 1, + "type" : "boolean" + }, + "match-calendar" : { + "description" : "Match notification timestamp", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "match-field" : { + "description" : "Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "match-severity" : { + "description" : "Notification severities to match", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "mode" : { + "default" : "all", + "description" : "Choose between 'all' and 'any' for when multiple properties are specified", + "enum" : [ + "all", + "any" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the matcher.", + "format" : "pve-configid", + "type" : "string" + }, + "target" : { + "description" : "Targets to notify on match", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update existing matcher", + "method" : "PUT", + "name" : "update_matcher", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this matcher", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "invert-match" : { + "description" : "Invert match of the whole matcher", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "match-calendar" : { + "description" : "Match notification timestamp", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "match-field" : { + "description" : "Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "match-severity" : { + "description" : "Notification severities to match", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mode" : { + "default" : "all", + "description" : "Choose between 'all' and 'any' for when multiple properties are specified", + "enum" : [ + "all", + "any" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the matcher.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Targets to notify on match", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/notifications/matchers/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns a list of all matchers", + "method" : "GET", + "name" : "get_matchers", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Use" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string" + }, + "disable" : { + "default" : 0, + "description" : "Disable this matcher", + "optional" : 1, + "type" : "boolean" + }, + "invert-match" : { + "description" : "Invert match of the whole matcher", + "optional" : 1, + "type" : "boolean" + }, + "match-calendar" : { + "description" : "Match notification timestamp", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "match-field" : { + "description" : "Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "match-severity" : { + "description" : "Notification severities to match", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "mode" : { + "default" : "all", + "description" : "Choose between 'all' and 'any' for when multiple properties are specified", + "enum" : [ + "all", + "any" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the matcher.", + "format" : "pve-configid", + "type" : "string" + }, + "origin" : { + "description" : "Show if this entry was created by a user or was built-in", + "enum" : [ + "user-created", + "builtin", + "modified-builtin" + ], + "type" : "string" + }, + "target" : { + "description" : "Targets to notify on match", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new matcher", + "method" : "POST", + "name" : "create_matcher", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Comment", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "default" : 0, + "description" : "Disable this matcher", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "invert-match" : { + "description" : "Invert match of the whole matcher", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "match-calendar" : { + "description" : "Match notification timestamp", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "match-field" : { + "description" : "Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "match-severity" : { + "description" : "Notification severities to match", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mode" : { + "default" : "all", + "description" : "Choose between 'all' and 'any' for when multiple properties are specified", + "enum" : [ + "all", + "any" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "Name of the matcher.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Targets to notify on match", + "items" : { + "format" : "pve-configid", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/notifications/matchers", + "text" : "matchers" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index for notification-related API endpoints.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/notifications", + "text" : "notifications" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Return the version of the cluster join API available on this node.", + "method" : "GET", + "name" : "join_api_version", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "description" : "Cluster Join API version, currently 1", + "minimum" : 0, + "type" : "integer" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/apiversion", + "text" : "apiversion" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Removes a node from the cluster configuration.", + "method" : "DELETE", + "name" : "delnode", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Adds a node to the cluster configuration. This call is for internal use.", + "method" : "POST", + "name" : "addnode", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "apiversion" : { + "description" : "The JOIN_API_VERSION of the new node.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "force" : { + "description" : "Do not throw error if node already exists.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "link[n]" : { + "description" : "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)", + "format" : { + "address" : { + "default_key" : 1, + "description" : "Hostname (or IP) of this corosync link address.", + "format" : "address", + "format_description" : "IP", + "type" : "string" + }, + "priority" : { + "default" : 0, + "description" : "The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.", + "maximum" : 255, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[address=] [,priority=]" + }, + "new_node_ip" : { + "description" : "IP Address of node to add. Used as fallback if no links are given.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nodeid" : { + "description" : "Node id for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "votes" : { + "description" : "Number of votes for this node", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "protected" : 1, + "returns" : { + "properties" : { + "corosync_authkey" : { + "type" : "string" + }, + "corosync_conf" : { + "type" : "string" + }, + "warnings" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/nodes/{node}", + "text" : "{node}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Corosync node list.", + "method" : "GET", + "name" : "nodes", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "node" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{node}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/config/nodes", + "text" : "nodes" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get information needed to join this cluster over the connected node.", + "method" : "GET", + "name" : "join_info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "default" : "current connected node", + "description" : "The node for which the joinee gets the nodeinfo. ", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "config_digest" : { + "type" : "string" + }, + "nodelist" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "name" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "nodeid" : { + "description" : "Node id for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "pve_addr" : { + "format" : "ip", + "type" : "string" + }, + "pve_fp" : { + "description" : "Certificate SHA 256 fingerprint.", + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "quorum_votes" : { + "minimum" : 0, + "type" : "integer" + }, + "ring0_addr" : { + "description" : "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)", + "format" : { + "address" : { + "default_key" : 1, + "description" : "Hostname (or IP) of this corosync link address.", + "format" : "address", + "format_description" : "IP", + "type" : "string" + }, + "priority" : { + "default" : 0, + "description" : "The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.", + "maximum" : 255, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "preferred_node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "totem" : { + "type" : "object" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Joins this node into an existing cluster. If no links are given, default to IP resolved by node's hostname on single link (fallback fails for clusters with multiple links).", + "method" : "POST", + "name" : "join", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "force" : { + "description" : "Do not throw error if node already exists.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hostname" : { + "description" : "Hostname (or IP) of an existing cluster member.", + "type" : "string", + "typetext" : "" + }, + "link[n]" : { + "description" : "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)", + "format" : { + "address" : { + "default_key" : 1, + "description" : "Hostname (or IP) of this corosync link address.", + "format" : "address", + "format_description" : "IP", + "type" : "string" + }, + "priority" : { + "default" : 0, + "description" : "The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.", + "maximum" : 255, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[address=] [,priority=]" + }, + "nodeid" : { + "description" : "Node id for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "password" : { + "description" : "Superuser (root) password of peer node.", + "maxLength" : 128, + "type" : "string", + "typetext" : "" + }, + "votes" : { + "description" : "Number of votes for this node", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/join", + "text" : "join" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get corosync totem protocol settings.", + "method" : "GET", + "name" : "totem", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/totem", + "text" : "totem" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get QDevice status", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/config/qdevice", + "text" : "qdevice" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Generate new cluster configuration. If no links given, default to local IP address as link0.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "clustername" : { + "description" : "The name of the cluster.", + "format" : "pve-node", + "maxLength" : 15, + "type" : "string", + "typetext" : "" + }, + "link[n]" : { + "description" : "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)", + "format" : { + "address" : { + "default_key" : 1, + "description" : "Hostname (or IP) of this corosync link address.", + "format" : "address", + "format_description" : "IP", + "type" : "string" + }, + "priority" : { + "default" : 0, + "description" : "The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.", + "maximum" : 255, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[address=] [,priority=]" + }, + "nodeid" : { + "description" : "Node id for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "votes" : { + "description" : "Number of votes for this node.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/config", + "text" : "config" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "dest" : { + "optional" : 1, + "type" : "string" + }, + "dport" : { + "optional" : 1, + "type" : "string" + }, + "enable" : { + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "optional" : 1, + "type" : "string" + }, + "iface" : { + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "optional" : 1, + "type" : "string" + }, + "pos" : { + "type" : "integer" + }, + "proto" : { + "optional" : 1, + "type" : "string" + }, + "source" : { + "optional" : 1, + "type" : "string" + }, + "sport" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/groups/{group}/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete security group.", + "method" : "DELETE", + "name" : "delete_security_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "pos" : { + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 0, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/groups/{group}", + "text" : "{group}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List security groups.", + "method" : "GET", + "name" : "list_security_groups", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{group}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new security group.", + "method" : "POST", + "name" : "create_security_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "Security Group name.", + "maxLength" : 18, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "rename" : { + "description" : "Rename/update an existing security group. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing group.", + "maxLength" : 18, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/groups", + "text" : "groups" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "dest" : { + "optional" : 1, + "type" : "string" + }, + "dport" : { + "optional" : 1, + "type" : "string" + }, + "enable" : { + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "optional" : 1, + "type" : "string" + }, + "iface" : { + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "optional" : 1, + "type" : "string" + }, + "pos" : { + "type" : "integer" + }, + "proto" : { + "optional" : 1, + "type" : "string" + }, + "source" : { + "optional" : 1, + "type" : "string" + }, + "sport" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "pos" : { + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 0, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/rules", + "text" : "rules" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network from IPSet.", + "method" : "DELETE", + "name" : "remove_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read IP or Network settings from IPSet.", + "method" : "GET", + "name" : "read_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network settings", + "method" : "PUT", + "name" : "update_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/ipset/{name}/{cidr}", + "text" : "{cidr}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete IPSet", + "method" : "DELETE", + "name" : "delete_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "Delete all members of the IPSet, if there are any.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List IPSet content", + "method" : "GET", + "name" : "get_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{cidr}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add IP or Network to IPSet.", + "method" : "POST", + "name" : "create_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/ipset/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List IPSets", + "method" : "GET", + "name" : "ipset_index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new IPSet", + "method" : "POST", + "name" : "create_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "rename" : { + "description" : "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/ipset", + "text" : "ipset" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network alias.", + "method" : "DELETE", + "name" : "remove_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read alias.", + "method" : "GET", + "name" : "read_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network alias.", + "method" : "PUT", + "name" : "update_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "rename" : { + "description" : "Rename an existing alias.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/aliases/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List aliases", + "method" : "GET", + "name" : "get_aliases", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create IP or Network Alias.", + "method" : "POST", + "name" : "create_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall/aliases", + "text" : "aliases" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "properties" : { + "ebtables" : { + "default" : 1, + "description" : "Enable ebtables rules cluster wide.", + "optional" : 1, + "type" : "boolean" + }, + "enable" : { + "description" : "Enable or disable the firewall cluster wide.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "log_ratelimit" : { + "description" : "Log ratelimiting settings", + "format" : { + "burst" : { + "default" : 5, + "description" : "Initial burst of packages which will always get logged before the rate is applied", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "enable" : { + "default" : "1", + "default_key" : 1, + "description" : "Enable or disable log rate limiting", + "type" : "boolean" + }, + "rate" : { + "default" : "1/second", + "description" : "Frequency with which the burst bucket gets refilled", + "format_description" : "rate", + "optional" : 1, + "pattern" : "[1-9][0-9]*\\/(second|minute|hour|day)", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "policy_forward" : { + "description" : "Forward policy.", + "enum" : [ + "ACCEPT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ebtables" : { + "default" : 1, + "description" : "Enable ebtables rules cluster wide.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "enable" : { + "description" : "Enable or disable the firewall cluster wide.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "log_ratelimit" : { + "description" : "Log ratelimiting settings", + "format" : { + "burst" : { + "default" : 5, + "description" : "Initial burst of packages which will always get logged before the rate is applied", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "enable" : { + "default" : "1", + "default_key" : 1, + "description" : "Enable or disable log rate limiting", + "type" : "boolean" + }, + "rate" : { + "default" : "1/second", + "description" : "Frequency with which the burst bucket gets refilled", + "format_description" : "rate", + "optional" : 1, + "pattern" : "[1-9][0-9]*\\/(second|minute|hour|day)", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[enable=]<1|0> [,burst=] [,rate=]" + }, + "policy_forward" : { + "description" : "Forward policy.", + "enum" : [ + "ACCEPT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List available macros", + "method" : "GET", + "name" : "get_macros", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "descr" : { + "description" : "More verbose description (if available).", + "type" : "string" + }, + "macro" : { + "description" : "Macro name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/macros", + "text" : "macros" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Lists possible IPSet/Alias reference which are allowed in source/dest properties.", + "method" : "GET", + "name" : "refs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list references of specified type.", + "enum" : [ + "alias", + "ipset" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "ref" : { + "type" : "string" + }, + "scope" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "alias", + "ipset" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/firewall/refs", + "text" : "refs" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/firewall", + "text" : "firewall" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns included guests and the backup status of their disks. Optimized to be used in ExtJS tree views.", + "method" : "GET", + "name" : "get_volume_backup_included", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "pattern" : "\\S+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "Root node of the tree object. Children represent guests, grandchildren represent volumes of that guest.", + "properties" : { + "children" : { + "items" : { + "properties" : { + "children" : { + "description" : "The volumes of the guest with the information if they will be included in backups.", + "items" : { + "properties" : { + "id" : { + "description" : "Configuration key of the volume.", + "type" : "string" + }, + "included" : { + "description" : "Whether the volume is included in the backup or not.", + "type" : "boolean" + }, + "name" : { + "description" : "Name of the volume.", + "type" : "string" + }, + "reason" : { + "description" : "The reason why the volume is included (or excluded).", + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "id" : { + "description" : "VMID of the guest.", + "type" : "integer" + }, + "name" : { + "description" : "Name of the guest", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Type of the guest, VM, CT or unknown for removed but not purged guests.", + "enum" : [ + "qemu", + "lxc", + "unknown" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/backup/{id}/included_volumes", + "text" : "included_volumes" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete vzdump backup job definition.", + "method" : "DELETE", + "name" : "delete_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "pattern" : "\\S+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read vzdump backup job definition.", + "method" : "GET", + "name" : "read_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "pattern" : "\\S+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update vzdump backup job definition.", + "method" : "PUT", + "name" : "update_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (in KiB/s).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "comment" : { + "description" : "Description for the Job.", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dow" : { + "description" : "Day of week selection.", + "format" : "pve-day-of-week-list", + "optional" : 1, + "requires" : "starttime", + "type" : "string", + "typetext" : "" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enabled" : { + "default" : "1", + "description" : "Enable or disable the job.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "fleecing" : { + "description" : "Options for backup fleecing (VM only).", + "format" : "backup-fleecing", + "optional" : 1, + "type" : "string", + "typetext" : "[[enabled=]<1|0>] [,storage=]" + }, + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "pattern" : "\\S+", + "type" : "string" + }, + "ionice" : { + "default" : 7, + "description" : "Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 8)" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mailnotification" : { + "default" : "always", + "description" : "Deprecated: use notification targets/matchers instead. Specify when to send a notification mail", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "maxfiles" : { + "description" : "Deprecated: use 'prune-backups' instead. Maximal number of backup files per guest system.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "notes-template" : { + "description" : "Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.", + "maxLength" : 1024, + "optional" : 1, + "requires" : "storage", + "type" : "string", + "typetext" : "" + }, + "notification-mode" : { + "default" : "auto", + "description" : "Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.", + "enum" : [ + "auto", + "legacy-sendmail", + "notification-system" + ], + "optional" : 1, + "type" : "string" + }, + "notification-policy" : { + "default" : "always", + "description" : "Deprecated: Do not use", + "enum" : [ + "always", + "failure", + "never" + ], + "optional" : 1, + "type" : "string" + }, + "notification-target" : { + "description" : "Deprecated: Do not use", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pbs-change-detection-mode" : { + "description" : "PBS mode used to detect file changes and switch encoding format for container backups.", + "enum" : [ + "legacy", + "data", + "metadata" + ], + "optional" : 1, + "type" : "string" + }, + "performance" : { + "description" : "Other performance-related settings.", + "format" : "backup-performance", + "optional" : 1, + "type" : "string", + "typetext" : "[max-workers=] [,pbs-entries-max=]" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protected" : { + "description" : "If true, mark backup(s) as protected.", + "optional" : 1, + "requires" : "storage", + "type" : "boolean", + "typetext" : "" + }, + "prune-backups" : { + "default" : "keep-all=1", + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove" : { + "default" : 1, + "description" : "Prune older backups according to 'prune-backups'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "repeat-missed" : { + "default" : 0, + "description" : "If true, the job will be run as soon as possible if it was missed while the scheduler was not running.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "schedule" : { + "description" : "Backup schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "starttime" : { + "description" : "Job Start time.", + "optional" : 1, + "pattern" : "\\d{1,2}:\\d{1,2}", + "type" : "string", + "typetext" : "HH:MM" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/backup/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List vzdump backup schedule.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "id" : { + "description" : "The job ID.", + "maxLength" : 50, + "pattern" : "\\S+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new vzdump backup job.", + "method" : "POST", + "name" : "create_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (in KiB/s).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "comment" : { + "description" : "Description for the Job.", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "dow" : { + "default" : "mon,tue,wed,thu,fri,sat,sun", + "description" : "Day of week selection.", + "format" : "pve-day-of-week-list", + "optional" : 1, + "requires" : "starttime", + "type" : "string", + "typetext" : "" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enabled" : { + "default" : "1", + "description" : "Enable or disable the job.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "fleecing" : { + "description" : "Options for backup fleecing (VM only).", + "format" : "backup-fleecing", + "optional" : 1, + "type" : "string", + "typetext" : "[[enabled=]<1|0>] [,storage=]" + }, + "id" : { + "description" : "Job ID (will be autogenerated).", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ionice" : { + "default" : 7, + "description" : "Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 8)" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mailnotification" : { + "default" : "always", + "description" : "Deprecated: use notification targets/matchers instead. Specify when to send a notification mail", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "maxfiles" : { + "description" : "Deprecated: use 'prune-backups' instead. Maximal number of backup files per guest system.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "notes-template" : { + "description" : "Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.", + "maxLength" : 1024, + "optional" : 1, + "requires" : "storage", + "type" : "string", + "typetext" : "" + }, + "notification-mode" : { + "default" : "auto", + "description" : "Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.", + "enum" : [ + "auto", + "legacy-sendmail", + "notification-system" + ], + "optional" : 1, + "type" : "string" + }, + "notification-policy" : { + "default" : "always", + "description" : "Deprecated: Do not use", + "enum" : [ + "always", + "failure", + "never" + ], + "optional" : 1, + "type" : "string" + }, + "notification-target" : { + "description" : "Deprecated: Do not use", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pbs-change-detection-mode" : { + "description" : "PBS mode used to detect file changes and switch encoding format for container backups.", + "enum" : [ + "legacy", + "data", + "metadata" + ], + "optional" : 1, + "type" : "string" + }, + "performance" : { + "description" : "Other performance-related settings.", + "format" : "backup-performance", + "optional" : 1, + "type" : "string", + "typetext" : "[max-workers=] [,pbs-entries-max=]" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protected" : { + "description" : "If true, mark backup(s) as protected.", + "optional" : 1, + "requires" : "storage", + "type" : "boolean", + "typetext" : "" + }, + "prune-backups" : { + "default" : "keep-all=1", + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove" : { + "default" : 1, + "description" : "Prune older backups according to 'prune-backups'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "repeat-missed" : { + "default" : 0, + "description" : "If true, the job will be run as soon as possible if it was missed while the scheduler was not running.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "schedule" : { + "description" : "Backup schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "starttime" : { + "description" : "Job Start time.", + "optional" : 1, + "pattern" : "\\d{1,2}:\\d{1,2}", + "type" : "string", + "typetext" : "HH:MM" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/backup", + "text" : "backup" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Shows all guests which are not covered by any backup job.", + "method" : "GET", + "name" : "get_guests_not_in_backup", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "Contains the guest objects.", + "items" : { + "properties" : { + "name" : { + "description" : "Name of the guest", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Type of the guest.", + "enum" : [ + "qemu", + "lxc" + ], + "type" : "string" + }, + "vmid" : { + "description" : "VMID of the guest.", + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/backup-info/not-backed-up", + "text" : "not-backed-up" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index for backup info related endpoints", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "returns" : { + "description" : "Directory index.", + "items" : { + "properties" : { + "subdir" : { + "description" : "API sub-directory endpoint", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/backup-info", + "text" : "backup-info" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Request resource migration (online) to another node.", + "method" : "POST", + "name" : "migrate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/resources/{sid}/migrate", + "text" : "migrate" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Request resource relocatzion to another node. This stops the service on the old node, and restarts it on the target node.", + "method" : "POST", + "name" : "relocate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/resources/{sid}/relocate", + "text" : "relocate" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete resource configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read resource configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "properties" : { + "comment" : { + "description" : "Description.", + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Can be used to prevent concurrent modifications.", + "type" : "string" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string" + }, + "max_relocate" : { + "description" : "Maximal number of service relocate tries when a service failes to start.", + "optional" : 1, + "type" : "integer" + }, + "max_restart" : { + "description" : "Maximal number of tries to restart the service on a node after its start failed.", + "optional" : 1, + "type" : "integer" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + }, + "state" : { + "description" : "Requested resource state.", + "enum" : [ + "started", + "stopped", + "enabled", + "disabled", + "ignored" + ], + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "The type of the resources.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update resource configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "max_relocate" : { + "default" : 1, + "description" : "Maximal number of service relocate tries when a service failes to start.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "max_restart" : { + "default" : 1, + "description" : "Maximal number of tries to restart the service on a node after its start failed.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + }, + "state" : { + "default" : "started", + "description" : "Requested resource state.", + "enum" : [ + "started", + "stopped", + "enabled", + "disabled", + "ignored" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Requested resource state. The CRM reads this state and acts accordingly.\nPlease note that `enabled` is just an alias for `started`.\n\n`started`;;\n\nThe CRM tries to start the resource. Service state is\nset to `started` after successful start. On node failures, or when start\nfails, it tries to recover the resource. If everything fails, service\nstate it set to `error`.\n\n`stopped`;;\n\nThe CRM tries to keep the resource in `stopped` state, but it\nstill tries to relocate the resources on node failures.\n\n`disabled`;;\n\nThe CRM tries to put the resource in `stopped` state, but does not try\nto relocate the resources on node failures. The main purpose of this\nstate is error recovery, because it is the only way to move a resource out\nof the `error` state.\n\n`ignored`;;\n\nThe resource gets removed from the manager status and so the CRM and the LRM do\nnot touch the resource anymore. All {pve} API calls affecting this resource\nwill be executed, directly bypassing the HA stack. CRM commands will be thrown\naway while there source is in this state. The resource will not get relocated\non node failures.\n\n" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/resources/{sid}", + "text" : "{sid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List HA resources.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list resources of specific type", + "enum" : [ + "ct", + "vm" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "sid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{sid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new HA resource.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "max_relocate" : { + "default" : 1, + "description" : "Maximal number of service relocate tries when a service failes to start.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "max_restart" : { + "default" : 1, + "description" : "Maximal number of tries to restart the service on a node after its start failed.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "sid" : { + "description" : "HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).", + "format" : "pve-ha-resource-or-vm-id", + "type" : "string", + "typetext" : ":" + }, + "state" : { + "default" : "started", + "description" : "Requested resource state.", + "enum" : [ + "started", + "stopped", + "enabled", + "disabled", + "ignored" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Requested resource state. The CRM reads this state and acts accordingly.\nPlease note that `enabled` is just an alias for `started`.\n\n`started`;;\n\nThe CRM tries to start the resource. Service state is\nset to `started` after successful start. On node failures, or when start\nfails, it tries to recover the resource. If everything fails, service\nstate it set to `error`.\n\n`stopped`;;\n\nThe CRM tries to keep the resource in `stopped` state, but it\nstill tries to relocate the resources on node failures.\n\n`disabled`;;\n\nThe CRM tries to put the resource in `stopped` state, but does not try\nto relocate the resources on node failures. The main purpose of this\nstate is error recovery, because it is the only way to move a resource out\nof the `error` state.\n\n`ignored`;;\n\nThe resource gets removed from the manager status and so the CRM and the LRM do\nnot touch the resource anymore. All {pve} API calls affecting this resource\nwill be executed, directly bypassing the HA stack. CRM commands will be thrown\naway while there source is in this state. The resource will not get relocated\non node failures.\n\n" + }, + "type" : { + "description" : "Resource type.", + "enum" : [ + "ct", + "vm" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/resources", + "text" : "resources" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete ha group configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read ha group configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : {} + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update ha group configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names with optional priority.", + "format" : "pve-ha-group-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "[:]{,[:]}*", + "verbose_description" : "List of cluster node members, where a priority can be given to each node. A resource bound to a group will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the services will get distributed to those nodes. The priorities have a relative meaning only. The higher the number, the higher the priority." + }, + "nofailback" : { + "default" : 0, + "description" : "The CRM tries to run services on the node with the highest priority. If a node with higher priority comes online, the CRM migrates the service to that node. Enabling nofailback prevents that behavior.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restricted" : { + "default" : 0, + "description" : "Resources bound to restricted groups may only run on nodes defined by the group.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Resources bound to restricted groups may only run on nodes defined by the group. The resource will be placed in the stopped state if no group node member is online. Resources on unrestricted groups may run on any cluster node if all group members are offline, but they will migrate back as soon as a group member comes online. One can implement a 'preferred node' behavior using an unrestricted group with only one member." + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/groups/{group}", + "text" : "{group}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get HA groups.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "group" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{group}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new HA group.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group" : { + "description" : "The HA group identifier.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names with optional priority.", + "format" : "pve-ha-group-node-list", + "optional" : 0, + "type" : "string", + "typetext" : "[:]{,[:]}*", + "verbose_description" : "List of cluster node members, where a priority can be given to each node. A resource bound to a group will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the services will get distributed to those nodes. The priorities have a relative meaning only. The higher the number, the higher the priority." + }, + "nofailback" : { + "default" : 0, + "description" : "The CRM tries to run services on the node with the highest priority. If a node with higher priority comes online, the CRM migrates the service to that node. Enabling nofailback prevents that behavior.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restricted" : { + "default" : 0, + "description" : "Resources bound to restricted groups may only run on nodes defined by the group.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Resources bound to restricted groups may only run on nodes defined by the group. The resource will be placed in the stopped state if no group node member is online. Resources on unrestricted groups may run on any cluster node if all group members are offline, but they will migrate back as soon as a group member comes online. One can implement a 'preferred node' behavior using an unrestricted group with only one member." + }, + "type" : { + "description" : "Group type.", + "enum" : [ + "group" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/groups", + "text" : "groups" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get HA manger status.", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "crm_state" : { + "description" : "For type 'service'. Service state as seen by the CRM.", + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "Status entry ID (quorum, master, lrm:, service:).", + "type" : "string" + }, + "max_relocate" : { + "description" : "For type 'service'.", + "optional" : 1, + "type" : "integer" + }, + "max_restart" : { + "description" : "For type 'service'.", + "optional" : 1, + "type" : "integer" + }, + "node" : { + "description" : "Node associated to status entry.", + "type" : "string" + }, + "quorate" : { + "description" : "For type 'quorum'. Whether the cluster is quorate or not.", + "optional" : 1, + "type" : "boolean" + }, + "request_state" : { + "description" : "For type 'service'. Requested service state.", + "optional" : 1, + "type" : "string" + }, + "sid" : { + "description" : "For type 'service'. Service ID.", + "optional" : 1, + "type" : "string" + }, + "state" : { + "description" : "For type 'service'. Verbose service state.", + "optional" : 1, + "type" : "string" + }, + "status" : { + "description" : "Status of the entry (value depends on type).", + "type" : "string" + }, + "timestamp" : { + "description" : "For type 'lrm','master'. Timestamp of the status information.", + "optional" : 1, + "type" : "integer" + }, + "type" : { + "description" : "Type of status entry.", + "enum" : [ + "quorum", + "master", + "lrm", + "service" + ] + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/status/current", + "text" : "current" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get full HA manger status, including LRM status.", + "method" : "GET", + "name" : "manager_status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ha/status/manager_status", + "text" : "manager_status" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha/status", + "text" : "status" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ha", + "text" : "ha" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete ACME plugin configuration.", + "method" : "DELETE", + "name" : "delete_plugin", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Unique identifier for ACME plugin instance.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get ACME plugin configuration.", + "method" : "GET", + "name" : "get_plugin_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Unique identifier for ACME plugin instance.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update ACME plugin configuration.", + "method" : "PUT", + "name" : "update_plugin", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "api" : { + "description" : "API plugin name", + "enum" : [ + "1984hosting", + "acmedns", + "acmeproxy", + "active24", + "ad", + "ali", + "alviy", + "anx", + "artfiles", + "arvan", + "aurora", + "autodns", + "aws", + "azion", + "azure", + "bookmyname", + "bunny", + "cf", + "clouddns", + "cloudns", + "cn", + "conoha", + "constellix", + "cpanel", + "curanet", + "cyon", + "da", + "ddnss", + "desec", + "df", + "dgon", + "dnsexit", + "dnshome", + "dnsimple", + "dnsservices", + "doapi", + "domeneshop", + "dp", + "dpi", + "dreamhost", + "duckdns", + "durabledns", + "dyn", + "dynu", + "dynv6", + "easydns", + "edgedns", + "euserv", + "exoscale", + "fornex", + "freedns", + "gandi_livedns", + "gcloud", + "gcore", + "gd", + "geoscaling", + "googledomains", + "he", + "hetzner", + "hexonet", + "hostingde", + "huaweicloud", + "infoblox", + "infomaniak", + "internetbs", + "inwx", + "ionos", + "ionos_cloud", + "ipv64", + "ispconfig", + "jd", + "joker", + "kappernet", + "kas", + "kinghost", + "knot", + "la", + "leaseweb", + "lexicon", + "limacity", + "linode", + "linode_v4", + "loopia", + "lua", + "maradns", + "me", + "miab", + "misaka", + "myapi", + "mydevil", + "mydnsjp", + "mythic_beasts", + "namecheap", + "namecom", + "namesilo", + "nanelo", + "nederhost", + "neodigit", + "netcup", + "netlify", + "nic", + "njalla", + "nm", + "nsd", + "nsone", + "nsupdate", + "nw", + "oci", + "omglol", + "one", + "online", + "openprovider", + "openstack", + "opnsense", + "ovh", + "pdns", + "pleskxml", + "pointhq", + "porkbun", + "rackcorp", + "rackspace", + "rage4", + "rcode0", + "regru", + "scaleway", + "schlundtech", + "selectel", + "selfhost", + "servercow", + "simply", + "technitium", + "tele3", + "tencent", + "timeweb", + "transip", + "udr", + "ultra", + "unoeuro", + "variomedia", + "veesp", + "vercel", + "vscale", + "vultr", + "websupport", + "west_cn", + "world4you", + "yandex360", + "yc", + "zilore", + "zone", + "zoneedit", + "zonomi" + ], + "optional" : 1, + "type" : "string" + }, + "data" : { + "description" : "DNS plugin data. (base64 encoded)", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "ACME Plugin ID name", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "validation-delay" : { + "default" : 30, + "description" : "Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.", + "maximum" : 172800, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 172800)" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/plugins/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "ACME plugin index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list ACME plugins of a specific type", + "enum" : [ + "dns", + "standalone" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "plugin" : { + "description" : "Unique identifier for ACME plugin instance.", + "format" : "pve-configid", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{plugin}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add ACME plugin configuration.", + "method" : "POST", + "name" : "add_plugin", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "api" : { + "description" : "API plugin name", + "enum" : [ + "1984hosting", + "acmedns", + "acmeproxy", + "active24", + "ad", + "ali", + "alviy", + "anx", + "artfiles", + "arvan", + "aurora", + "autodns", + "aws", + "azion", + "azure", + "bookmyname", + "bunny", + "cf", + "clouddns", + "cloudns", + "cn", + "conoha", + "constellix", + "cpanel", + "curanet", + "cyon", + "da", + "ddnss", + "desec", + "df", + "dgon", + "dnsexit", + "dnshome", + "dnsimple", + "dnsservices", + "doapi", + "domeneshop", + "dp", + "dpi", + "dreamhost", + "duckdns", + "durabledns", + "dyn", + "dynu", + "dynv6", + "easydns", + "edgedns", + "euserv", + "exoscale", + "fornex", + "freedns", + "gandi_livedns", + "gcloud", + "gcore", + "gd", + "geoscaling", + "googledomains", + "he", + "hetzner", + "hexonet", + "hostingde", + "huaweicloud", + "infoblox", + "infomaniak", + "internetbs", + "inwx", + "ionos", + "ionos_cloud", + "ipv64", + "ispconfig", + "jd", + "joker", + "kappernet", + "kas", + "kinghost", + "knot", + "la", + "leaseweb", + "lexicon", + "limacity", + "linode", + "linode_v4", + "loopia", + "lua", + "maradns", + "me", + "miab", + "misaka", + "myapi", + "mydevil", + "mydnsjp", + "mythic_beasts", + "namecheap", + "namecom", + "namesilo", + "nanelo", + "nederhost", + "neodigit", + "netcup", + "netlify", + "nic", + "njalla", + "nm", + "nsd", + "nsone", + "nsupdate", + "nw", + "oci", + "omglol", + "one", + "online", + "openprovider", + "openstack", + "opnsense", + "ovh", + "pdns", + "pleskxml", + "pointhq", + "porkbun", + "rackcorp", + "rackspace", + "rage4", + "rcode0", + "regru", + "scaleway", + "schlundtech", + "selectel", + "selfhost", + "servercow", + "simply", + "technitium", + "tele3", + "tencent", + "timeweb", + "transip", + "udr", + "ultra", + "unoeuro", + "variomedia", + "veesp", + "vercel", + "vscale", + "vultr", + "websupport", + "west_cn", + "world4you", + "yandex360", + "yc", + "zilore", + "zone", + "zoneedit", + "zonomi" + ], + "optional" : 1, + "type" : "string" + }, + "data" : { + "description" : "DNS plugin data. (base64 encoded)", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "ACME Plugin ID name", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "ACME challenge type.", + "enum" : [ + "dns", + "standalone" + ], + "type" : "string" + }, + "validation-delay" : { + "default" : 30, + "description" : "Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.", + "maximum" : 172800, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 172800)" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/acme/plugins", + "text" : "plugins" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Deactivate existing ACME account at CA.", + "method" : "DELETE", + "name" : "deactivate_account", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Return existing ACME account information.", + "method" : "GET", + "name" : "get_account", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "account" : { + "optional" : 1, + "renderer" : "yaml", + "type" : "object" + }, + "directory" : { + "description" : "URL of ACME CA directory endpoint.", + "optional" : 1, + "pattern" : "^https?://.*", + "type" : "string" + }, + "location" : { + "optional" : 1, + "type" : "string" + }, + "tos" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update existing ACME account information with CA. Note: not specifying any new account information triggers a refresh.", + "method" : "PUT", + "name" : "update_account", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "contact" : { + "description" : "Contact email addresses.", + "format" : "email-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/account/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "ACMEAccount index.", + "method" : "GET", + "name" : "account_index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Register a new ACME account with CA.", + "method" : "POST", + "name" : "register_account", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "contact" : { + "description" : "Contact email addresses.", + "format" : "email-list", + "type" : "string", + "typetext" : "" + }, + "directory" : { + "default" : "https://acme-v02.api.letsencrypt.org/directory", + "description" : "URL of ACME CA directory endpoint.", + "optional" : 1, + "pattern" : "^https?://.*", + "type" : "string" + }, + "eab-hmac-key" : { + "description" : "HMAC key for External Account Binding.", + "optional" : 1, + "requires" : "eab-kid", + "type" : "string", + "typetext" : "" + }, + "eab-kid" : { + "description" : "Key Identifier for External Account Binding.", + "optional" : 1, + "requires" : "eab-hmac-key", + "type" : "string", + "typetext" : "" + }, + "name" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tos_url" : { + "description" : "URL of CA TermsOfService - setting this indicates agreement.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/acme/account", + "text" : "account" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Retrieve ACME TermsOfService URL from CA. Deprecated, please use /cluster/acme/meta.", + "method" : "GET", + "name" : "get_tos", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "directory" : { + "default" : "https://acme-v02.api.letsencrypt.org/directory", + "description" : "URL of ACME CA directory endpoint.", + "optional" : 1, + "pattern" : "^https?://.*", + "type" : "string" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "description" : "ACME TermsOfService URL.", + "optional" : 1, + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/tos", + "text" : "tos" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Retrieve ACME Directory Meta Information", + "method" : "GET", + "name" : "get_meta", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "directory" : { + "default" : "https://acme-v02.api.letsencrypt.org/directory", + "description" : "URL of ACME CA directory endpoint.", + "optional" : 1, + "pattern" : "^https?://.*", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "additionalProperties" : 1, + "properties" : { + "caaIdentities" : { + "description" : "Hostnames referring to the ACME servers.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "externalAccountRequired" : { + "description" : "EAB Required", + "optional" : 1, + "type" : "boolean" + }, + "termsOfService" : { + "description" : "ACME TermsOfService URL.", + "optional" : 1, + "type" : "string" + }, + "website" : { + "description" : "URL to more information about the ACME server.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/meta", + "text" : "meta" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get named known ACME directory endpoints.", + "method" : "GET", + "name" : "get_directories", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "type" : "string" + }, + "url" : { + "description" : "URL of ACME CA directory endpoint.", + "pattern" : "^https?://.*", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/directories", + "text" : "directories" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get schema of ACME challenge types.", + "method" : "GET", + "name" : "challengeschema", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "type" : "string" + }, + "name" : { + "description" : "Human readable name, falls back to id", + "type" : "string" + }, + "schema" : { + "type" : "object" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/acme/challenge-schema", + "text" : "challenge-schema" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "ACMEAccount index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/acme", + "text" : "acme" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get ceph metadata.", + "method" : "GET", + "name" : "metadata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "scope" : { + "default" : "all", + "enum" : [ + "all", + "versions" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "returns" : { + "description" : "Items for each type of service containing objects for each instance.", + "properties" : { + "mds" : { + "description" : "Metadata servers configured in the cluster and their properties.", + "properties" : { + "{id}" : { + "description" : "Useful properties are listed, but not the full list.", + "properties" : { + "addr" : { + "description" : "Bind addresses and ports.", + "type" : "string" + }, + "ceph_release" : { + "description" : "Ceph release codename currently used.", + "type" : "string" + }, + "ceph_version" : { + "description" : "Version info currently used by the service.", + "type" : "string" + }, + "ceph_version_short" : { + "description" : "Short version (numerical) info currently used by the service.", + "type" : "string" + }, + "hostname" : { + "description" : "Hostname on which the service is running.", + "type" : "string" + }, + "mem_swap_kb" : { + "description" : "Memory of the service currently in swap.", + "type" : "integer" + }, + "mem_total_kb" : { + "description" : "Memory consumption of the service.", + "type" : "integer" + }, + "name" : { + "description" : "Name of the service instance.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "type" : "object" + }, + "mgr" : { + "description" : "Managers configured in the cluster and their properties.", + "properties" : { + "{id}" : { + "description" : "Useful properties are listed, but not the full list.", + "properties" : { + "addr" : { + "description" : "Bind address", + "type" : "string" + }, + "ceph_release" : { + "description" : "Ceph release codename currently used.", + "type" : "string" + }, + "ceph_version" : { + "description" : "Version info currently used by the service.", + "type" : "string" + }, + "ceph_version_short" : { + "description" : "Short version (numerical) info currently used by the service.", + "type" : "string" + }, + "hostname" : { + "description" : "Hostname on which the service is running.", + "type" : "string" + }, + "mem_swap_kb" : { + "description" : "Memory of the service currently in swap.", + "type" : "integer" + }, + "mem_total_kb" : { + "description" : "Memory consumption of the service.", + "type" : "integer" + }, + "name" : { + "description" : "Name of the service instance.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "type" : "object" + }, + "mon" : { + "description" : "Monitors configured in the cluster and their properties.", + "properties" : { + "{id}" : { + "description" : "Useful properties are listed, but not the full list.", + "properties" : { + "addrs" : { + "description" : "Bind addresses and ports.", + "type" : "string" + }, + "ceph_release" : { + "description" : "Ceph release codename currently used.", + "type" : "string" + }, + "ceph_version" : { + "description" : "Version info currently used by the service.", + "type" : "string" + }, + "ceph_version_short" : { + "description" : "Short version (numerical) info currently used by the service.", + "type" : "string" + }, + "hostname" : { + "description" : "Hostname on which the service is running.", + "type" : "string" + }, + "mem_swap_kb" : { + "description" : "Memory of the service currently in swap.", + "type" : "integer" + }, + "mem_total_kb" : { + "description" : "Memory consumption of the service.", + "type" : "integer" + }, + "name" : { + "description" : "Name of the service instance.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "type" : "object" + }, + "node" : { + "description" : "Ceph version installed on the nodes.", + "properties" : { + "{node}" : { + "properties" : { + "buildcommit" : { + "description" : "GIT commit used for the build.", + "type" : "string" + }, + "version" : { + "description" : "Version info.", + "properties" : { + "parts" : { + "description" : "major, minor & patch", + "type" : "array" + }, + "str" : { + "description" : "Version as single string.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "type" : "object" + } + }, + "type" : "object" + }, + "osd" : { + "description" : "OSDs configured in the cluster and their properties.", + "properties" : { + "{id}" : { + "description" : "Useful properties are listed, but not the full list.", + "properties" : { + "back_addr" : { + "description" : "Bind addresses and ports for backend inter OSD traffic.", + "type" : "string" + }, + "ceph_release" : { + "description" : "Ceph release codename currently used.", + "type" : "string" + }, + "ceph_version" : { + "description" : "Version info currently used by the service.", + "type" : "string" + }, + "ceph_version_short" : { + "description" : "Short version (numerical) info currently used by the service.", + "type" : "string" + }, + "device_id" : { + "description" : "Devices used by the OSD.", + "type" : "string" + }, + "front_addr" : { + "description" : "Bind addresses and ports for frontend traffic to OSDs.", + "type" : "string" + }, + "hostname" : { + "description" : "Hostname on which the service is running.", + "type" : "string" + }, + "id" : { + "description" : "OSD ID.", + "type" : "integer" + }, + "mem_swap_kb" : { + "description" : "Memory of the service currently in swap.", + "type" : "integer" + }, + "mem_total_kb" : { + "description" : "Memory consumption of the service.", + "type" : "integer" + }, + "osd_data" : { + "description" : "Path to the OSD data directory.", + "type" : "string" + }, + "osd_objectstore" : { + "description" : "OSD objectstore type.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ceph/metadata", + "text" : "metadata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get ceph status.", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ceph/status", + "text" : "status" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the status of a specific ceph flag.", + "method" : "GET", + "name" : "get_flag", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "flag" : { + "description" : "The name of the flag name to get.", + "enum" : [ + "nobackfill", + "nodeep-scrub", + "nodown", + "noin", + "noout", + "norebalance", + "norecover", + "noscrub", + "notieragent", + "noup", + "pause" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "boolean" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set or clear (unset) a specific ceph flag", + "method" : "PUT", + "name" : "update_flag", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "flag" : { + "description" : "The ceph flag to update", + "enum" : [ + "nobackfill", + "nodeep-scrub", + "nodown", + "noin", + "noout", + "norebalance", + "norecover", + "noscrub", + "notieragent", + "noup", + "pause" + ], + "type" : "string" + }, + "value" : { + "description" : "The new value of the flag", + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/ceph/flags/{flag}", + "text" : "{flag}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "get the status of all ceph flags", + "method" : "GET", + "name" : "get_all_flags", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "description" : { + "description" : "Flag description.", + "type" : "string" + }, + "name" : { + "description" : "Flag name.", + "enum" : [ + "nobackfill", + "nodeep-scrub", + "nodown", + "noin", + "noout", + "norebalance", + "norecover", + "noscrub", + "notieragent", + "noup", + "pause" + ], + "type" : "string" + }, + "value" : { + "description" : "Flag value.", + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set/Unset multiple ceph flags at once.", + "method" : "PUT", + "name" : "set_flags", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "nobackfill" : { + "description" : "Backfilling of PGs is suspended.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nodeep-scrub" : { + "description" : "Deep Scrubbing is disabled.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nodown" : { + "description" : "OSD failure reports are being ignored, such that the monitors will not mark OSDs down.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "noin" : { + "description" : "OSDs that were previously marked out will not be marked back in when they start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "noout" : { + "description" : "OSDs will not automatically be marked out after the configured interval.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "norebalance" : { + "description" : "Rebalancing of PGs is suspended.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "norecover" : { + "description" : "Recovery of PGs is suspended.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "noscrub" : { + "description" : "Scrubbing is disabled.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "notieragent" : { + "description" : "Cache tiering activity is suspended.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "noup" : { + "description" : "OSDs are not allowed to start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "pause" : { + "description" : "Pauses read and writes.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ceph/flags", + "text" : "flags" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Cluster ceph index.", + "method" : "GET", + "name" : "cephindex", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/ceph", + "text" : "ceph" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete realm-sync job definition.", + "method" : "DELETE", + "name" : "delete_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read realm-sync job definition.", + "method" : "GET", + "name" : "read_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new realm-sync job.", + "method" : "POST", + "name" : "create_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description for the Job.", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable-new" : { + "default" : "1", + "description" : "Enable newly synced users immediately.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "enabled" : { + "default" : 1, + "description" : "Determines if the job is enabled.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the job.", + "format" : "pve-configid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + }, + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "remove-vanished" : { + "default" : "none", + "description" : "A semicolon-separated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).", + "optional" : 1, + "pattern" : "(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none", + "type" : "string", + "typetext" : "([acl];[properties];[entry])|none" + }, + "schedule" : { + "description" : "Backup schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "type" : "string", + "typetext" : "" + }, + "scope" : { + "description" : "Select what to sync.", + "enum" : [ + "users", + "groups", + "both" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/access/realm/{realm}", + [ + "Realm.AllocateUser" + ] + ], + [ + "perm", + "/access/groups", + [ + "User.Modify" + ] + ] + ], + "description" : "'Realm.AllocateUser' on '/access/realm/' and 'User.Modify' permissions to '/access/groups/'." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update realm-sync job definition.", + "method" : "PUT", + "name" : "update_job", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "description" : "Description for the Job.", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable-new" : { + "default" : "1", + "description" : "Enable newly synced users immediately.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "enabled" : { + "default" : 1, + "description" : "Determines if the job is enabled.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the job.", + "format" : "pve-configid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + }, + "remove-vanished" : { + "default" : "none", + "description" : "A semicolon-separated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).", + "optional" : 1, + "pattern" : "(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none", + "type" : "string", + "typetext" : "([acl];[properties];[entry])|none" + }, + "schedule" : { + "description" : "Backup schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "type" : "string", + "typetext" : "" + }, + "scope" : { + "description" : "Select what to sync.", + "enum" : [ + "users", + "groups", + "both" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/access/realm/{realm}", + [ + "Realm.AllocateUser" + ] + ], + [ + "perm", + "/access/groups", + [ + "User.Modify" + ] + ] + ], + "description" : "'Realm.AllocateUser' on '/access/realm/' and 'User.Modify' permissions to '/access/groups/'." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/jobs/realm-sync/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List configured realm-sync-jobs.", + "method" : "GET", + "name" : "syncjob_index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "A comment for the job.", + "optional" : 1, + "type" : "string" + }, + "enabled" : { + "description" : "If the job is enabled or not.", + "type" : "boolean" + }, + "id" : { + "description" : "The ID of the entry.", + "type" : "string" + }, + "last-run" : { + "description" : "Last execution time of the job in seconds since the beginning of the UNIX epoch", + "optional" : 1, + "type" : "integer" + }, + "next-run" : { + "description" : "Next planned execution time of the job in seconds since the beginning of the UNIX epoch.", + "optional" : 1, + "type" : "integer" + }, + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string" + }, + "remove-vanished" : { + "default" : "none", + "description" : "A semicolon-separated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).", + "optional" : "1", + "pattern" : "(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none", + "type" : "string", + "typetext" : "([acl];[properties];[entry])|none" + }, + "schedule" : { + "description" : "The configured sync schedule.", + "type" : "string" + }, + "scope" : { + "description" : "Select what to sync.", + "enum" : [ + "users", + "groups", + "both" + ], + "optional" : "1", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/jobs/realm-sync", + "text" : "realm-sync" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Returns a list of future schedule runtimes.", + "method" : "GET", + "name" : "schedule-analyze", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "iterations" : { + "default" : 10, + "description" : "Number of event-iteration to simulate and return.", + "maximum" : 100, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 100)" + }, + "schedule" : { + "description" : "Job schedule. The format is a subset of `systemd` calendar events.", + "format" : "pve-calendar-event", + "maxLength" : 128, + "type" : "string", + "typetext" : "" + }, + "starttime" : { + "description" : "UNIX timestamp to start the calculation from. Defaults to the current time.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "description" : "An array of the next events since .", + "items" : { + "properties" : { + "timestamp" : { + "description" : "UNIX timestamp for the run.", + "type" : "integer" + }, + "utc" : { + "description" : "UTC timestamp for the run.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/jobs/schedule-analyze", + "text" : "schedule-analyze" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index for jobs related endpoints.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "description" : "Directory index.", + "items" : { + "properties" : { + "subdir" : { + "description" : "API sub-directory endpoint", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/jobs", + "text" : "jobs" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove directory mapping.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/dir", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get directory mapping.", + "method" : "GET", + "name" : "get", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update a directory mapping.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description of the directory mapping", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the directory mapping", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "map" : { + "description" : "A list of maps for the cluster nodes.", + "items" : { + "format" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "path" : { + "description" : "Absolute directory path that should be shared with the guest.", + "format" : "pve-storage-path-in-property-string", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/mapping/dir/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List directory mapping", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "check-node" : { + "description" : "If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the directory to the response.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/dir/'.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "checks" : { + "description" : "A list of checks, only present if 'check-node' is set.", + "items" : { + "properties" : { + "message" : { + "description" : "The message of the error", + "type" : "string" + }, + "severity" : { + "description" : "The severity of the error", + "enum" : [ + "warning", + "error" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "description" : { + "description" : "A description of the logical mapping.", + "type" : "string" + }, + "id" : { + "description" : "The logical ID of the mapping.", + "type" : "string" + }, + "map" : { + "description" : "The entries of the mapping.", + "items" : { + "description" : "A mapping for a node.", + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new directory mapping.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "Description of the directory mapping", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the directory mapping", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "map" : { + "description" : "A list of maps for the cluster nodes.", + "items" : { + "format" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "path" : { + "description" : "Absolute directory path that should be shared with the guest.", + "format" : "pve-storage-path-in-property-string", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 0, + "type" : "array", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/dir", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/mapping/dir", + "text" : "dir" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove Hardware Mapping.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/pci", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get PCI Mapping.", + "method" : "GET", + "name" : "get", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update a hardware mapping.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description of the logical PCI device.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the logical PCI mapping.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "live-migration-capable" : { + "default" : 0, + "description" : "Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "map" : { + "description" : "A list of maps for the cluster nodes.", + "items" : { + "format" : { + "description" : { + "description" : "Description of the node specific device.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "The vendor and device ID that is expected. Used for detecting hardware changes", + "pattern" : "(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)", + "type" : "string" + }, + "iommugroup" : { + "description" : "The IOMMU group in which the device is to be expected in. Used for detecting hardware changes.", + "optional" : 1, + "type" : "integer" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "path" : { + "description" : "The path to the device. If the function is omitted, the whole device is mapped. In that case use the attributes of the first device. You can give multiple paths as a semicolon seperated list, the first available will then be chosen on guest start.", + "pattern" : "(?:[a-f0-9]{4,}:[a-f0-9]{2}:[a-f0-9]{2}(?:.[a-f0-9])?;)*[a-f0-9]{4,}:[a-f0-9]{2}:[a-f0-9]{2}(?:.[a-f0-9])?", + "type" : "string" + }, + "subsystem-id" : { + "description" : "The subsystem vendor and device ID that is expected. Used for detecting hardware changes.", + "optional" : 1, + "pattern" : "(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "mdev" : { + "default" : 0, + "description" : "Marks the device(s) as being capable of providing mediated devices.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/mapping/pci/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List PCI Hardware Mapping", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "check-node" : { + "description" : "If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the devices to the response.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/pci/'.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "checks" : { + "description" : "A list of checks, only present if 'check_node' is set.", + "items" : { + "properties" : { + "message" : { + "description" : "The message of the error", + "type" : "string" + }, + "severity" : { + "description" : "The severity of the error", + "enum" : [ + "warning", + "error" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "description" : { + "description" : "A description of the logical mapping.", + "type" : "string" + }, + "id" : { + "description" : "The logical ID of the mapping.", + "type" : "string" + }, + "map" : { + "description" : "The entries of the mapping.", + "items" : { + "description" : "A mapping for a node.", + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new hardware mapping.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "Description of the logical PCI device.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the logical PCI mapping.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "live-migration-capable" : { + "default" : 0, + "description" : "Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "map" : { + "description" : "A list of maps for the cluster nodes.", + "items" : { + "format" : { + "description" : { + "description" : "Description of the node specific device.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "The vendor and device ID that is expected. Used for detecting hardware changes", + "pattern" : "(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)", + "type" : "string" + }, + "iommugroup" : { + "description" : "The IOMMU group in which the device is to be expected in. Used for detecting hardware changes.", + "optional" : 1, + "type" : "integer" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "path" : { + "description" : "The path to the device. If the function is omitted, the whole device is mapped. In that case use the attributes of the first device. You can give multiple paths as a semicolon seperated list, the first available will then be chosen on guest start.", + "pattern" : "(?:[a-f0-9]{4,}:[a-f0-9]{2}:[a-f0-9]{2}(?:.[a-f0-9])?;)*[a-f0-9]{4,}:[a-f0-9]{2}:[a-f0-9]{2}(?:.[a-f0-9])?", + "type" : "string" + }, + "subsystem-id" : { + "description" : "The subsystem vendor and device ID that is expected. Used for detecting hardware changes.", + "optional" : 1, + "pattern" : "(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)", + "type" : "string" + } + }, + "type" : "string" + }, + "optional" : 0, + "type" : "array", + "typetext" : "" + }, + "mdev" : { + "default" : 0, + "description" : "Marks the device(s) as being capable of providing mediated devices.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/pci", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/mapping/pci", + "text" : "pci" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove Hardware Mapping.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/usb", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get USB Mapping.", + "method" : "GET", + "name" : "get", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update a hardware mapping.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description of the logical USB device.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the logical USB mapping.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "map" : { + "description" : "A list of maps for the cluster nodes.", + "items" : { + "format" : { + "description" : { + "description" : "Description of the node specific device.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "The vendor and device ID that is expected. If a USB path is given, it is only used for detecting hardware changes", + "pattern" : "(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "path" : { + "description" : "The path to the usb device.", + "optional" : 1, + "pattern" : "(?^:^(\\d+)\\-(\\d+(\\.\\d+)*)$)", + "type" : "string" + } + }, + "type" : "string" + }, + "type" : "array", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/mapping/usb/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List USB Hardware Mappings", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "check-node" : { + "description" : "If given, checks the configurations on the given node for correctness, and adds relevant errors to the devices.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/usb/'.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "description" : { + "description" : "A description of the logical mapping.", + "type" : "string" + }, + "error" : { + "description" : "A list of errors when 'check_node' is given.", + "items" : { + "properties" : { + "message" : { + "description" : "The message of the error", + "type" : "string" + }, + "severity" : { + "description" : "The severity of the error", + "type" : "string" + } + }, + "type" : "object" + } + }, + "id" : { + "description" : "The logical ID of the mapping.", + "type" : "string" + }, + "map" : { + "description" : "The entries of the mapping.", + "items" : { + "description" : "A mapping for a node.", + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new hardware mapping.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "Description of the logical USB device.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "id" : { + "description" : "The ID of the logical USB mapping.", + "format" : "pve-configid", + "type" : "string", + "typetext" : "" + }, + "map" : { + "description" : "A list of maps for the cluster nodes.", + "items" : { + "format" : { + "description" : { + "description" : "Description of the node specific device.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "The vendor and device ID that is expected. If a USB path is given, it is only used for detecting hardware changes", + "pattern" : "(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "path" : { + "description" : "The path to the usb device.", + "optional" : 1, + "pattern" : "(?^:^(\\d+)\\-(\\d+(\\.\\d+)*)$)", + "type" : "string" + } + }, + "type" : "string" + }, + "type" : "array", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/mapping/usb", + [ + "Mapping.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/mapping/usb", + "text" : "usb" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List resource types.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/mapping", + "text" : "mapping" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'", + "user" : "all" + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "dest" : { + "optional" : 1, + "type" : "string" + }, + "dport" : { + "optional" : 1, + "type" : "string" + }, + "enable" : { + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "optional" : 1, + "type" : "string" + }, + "iface" : { + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "optional" : 1, + "type" : "string" + }, + "pos" : { + "type" : "integer" + }, + "proto" : { + "optional" : 1, + "type" : "string" + }, + "source" : { + "optional" : 1, + "type" : "string" + }, + "sport" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 1, + "type" : "string" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'", + "user" : "all" + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "pos" : { + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 0, + "type" : "string" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/vnets/{vnet}/firewall/rules", + "text" : "rules" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get vnet firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'", + "user" : "all" + }, + "returns" : { + "properties" : { + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean" + }, + "log_level_forward" : { + "description" : "Log level for forwarded traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "policy_forward" : { + "description" : "Forward policy.", + "enum" : [ + "ACCEPT", + "DROP" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "log_level_forward" : { + "description" : "Log level for forwarded traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "policy_forward" : { + "description" : "Forward policy.", + "enum" : [ + "ACCEPT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/vnets/{vnet}/firewall/options", + "text" : "options" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/vnets/{vnet}/firewall", + "text" : "firewall" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn subnet object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "subnet" : { + "description" : "The SDN subnet object identifier.", + "format" : "pve-sdn-subnet-id", + "type" : "string", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn subnet configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "subnet" : { + "description" : "The SDN subnet object identifier.", + "format" : "pve-sdn-subnet-id", + "type" : "string", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user" : "all" + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn subnet object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp-dns-server" : { + "description" : "IP address for the DNS server", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp-range" : { + "description" : "A list of DHCP ranges for this subnet", + "items" : { + "format" : "pve-sdn-dhcp-range", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dnszoneprefix" : { + "description" : "dns domain zone prefix ex: 'adm' -> .adm.mydomain.com", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway" : { + "description" : "Subnet Gateway: Will be assign on vnet for layer3 zones", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "snat" : { + "description" : "enable masquerade for this subnet if pve-firewall", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "subnet" : { + "description" : "The SDN subnet object identifier.", + "format" : "pve-sdn-subnet-id", + "type" : "string", + "typetext" : "" + }, + "vnet" : { + "description" : "associated vnet", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "description" : "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "text" : "{subnet}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN subnets index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{subnet}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn subnet object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dhcp-dns-server" : { + "description" : "IP address for the DNS server", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp-range" : { + "description" : "A list of DHCP ranges for this subnet", + "items" : { + "format" : "pve-sdn-dhcp-range", + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "dnszoneprefix" : { + "description" : "dns domain zone prefix ex: 'adm' -> .adm.mydomain.com", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway" : { + "description" : "Subnet Gateway: Will be assign on vnet for layer3 zones", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "snat" : { + "description" : "enable masquerade for this subnet if pve-firewall", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "subnet" : { + "description" : "The SDN subnet object identifier.", + "format" : "pve-sdn-subnet-id", + "type" : "string", + "typetext" : "" + }, + "type" : { + "enum" : [ + "subnet" + ], + "type" : "string" + }, + "vnet" : { + "description" : "associated vnet", + "optional" : 0, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "description" : "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/vnets/{vnet}/subnets", + "text" : "subnets" + }, + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete IP Mappings in a VNet", + "method" : "DELETE", + "name" : "ipdelete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ip" : { + "description" : "The IP address to delete", + "format" : "ip", + "type" : "string", + "typetext" : "" + }, + "mac" : { + "description" : "Unicast MAC address.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}/{vnet}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create IP Mapping in a VNet", + "method" : "POST", + "name" : "ipcreate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ip" : { + "description" : "The IP address to associate with the given MAC address", + "format" : "ip", + "type" : "string", + "typetext" : "" + }, + "mac" : { + "description" : "Unicast MAC address.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}/{vnet}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP Mapping in a VNet", + "method" : "PUT", + "name" : "ipupdate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ip" : { + "description" : "The IP address to associate with the given MAC address", + "format" : "ip", + "type" : "string", + "typetext" : "" + }, + "mac" : { + "description" : "Unicast MAC address.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}/{vnet}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/vnets/{vnet}/ips", + "text" : "ips" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn vnet object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn vnet configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user" : "all" + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn vnet object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "alias" : { + "description" : "alias name of the vnet", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})", + "type" : "string" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "isolate-ports" : { + "description" : "If true, sets the isolated property for all members of this VNet", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tag" : { + "description" : "vlan or vxlan id", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "vlanaware" : { + "description" : "Allow vm VLANs to pass through this vnet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "zone id", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "description" : "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/vnets/{vnet}", + "text" : "{vnet}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN vnets index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{vnet}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn vnet object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "alias" : { + "description" : "alias name of the vnet", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})", + "type" : "string" + }, + "isolate-ports" : { + "description" : "If true, sets the isolated property for all members of this VNet", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tag" : { + "description" : "vlan or vxlan id", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "type" : { + "description" : "Type", + "enum" : [ + "vnet" + ], + "optional" : 1, + "type" : "string" + }, + "vlanaware" : { + "description" : "Allow vm VLANs to pass through this vnet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vnet" : { + "description" : "The SDN vnet object identifier.", + "format" : "pve-sdn-vnet-id", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "zone id", + "optional" : 0, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/vnets", + "text" : "vnets" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn zone object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn zone configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn zone object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "advertise-subnets" : { + "description" : "Advertise evpn subnets if you have silent hosts", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bridge" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge-disable-mac-learning" : { + "description" : "Disable auto mac learning.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "controller" : { + "description" : "Frr router name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp" : { + "description" : "Type of the DHCP backend for this zone", + "enum" : [ + "dnsmasq" + ], + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable-arp-nd-suppression" : { + "description" : "Disable ipv4 arp && ipv6 neighbour discovery suppression", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "dns" : { + "description" : "dns api server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dnszone" : { + "description" : "dns domain zone ex: mydomain.com", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dp-id" : { + "description" : "Faucet dataplane id", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "exitnodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exitnodes-local-routing" : { + "description" : "Allow exitnodes to connect to evpn guests", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "exitnodes-primary" : { + "description" : "Force traffic to this exitnode first.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ipam" : { + "description" : "use a specific ipam", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mac" : { + "description" : "Anycast logical router mac address", + "format" : "mac-addr", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mtu" : { + "description" : "MTU", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peers" : { + "description" : "peers address list.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "reversedns" : { + "description" : "reverse dns api server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rt-import" : { + "description" : "Route-Target import", + "format" : "pve-sdn-bgp-rt-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tag" : { + "description" : "Service-VLAN Tag", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vlan-protocol" : { + "default" : "802.1q", + "enum" : [ + "802.1q", + "802.1ad" + ], + "optional" : 1, + "type" : "string" + }, + "vrf-vxlan" : { + "description" : "l3vni.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "vxlan-port" : { + "description" : "Vxlan tunnel udp port (default 4789).", + "maximum" : 65536, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65536)" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/zones/{zone}", + "text" : "{zone}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN zones index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "type" : { + "description" : "Only list SDN zones of specific type", + "enum" : [ + "evpn", + "faucet", + "qinq", + "simple", + "vlan", + "vxlan" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "dhcp" : { + "optional" : 1, + "type" : "string" + }, + "dns" : { + "optional" : 1, + "type" : "string" + }, + "dnszone" : { + "optional" : 1, + "type" : "string" + }, + "ipam" : { + "optional" : 1, + "type" : "string" + }, + "mtu" : { + "optional" : 1, + "type" : "integer" + }, + "nodes" : { + "optional" : 1, + "type" : "string" + }, + "pending" : { + "optional" : 1, + "type" : "boolean" + }, + "reversedns" : { + "optional" : 1, + "type" : "string" + }, + "state" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + }, + "zone" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{zone}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn zone object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "advertise-subnets" : { + "description" : "Advertise evpn subnets if you have silent hosts", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bridge" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge-disable-mac-learning" : { + "description" : "Disable auto mac learning.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "controller" : { + "description" : "Frr router name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp" : { + "description" : "Type of the DHCP backend for this zone", + "enum" : [ + "dnsmasq" + ], + "optional" : 1, + "type" : "string" + }, + "disable-arp-nd-suppression" : { + "description" : "Disable ipv4 arp && ipv6 neighbour discovery suppression", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "dns" : { + "description" : "dns api server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dnszone" : { + "description" : "dns domain zone ex: mydomain.com", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dp-id" : { + "description" : "Faucet dataplane id", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "exitnodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exitnodes-local-routing" : { + "description" : "Allow exitnodes to connect to evpn guests", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "exitnodes-primary" : { + "description" : "Force traffic to this exitnode first.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ipam" : { + "description" : "use a specific ipam", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mac" : { + "description" : "Anycast logical router mac address", + "format" : "mac-addr", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mtu" : { + "description" : "MTU", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "nodes" : { + "description" : "List of cluster node names.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peers" : { + "description" : "peers address list.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "reversedns" : { + "description" : "reverse dns api server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rt-import" : { + "description" : "Route-Target import", + "format" : "pve-sdn-bgp-rt-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tag" : { + "description" : "Service-VLAN Tag", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "evpn", + "faucet", + "qinq", + "simple", + "vlan", + "vxlan" + ], + "format" : "pve-configid", + "type" : "string" + }, + "vlan-protocol" : { + "default" : "802.1q", + "enum" : [ + "802.1q", + "802.1ad" + ], + "optional" : 1, + "type" : "string" + }, + "vrf-vxlan" : { + "description" : "l3vni.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "vxlan-port" : { + "description" : "Vxlan tunnel udp port (default 4789).", + "maximum" : 65536, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65536)" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/zones", + "text" : "zones" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn controller object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "controller" : { + "description" : "The SDN controller object identifier.", + "format" : "pve-sdn-controller-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn controller configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "controller" : { + "description" : "The SDN controller object identifier.", + "format" : "pve-sdn-controller-id", + "type" : "string", + "typetext" : "" + }, + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/controllers/{controller}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn controller object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "asn" : { + "description" : "autonomous system number", + "maximum" : 4294967296, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 4294967296)" + }, + "bgp-multipath-as-path-relax" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "controller" : { + "description" : "The SDN controller object identifier.", + "format" : "pve-sdn-controller-id", + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ebgp" : { + "description" : "Enable ebgp. (remote-as external)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ebgp-multihop" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "isis-domain" : { + "description" : "ISIS domain.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "isis-ifaces" : { + "description" : "ISIS interface.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "isis-net" : { + "description" : "ISIS network entity title.", + "format" : "pve-sdn-isis-net", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "loopback" : { + "description" : "source loopback interface.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peers" : { + "description" : "peers address list.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/controllers/{controller}", + "text" : "{controller}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN controllers index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "pending" : { + "description" : "Display pending config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "running" : { + "description" : "Display running config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "type" : { + "description" : "Only list sdn controllers of specific type", + "enum" : [ + "bgp", + "evpn", + "faucet", + "isis" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/controllers/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "controller" : { + "type" : "string" + }, + "pending" : { + "optional" : 1, + "type" : "boolean" + }, + "state" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{controller}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn controller object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "asn" : { + "description" : "autonomous system number", + "maximum" : 4294967296, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 4294967296)" + }, + "bgp-multipath-as-path-relax" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "controller" : { + "description" : "The SDN controller object identifier.", + "format" : "pve-sdn-controller-id", + "type" : "string", + "typetext" : "" + }, + "ebgp" : { + "description" : "Enable ebgp. (remote-as external)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ebgp-multihop" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "isis-domain" : { + "description" : "ISIS domain.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "isis-ifaces" : { + "description" : "ISIS interface.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "isis-net" : { + "description" : "ISIS network entity title.", + "format" : "pve-sdn-isis-net", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "loopback" : { + "description" : "source loopback interface.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "peers" : { + "description" : "peers address list.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "bgp", + "evpn", + "faucet", + "isis" + ], + "format" : "pve-configid", + "type" : "string" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/controllers", + "text" : "controllers" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List PVE IPAM Entries", + "method" : "GET", + "name" : "ipamindex", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ipam" : { + "description" : "The SDN ipam object identifier.", + "format" : "pve-sdn-ipam-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/ipams/{ipam}/status", + "text" : "status" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn ipam object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ipam" : { + "description" : "The SDN ipam object identifier.", + "format" : "pve-sdn-ipam-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn ipam configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "ipam" : { + "description" : "The SDN ipam object identifier.", + "format" : "pve-sdn-ipam-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/ipams/{ipam}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn ipam object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "ipam" : { + "description" : "The SDN ipam object identifier.", + "format" : "pve-sdn-ipam-id", + "type" : "string", + "typetext" : "" + }, + "section" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "token" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "url" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/ipams/{ipam}", + "text" : "{ipam}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN ipams index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list sdn ipams of specific type", + "enum" : [ + "netbox", + "phpipam", + "pve" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/ipams/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "ipam" : { + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{ipam}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn ipam object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "ipam" : { + "description" : "The SDN ipam object identifier.", + "format" : "pve-sdn-ipam-id", + "type" : "string", + "typetext" : "" + }, + "section" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "token" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "netbox", + "phpipam", + "pve" + ], + "format" : "pve-configid", + "type" : "string" + }, + "url" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/ipams", + "text" : "ipams" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete sdn dns object configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dns" : { + "description" : "The SDN dns object identifier.", + "format" : "pve-sdn-dns-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read sdn dns configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dns" : { + "description" : "The SDN dns object identifier.", + "format" : "pve-sdn-dns-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/dns/{dns}", + [ + "SDN.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update sdn dns object configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dns" : { + "description" : "The SDN dns object identifier.", + "format" : "pve-sdn-dns-id", + "type" : "string", + "typetext" : "" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "key" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "reversemaskv6" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "ttl" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "url" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/sdn/dns/{dns}", + "text" : "{dns}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN dns index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list sdn dns of specific type", + "enum" : [ + "powerdns" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/dns/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "dns" : { + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{dns}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new sdn dns object.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dns" : { + "description" : "The SDN dns object identifier.", + "format" : "pve-sdn-dns-id", + "type" : "string", + "typetext" : "" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "key" : { + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "reversemaskv6" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "reversev6mask" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "ttl" : { + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "type" : { + "description" : "Plugin type.", + "enum" : [ + "powerdns" + ], + "format" : "pve-configid", + "type" : "string" + }, + "url" : { + "optional" : 0, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn/dns", + "text" : "dns" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/sdn", + [ + "SDN.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Apply sdn controller changes && reload.", + "method" : "PUT", + "name" : "reload", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/cluster/sdn", + "text" : "sdn" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read cluster log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "max" : { + "description" : "Maximum number of entries.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Resources index (cluster wide).", + "method" : "GET", + "name" : "resources", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Resource type.", + "enum" : [ + "vm", + "storage", + "node", + "sdn" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "cgroup-mode" : { + "description" : "The cgroup mode the node operates under (for type 'node').", + "optional" : 1, + "type" : "integer" + }, + "content" : { + "description" : "Allowed storage content types (for type 'storage').", + "format" : "pve-storage-content-list", + "optional" : 1, + "type" : "string" + }, + "cpu" : { + "description" : "CPU utilization (for types 'node', 'qemu' and 'lxc').", + "minimum" : 0, + "optional" : 1, + "renderer" : "fraction_as_percentage", + "type" : "number" + }, + "disk" : { + "description" : "Used disk space in bytes (for type 'storage'), used root image space for VMs (for types 'qemu' and 'lxc').", + "minimum" : 0, + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "diskread" : { + "description" : "The amount of bytes the guest read from its block devices since the guest was started. This info is not available for all storage types. (for types 'qemu' and 'lxc')", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "diskwrite" : { + "description" : "The amount of bytes the guest wrote to its block devices since the guest was started. This info is not available for all storage types. (for types 'qemu' and 'lxc')", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "hastate" : { + "description" : "HA service status (for HA managed VMs).", + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "Resource id.", + "type" : "string" + }, + "level" : { + "description" : "Support level (for type 'node').", + "optional" : 1, + "type" : "string" + }, + "lock" : { + "description" : "The guest's current config lock (for types 'qemu' and 'lxc')", + "optional" : 1, + "type" : "string" + }, + "maxcpu" : { + "description" : "Number of available CPUs (for types 'node', 'qemu' and 'lxc').", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "maxdisk" : { + "description" : "Storage size in bytes (for type 'storage'), root image size for VMs (for types 'qemu' and 'lxc').", + "minimum" : 0, + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Number of available memory in bytes (for types 'node', 'qemu' and 'lxc').", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "mem" : { + "description" : "Used memory in bytes (for types 'node', 'qemu' and 'lxc').", + "minimum" : 0, + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "Name of the resource.", + "optional" : 1, + "type" : "string" + }, + "netin" : { + "description" : "The amount of traffic in bytes that was sent to the guest over the network since it was started. (for types 'qemu' and 'lxc')", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "netout" : { + "description" : "The amount of traffic in bytes that was sent from the guest over the network since it was started. (for types 'qemu' and 'lxc')", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "node" : { + "description" : "The cluster node name (for types 'node', 'storage', 'qemu', and 'lxc').", + "format" : "pve-node", + "optional" : 1, + "type" : "string" + }, + "plugintype" : { + "description" : "More specific type, if available.", + "optional" : 1, + "type" : "string" + }, + "pool" : { + "description" : "The pool name (for types 'pool', 'qemu' and 'lxc').", + "optional" : 1, + "type" : "string" + }, + "status" : { + "description" : "Resource type dependent status.", + "optional" : 1, + "type" : "string" + }, + "storage" : { + "description" : "The storage identifier (for type 'storage').", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string" + }, + "tags" : { + "description" : "The guest's tags (for types 'qemu' and 'lxc')", + "optional" : 1, + "type" : "string" + }, + "template" : { + "default" : 0, + "description" : "Determines if the guest is a template. (for types 'qemu' and 'lxc')", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "description" : "Resource type.", + "enum" : [ + "node", + "storage", + "pool", + "qemu", + "lxc", + "openvz", + "sdn" + ], + "type" : "string" + }, + "uptime" : { + "description" : "Uptime of node or virtual guest in seconds (for types 'node', 'qemu' and 'lxc').", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The numerical vmid (for types 'qemu' and 'lxc').", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/resources", + "text" : "resources" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List recent tasks (cluster wide).", + "method" : "GET", + "name" : "tasks", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "upid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/tasks", + "text" : "tasks" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get datacenter options. Without 'Sys.Audit' on '/' not all options are returned.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ], + "user" : "all" + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set datacenter options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "description" : "Set I/O bandwidth limit for various operations (in KiB/s).", + "format" : { + "clone" : { + "description" : "bandwidth limit in KiB/s for cloning disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "default" : { + "description" : "default bandwidth limit in KiB/s", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "migration" : { + "description" : "bandwidth limit in KiB/s for migrating guests (including moving local disks)", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "move" : { + "description" : "bandwidth limit in KiB/s for moving disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "restore" : { + "description" : "bandwidth limit in KiB/s for restoring guests from backups", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[clone=] [,default=] [,migration=] [,move=] [,restore=]" + }, + "consent-text" : { + "description" : "Consent text that is displayed before logging in.", + "maxLength" : 65536, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "console" : { + "description" : "Select the default Console viewer. You can either use the builtin java applet (VNC; deprecated and maps to html5), an external virt-viewer comtatible application (SPICE), an HTML5 based vnc viewer (noVNC), or an HTML5 based console client (xtermjs). If the selected viewer is not available (e.g. SPICE not activated for the VM), the fallback is noVNC.", + "enum" : [ + "applet", + "vv", + "html5", + "xtermjs" + ], + "optional" : 1, + "type" : "string" + }, + "crs" : { + "description" : "Cluster resource scheduling settings.", + "format" : { + "ha" : { + "default" : "basic", + "description" : "Use this resource scheduler mode for HA.", + "enum" : [ + "basic", + "static" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Configures how the HA manager should select nodes to start or recover services. With 'basic', only the number of services is used, with 'static', static CPU and memory configuration of services is considered." + }, + "ha-rebalance-on-start" : { + "default" : 0, + "description" : "Set to use CRS for selecting a suited node when a HA services request-state changes from stop to start.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[ha=] [,ha-rebalance-on-start=<1|0>]" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Datacenter description. Shown in the web-interface datacenter notes panel. This is saved as comment inside the configuration file.", + "maxLength" : 65536, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "email_from" : { + "description" : "Specify email address to send notification from (default is root@$hostname)", + "format" : "email-opt", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fencing" : { + "default" : "watchdog", + "description" : "Set the fencing mode of the HA cluster. Hardware mode needs a valid configuration of fence devices in /etc/pve/ha/fence.cfg. With both all two modes are used.\n\nWARNING: 'hardware' and 'both' are EXPERIMENTAL & WIP", + "enum" : [ + "watchdog", + "hardware", + "both" + ], + "optional" : 1, + "type" : "string" + }, + "ha" : { + "description" : "Cluster wide HA settings.", + "format" : { + "shutdown_policy" : { + "default" : "conditional", + "description" : "The policy for HA services on node shutdown. 'freeze' disables auto-recovery, 'failover' ensures recovery, 'conditional' recovers on poweroff and freezes on reboot. 'migrate' will migrate running services to other nodes, if possible. With 'freeze' or 'failover', HA Services will always get stopped first on shutdown.", + "enum" : [ + "freeze", + "failover", + "conditional", + "migrate" + ], + "type" : "string", + "verbose_description" : "Describes the policy for handling HA services on poweroff or reboot of a node. Freeze will always freeze services which are still located on the node on shutdown, those services won't be recovered by the HA manager. Failover will not mark the services as frozen and thus the services will get recovered to other nodes, if the shutdown node does not come up again quickly (< 1min). 'conditional' chooses automatically depending on the type of shutdown, i.e., on a reboot the service will be frozen but on a poweroff the service will stay as is, and thus get recovered after about 2 minutes. Migrate will try to move all running services to another node when a reboot or shutdown was triggered. The poweroff process will only continue once no running services are located on the node anymore. If the node comes up again, the service will be moved back to the previously powered-off node, at least if no other migration, reloaction or recovery took place." + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "shutdown_policy=" + }, + "http_proxy" : { + "description" : "Specify external http proxy which is used for downloads (example: 'http://username:password@host:port/')", + "optional" : 1, + "pattern" : "http://.*", + "type" : "string" + }, + "keyboard" : { + "description" : "Default keybord layout for vnc server.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "language" : { + "description" : "Default GUI language.", + "enum" : [ + "ar", + "ca", + "da", + "de", + "en", + "es", + "eu", + "fa", + "fr", + "hr", + "he", + "it", + "ja", + "ka", + "kr", + "nb", + "nl", + "nn", + "pl", + "pt_BR", + "ru", + "sl", + "sv", + "tr", + "ukr", + "zh_CN", + "zh_TW" + ], + "optional" : 1, + "type" : "string" + }, + "mac_prefix" : { + "default" : "BC:24:11", + "description" : "Prefix for the auto-generated MAC addresses of virtual guests. The default 'BC:24:11' is the OUI assigned by the IEEE to Proxmox Server Solutions GmbH for a 24-bit large MAC block. You're allowed to use this in local networks, i.e., those not directly reachable by the public (e.g., in a LAN or behind NAT).", + "format" : "mac-prefix", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "Prefix for the auto-generated MAC addresses of virtual guests. The default `BC:24:11` is the Organizationally Unique Identifier (OUI) assigned by the IEEE to Proxmox Server Solutions GmbH for a MAC Address Block Large (MA-L). You're allowed to use this in local networks, i.e., those not directly reachable by the public (e.g., in a LAN or NAT/Masquerading).\n \nNote that when you run multiple cluster that (partially) share the networks of their virtual guests, it's highly recommended that you extend the default MAC prefix, or generate a custom (valid) one, to reduce the chance of MAC collisions. For example, add a separate extra hexadecimal to the Proxmox OUI for each cluster, like `BC:24:11:0` for the first, `BC:24:11:1` for the second, and so on.\n Alternatively, you can also separate the networks of the guests logically, e.g., by using VLANs.\n\nFor publicly accessible guests it's recommended that you get your own https://standards.ieee.org/products-programs/regauth/[OUI from the IEEE] registered or coordinate with your, or your hosting providers, network admins." + }, + "max_workers" : { + "description" : "Defines how many workers (per node) are maximal started on actions like 'stopall VMs' or task from the ha-manager.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "migration" : { + "description" : "For cluster wide migration settings.", + "format" : { + "network" : { + "description" : "CIDR of the (sub) network that is used for migration.", + "format" : "CIDR", + "format_description" : "CIDR", + "optional" : 1, + "type" : "string" + }, + "type" : { + "default" : "secure", + "default_key" : 1, + "description" : "Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.", + "enum" : [ + "secure", + "insecure" + ], + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[type=] [,network=]" + }, + "migration_unsecure" : { + "description" : "Migration is secure using SSH tunnel by default. For secure private networks you can disable it to speed up migration. Deprecated, use the 'migration' property instead!", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "next-id" : { + "description" : "Control the range for the free VMID auto-selection pool.", + "format" : { + "lower" : { + "default" : 100, + "description" : "Lower, inclusive boundary for free next-id API range.", + "max" : 999999999, + "min" : 100, + "optional" : 1, + "type" : "integer" + }, + "upper" : { + "default" : 1000000, + "description" : "Upper, exclusive boundary for free next-id API range.", + "max" : 1000000000, + "min" : 100, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[lower=] [,upper=]" + }, + "notify" : { + "description" : "Cluster-wide notification settings.", + "format" : { + "fencing" : { + "description" : "UNUSED - Use datacenter notification settings instead.", + "enum" : [ + "always", + "never" + ], + "optional" : 1, + "type" : "string" + }, + "package-updates" : { + "default" : "auto", + "description" : "DEPRECATED: Use datacenter notification settings instead. Control when the daily update job should send out notifications.", + "enum" : [ + "auto", + "always", + "never" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "DEPRECATED: Use datacenter notification settings instead.\nControl how often the daily update job should send out notifications:\n* 'auto' daily for systems with a valid subscription, as those are assumed to be production-ready and thus should know about pending updates.\n* 'always' every update, if there are new pending updates.\n* 'never' never send a notification for new pending updates.\n" + }, + "replication" : { + "description" : "UNUSED - Use datacenter notification settings instead.", + "enum" : [ + "always", + "never" + ], + "optional" : 1, + "type" : "string" + }, + "target-fencing" : { + "description" : "UNUSED - Use datacenter notification settings instead.", + "format_description" : "TARGET", + "optional" : 1, + "type" : "string" + }, + "target-package-updates" : { + "description" : "UNUSED - Use datacenter notification settings instead.", + "format_description" : "TARGET", + "optional" : 1, + "type" : "string" + }, + "target-replication" : { + "description" : "UNUSED - Use datacenter notification settings instead.", + "format_description" : "TARGET", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[fencing=] [,package-updates=] [,replication=] [,target-fencing=] [,target-package-updates=] [,target-replication=]" + }, + "registered-tags" : { + "description" : "A list of tags that require a `Sys.Modify` on '/' to set and delete. Tags set here that are also in 'user-tag-access' also require `Sys.Modify`.", + "optional" : 1, + "pattern" : "(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*);)*(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*)", + "type" : "string", + "typetext" : "[;...]" + }, + "tag-style" : { + "description" : "Tag style options.", + "format" : { + "case-sensitive" : { + "default" : 0, + "description" : "Controls if filtering for unique tags on update should check case-sensitive.", + "optional" : 1, + "type" : "boolean" + }, + "color-map" : { + "description" : "Manual color mapping for tags (semicolon separated).", + "optional" : 1, + "pattern" : "(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*):[0-9a-fA-F]{6}(?::[0-9a-fA-F]{6})?)(?:;(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*):[0-9a-fA-F]{6}(?::[0-9a-fA-F]{6})?))*", + "type" : "string", + "typetext" : ":[:][;=...]" + }, + "ordering" : { + "default" : "alphabetical", + "description" : "Controls the sorting of the tags in the web-interface and the API update.", + "enum" : [ + "config", + "alphabetical" + ], + "optional" : 1, + "type" : "string" + }, + "shape" : { + "default" : "circle", + "description" : "Tag shape for the web ui tree. 'full' draws the full tag. 'circle' draws only a circle with the background color. 'dense' only draws a small rectancle (useful when many tags are assigned to each guest).'none' disables showing the tags.", + "enum" : [ + "full", + "circle", + "dense", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[case-sensitive=<1|0>] [,color-map=:[:][;=...]] [,ordering=] [,shape=]" + }, + "u2f" : { + "description" : "u2f", + "format" : { + "appid" : { + "description" : "U2F AppId URL override. Defaults to the origin.", + "format_description" : "APPID", + "optional" : 1, + "type" : "string" + }, + "origin" : { + "description" : "U2F Origin override. Mostly useful for single nodes with a single URL.", + "format_description" : "URL", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[appid=] [,origin=]" + }, + "user-tag-access" : { + "description" : "Privilege options for user-settable tags", + "format" : { + "user-allow" : { + "default" : "free", + "description" : "Controls tag usage for users without `Sys.Modify` on `/` by either allowing `none`, a `list`, already `existing` or anything (`free`).", + "enum" : [ + "none", + "list", + "existing", + "free" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Controls which tags can be set or deleted on resources a user controls (such as guests). Users with the `Sys.Modify` privilege on `/` are alwaysunrestricted.\n* 'none' no tags are usable.\n* 'list' tags from 'user-allow-list' are usable.\n* 'existing' like list, but already existing tags of resources are also usable.\n* 'free' no tag restrictions.\n" + }, + "user-allow-list" : { + "description" : "List of tags users are allowed to set and delete (semicolon separated) for 'user-allow' values 'list' and 'existing'.", + "optional" : 1, + "pattern" : "(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*)(?:;(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*))*", + "type" : "string", + "typetext" : "[;...]" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[user-allow=] [,user-allow-list=[;...]]" + }, + "webauthn" : { + "description" : "webauthn configuration", + "format" : { + "allow-subdomains" : { + "default" : 1, + "description" : "Whether to allow the origin to be a subdomain, rather than the exact URL.", + "optional" : 1, + "type" : "boolean" + }, + "id" : { + "description" : "Relying party ID. Must be the domain name without protocol, port or location. Changing this *will* break existing credentials.", + "format_description" : "DOMAINNAME", + "optional" : 1, + "type" : "string" + }, + "origin" : { + "description" : "Site origin. Must be a `https://` URL (or `http://localhost`). Should contain the address users type in their browsers to access the web interface. Changing this *may* break existing credentials.", + "format_description" : "URL", + "optional" : 1, + "type" : "string" + }, + "rp" : { + "description" : "Relying party name. Any text identifier. Changing this *may* break existing credentials.", + "format_description" : "RELYING_PARTY", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[allow-subdomains=<1|0>] [,id=] [,origin=] [,rp=]" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/cluster/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get cluster status information.", + "method" : "GET", + "name" : "get_status", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + }, + "ip" : { + "description" : "[node] IP of the resolved nodename.", + "optional" : 1, + "type" : "string" + }, + "level" : { + "description" : "[node] Proxmox VE Subscription level, indicates if eligible for enterprise support as well as access to the stable Proxmox VE Enterprise Repository.", + "optional" : 1, + "type" : "string" + }, + "local" : { + "description" : "[node] Indicates if this is the responding node.", + "optional" : 1, + "type" : "boolean" + }, + "name" : { + "type" : "string" + }, + "nodeid" : { + "description" : "[node] ID of the node from the corosync configuration.", + "optional" : 1, + "type" : "integer" + }, + "nodes" : { + "description" : "[cluster] Nodes count, including offline nodes.", + "optional" : 1, + "type" : "integer" + }, + "online" : { + "description" : "[node] Indicates if the node is online or offline.", + "optional" : 1, + "type" : "boolean" + }, + "quorate" : { + "description" : "[cluster] Indicates if there is a majority of nodes online to make decisions", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "description" : "Indicates the type, either cluster or node. The type defines the object properties e.g. quorate available for type cluster.", + "enum" : [ + "cluster", + "node" + ], + "type" : "string" + }, + "version" : { + "description" : "[cluster] Current version of the corosync configuration file.", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/cluster/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get next free VMID. Pass a VMID to assert that its free (at time of check).", + "method" : "GET", + "name" : "nextid", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "description" : "The next free VMID.", + "type" : "integer" + } + } + }, + "leaf" : 1, + "path" : "/cluster/nextid", + "text" : "nextid" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Cluster index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/cluster", + "text" : "cluster" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "dest" : { + "optional" : 1, + "type" : "string" + }, + "dport" : { + "optional" : 1, + "type" : "string" + }, + "enable" : { + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "optional" : 1, + "type" : "string" + }, + "iface" : { + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "optional" : 1, + "type" : "string" + }, + "pos" : { + "type" : "integer" + }, + "proto" : { + "optional" : 1, + "type" : "string" + }, + "source" : { + "optional" : 1, + "type" : "string" + }, + "sport" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "pos" : { + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 0, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/rules", + "text" : "rules" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network alias.", + "method" : "DELETE", + "name" : "remove_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read alias.", + "method" : "GET", + "name" : "read_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network alias.", + "method" : "PUT", + "name" : "update_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "rename" : { + "description" : "Rename an existing alias.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List aliases", + "method" : "GET", + "name" : "get_aliases", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create IP or Network Alias.", + "method" : "POST", + "name" : "create_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/aliases", + "text" : "aliases" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network from IPSet.", + "method" : "DELETE", + "name" : "remove_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read IP or Network settings from IPSet.", + "method" : "GET", + "name" : "read_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network settings", + "method" : "PUT", + "name" : "update_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "text" : "{cidr}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete IPSet", + "method" : "DELETE", + "name" : "delete_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "Delete all members of the IPSet, if there are any.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List IPSet content", + "method" : "GET", + "name" : "get_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{cidr}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add IP or Network to IPSet.", + "method" : "POST", + "name" : "create_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List IPSets", + "method" : "GET", + "name" : "ipset_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new IPSet", + "method" : "POST", + "name" : "create_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "rename" : { + "description" : "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/ipset", + "text" : "ipset" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get VM firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "dhcp" : { + "default" : 0, + "description" : "Enable DHCP.", + "optional" : 1, + "type" : "boolean" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean" + }, + "ipfilter" : { + "description" : "Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.", + "optional" : 1, + "type" : "boolean" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macfilter" : { + "default" : 1, + "description" : "Enable/disable MAC address filter.", + "optional" : 1, + "type" : "boolean" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "radv" : { + "description" : "Allow sending Router Advertisement.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp" : { + "default" : 0, + "description" : "Enable DHCP.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ipfilter" : { + "description" : "Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macfilter" : { + "default" : 1, + "description" : "Enable/disable MAC address filter.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "radv" : { + "description" : "Allow sending Router Advertisement.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read firewall log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display log since this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "until" : { + "description" : "Display log until this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Lists possible IPSet/Alias reference which are allowed in source/dest properties.", + "method" : "GET", + "name" : "refs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Only list references of specified type.", + "enum" : [ + "alias", + "ipset" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "ref" : { + "type" : "string" + }, + "scope" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "alias", + "ipset" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/firewall/refs", + "text" : "refs" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/firewall", + "text" : "firewall" + }, + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute fsfreeze-freeze.", + "method" : "POST", + "name" : "fsfreeze-freeze", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze", + "text" : "fsfreeze-freeze" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute fsfreeze-status.", + "method" : "POST", + "name" : "fsfreeze-status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status", + "text" : "fsfreeze-status" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute fsfreeze-thaw.", + "method" : "POST", + "name" : "fsfreeze-thaw", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw", + "text" : "fsfreeze-thaw" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute fstrim.", + "method" : "POST", + "name" : "fstrim", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/fstrim", + "text" : "fstrim" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-fsinfo.", + "method" : "GET", + "name" : "get-fsinfo", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-fsinfo", + "text" : "get-fsinfo" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-host-name.", + "method" : "GET", + "name" : "get-host-name", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-host-name", + "text" : "get-host-name" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-memory-block-info.", + "method" : "GET", + "name" : "get-memory-block-info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info", + "text" : "get-memory-block-info" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-memory-blocks.", + "method" : "GET", + "name" : "get-memory-blocks", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks", + "text" : "get-memory-blocks" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-osinfo.", + "method" : "GET", + "name" : "get-osinfo", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-osinfo", + "text" : "get-osinfo" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-time.", + "method" : "GET", + "name" : "get-time", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-time", + "text" : "get-time" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-timezone.", + "method" : "GET", + "name" : "get-timezone", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-timezone", + "text" : "get-timezone" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-users.", + "method" : "GET", + "name" : "get-users", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-users", + "text" : "get-users" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute get-vcpus.", + "method" : "GET", + "name" : "get-vcpus", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/get-vcpus", + "text" : "get-vcpus" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute info.", + "method" : "GET", + "name" : "info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/info", + "text" : "info" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Execute network-get-interfaces.", + "method" : "GET", + "name" : "network-get-interfaces", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces", + "text" : "network-get-interfaces" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute ping.", + "method" : "POST", + "name" : "ping", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/ping", + "text" : "ping" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute shutdown.", + "method" : "POST", + "name" : "shutdown", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/shutdown", + "text" : "shutdown" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute suspend-disk.", + "method" : "POST", + "name" : "suspend-disk", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/suspend-disk", + "text" : "suspend-disk" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute suspend-hybrid.", + "method" : "POST", + "name" : "suspend-hybrid", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid", + "text" : "suspend-hybrid" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute suspend-ram.", + "method" : "POST", + "name" : "suspend-ram", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/suspend-ram", + "text" : "suspend-ram" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Sets the password for the given user to the given password", + "method" : "POST", + "name" : "set-user-password", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "crypted" : { + "default" : 0, + "description" : "set to 1 if the password has already been passed through crypt()", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The new password.", + "maxLength" : 1024, + "minLength" : 5, + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "The user to set the password for.", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/set-user-password", + "text" : "set-user-password" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Executes the given command in the vm via the guest-agent and returns an object with the pid.", + "method" : "POST", + "name" : "exec", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "command" : { + "description" : "The command as a list of program + arguments.", + "items" : { + "description" : "A single part of the program + arguments.", + "format" : "string" + }, + "type" : "array", + "typetext" : "" + }, + "input-data" : { + "description" : "Data to pass as 'input-data' to the guest. Usually treated as STDIN to 'command'.", + "maxLength" : 65536, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "pid" : { + "description" : "The PID of the process started by the guest-agent.", + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/exec", + "text" : "exec" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Gets the status of the given pid started by the guest-agent", + "method" : "GET", + "name" : "exec-status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pid" : { + "description" : "The PID to query", + "type" : "integer", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "err-data" : { + "description" : "stderr of the process", + "optional" : 1, + "type" : "string" + }, + "err-truncated" : { + "description" : "true if stderr was not fully captured", + "optional" : 1, + "type" : "boolean" + }, + "exitcode" : { + "description" : "process exit code if it was normally terminated.", + "optional" : 1, + "type" : "integer" + }, + "exited" : { + "description" : "Tells if the given command has exited yet.", + "type" : "boolean" + }, + "out-data" : { + "description" : "stdout of the process", + "optional" : 1, + "type" : "string" + }, + "out-truncated" : { + "description" : "true if stdout was not fully captured", + "optional" : 1, + "type" : "boolean" + }, + "signal" : { + "description" : "signal number or exception code if the process was abnormally terminated.", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/exec-status", + "text" : "exec-status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Reads the given file via guest agent. Is limited to 16777216 bytes.", + "method" : "GET", + "name" : "file-read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "file" : { + "description" : "The path to the file", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a `content` property.", + "properties" : { + "content" : { + "description" : "The content of the file, maximum 16777216", + "type" : "string" + }, + "truncated" : { + "description" : "If set to 1, the output is truncated and not complete", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/file-read", + "text" : "file-read" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Writes the given file via guest agent.", + "method" : "POST", + "name" : "file-write", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "content" : { + "description" : "The content to write into the file.", + "maxLength" : 61440, + "type" : "string", + "typetext" : "" + }, + "encode" : { + "default" : 1, + "description" : "If set, the content will be encoded as base64 (required by QEMU).Otherwise the content needs to be encoded beforehand - defaults to true.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "file" : { + "description" : "The path to the file.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/agent/file-write", + "text" : "file-write" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "QEMU Guest Agent command index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 1, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "description" : "Returns the list of QEMU Guest Agent commands", + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Execute QEMU Guest Agent commands.", + "method" : "POST", + "name" : "agent", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "command" : { + "description" : "The QGA command.", + "enum" : [ + "fsfreeze-freeze", + "fsfreeze-status", + "fsfreeze-thaw", + "fstrim", + "get-fsinfo", + "get-host-name", + "get-memory-block-info", + "get-memory-blocks", + "get-osinfo", + "get-time", + "get-timezone", + "get-users", + "get-vcpus", + "info", + "network-get-interfaces", + "ping", + "shutdown", + "suspend-disk", + "suspend-hybrid", + "suspend-ram" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Returns an object with a single `result` property.", + "type" : "object" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/agent", + "text" : "agent" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read VM RRD statistics (returns PNG)", + "method" : "GET", + "name" : "rrd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "ds" : { + "description" : "The list of datasources you want to display.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "filename" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/rrd", + "text" : "rrd" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read VM RRD statistics", + "method" : "GET", + "name" : "rrddata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/rrddata", + "text" : "rrddata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the virtual machine configuration with pending configuration changes applied. Set the 'current' parameter to get the current configuration instead.", + "method" : "GET", + "name" : "vm_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "current" : { + "default" : 0, + "description" : "Get current values (instead of pending values).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapshot" : { + "description" : "Fetch config values from given snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "description" : "The VM configuration.", + "properties" : { + "acpi" : { + "default" : 1, + "description" : "Enable/disable ACPI.", + "optional" : 1, + "type" : "boolean" + }, + "affinity" : { + "description" : "List of host cores used to execute guest processes, for example: 0,5,8-11", + "format" : "pve-cpuset", + "optional" : 1, + "type" : "string" + }, + "agent" : { + "description" : "Enable/disable communication with the QEMU Guest Agent and its properties.", + "format" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.", + "type" : "boolean" + }, + "freeze-fs-on-backup" : { + "default" : 1, + "description" : "Freeze/thaw guest filesystems on backup for consistency.", + "optional" : 1, + "type" : "boolean" + }, + "fstrim_cloned_disks" : { + "default" : 0, + "description" : "Run fstrim after moving a disk or migrating the VM.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default" : "virtio", + "description" : "Select the agent type", + "enum" : [ + "virtio", + "isa" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "amd-sev" : { + "description" : "Secure Encrypted Virtualization (SEV) features by AMD CPUs", + "format" : "pve-qemu-sev-fmt", + "optional" : 1, + "type" : "string" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "args" : { + "description" : "Arbitrary arguments passed to kvm.", + "optional" : 1, + "type" : "string", + "verbose_description" : "Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -smbios 'type=0,vendor=FOO'\n\nNOTE: this option is for experts only.\n" + }, + "audio0" : { + "description" : "Configure a audio device, useful in combination with QXL/Spice.", + "format" : { + "device" : { + "description" : "Configure an audio device.", + "enum" : [ + "ich9-intel-hda", + "intel-hda", + "AC97" + ], + "type" : "string" + }, + "driver" : { + "default" : "spice", + "description" : "Driver backend for the audio device.", + "enum" : [ + "spice", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "autostart" : { + "default" : 0, + "description" : "Automatic restart after crash (currently ignored).", + "optional" : 1, + "type" : "boolean" + }, + "balloon" : { + "description" : "Amount of target RAM for the VM in MiB. Using zero disables the ballon driver.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "bios" : { + "default" : "seabios", + "description" : "Select BIOS implementation.", + "enum" : [ + "seabios", + "ovmf" + ], + "optional" : 1, + "type" : "string" + }, + "boot" : { + "description" : "Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.", + "format" : "pve-qm-boot", + "optional" : 1, + "type" : "string" + }, + "bootdisk" : { + "description" : "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format" : "pve-qm-bootdisk", + "optional" : 1, + "pattern" : "(ide|sata|scsi|virtio)\\d+", + "type" : "string" + }, + "cdrom" : { + "description" : "This is an alias for option -ide2", + "format" : "pve-qm-ide", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cicustom" : { + "description" : "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format" : "pve-qm-cicustom", + "optional" : 1, + "type" : "string" + }, + "cipassword" : { + "description" : "cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.", + "optional" : 1, + "type" : "string" + }, + "citype" : { + "description" : "Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.", + "enum" : [ + "configdrive2", + "nocloud", + "opennebula" + ], + "optional" : 1, + "type" : "string" + }, + "ciupgrade" : { + "default" : 1, + "description" : "cloud-init: do an automatic package upgrade after the first boot.", + "optional" : 1, + "type" : "boolean" + }, + "ciuser" : { + "description" : "cloud-init: User name to change ssh keys and password for instead of the image's configured default user.", + "optional" : 1, + "type" : "string" + }, + "cores" : { + "default" : 1, + "description" : "The number of cores per socket.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cpu" : { + "description" : "Emulated CPU type.", + "format" : "pve-vm-cpu-conf", + "optional" : 1, + "type" : "string" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "verbose_description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit." + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 262144, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "verbose_description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs." + }, + "description" : { + "description" : "Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "SHA1 digest of configuration file. This can be used to prevent concurrent modifications.", + "type" : "string" + }, + "efidisk0" : { + "description" : "Configure a disk for storing EFI vars.", + "format" : { + "efitype" : { + "default" : "2m", + "description" : "Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarch64 (ARM).", + "enum" : [ + "2m", + "4m" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "pre-enrolled-keys" : { + "default" : 0, + "description" : "Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string" + }, + "freeze" : { + "description" : "Freeze CPU at startup (use 'c' monitor command to start execution).", + "optional" : 1, + "type" : "boolean" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the vms lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string" + }, + "hostpci[n]" : { + "description" : "Map host PCI devices into guest.", + "format" : "pve-qm-hostpci", + "optional" : 1, + "type" : "string", + "verbose_description" : "Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "hotplug" : { + "default" : "network,disk,usb", + "description" : "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.", + "format" : "pve-hotplug-features", + "optional" : 1, + "type" : "string" + }, + "hugepages" : { + "description" : "Enable/disable hugepages memory.", + "enum" : [ + "any", + "2", + "1024" + ], + "optional" : 1, + "type" : "string" + }, + "ide[n]" : { + "description" : "Use volume as IDE hard disk or CD-ROM (n is 0 to 3).", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "model" : { + "description" : "The drive's reported model name, url-encoded, up to 40 bytes long.", + "format" : "urlencoded", + "format_description" : "model", + "maxLength" : 120, + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "ipconfig[n]" : { + "description" : "cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n", + "format" : "pve-qm-ipconfig", + "optional" : 1, + "type" : "string" + }, + "ivshmem" : { + "description" : "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + "format" : { + "name" : { + "description" : "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + "format_description" : "string", + "optional" : 1, + "pattern" : "[a-zA-Z0-9\\-]+", + "type" : "string" + }, + "size" : { + "description" : "The size of the file in MB.", + "minimum" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string" + }, + "keephugepages" : { + "default" : 0, + "description" : "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "optional" : 1, + "type" : "boolean" + }, + "keyboard" : { + "default" : null, + "description" : "Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "kvm" : { + "default" : 1, + "description" : "Enable/disable KVM hardware virtualization.", + "optional" : 1, + "type" : "boolean" + }, + "localtime" : { + "description" : "Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.", + "optional" : 1, + "type" : "boolean" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ], + "optional" : 1, + "type" : "string" + }, + "machine" : { + "description" : "Specify the QEMU machine.", + "format" : { + "enable-s3" : { + "description" : "Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "enable-s4" : { + "description" : "Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default_key" : 1, + "description" : "Specifies the QEMU machine type.", + "format_description" : "machine type", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "viommu" : { + "description" : "Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).", + "enum" : [ + "intel", + "virtio" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "memory" : { + "description" : "Memory properties.", + "format" : { + "current" : { + "default" : 512, + "default_key" : 1, + "description" : "Current amount of online RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.", + "minimum" : 16, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string" + }, + "migrate_downtime" : { + "default" : 0.1, + "description" : "Set maximum tolerated downtime (in seconds) for migrations. Should the migration not be able to converge in the very end, because too much newly dirtied RAM needs to be transferred, the limit will be increased automatically step-by-step until migration can converge.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "migrate_speed" : { + "default" : 0, + "description" : "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "Set a name for the VM. Only used on the configuration web interface.", + "format" : "dns-name", + "optional" : 1, + "type" : "string" + }, + "nameserver" : { + "description" : "cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "format" : "address-list", + "optional" : 1, + "type" : "string" + }, + "net[n]" : { + "description" : "Specify network devices.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n", + "format" : "pve-bridge-id", + "format_description" : "bridge", + "optional" : 1, + "type" : "string" + }, + "e1000" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82540em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82544gc" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82545em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000e" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "firewall" : { + "description" : "Whether this interface should be protected by the firewall.", + "optional" : 1, + "type" : "boolean" + }, + "i82551" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82557b" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82559er" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "macaddr" : { + "description" : "MAC address. That address must be unique within your network. This is automatically generated if not specified.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "model" : { + "default_key" : 1, + "description" : "Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.", + "enum" : [ + "e1000", + "e1000-82540em", + "e1000-82544gc", + "e1000-82545em", + "e1000e", + "i82551", + "i82557b", + "i82559er", + "ne2k_isa", + "ne2k_pci", + "pcnet", + "rtl8139", + "virtio", + "vmxnet3" + ], + "type" : "string" + }, + "mtu" : { + "description" : "Force MTU, for VirtIO only. Set to '1' to use the bridge MTU", + "maximum" : 65520, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "ne2k_isa" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "ne2k_pci" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "pcnet" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "queues" : { + "description" : "Number of packet queues to be used on the device.", + "maximum" : 64, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "rtl8139" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "tag" : { + "description" : "VLAN tag to apply to packets on this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN trunks to pass through this interface.", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "virtio" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "vmxnet3" : { + "alias" : "macaddr", + "keyAlias" : "model" + } + }, + "optional" : 1, + "type" : "string" + }, + "numa" : { + "default" : 0, + "description" : "Enable/disable NUMA.", + "optional" : 1, + "type" : "boolean" + }, + "numa[n]" : { + "description" : "NUMA topology.", + "format" : { + "cpus" : { + "description" : "CPUs accessing this NUMA node.", + "format_description" : "id[-id];...", + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "hostnodes" : { + "description" : "Host NUMA nodes to use.", + "format_description" : "id[-id];...", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "memory" : { + "description" : "Amount of memory this NUMA node provides.", + "optional" : 1, + "type" : "number" + }, + "policy" : { + "description" : "NUMA allocation policy.", + "enum" : [ + "preferred", + "bind", + "interleave" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean" + }, + "ostype" : { + "description" : "Specify guest operating system.", + "enum" : [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "win11", + "l24", + "l26", + "solaris" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022/2025\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 6.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n" + }, + "parallel[n]" : { + "description" : "Map host parallel devices (n is 0 to 2).", + "optional" : 1, + "pattern" : "/dev/parport\\d+|/dev/usb/lp\\d+", + "type" : "string", + "verbose_description" : "Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "optional" : 1, + "type" : "boolean" + }, + "reboot" : { + "default" : 1, + "description" : "Allow reboot. If set to '0' the VM exit on reboot.", + "optional" : 1, + "type" : "boolean" + }, + "rng0" : { + "description" : "Configure a VirtIO-based Random Number Generator.", + "format" : "pve-qm-rng", + "optional" : 1, + "type" : "string" + }, + "sata[n]" : { + "description" : "Use volume as SATA hard disk or CD-ROM (n is 0 to 5).", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "scsi[n]" : { + "description" : "Use volume as SCSI hard disk or CD-ROM (n is 0 to 30).", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "product" : { + "description" : "The drive's product name, up to 16 bytes long.", + "format_description" : "product", + "optional" : 1, + "pattern" : "[A-Za-z0-9\\-_\\s]{,16}", + "type" : "string" + }, + "queues" : { + "description" : "Number of queues.", + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "scsiblock" : { + "default" : 0, + "description" : "whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "vendor" : { + "description" : "The drive's vendor name, up to 8 bytes long.", + "format_description" : "vendor", + "optional" : 1, + "pattern" : "[A-Za-z0-9\\-_\\s]{,8}", + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "scsihw" : { + "default" : "lsi", + "description" : "SCSI controller model", + "enum" : [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "optional" : 1, + "type" : "string" + }, + "serial[n]" : { + "description" : "Create a serial device inside the VM (n is 0 to 3)", + "optional" : 1, + "pattern" : "(/dev/.+|socket)", + "type" : "string", + "verbose_description" : "Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "shares" : { + "default" : 1000, + "description" : "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.", + "maximum" : 50000, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "smbios1" : { + "description" : "Specify SMBIOS type 1 fields.", + "format" : "pve-qm-smbios1", + "maxLength" : 512, + "optional" : 1, + "type" : "string" + }, + "smp" : { + "default" : 1, + "description" : "The number of CPUs. Please use option -sockets instead.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "sockets" : { + "default" : 1, + "description" : "The number of CPU sockets.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "spice_enhancements" : { + "description" : "Configure additional enhancements for SPICE.", + "format" : { + "foldersharing" : { + "default" : "0", + "description" : "Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.", + "optional" : 1, + "type" : "boolean" + }, + "videostreaming" : { + "default" : "off", + "description" : "Enable video streaming. Uses compression for detected video streams.", + "enum" : [ + "off", + "all", + "filter" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "sshkeys" : { + "description" : "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format" : "urlencoded", + "optional" : 1, + "type" : "string" + }, + "startdate" : { + "default" : "now", + "description" : "Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.", + "optional" : 1, + "pattern" : "(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)", + "type" : "string", + "typetext" : "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "tablet" : { + "default" : 1, + "description" : "Enable/disable the USB tablet device.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)." + }, + "tags" : { + "description" : "Tags of the VM. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string" + }, + "tdf" : { + "default" : 0, + "description" : "Enable/disable time drift fix.", + "optional" : 1, + "type" : "boolean" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean" + }, + "tpmstate0" : { + "description" : "Configure a Disk for storing TPM state. The format is fixed to 'raw'.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "version" : { + "default" : "v1.2", + "description" : "The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.", + "enum" : [ + "v1.2", + "v2.0" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string" + }, + "usb[n]" : { + "description" : "Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).", + "format" : { + "host" : { + "default_key" : 1, + "description" : "The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadecimal numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n\nEither this or the 'mapping' key must be set.\n", + "format_description" : "HOSTUSBDEVICE|spice", + "optional" : 1, + "pattern" : "(?^:(?:(?:(?^:(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})))|(?:(?^:(\\d+)\\-(\\d+(\\.\\d+)*)))|[Ss][Pp][Ii][Cc][Ee]))", + "type" : "string" + }, + "mapping" : { + "description" : "The ID of a cluster wide mapping. Either this or the default-key 'host' must be set.", + "format" : "pve-configid", + "format_description" : "mapping-id", + "optional" : 1, + "type" : "string" + }, + "usb3" : { + "default" : 0, + "description" : "Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string" + }, + "vcpus" : { + "default" : 0, + "description" : "Number of hotplugged vcpus.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "vga" : { + "description" : "Configure the VGA hardware.", + "format" : { + "clipboard" : { + "description" : "Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Migration with VNC clipboard is not yet supported!", + "enum" : [ + "vnc" + ], + "optional" : 1, + "type" : "string" + }, + "memory" : { + "description" : "Sets the VGA memory (in MiB). Has no effect with serial display.", + "maximum" : 512, + "minimum" : 4, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "default" : "std", + "default_key" : 1, + "description" : "Select the VGA type. Using type 'cirrus' is not recommended.", + "enum" : [ + "cirrus", + "qxl", + "qxl2", + "qxl3", + "qxl4", + "none", + "serial0", + "serial1", + "serial2", + "serial3", + "std", + "virtio", + "virtio-gl", + "vmware" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "verbose_description" : "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal." + }, + "virtio[n]" : { + "description" : "Use volume as VIRTIO hard disk (n is 0 to 15).", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "virtiofs[n]" : { + "description" : "Configuration for sharing a directory between host and guest using Virtio-fs.", + "format" : { + "cache" : { + "default" : "auto", + "description" : "The caching policy the file system should use (auto, always, metadata, never).", + "enum" : [ + "auto", + "always", + "metadata", + "never" + ], + "optional" : 1, + "type" : "string" + }, + "direct-io" : { + "default" : 0, + "description" : "Honor the O_DIRECT flag passed down by guest applications.", + "optional" : 1, + "type" : "boolean" + }, + "dirid" : { + "default_key" : 1, + "description" : "Mapping identifier of the directory mapping to be shared with the guest. Also used as a mount tag inside the VM.", + "format" : "pve-configid", + "format_description" : "mapping-id", + "type" : "string" + }, + "expose-acl" : { + "default" : 0, + "description" : "Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.", + "optional" : 1, + "type" : "boolean" + }, + "expose-xattr" : { + "default" : 0, + "description" : "Enable support for extended attributes for this mount.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string" + }, + "vmgenid" : { + "default" : "1 (autogenerated)", + "description" : "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "format_description" : "UUID", + "optional" : 1, + "pattern" : "(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])", + "type" : "string", + "verbose_description" : "The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file." + }, + "vmstatestorage" : { + "description" : "Default storage for VM state volumes/files.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string" + }, + "watchdog" : { + "description" : "Create a virtual hardware watchdog device.", + "format" : "pve-qm-watchdog", + "optional" : 1, + "type" : "string", + "verbose_description" : "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Set virtual machine options (asynchronous API).", + "method" : "POST", + "name" : "update_vm_async", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acpi" : { + "default" : 1, + "description" : "Enable/disable ACPI.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "affinity" : { + "description" : "List of host cores used to execute guest processes, for example: 0,5,8-11", + "format" : "pve-cpuset", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "agent" : { + "description" : "Enable/disable communication with the QEMU Guest Agent and its properties.", + "format" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.", + "type" : "boolean" + }, + "freeze-fs-on-backup" : { + "default" : 1, + "description" : "Freeze/thaw guest filesystems on backup for consistency.", + "optional" : 1, + "type" : "boolean" + }, + "fstrim_cloned_disks" : { + "default" : 0, + "description" : "Run fstrim after moving a disk or migrating the VM.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default" : "virtio", + "description" : "Select the agent type", + "enum" : [ + "virtio", + "isa" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[enabled=]<1|0> [,freeze-fs-on-backup=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]" + }, + "amd-sev" : { + "description" : "Secure Encrypted Virtualization (SEV) features by AMD CPUs", + "format" : "pve-qemu-sev-fmt", + "optional" : 1, + "type" : "string", + "typetext" : "[type=] [,allow-smt=<1|0>] [,kernel-hashes=<1|0>] [,no-debug=<1|0>] [,no-key-sharing=<1|0>]" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "args" : { + "description" : "Arbitrary arguments passed to kvm.", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -smbios 'type=0,vendor=FOO'\n\nNOTE: this option is for experts only.\n" + }, + "audio0" : { + "description" : "Configure a audio device, useful in combination with QXL/Spice.", + "format" : { + "device" : { + "description" : "Configure an audio device.", + "enum" : [ + "ich9-intel-hda", + "intel-hda", + "AC97" + ], + "type" : "string" + }, + "driver" : { + "default" : "spice", + "description" : "Driver backend for the audio device.", + "enum" : [ + "spice", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "device= [,driver=]" + }, + "autostart" : { + "default" : 0, + "description" : "Automatic restart after crash (currently ignored).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "background_delay" : { + "description" : "Time to wait for the task to finish. We return 'null' if the task finish within that time.", + "maximum" : 30, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 30)" + }, + "balloon" : { + "description" : "Amount of target RAM for the VM in MiB. Using zero disables the ballon driver.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "bios" : { + "default" : "seabios", + "description" : "Select BIOS implementation.", + "enum" : [ + "seabios", + "ovmf" + ], + "optional" : 1, + "type" : "string" + }, + "boot" : { + "description" : "Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.", + "format" : "pve-qm-boot", + "optional" : 1, + "type" : "string", + "typetext" : "[[legacy=]<[acdn]{1,4}>] [,order=]" + }, + "bootdisk" : { + "description" : "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format" : "pve-qm-bootdisk", + "optional" : 1, + "pattern" : "(ide|sata|scsi|virtio)\\d+", + "type" : "string" + }, + "cdrom" : { + "description" : "This is an alias for option -ide2", + "format" : "pve-qm-ide", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cicustom" : { + "description" : "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format" : "pve-qm-cicustom", + "optional" : 1, + "type" : "string", + "typetext" : "[meta=] [,network=] [,user=] [,vendor=]" + }, + "cipassword" : { + "description" : "cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "citype" : { + "description" : "Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.", + "enum" : [ + "configdrive2", + "nocloud", + "opennebula" + ], + "optional" : 1, + "type" : "string" + }, + "ciupgrade" : { + "default" : 1, + "description" : "cloud-init: do an automatic package upgrade after the first boot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ciuser" : { + "description" : "cloud-init: User name to change ssh keys and password for instead of the image's configured default user.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cores" : { + "default" : 1, + "description" : "The number of cores per socket.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "cpu" : { + "description" : "Emulated CPU type.", + "format" : "pve-vm-cpu-conf", + "optional" : 1, + "type" : "string", + "typetext" : "[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 128)", + "verbose_description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit." + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 262144, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 262144)", + "verbose_description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs." + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "efidisk0" : { + "description" : "Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "efitype" : { + "default" : "2m", + "description" : "Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarch64 (ARM).", + "enum" : [ + "2m", + "4m" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "pre-enrolled-keys" : { + "default" : 0, + "description" : "Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,pre-enrolled-keys=<1|0>] [,size=]" + }, + "force" : { + "description" : "Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.", + "optional" : 1, + "requires" : "delete", + "type" : "boolean", + "typetext" : "" + }, + "freeze" : { + "description" : "Freeze CPU at startup (use 'c' monitor command to start execution).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the vms lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostpci[n]" : { + "description" : "Map host PCI devices into guest.", + "format" : "pve-qm-hostpci", + "optional" : 1, + "type" : "string", + "typetext" : "[[host=]] [,device-id=] [,legacy-igd=<1|0>] [,mapping=] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]", + "verbose_description" : "Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "hotplug" : { + "default" : "network,disk,usb", + "description" : "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.", + "format" : "pve-hotplug-features", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hugepages" : { + "description" : "Enable/disable hugepages memory.", + "enum" : [ + "any", + "2", + "1024" + ], + "optional" : 1, + "type" : "string" + }, + "ide[n]" : { + "description" : "Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "model" : { + "description" : "The drive's reported model name, url-encoded, up to 40 bytes long.", + "format" : "urlencoded", + "format_description" : "model", + "maxLength" : 120, + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "import-working-storage" : { + "description" : "A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ipconfig[n]" : { + "description" : "cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n", + "format" : "pve-qm-ipconfig", + "optional" : 1, + "type" : "string", + "typetext" : "[gw=] [,gw6=] [,ip=] [,ip6=]" + }, + "ivshmem" : { + "description" : "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + "format" : { + "name" : { + "description" : "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + "format_description" : "string", + "optional" : 1, + "pattern" : "[a-zA-Z0-9\\-]+", + "type" : "string" + }, + "size" : { + "description" : "The size of the file in MB.", + "minimum" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "size= [,name=]" + }, + "keephugepages" : { + "default" : 0, + "description" : "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "keyboard" : { + "default" : null, + "description" : "Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "kvm" : { + "default" : 1, + "description" : "Enable/disable KVM hardware virtualization.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "localtime" : { + "description" : "Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ], + "optional" : 1, + "type" : "string" + }, + "machine" : { + "description" : "Specify the QEMU machine.", + "format" : { + "enable-s3" : { + "description" : "Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "enable-s4" : { + "description" : "Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default_key" : 1, + "description" : "Specifies the QEMU machine type.", + "format_description" : "machine type", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "viommu" : { + "description" : "Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).", + "enum" : [ + "intel", + "virtio" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,enable-s3=<1|0>] [,enable-s4=<1|0>] [,viommu=]" + }, + "memory" : { + "description" : "Memory properties.", + "format" : { + "current" : { + "default" : 512, + "default_key" : 1, + "description" : "Current amount of online RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.", + "minimum" : 16, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[current=]" + }, + "migrate_downtime" : { + "default" : 0.1, + "description" : "Set maximum tolerated downtime (in seconds) for migrations. Should the migration not be able to converge in the very end, because too much newly dirtied RAM needs to be transferred, the limit will be increased automatically step-by-step until migration can converge.", + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "migrate_speed" : { + "default" : 0, + "description" : "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "name" : { + "description" : "Set a name for the VM. Only used on the configuration web interface.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nameserver" : { + "description" : "cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "format" : "address-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specify network devices.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n", + "format" : "pve-bridge-id", + "format_description" : "bridge", + "optional" : 1, + "type" : "string" + }, + "e1000" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82540em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82544gc" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82545em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000e" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "firewall" : { + "description" : "Whether this interface should be protected by the firewall.", + "optional" : 1, + "type" : "boolean" + }, + "i82551" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82557b" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82559er" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "macaddr" : { + "description" : "MAC address. That address must be unique within your network. This is automatically generated if not specified.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "model" : { + "default_key" : 1, + "description" : "Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.", + "enum" : [ + "e1000", + "e1000-82540em", + "e1000-82544gc", + "e1000-82545em", + "e1000e", + "i82551", + "i82557b", + "i82559er", + "ne2k_isa", + "ne2k_pci", + "pcnet", + "rtl8139", + "virtio", + "vmxnet3" + ], + "type" : "string" + }, + "mtu" : { + "description" : "Force MTU, for VirtIO only. Set to '1' to use the bridge MTU", + "maximum" : 65520, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "ne2k_isa" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "ne2k_pci" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "pcnet" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "queues" : { + "description" : "Number of packet queues to be used on the device.", + "maximum" : 64, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "rtl8139" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "tag" : { + "description" : "VLAN tag to apply to packets on this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN trunks to pass through this interface.", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "virtio" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "vmxnet3" : { + "alias" : "macaddr", + "keyAlias" : "model" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "numa" : { + "default" : 0, + "description" : "Enable/disable NUMA.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "numa[n]" : { + "description" : "NUMA topology.", + "format" : { + "cpus" : { + "description" : "CPUs accessing this NUMA node.", + "format_description" : "id[-id];...", + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "hostnodes" : { + "description" : "Host NUMA nodes to use.", + "format_description" : "id[-id];...", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "memory" : { + "description" : "Amount of memory this NUMA node provides.", + "optional" : 1, + "type" : "number" + }, + "policy" : { + "description" : "NUMA allocation policy.", + "enum" : [ + "preferred", + "bind", + "interleave" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "cpus= [,hostnodes=] [,memory=] [,policy=]" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostype" : { + "description" : "Specify guest operating system.", + "enum" : [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "win11", + "l24", + "l26", + "solaris" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022/2025\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 6.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n" + }, + "parallel[n]" : { + "description" : "Map host parallel devices (n is 0 to 2).", + "optional" : 1, + "pattern" : "/dev/parport\\d+|/dev/usb/lp\\d+", + "type" : "string", + "verbose_description" : "Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "reboot" : { + "default" : 1, + "description" : "Allow reboot. If set to '0' the VM exit on reboot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "revert" : { + "description" : "Revert a pending change.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rng0" : { + "description" : "Configure a VirtIO-based Random Number Generator.", + "format" : "pve-qm-rng", + "optional" : 1, + "type" : "string", + "typetext" : "[source=] [,max_bytes=] [,period=]" + }, + "sata[n]" : { + "description" : "Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "scsi[n]" : { + "description" : "Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "product" : { + "description" : "The drive's product name, up to 16 bytes long.", + "format_description" : "product", + "optional" : 1, + "pattern" : "[A-Za-z0-9\\-_\\s]{,16}", + "type" : "string" + }, + "queues" : { + "description" : "Number of queues.", + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "scsiblock" : { + "default" : 0, + "description" : "whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "vendor" : { + "description" : "The drive's vendor name, up to 8 bytes long.", + "format_description" : "vendor", + "optional" : 1, + "pattern" : "[A-Za-z0-9\\-_\\s]{,8}", + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,product=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,vendor=] [,werror=] [,wwn=]" + }, + "scsihw" : { + "default" : "lsi", + "description" : "SCSI controller model", + "enum" : [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "serial[n]" : { + "description" : "Create a serial device inside the VM (n is 0 to 3)", + "optional" : 1, + "pattern" : "(/dev/.+|socket)", + "type" : "string", + "verbose_description" : "Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "shares" : { + "default" : 1000, + "description" : "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.", + "maximum" : 50000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 50000)" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "smbios1" : { + "description" : "Specify SMBIOS type 1 fields.", + "format" : "pve-qm-smbios1", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]" + }, + "smp" : { + "default" : 1, + "description" : "The number of CPUs. Please use option -sockets instead.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "sockets" : { + "default" : 1, + "description" : "The number of CPU sockets.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "spice_enhancements" : { + "description" : "Configure additional enhancements for SPICE.", + "format" : { + "foldersharing" : { + "default" : "0", + "description" : "Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.", + "optional" : 1, + "type" : "boolean" + }, + "videostreaming" : { + "default" : "off", + "description" : "Enable video streaming. Uses compression for detected video streams.", + "enum" : [ + "off", + "all", + "filter" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[foldersharing=<1|0>] [,videostreaming=]" + }, + "sshkeys" : { + "description" : "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format" : "urlencoded", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "startdate" : { + "default" : "now", + "description" : "Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.", + "optional" : 1, + "pattern" : "(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)", + "type" : "string", + "typetext" : "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "tablet" : { + "default" : 1, + "description" : "Enable/disable the USB tablet device.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)." + }, + "tags" : { + "description" : "Tags of the VM. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tdf" : { + "default" : 0, + "description" : "Enable/disable time drift fix.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tpmstate0" : { + "description" : "Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "version" : { + "default" : "v1.2", + "description" : "The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.", + "enum" : [ + "v1.2", + "v2.0" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,import-from=] [,size=] [,version=]" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=]" + }, + "usb[n]" : { + "description" : "Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).", + "format" : { + "host" : { + "default_key" : 1, + "description" : "The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadecimal numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n\nEither this or the 'mapping' key must be set.\n", + "format_description" : "HOSTUSBDEVICE|spice", + "optional" : 1, + "pattern" : "(?^:(?:(?:(?^:(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})))|(?:(?^:(\\d+)\\-(\\d+(\\.\\d+)*)))|[Ss][Pp][Ii][Cc][Ee]))", + "type" : "string" + }, + "mapping" : { + "description" : "The ID of a cluster wide mapping. Either this or the default-key 'host' must be set.", + "format" : "pve-configid", + "format_description" : "mapping-id", + "optional" : 1, + "type" : "string" + }, + "usb3" : { + "default" : 0, + "description" : "Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[host=]] [,mapping=] [,usb3=<1|0>]" + }, + "vcpus" : { + "default" : 0, + "description" : "Number of hotplugged vcpus.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vga" : { + "description" : "Configure the VGA hardware.", + "format" : { + "clipboard" : { + "description" : "Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Migration with VNC clipboard is not yet supported!", + "enum" : [ + "vnc" + ], + "optional" : 1, + "type" : "string" + }, + "memory" : { + "description" : "Sets the VGA memory (in MiB). Has no effect with serial display.", + "maximum" : 512, + "minimum" : 4, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "default" : "std", + "default_key" : 1, + "description" : "Select the VGA type. Using type 'cirrus' is not recommended.", + "enum" : [ + "cirrus", + "qxl", + "qxl2", + "qxl3", + "qxl4", + "none", + "serial0", + "serial1", + "serial2", + "serial3", + "std", + "virtio", + "virtio-gl", + "vmware" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,clipboard=] [,memory=]", + "verbose_description" : "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal." + }, + "virtio[n]" : { + "description" : "Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]" + }, + "virtiofs[n]" : { + "description" : "Configuration for sharing a directory between host and guest using Virtio-fs.", + "format" : { + "cache" : { + "default" : "auto", + "description" : "The caching policy the file system should use (auto, always, metadata, never).", + "enum" : [ + "auto", + "always", + "metadata", + "never" + ], + "optional" : 1, + "type" : "string" + }, + "direct-io" : { + "default" : 0, + "description" : "Honor the O_DIRECT flag passed down by guest applications.", + "optional" : 1, + "type" : "boolean" + }, + "dirid" : { + "default_key" : 1, + "description" : "Mapping identifier of the directory mapping to be shared with the guest. Also used as a mount tag inside the VM.", + "format" : "pve-configid", + "format_description" : "mapping-id", + "type" : "string" + }, + "expose-acl" : { + "default" : 0, + "description" : "Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.", + "optional" : 1, + "type" : "boolean" + }, + "expose-xattr" : { + "default" : 0, + "description" : "Enable support for extended attributes for this mount.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[dirid=] [,cache=] [,direct-io=<1|0>] [,expose-acl=<1|0>] [,expose-xattr=<1|0>]" + }, + "vmgenid" : { + "default" : "1 (autogenerated)", + "description" : "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "format_description" : "UUID", + "optional" : 1, + "pattern" : "(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])", + "type" : "string", + "verbose_description" : "The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file." + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vmstatestorage" : { + "description" : "Default storage for VM state volumes/files.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "watchdog" : { + "description" : "Create a virtual hardware watchdog device.", + "format" : "pve-qm-watchdog", + "optional" : 1, + "type" : "string", + "typetext" : "[[model=]] [,action=]", + "verbose_description" : "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk", + "VM.Config.CDROM", + "VM.Config.CPU", + "VM.Config.Memory", + "VM.Config.Network", + "VM.Config.HWType", + "VM.Config.Options", + "VM.Config.Cloudinit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "optional" : 1, + "type" : "string" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set virtual machine options (synchronous API) - You should consider using the POST method instead for any actions involving hotplug or storage allocation.", + "method" : "PUT", + "name" : "update_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acpi" : { + "default" : 1, + "description" : "Enable/disable ACPI.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "affinity" : { + "description" : "List of host cores used to execute guest processes, for example: 0,5,8-11", + "format" : "pve-cpuset", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "agent" : { + "description" : "Enable/disable communication with the QEMU Guest Agent and its properties.", + "format" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.", + "type" : "boolean" + }, + "freeze-fs-on-backup" : { + "default" : 1, + "description" : "Freeze/thaw guest filesystems on backup for consistency.", + "optional" : 1, + "type" : "boolean" + }, + "fstrim_cloned_disks" : { + "default" : 0, + "description" : "Run fstrim after moving a disk or migrating the VM.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default" : "virtio", + "description" : "Select the agent type", + "enum" : [ + "virtio", + "isa" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[enabled=]<1|0> [,freeze-fs-on-backup=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]" + }, + "amd-sev" : { + "description" : "Secure Encrypted Virtualization (SEV) features by AMD CPUs", + "format" : "pve-qemu-sev-fmt", + "optional" : 1, + "type" : "string", + "typetext" : "[type=] [,allow-smt=<1|0>] [,kernel-hashes=<1|0>] [,no-debug=<1|0>] [,no-key-sharing=<1|0>]" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "args" : { + "description" : "Arbitrary arguments passed to kvm.", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -smbios 'type=0,vendor=FOO'\n\nNOTE: this option is for experts only.\n" + }, + "audio0" : { + "description" : "Configure a audio device, useful in combination with QXL/Spice.", + "format" : { + "device" : { + "description" : "Configure an audio device.", + "enum" : [ + "ich9-intel-hda", + "intel-hda", + "AC97" + ], + "type" : "string" + }, + "driver" : { + "default" : "spice", + "description" : "Driver backend for the audio device.", + "enum" : [ + "spice", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "device= [,driver=]" + }, + "autostart" : { + "default" : 0, + "description" : "Automatic restart after crash (currently ignored).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "balloon" : { + "description" : "Amount of target RAM for the VM in MiB. Using zero disables the ballon driver.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "bios" : { + "default" : "seabios", + "description" : "Select BIOS implementation.", + "enum" : [ + "seabios", + "ovmf" + ], + "optional" : 1, + "type" : "string" + }, + "boot" : { + "description" : "Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.", + "format" : "pve-qm-boot", + "optional" : 1, + "type" : "string", + "typetext" : "[[legacy=]<[acdn]{1,4}>] [,order=]" + }, + "bootdisk" : { + "description" : "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format" : "pve-qm-bootdisk", + "optional" : 1, + "pattern" : "(ide|sata|scsi|virtio)\\d+", + "type" : "string" + }, + "cdrom" : { + "description" : "This is an alias for option -ide2", + "format" : "pve-qm-ide", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cicustom" : { + "description" : "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format" : "pve-qm-cicustom", + "optional" : 1, + "type" : "string", + "typetext" : "[meta=] [,network=] [,user=] [,vendor=]" + }, + "cipassword" : { + "description" : "cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "citype" : { + "description" : "Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.", + "enum" : [ + "configdrive2", + "nocloud", + "opennebula" + ], + "optional" : 1, + "type" : "string" + }, + "ciupgrade" : { + "default" : 1, + "description" : "cloud-init: do an automatic package upgrade after the first boot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ciuser" : { + "description" : "cloud-init: User name to change ssh keys and password for instead of the image's configured default user.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cores" : { + "default" : 1, + "description" : "The number of cores per socket.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "cpu" : { + "description" : "Emulated CPU type.", + "format" : "pve-vm-cpu-conf", + "optional" : 1, + "type" : "string", + "typetext" : "[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 128)", + "verbose_description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit." + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 262144, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 262144)", + "verbose_description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs." + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "efidisk0" : { + "description" : "Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "efitype" : { + "default" : "2m", + "description" : "Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarch64 (ARM).", + "enum" : [ + "2m", + "4m" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "pre-enrolled-keys" : { + "default" : 0, + "description" : "Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,pre-enrolled-keys=<1|0>] [,size=]" + }, + "force" : { + "description" : "Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.", + "optional" : 1, + "requires" : "delete", + "type" : "boolean", + "typetext" : "" + }, + "freeze" : { + "description" : "Freeze CPU at startup (use 'c' monitor command to start execution).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the vms lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostpci[n]" : { + "description" : "Map host PCI devices into guest.", + "format" : "pve-qm-hostpci", + "optional" : 1, + "type" : "string", + "typetext" : "[[host=]] [,device-id=] [,legacy-igd=<1|0>] [,mapping=] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]", + "verbose_description" : "Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "hotplug" : { + "default" : "network,disk,usb", + "description" : "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.", + "format" : "pve-hotplug-features", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hugepages" : { + "description" : "Enable/disable hugepages memory.", + "enum" : [ + "any", + "2", + "1024" + ], + "optional" : 1, + "type" : "string" + }, + "ide[n]" : { + "description" : "Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "model" : { + "description" : "The drive's reported model name, url-encoded, up to 40 bytes long.", + "format" : "urlencoded", + "format_description" : "model", + "maxLength" : 120, + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "ipconfig[n]" : { + "description" : "cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n", + "format" : "pve-qm-ipconfig", + "optional" : 1, + "type" : "string", + "typetext" : "[gw=] [,gw6=] [,ip=] [,ip6=]" + }, + "ivshmem" : { + "description" : "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + "format" : { + "name" : { + "description" : "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + "format_description" : "string", + "optional" : 1, + "pattern" : "[a-zA-Z0-9\\-]+", + "type" : "string" + }, + "size" : { + "description" : "The size of the file in MB.", + "minimum" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "size= [,name=]" + }, + "keephugepages" : { + "default" : 0, + "description" : "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "keyboard" : { + "default" : null, + "description" : "Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "kvm" : { + "default" : 1, + "description" : "Enable/disable KVM hardware virtualization.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "localtime" : { + "description" : "Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ], + "optional" : 1, + "type" : "string" + }, + "machine" : { + "description" : "Specify the QEMU machine.", + "format" : { + "enable-s3" : { + "description" : "Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "enable-s4" : { + "description" : "Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default_key" : 1, + "description" : "Specifies the QEMU machine type.", + "format_description" : "machine type", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "viommu" : { + "description" : "Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).", + "enum" : [ + "intel", + "virtio" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,enable-s3=<1|0>] [,enable-s4=<1|0>] [,viommu=]" + }, + "memory" : { + "description" : "Memory properties.", + "format" : { + "current" : { + "default" : 512, + "default_key" : 1, + "description" : "Current amount of online RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.", + "minimum" : 16, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[current=]" + }, + "migrate_downtime" : { + "default" : 0.1, + "description" : "Set maximum tolerated downtime (in seconds) for migrations. Should the migration not be able to converge in the very end, because too much newly dirtied RAM needs to be transferred, the limit will be increased automatically step-by-step until migration can converge.", + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "migrate_speed" : { + "default" : 0, + "description" : "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "name" : { + "description" : "Set a name for the VM. Only used on the configuration web interface.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nameserver" : { + "description" : "cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "format" : "address-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specify network devices.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n", + "format" : "pve-bridge-id", + "format_description" : "bridge", + "optional" : 1, + "type" : "string" + }, + "e1000" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82540em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82544gc" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82545em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000e" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "firewall" : { + "description" : "Whether this interface should be protected by the firewall.", + "optional" : 1, + "type" : "boolean" + }, + "i82551" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82557b" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82559er" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "macaddr" : { + "description" : "MAC address. That address must be unique within your network. This is automatically generated if not specified.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "model" : { + "default_key" : 1, + "description" : "Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.", + "enum" : [ + "e1000", + "e1000-82540em", + "e1000-82544gc", + "e1000-82545em", + "e1000e", + "i82551", + "i82557b", + "i82559er", + "ne2k_isa", + "ne2k_pci", + "pcnet", + "rtl8139", + "virtio", + "vmxnet3" + ], + "type" : "string" + }, + "mtu" : { + "description" : "Force MTU, for VirtIO only. Set to '1' to use the bridge MTU", + "maximum" : 65520, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "ne2k_isa" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "ne2k_pci" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "pcnet" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "queues" : { + "description" : "Number of packet queues to be used on the device.", + "maximum" : 64, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "rtl8139" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "tag" : { + "description" : "VLAN tag to apply to packets on this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN trunks to pass through this interface.", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "virtio" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "vmxnet3" : { + "alias" : "macaddr", + "keyAlias" : "model" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "numa" : { + "default" : 0, + "description" : "Enable/disable NUMA.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "numa[n]" : { + "description" : "NUMA topology.", + "format" : { + "cpus" : { + "description" : "CPUs accessing this NUMA node.", + "format_description" : "id[-id];...", + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "hostnodes" : { + "description" : "Host NUMA nodes to use.", + "format_description" : "id[-id];...", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "memory" : { + "description" : "Amount of memory this NUMA node provides.", + "optional" : 1, + "type" : "number" + }, + "policy" : { + "description" : "NUMA allocation policy.", + "enum" : [ + "preferred", + "bind", + "interleave" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "cpus= [,hostnodes=] [,memory=] [,policy=]" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostype" : { + "description" : "Specify guest operating system.", + "enum" : [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "win11", + "l24", + "l26", + "solaris" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022/2025\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 6.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n" + }, + "parallel[n]" : { + "description" : "Map host parallel devices (n is 0 to 2).", + "optional" : 1, + "pattern" : "/dev/parport\\d+|/dev/usb/lp\\d+", + "type" : "string", + "verbose_description" : "Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "reboot" : { + "default" : 1, + "description" : "Allow reboot. If set to '0' the VM exit on reboot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "revert" : { + "description" : "Revert a pending change.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rng0" : { + "description" : "Configure a VirtIO-based Random Number Generator.", + "format" : "pve-qm-rng", + "optional" : 1, + "type" : "string", + "typetext" : "[source=] [,max_bytes=] [,period=]" + }, + "sata[n]" : { + "description" : "Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "scsi[n]" : { + "description" : "Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "product" : { + "description" : "The drive's product name, up to 16 bytes long.", + "format_description" : "product", + "optional" : 1, + "pattern" : "[A-Za-z0-9\\-_\\s]{,16}", + "type" : "string" + }, + "queues" : { + "description" : "Number of queues.", + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "scsiblock" : { + "default" : 0, + "description" : "whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "vendor" : { + "description" : "The drive's vendor name, up to 8 bytes long.", + "format_description" : "vendor", + "optional" : 1, + "pattern" : "[A-Za-z0-9\\-_\\s]{,8}", + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,product=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,vendor=] [,werror=] [,wwn=]" + }, + "scsihw" : { + "default" : "lsi", + "description" : "SCSI controller model", + "enum" : [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "serial[n]" : { + "description" : "Create a serial device inside the VM (n is 0 to 3)", + "optional" : 1, + "pattern" : "(/dev/.+|socket)", + "type" : "string", + "verbose_description" : "Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "shares" : { + "default" : 1000, + "description" : "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.", + "maximum" : 50000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 50000)" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "smbios1" : { + "description" : "Specify SMBIOS type 1 fields.", + "format" : "pve-qm-smbios1", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]" + }, + "smp" : { + "default" : 1, + "description" : "The number of CPUs. Please use option -sockets instead.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "sockets" : { + "default" : 1, + "description" : "The number of CPU sockets.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "spice_enhancements" : { + "description" : "Configure additional enhancements for SPICE.", + "format" : { + "foldersharing" : { + "default" : "0", + "description" : "Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.", + "optional" : 1, + "type" : "boolean" + }, + "videostreaming" : { + "default" : "off", + "description" : "Enable video streaming. Uses compression for detected video streams.", + "enum" : [ + "off", + "all", + "filter" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[foldersharing=<1|0>] [,videostreaming=]" + }, + "sshkeys" : { + "description" : "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format" : "urlencoded", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "startdate" : { + "default" : "now", + "description" : "Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.", + "optional" : 1, + "pattern" : "(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)", + "type" : "string", + "typetext" : "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "tablet" : { + "default" : 1, + "description" : "Enable/disable the USB tablet device.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)." + }, + "tags" : { + "description" : "Tags of the VM. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tdf" : { + "default" : 0, + "description" : "Enable/disable time drift fix.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tpmstate0" : { + "description" : "Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "version" : { + "default" : "v1.2", + "description" : "The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.", + "enum" : [ + "v1.2", + "v2.0" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,import-from=] [,size=] [,version=]" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=]" + }, + "usb[n]" : { + "description" : "Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).", + "format" : { + "host" : { + "default_key" : 1, + "description" : "The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadecimal numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n\nEither this or the 'mapping' key must be set.\n", + "format_description" : "HOSTUSBDEVICE|spice", + "optional" : 1, + "pattern" : "(?^:(?:(?:(?^:(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})))|(?:(?^:(\\d+)\\-(\\d+(\\.\\d+)*)))|[Ss][Pp][Ii][Cc][Ee]))", + "type" : "string" + }, + "mapping" : { + "description" : "The ID of a cluster wide mapping. Either this or the default-key 'host' must be set.", + "format" : "pve-configid", + "format_description" : "mapping-id", + "optional" : 1, + "type" : "string" + }, + "usb3" : { + "default" : 0, + "description" : "Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[host=]] [,mapping=] [,usb3=<1|0>]" + }, + "vcpus" : { + "default" : 0, + "description" : "Number of hotplugged vcpus.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vga" : { + "description" : "Configure the VGA hardware.", + "format" : { + "clipboard" : { + "description" : "Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Migration with VNC clipboard is not yet supported!", + "enum" : [ + "vnc" + ], + "optional" : 1, + "type" : "string" + }, + "memory" : { + "description" : "Sets the VGA memory (in MiB). Has no effect with serial display.", + "maximum" : 512, + "minimum" : 4, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "default" : "std", + "default_key" : 1, + "description" : "Select the VGA type. Using type 'cirrus' is not recommended.", + "enum" : [ + "cirrus", + "qxl", + "qxl2", + "qxl3", + "qxl4", + "none", + "serial0", + "serial1", + "serial2", + "serial3", + "std", + "virtio", + "virtio-gl", + "vmware" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,clipboard=] [,memory=]", + "verbose_description" : "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal." + }, + "virtio[n]" : { + "description" : "Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]" + }, + "virtiofs[n]" : { + "description" : "Configuration for sharing a directory between host and guest using Virtio-fs.", + "format" : { + "cache" : { + "default" : "auto", + "description" : "The caching policy the file system should use (auto, always, metadata, never).", + "enum" : [ + "auto", + "always", + "metadata", + "never" + ], + "optional" : 1, + "type" : "string" + }, + "direct-io" : { + "default" : 0, + "description" : "Honor the O_DIRECT flag passed down by guest applications.", + "optional" : 1, + "type" : "boolean" + }, + "dirid" : { + "default_key" : 1, + "description" : "Mapping identifier of the directory mapping to be shared with the guest. Also used as a mount tag inside the VM.", + "format" : "pve-configid", + "format_description" : "mapping-id", + "type" : "string" + }, + "expose-acl" : { + "default" : 0, + "description" : "Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.", + "optional" : 1, + "type" : "boolean" + }, + "expose-xattr" : { + "default" : 0, + "description" : "Enable support for extended attributes for this mount.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[dirid=] [,cache=] [,direct-io=<1|0>] [,expose-acl=<1|0>] [,expose-xattr=<1|0>]" + }, + "vmgenid" : { + "default" : "1 (autogenerated)", + "description" : "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "format_description" : "UUID", + "optional" : 1, + "pattern" : "(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])", + "type" : "string", + "verbose_description" : "The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file." + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vmstatestorage" : { + "description" : "Default storage for VM state volumes/files.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "watchdog" : { + "description" : "Create a virtual hardware watchdog device.", + "format" : "pve-qm-watchdog", + "optional" : 1, + "type" : "string", + "typetext" : "[[model=]] [,action=]", + "verbose_description" : "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk", + "VM.Config.CDROM", + "VM.Config.CPU", + "VM.Config.Memory", + "VM.Config.Network", + "VM.Config.HWType", + "VM.Config.Options", + "VM.Config.Cloudinit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/config", + "text" : "config" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the virtual machine configuration with both current and pending values.", + "method" : "GET", + "name" : "vm_pending", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "delete" : { + "description" : "Indicates a pending delete request if present and not 0. The value 2 indicates a force-delete request.", + "maximum" : 2, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "key" : { + "description" : "Configuration option name.", + "type" : "string" + }, + "pending" : { + "description" : "Pending value.", + "optional" : 1, + "type" : "string" + }, + "value" : { + "description" : "Current value.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/pending", + "text" : "pending" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get automatically generated cloudinit config.", + "method" : "GET", + "name" : "cloudinit_generated_config_dump", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Config type.", + "enum" : [ + "user", + "network", + "meta" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/cloudinit/dump", + "text" : "dump" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the cloudinit configuration with both current and pending values.", + "method" : "GET", + "name" : "cloudinit_pending", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "delete" : { + "description" : "Indicates a pending delete request if present and not 0. ", + "maximum" : 1, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "key" : { + "description" : "Configuration option name.", + "type" : "string" + }, + "pending" : { + "description" : "The new pending value.", + "optional" : 1, + "type" : "string" + }, + "value" : { + "description" : "Value as it was used to generate the current cloudinit image.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Regenerate and change cloudinit config drive.", + "method" : "PUT", + "name" : "cloudinit_update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Cloudinit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/cloudinit", + "text" : "cloudinit" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Unlink/delete disk images.", + "method" : "PUT", + "name" : "unlink", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "idlist" : { + "description" : "A list of disk IDs you want to delete.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/unlink", + "text" : "unlink" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a TCP VNC proxy connections.", + "method" : "POST", + "name" : "vncproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "generate-password" : { + "default" : 0, + "description" : "Generates a random password to be used as ticket instead of the API ticket.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "websocket" : { + "description" : "Prepare for websocket upgrade (only required when using serial terminal, otherwise upgrade is always possible).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "cert" : { + "type" : "string" + }, + "password" : { + "description" : "Returned if requested with 'generate-password' param. Consists of printable ASCII characters ('!' .. '~').", + "optional" : 1, + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/vncproxy", + "text" : "vncproxy" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a TCP proxy connections.", + "method" : "POST", + "name" : "termproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "serial" : { + "description" : "opens a serial terminal (defaults to display)", + "enum" : [ + "serial0", + "serial1", + "serial2", + "serial3" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/termproxy", + "text" : "termproxy" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Opens a weksocket for VNC traffic.", + "method" : "GET", + "name" : "vncwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Port number returned by previous vncproxy call.", + "maximum" : 5999, + "minimum" : 5900, + "type" : "integer", + "typetext" : " (5900 - 5999)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vncticket" : { + "description" : "Ticket from previous call to vncproxy.", + "maxLength" : 512, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ], + "description" : "You also need to pass a valid ticket (vncticket)." + }, + "returns" : { + "properties" : { + "port" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/vncwebsocket", + "text" : "vncwebsocket" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Returns a SPICE configuration to connect to the VM.", + "method" : "POST", + "name" : "spiceproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "proxy" : { + "description" : "SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).", + "format" : "address", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 1, + "description" : "Returned values can be directly passed to the 'remote-viewer' application.", + "properties" : { + "host" : { + "type" : "string" + }, + "password" : { + "type" : "string" + }, + "proxy" : { + "type" : "string" + }, + "tls-port" : { + "type" : "integer" + }, + "type" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/spiceproxy", + "text" : "spiceproxy" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get virtual machine status.", + "method" : "GET", + "name" : "vm_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "agent" : { + "description" : "QEMU Guest Agent is enabled in config.", + "optional" : 1, + "type" : "boolean" + }, + "clipboard" : { + "description" : "Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added.", + "enum" : [ + "vnc" + ], + "optional" : 1, + "type" : "string" + }, + "cpu" : { + "description" : "Current CPU usage.", + "optional" : 1, + "type" : "number" + }, + "cpus" : { + "description" : "Maximum usable CPUs.", + "optional" : 1, + "type" : "number" + }, + "diskread" : { + "description" : "The amount of bytes the guest read from it's block devices since the guest was started. (Note: This info is not available for all storage types.)", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "diskwrite" : { + "description" : "The amount of bytes the guest wrote from it's block devices since the guest was started. (Note: This info is not available for all storage types.)", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "ha" : { + "description" : "HA manager service status.", + "type" : "object" + }, + "lock" : { + "description" : "The current config lock, if any.", + "optional" : 1, + "type" : "string" + }, + "maxdisk" : { + "description" : "Root disk size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Maximum memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "mem" : { + "description" : "Currently used memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "VM (host)name.", + "optional" : 1, + "type" : "string" + }, + "netin" : { + "description" : "The amount of traffic in bytes that was sent to the guest over the network since it was started.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "netout" : { + "description" : "The amount of traffic in bytes that was sent from the guest over the network since it was started.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "pid" : { + "description" : "PID of the QEMU process, if the VM is running.", + "optional" : 1, + "type" : "integer" + }, + "qmpstatus" : { + "description" : "VM run state from the 'query-status' QMP monitor command.", + "optional" : 1, + "type" : "string" + }, + "running-machine" : { + "description" : "The currently running machine type (if running).", + "optional" : 1, + "type" : "string" + }, + "running-qemu" : { + "description" : "The QEMU version the VM is currently using (if running).", + "optional" : 1, + "type" : "string" + }, + "serial" : { + "description" : "Guest has serial device configured.", + "optional" : 1, + "type" : "boolean" + }, + "spice" : { + "description" : "QEMU VGA configuration supports spice.", + "optional" : 1, + "type" : "boolean" + }, + "status" : { + "description" : "QEMU process status.", + "enum" : [ + "stopped", + "running" + ], + "type" : "string" + }, + "tags" : { + "description" : "The current configured tags, if any", + "optional" : 1, + "type" : "string" + }, + "template" : { + "default" : 0, + "description" : "Determines if the guest is a template.", + "optional" : 1, + "type" : "boolean" + }, + "uptime" : { + "description" : "Uptime in seconds.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/current", + "text" : "current" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start virtual machine.", + "method" : "POST", + "name" : "vm_start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force-cpu" : { + "description" : "Override QEMU's -cpu argument with the given string.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "machine" : { + "description" : "Specify the QEMU machine.", + "format" : { + "enable-s3" : { + "description" : "Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "enable-s4" : { + "description" : "Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default_key" : 1, + "description" : "Specifies the QEMU machine type.", + "format_description" : "machine type", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "viommu" : { + "description" : "Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).", + "enum" : [ + "intel", + "virtio" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,enable-s3=<1|0>] [,enable-s4=<1|0>] [,viommu=]" + }, + "migratedfrom" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "migration_network" : { + "description" : "CIDR of the (sub) network that is used for migration.", + "format" : "CIDR", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "migration_type" : { + "description" : "Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.", + "enum" : [ + "secure", + "insecure" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stateuri" : { + "description" : "Some command save/restore state from this location.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "targetstorage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storage-pair-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : "max(30, vm memory in GiB)", + "description" : "Wait maximal timeout seconds.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop virtual machine. The qemu process will exit immediately. This is akin to pulling the power plug of a running computer and may damage the VM data.", + "method" : "POST", + "name" : "vm_stop", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "keepActive" : { + "default" : 0, + "description" : "Do not deactivate storage volumes.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "migratedfrom" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "overrule-shutdown" : { + "default" : 0, + "description" : "Try to abort active 'qmshutdown' tasks before stopping.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "timeout" : { + "description" : "Wait maximal timeout seconds.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/stop", + "text" : "stop" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Reset virtual machine.", + "method" : "POST", + "name" : "vm_reset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/reset", + "text" : "reset" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Shutdown virtual machine. This is similar to pressing the power button on a physical machine. This will send an ACPI event for the guest OS, which should then proceed to a clean shutdown.", + "method" : "POST", + "name" : "vm_shutdown", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "forceStop" : { + "default" : 0, + "description" : "Make sure the VM stops.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "keepActive" : { + "default" : 0, + "description" : "Do not deactivate storage volumes.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "timeout" : { + "description" : "Wait maximal timeout seconds.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/shutdown", + "text" : "shutdown" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Reboot the VM by shutting it down, and starting it again. Applies pending changes.", + "method" : "POST", + "name" : "vm_reboot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "description" : "Wait maximal timeout seconds for the shutdown.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/reboot", + "text" : "reboot" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Suspend virtual machine.", + "method" : "POST", + "name" : "vm_suspend", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "statestorage" : { + "description" : "The storage for the VM state", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "requires" : "todisk", + "type" : "string", + "typetext" : "" + }, + "todisk" : { + "default" : 0, + "description" : "If set, suspends the VM to disk. Will be resumed on next VM start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ], + "description" : "You need 'VM.PowerMgmt' on /vms/{vmid}, and if you have set 'todisk', you need also 'VM.Config.Disk' on /vms/{vmid} and 'Datastore.AllocateSpace' on the storage for the vmstate." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/suspend", + "text" : "suspend" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Resume virtual machine.", + "method" : "POST", + "name" : "vm_resume", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "nocheck" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/status/resume", + "text" : "resume" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "vmcmdidx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/status", + "text" : "status" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Send key event to virtual machine.", + "method" : "PUT", + "name" : "vm_sendkey", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "key" : { + "description" : "The key (qemu monitor encoding).", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/sendkey", + "text" : "sendkey" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Check if feature for virtual machine is available.", + "method" : "GET", + "name" : "vm_feature", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "feature" : { + "description" : "Feature to check.", + "enum" : [ + "snapshot", + "clone", + "copy" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "hasFeature" : { + "type" : "boolean" + }, + "nodes" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/feature", + "text" : "feature" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a copy of virtual machine/template.", + "method" : "POST", + "name" : "clone_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "clone limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "description" : { + "description" : "Description for the new VM.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "format" : { + "description" : "Target format for file storage. Only valid for full clone.", + "enum" : [ + "raw", + "qcow2", + "vmdk" + ], + "optional" : 1, + "type" : "string" + }, + "full" : { + "description" : "Create a full copy of all disks. This is always done when you clone a normal VM. For VM templates, we try to create a linked clone by default.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "Set a name for the new VM.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "newid" : { + "description" : "VMID for the clone.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Add the new VM to the specified pool.", + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Target storage for full clone.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node. Only allowed if the original VM is on shared storage.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/vms/{vmid}", + [ + "VM.Clone" + ] + ], + [ + "or", + [ + "perm", + "/vms/{newid}", + [ + "VM.Allocate" + ] + ], + [ + "perm", + "/pool/{pool}", + [ + "VM.Allocate" + ], + "require_param", + "pool" + ] + ] + ], + "description" : "You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions on /vms/{newid} (or on the VM pool /pool/{pool}). You also need 'Datastore.AllocateSpace' on any used storage and 'SDN.Use' on any used bridge/vnet" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/clone", + "text" : "clone" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Move volume to different storage or to a different VM.", + "method" : "POST", + "name" : "move_vm_disk", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "move limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "delete" : { + "default" : 0, + "description" : "Delete the original disk after successful copy. By default the original disk is kept as unused disk.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1\"\n\t\t .\" digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disk" : { + "description" : "The disk you want to move.", + "enum" : [ + "ide0", + "ide1", + "ide2", + "ide3", + "scsi0", + "scsi1", + "scsi2", + "scsi3", + "scsi4", + "scsi5", + "scsi6", + "scsi7", + "scsi8", + "scsi9", + "scsi10", + "scsi11", + "scsi12", + "scsi13", + "scsi14", + "scsi15", + "scsi16", + "scsi17", + "scsi18", + "scsi19", + "scsi20", + "scsi21", + "scsi22", + "scsi23", + "scsi24", + "scsi25", + "scsi26", + "scsi27", + "scsi28", + "scsi29", + "scsi30", + "virtio0", + "virtio1", + "virtio2", + "virtio3", + "virtio4", + "virtio5", + "virtio6", + "virtio7", + "virtio8", + "virtio9", + "virtio10", + "virtio11", + "virtio12", + "virtio13", + "virtio14", + "virtio15", + "sata0", + "sata1", + "sata2", + "sata3", + "sata4", + "sata5", + "efidisk0", + "tpmstate0", + "unused0", + "unused1", + "unused2", + "unused3", + "unused4", + "unused5", + "unused6", + "unused7", + "unused8", + "unused9", + "unused10", + "unused11", + "unused12", + "unused13", + "unused14", + "unused15", + "unused16", + "unused17", + "unused18", + "unused19", + "unused20", + "unused21", + "unused22", + "unused23", + "unused24", + "unused25", + "unused26", + "unused27", + "unused28", + "unused29", + "unused30", + "unused31", + "unused32", + "unused33", + "unused34", + "unused35", + "unused36", + "unused37", + "unused38", + "unused39", + "unused40", + "unused41", + "unused42", + "unused43", + "unused44", + "unused45", + "unused46", + "unused47", + "unused48", + "unused49", + "unused50", + "unused51", + "unused52", + "unused53", + "unused54", + "unused55", + "unused56", + "unused57", + "unused58", + "unused59", + "unused60", + "unused61", + "unused62", + "unused63", + "unused64", + "unused65", + "unused66", + "unused67", + "unused68", + "unused69", + "unused70", + "unused71", + "unused72", + "unused73", + "unused74", + "unused75", + "unused76", + "unused77", + "unused78", + "unused79", + "unused80", + "unused81", + "unused82", + "unused83", + "unused84", + "unused85", + "unused86", + "unused87", + "unused88", + "unused89", + "unused90", + "unused91", + "unused92", + "unused93", + "unused94", + "unused95", + "unused96", + "unused97", + "unused98", + "unused99", + "unused100", + "unused101", + "unused102", + "unused103", + "unused104", + "unused105", + "unused106", + "unused107", + "unused108", + "unused109", + "unused110", + "unused111", + "unused112", + "unused113", + "unused114", + "unused115", + "unused116", + "unused117", + "unused118", + "unused119", + "unused120", + "unused121", + "unused122", + "unused123", + "unused124", + "unused125", + "unused126", + "unused127", + "unused128", + "unused129", + "unused130", + "unused131", + "unused132", + "unused133", + "unused134", + "unused135", + "unused136", + "unused137", + "unused138", + "unused139", + "unused140", + "unused141", + "unused142", + "unused143", + "unused144", + "unused145", + "unused146", + "unused147", + "unused148", + "unused149", + "unused150", + "unused151", + "unused152", + "unused153", + "unused154", + "unused155", + "unused156", + "unused157", + "unused158", + "unused159", + "unused160", + "unused161", + "unused162", + "unused163", + "unused164", + "unused165", + "unused166", + "unused167", + "unused168", + "unused169", + "unused170", + "unused171", + "unused172", + "unused173", + "unused174", + "unused175", + "unused176", + "unused177", + "unused178", + "unused179", + "unused180", + "unused181", + "unused182", + "unused183", + "unused184", + "unused185", + "unused186", + "unused187", + "unused188", + "unused189", + "unused190", + "unused191", + "unused192", + "unused193", + "unused194", + "unused195", + "unused196", + "unused197", + "unused198", + "unused199", + "unused200", + "unused201", + "unused202", + "unused203", + "unused204", + "unused205", + "unused206", + "unused207", + "unused208", + "unused209", + "unused210", + "unused211", + "unused212", + "unused213", + "unused214", + "unused215", + "unused216", + "unused217", + "unused218", + "unused219", + "unused220", + "unused221", + "unused222", + "unused223", + "unused224", + "unused225", + "unused226", + "unused227", + "unused228", + "unused229", + "unused230", + "unused231", + "unused232", + "unused233", + "unused234", + "unused235", + "unused236", + "unused237", + "unused238", + "unused239", + "unused240", + "unused241", + "unused242", + "unused243", + "unused244", + "unused245", + "unused246", + "unused247", + "unused248", + "unused249", + "unused250", + "unused251", + "unused252", + "unused253", + "unused254", + "unused255" + ], + "type" : "string" + }, + "format" : { + "description" : "Target Format.", + "enum" : [ + "raw", + "qcow2", + "vmdk" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Target storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target-digest" : { + "description" : "Prevent changes if the current config file of the target VM has a\"\n\t\t .\" different SHA1 digest. This can be used to detect concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target-disk" : { + "description" : "The config key the disk will be moved to on the target VM (for example, ide0 or scsi1). Default is the source disk key.", + "enum" : [ + "ide0", + "ide1", + "ide2", + "ide3", + "scsi0", + "scsi1", + "scsi2", + "scsi3", + "scsi4", + "scsi5", + "scsi6", + "scsi7", + "scsi8", + "scsi9", + "scsi10", + "scsi11", + "scsi12", + "scsi13", + "scsi14", + "scsi15", + "scsi16", + "scsi17", + "scsi18", + "scsi19", + "scsi20", + "scsi21", + "scsi22", + "scsi23", + "scsi24", + "scsi25", + "scsi26", + "scsi27", + "scsi28", + "scsi29", + "scsi30", + "virtio0", + "virtio1", + "virtio2", + "virtio3", + "virtio4", + "virtio5", + "virtio6", + "virtio7", + "virtio8", + "virtio9", + "virtio10", + "virtio11", + "virtio12", + "virtio13", + "virtio14", + "virtio15", + "sata0", + "sata1", + "sata2", + "sata3", + "sata4", + "sata5", + "efidisk0", + "tpmstate0", + "unused0", + "unused1", + "unused2", + "unused3", + "unused4", + "unused5", + "unused6", + "unused7", + "unused8", + "unused9", + "unused10", + "unused11", + "unused12", + "unused13", + "unused14", + "unused15", + "unused16", + "unused17", + "unused18", + "unused19", + "unused20", + "unused21", + "unused22", + "unused23", + "unused24", + "unused25", + "unused26", + "unused27", + "unused28", + "unused29", + "unused30", + "unused31", + "unused32", + "unused33", + "unused34", + "unused35", + "unused36", + "unused37", + "unused38", + "unused39", + "unused40", + "unused41", + "unused42", + "unused43", + "unused44", + "unused45", + "unused46", + "unused47", + "unused48", + "unused49", + "unused50", + "unused51", + "unused52", + "unused53", + "unused54", + "unused55", + "unused56", + "unused57", + "unused58", + "unused59", + "unused60", + "unused61", + "unused62", + "unused63", + "unused64", + "unused65", + "unused66", + "unused67", + "unused68", + "unused69", + "unused70", + "unused71", + "unused72", + "unused73", + "unused74", + "unused75", + "unused76", + "unused77", + "unused78", + "unused79", + "unused80", + "unused81", + "unused82", + "unused83", + "unused84", + "unused85", + "unused86", + "unused87", + "unused88", + "unused89", + "unused90", + "unused91", + "unused92", + "unused93", + "unused94", + "unused95", + "unused96", + "unused97", + "unused98", + "unused99", + "unused100", + "unused101", + "unused102", + "unused103", + "unused104", + "unused105", + "unused106", + "unused107", + "unused108", + "unused109", + "unused110", + "unused111", + "unused112", + "unused113", + "unused114", + "unused115", + "unused116", + "unused117", + "unused118", + "unused119", + "unused120", + "unused121", + "unused122", + "unused123", + "unused124", + "unused125", + "unused126", + "unused127", + "unused128", + "unused129", + "unused130", + "unused131", + "unused132", + "unused133", + "unused134", + "unused135", + "unused136", + "unused137", + "unused138", + "unused139", + "unused140", + "unused141", + "unused142", + "unused143", + "unused144", + "unused145", + "unused146", + "unused147", + "unused148", + "unused149", + "unused150", + "unused151", + "unused152", + "unused153", + "unused154", + "unused155", + "unused156", + "unused157", + "unused158", + "unused159", + "unused160", + "unused161", + "unused162", + "unused163", + "unused164", + "unused165", + "unused166", + "unused167", + "unused168", + "unused169", + "unused170", + "unused171", + "unused172", + "unused173", + "unused174", + "unused175", + "unused176", + "unused177", + "unused178", + "unused179", + "unused180", + "unused181", + "unused182", + "unused183", + "unused184", + "unused185", + "unused186", + "unused187", + "unused188", + "unused189", + "unused190", + "unused191", + "unused192", + "unused193", + "unused194", + "unused195", + "unused196", + "unused197", + "unused198", + "unused199", + "unused200", + "unused201", + "unused202", + "unused203", + "unused204", + "unused205", + "unused206", + "unused207", + "unused208", + "unused209", + "unused210", + "unused211", + "unused212", + "unused213", + "unused214", + "unused215", + "unused216", + "unused217", + "unused218", + "unused219", + "unused220", + "unused221", + "unused222", + "unused223", + "unused224", + "unused225", + "unused226", + "unused227", + "unused228", + "unused229", + "unused230", + "unused231", + "unused232", + "unused233", + "unused234", + "unused235", + "unused236", + "unused237", + "unused238", + "unused239", + "unused240", + "unused241", + "unused242", + "unused243", + "unused244", + "unused245", + "unused246", + "unused247", + "unused248", + "unused249", + "unused250", + "unused251", + "unused252", + "unused253", + "unused254", + "unused255" + ], + "optional" : 1, + "type" : "string" + }, + "target-vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ], + "description" : "You need 'VM.Config.Disk' permissions on /vms/{vmid}, and 'Datastore.AllocateSpace' permissions on the storage. To move a disk to another VM, you need the permissions on the target VM as well." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/move_disk", + "text" : "move_disk" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get preconditions for migration.", + "method" : "GET", + "name" : "migrate_vm_precondition", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "allowed_nodes" : { + "description" : "List of nodes allowed for migration.", + "items" : { + "description" : "An allowed node", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "local_disks" : { + "description" : "List local disks including CD-Rom, unused and not referenced disks", + "items" : { + "properties" : { + "cdrom" : { + "description" : "True if the disk is a cdrom.", + "type" : "boolean" + }, + "is_unused" : { + "description" : "True if the disk is unused.", + "type" : "boolean" + }, + "size" : { + "description" : "The size of the disk in bytes.", + "type" : "integer" + }, + "volid" : { + "description" : "The volid of the disk.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "local_resources" : { + "description" : "List local resources (e.g. pci, usb) that block migration.", + "items" : { + "description" : "A local resource", + "type" : "string" + }, + "type" : "array" + }, + "mapped-resource-info" : { + "description" : "Object of mapped resources with additional information such if they're live migratable.", + "type" : "object" + }, + "mapped-resources" : { + "description" : "List of mapped resources e.g. pci, usb. Deprecated, use 'mapped-resource-info' instead.", + "items" : { + "description" : "A mapped resource", + "type" : "string" + }, + "type" : "array" + }, + "not_allowed_nodes" : { + "description" : "List of not allowed nodes with additional information.", + "optional" : 1, + "properties" : { + "unavailable_storages" : { + "description" : "A list of not available storages.", + "items" : { + "description" : "A storage", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + }, + "running" : { + "description" : "Determines if the VM is running.", + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Migrate virtual machine. Creates a new migration task.", + "method" : "POST", + "name" : "migrate_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "migrate limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "force" : { + "description" : "Allow to migrate VMs which use local devices. Only root may use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "migration_network" : { + "description" : "CIDR of the (sub) network that is used for migration.", + "format" : "CIDR", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "migration_type" : { + "description" : "Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.", + "enum" : [ + "secure", + "insecure" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "online" : { + "description" : "Use online/live migration if VM is running. Ignored if VM is stopped.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "targetstorage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storage-pair-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "with-local-disks" : { + "description" : "Enable live storage migration for local disk", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/migrate", + "text" : "migrate" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migrate virtual machine to a remote cluster. Creates a new migration task. EXPERIMENTAL feature!", + "method" : "POST", + "name" : "remote_migrate_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "migrate limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "delete" : { + "default" : 0, + "description" : "Delete the original VM and related data after successful migration. By default the original VM is kept on the source cluster in a stopped state.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "online" : { + "description" : "Use online/live migration if VM is running. Ignored if VM is stopped.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target-bridge" : { + "description" : "Mapping from source to target bridges. Providing only a single bridge ID maps all source bridges to that bridge. Providing the special value '1' will map each source bridge to itself.", + "format" : "bridge-pair-list", + "type" : "string", + "typetext" : "" + }, + "target-endpoint" : { + "description" : "Remote target endpoint", + "format" : "proxmox-remote", + "type" : "string", + "typetext" : "apitoken= ,host=
[,fingerprint=] [,port=]" + }, + "target-storage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storage-pair-list", + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "target-vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/remote_migrate", + "text" : "remote_migrate" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute QEMU monitor commands.", + "method" : "POST", + "name" : "monitor", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "command" : { + "description" : "The monitor command.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Monitor" + ] + ], + "description" : "Sys.Modify is required for (sub)commands which are not read-only ('info *' and 'help')" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/monitor", + "text" : "monitor" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Extend volume size.", + "method" : "PUT", + "name" : "resize_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disk" : { + "description" : "The disk you want to resize.", + "enum" : [ + "ide0", + "ide1", + "ide2", + "ide3", + "scsi0", + "scsi1", + "scsi2", + "scsi3", + "scsi4", + "scsi5", + "scsi6", + "scsi7", + "scsi8", + "scsi9", + "scsi10", + "scsi11", + "scsi12", + "scsi13", + "scsi14", + "scsi15", + "scsi16", + "scsi17", + "scsi18", + "scsi19", + "scsi20", + "scsi21", + "scsi22", + "scsi23", + "scsi24", + "scsi25", + "scsi26", + "scsi27", + "scsi28", + "scsi29", + "scsi30", + "virtio0", + "virtio1", + "virtio2", + "virtio3", + "virtio4", + "virtio5", + "virtio6", + "virtio7", + "virtio8", + "virtio9", + "virtio10", + "virtio11", + "virtio12", + "virtio13", + "virtio14", + "virtio15", + "sata0", + "sata1", + "sata2", + "sata3", + "sata4", + "sata5", + "efidisk0", + "tpmstate0" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "size" : { + "description" : "The new size. With the `+` sign the value is added to the actual size of the volume and without it, the value is taken as an absolute one. Shrinking disk size is not supported.", + "pattern" : "\\+?\\d+(\\.\\d+)?[KMGT]?", + "type" : "string" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/resize", + "text" : "resize" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get snapshot configuration", + "method" : "GET", + "name" : "get_snapshot_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback", + "VM.Audit" + ], + "any", + 1 + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update snapshot metadata.", + "method" : "PUT", + "name" : "update_snapshot_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A textual description or comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "text" : "config" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Rollback VM state to specified snapshot.", + "method" : "POST", + "name" : "rollback", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Whether the VM should get started after rolling back successfully. (Note: VMs will be automatically started if the snapshot includes RAM.)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback", + "text" : "rollback" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete a VM snapshot.", + "method" : "DELETE", + "name" : "delsnapshot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "For removal from config file, even if removing disk snapshots fails.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "snapshot_cmd_idx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{cmd}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "text" : "{snapname}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all snapshots.", + "method" : "GET", + "name" : "snapshot_list", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "description" : { + "description" : "Snapshot description.", + "type" : "string" + }, + "name" : { + "description" : "Snapshot identifier. Value 'current' identifies the current VM.", + "type" : "string" + }, + "parent" : { + "description" : "Parent snapshot identifier.", + "optional" : 1, + "type" : "string" + }, + "snaptime" : { + "description" : "Snapshot creation time", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "vmstate" : { + "description" : "Snapshot includes RAM.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Snapshot a VM.", + "method" : "POST", + "name" : "snapshot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A textual description or comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vmstate" : { + "description" : "Save the vmstate", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}/snapshot", + "text" : "snapshot" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a Template.", + "method" : "POST", + "name" : "template", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "disk" : { + "description" : "If you want to convert only 1 disk to base image.", + "enum" : [ + "ide0", + "ide1", + "ide2", + "ide3", + "scsi0", + "scsi1", + "scsi2", + "scsi3", + "scsi4", + "scsi5", + "scsi6", + "scsi7", + "scsi8", + "scsi9", + "scsi10", + "scsi11", + "scsi12", + "scsi13", + "scsi14", + "scsi15", + "scsi16", + "scsi17", + "scsi18", + "scsi19", + "scsi20", + "scsi21", + "scsi22", + "scsi23", + "scsi24", + "scsi25", + "scsi26", + "scsi27", + "scsi28", + "scsi29", + "scsi30", + "virtio0", + "virtio1", + "virtio2", + "virtio3", + "virtio4", + "virtio5", + "virtio6", + "virtio7", + "virtio8", + "virtio9", + "virtio10", + "virtio11", + "virtio12", + "virtio13", + "virtio14", + "virtio15", + "sata0", + "sata1", + "sata2", + "sata3", + "sata4", + "sata5", + "efidisk0", + "tpmstate0" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + "description" : "You need 'VM.Allocate' permissions on /vms/{vmid}" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/template", + "text" : "template" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migration tunnel endpoint - only for internal use by VM migration.", + "method" : "POST", + "name" : "mtunnel", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bridges" : { + "description" : "List of network bridges to check availability. Will be checked again for actually used bridges during migration.", + "format" : "pve-bridge-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storages" : { + "description" : "List of storages to check permission and availability. Will be checked again for all actually used storages during migration.", + "format" : "pve-storage-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + [ + "perm", + "/", + [ + "Sys.Incoming" + ] + ] + ], + "description" : "You need 'VM.Allocate' permissions on '/vms/{vmid}' and Sys.Incoming on '/'. Further permission checks happen during the actual migration." + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "socket" : { + "type" : "string" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/mtunnel", + "text" : "mtunnel" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration.", + "method" : "GET", + "name" : "mtunnelwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "socket" : { + "description" : "unix socket to forward to", + "type" : "string", + "typetext" : "" + }, + "ticket" : { + "description" : "ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "description" : "You need to pass a ticket valid for the selected socket. Tickets can be created via the mtunnel API call, which will check permissions accordingly.", + "user" : "all" + }, + "returns" : { + "properties" : { + "port" : { + "optional" : 1, + "type" : "string" + }, + "socket" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/qemu/{vmid}/mtunnelwebsocket", + "text" : "mtunnelwebsocket" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy the VM and all used/owned volumes. Removes any VM specific permissions and firewall rules", + "method" : "DELETE", + "name" : "destroy_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "destroy-unreferenced-disks" : { + "default" : 0, + "description" : "If set, destroy additionally all disks not referenced in the config but with a matching VMID from all enabled storages.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "purge" : { + "description" : "Remove VMID from configurations, like backup & replication jobs and HA.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "vmdiridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu/{vmid}", + "text" : "{vmid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Virtual machine index (per node).", + "method" : "GET", + "name" : "vmlist", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "full" : { + "description" : "Determine the full status of active VMs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list VMs where you have VM.Audit permissions on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "cpu" : { + "description" : "Current CPU usage.", + "optional" : 1, + "type" : "number" + }, + "cpus" : { + "description" : "Maximum usable CPUs.", + "optional" : 1, + "type" : "number" + }, + "diskread" : { + "description" : "The amount of bytes the guest read from it's block devices since the guest was started. (Note: This info is not available for all storage types.)", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "diskwrite" : { + "description" : "The amount of bytes the guest wrote from it's block devices since the guest was started. (Note: This info is not available for all storage types.)", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "lock" : { + "description" : "The current config lock, if any.", + "optional" : 1, + "type" : "string" + }, + "maxdisk" : { + "description" : "Root disk size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Maximum memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "mem" : { + "description" : "Currently used memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "VM (host)name.", + "optional" : 1, + "type" : "string" + }, + "netin" : { + "description" : "The amount of traffic in bytes that was sent to the guest over the network since it was started.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "netout" : { + "description" : "The amount of traffic in bytes that was sent from the guest over the network since it was started.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "pid" : { + "description" : "PID of the QEMU process, if the VM is running.", + "optional" : 1, + "type" : "integer" + }, + "qmpstatus" : { + "description" : "VM run state from the 'query-status' QMP monitor command.", + "optional" : 1, + "type" : "string" + }, + "running-machine" : { + "description" : "The currently running machine type (if running).", + "optional" : 1, + "type" : "string" + }, + "running-qemu" : { + "description" : "The QEMU version the VM is currently using (if running).", + "optional" : 1, + "type" : "string" + }, + "serial" : { + "description" : "Guest has serial device configured.", + "optional" : 1, + "type" : "boolean" + }, + "status" : { + "description" : "QEMU process status.", + "enum" : [ + "stopped", + "running" + ], + "type" : "string" + }, + "tags" : { + "description" : "The current configured tags, if any", + "optional" : 1, + "type" : "string" + }, + "template" : { + "default" : 0, + "description" : "Determines if the guest is a template.", + "optional" : 1, + "type" : "boolean" + }, + "uptime" : { + "description" : "Uptime in seconds.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{vmid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create or restore a virtual machine.", + "method" : "POST", + "name" : "create_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acpi" : { + "default" : 1, + "description" : "Enable/disable ACPI.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "affinity" : { + "description" : "List of host cores used to execute guest processes, for example: 0,5,8-11", + "format" : "pve-cpuset", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "agent" : { + "description" : "Enable/disable communication with the QEMU Guest Agent and its properties.", + "format" : { + "enabled" : { + "default" : 0, + "default_key" : 1, + "description" : "Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.", + "type" : "boolean" + }, + "freeze-fs-on-backup" : { + "default" : 1, + "description" : "Freeze/thaw guest filesystems on backup for consistency.", + "optional" : 1, + "type" : "boolean" + }, + "fstrim_cloned_disks" : { + "default" : 0, + "description" : "Run fstrim after moving a disk or migrating the VM.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default" : "virtio", + "description" : "Select the agent type", + "enum" : [ + "virtio", + "isa" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[enabled=]<1|0> [,freeze-fs-on-backup=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]" + }, + "amd-sev" : { + "description" : "Secure Encrypted Virtualization (SEV) features by AMD CPUs", + "format" : "pve-qemu-sev-fmt", + "optional" : 1, + "type" : "string", + "typetext" : "[type=] [,allow-smt=<1|0>] [,kernel-hashes=<1|0>] [,no-debug=<1|0>] [,no-key-sharing=<1|0>]" + }, + "arch" : { + "description" : "Virtual processor architecture. Defaults to the host.", + "enum" : [ + "x86_64", + "aarch64" + ], + "optional" : 1, + "type" : "string" + }, + "archive" : { + "description" : "The backup archive. Either the file system path to a .tar or .vma file (use '-' to pipe data from stdin) or a proxmox storage backup volume identifier.", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "args" : { + "description" : "Arbitrary arguments passed to kvm.", + "optional" : 1, + "type" : "string", + "typetext" : "", + "verbose_description" : "Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -smbios 'type=0,vendor=FOO'\n\nNOTE: this option is for experts only.\n" + }, + "audio0" : { + "description" : "Configure a audio device, useful in combination with QXL/Spice.", + "format" : { + "device" : { + "description" : "Configure an audio device.", + "enum" : [ + "ich9-intel-hda", + "intel-hda", + "AC97" + ], + "type" : "string" + }, + "driver" : { + "default" : "spice", + "description" : "Driver backend for the audio device.", + "enum" : [ + "spice", + "none" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "device= [,driver=]" + }, + "autostart" : { + "default" : 0, + "description" : "Automatic restart after crash (currently ignored).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "balloon" : { + "description" : "Amount of target RAM for the VM in MiB. Using zero disables the ballon driver.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "bios" : { + "default" : "seabios", + "description" : "Select BIOS implementation.", + "enum" : [ + "seabios", + "ovmf" + ], + "optional" : 1, + "type" : "string" + }, + "boot" : { + "description" : "Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.", + "format" : "pve-qm-boot", + "optional" : 1, + "type" : "string", + "typetext" : "[[legacy=]<[acdn]{1,4}>] [,order=]" + }, + "bootdisk" : { + "description" : "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format" : "pve-qm-bootdisk", + "optional" : 1, + "pattern" : "(ide|sata|scsi|virtio)\\d+", + "type" : "string" + }, + "bwlimit" : { + "default" : "restore limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "cdrom" : { + "description" : "This is an alias for option -ide2", + "format" : "pve-qm-ide", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cicustom" : { + "description" : "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format" : "pve-qm-cicustom", + "optional" : 1, + "type" : "string", + "typetext" : "[meta=] [,network=] [,user=] [,vendor=]" + }, + "cipassword" : { + "description" : "cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "citype" : { + "description" : "Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.", + "enum" : [ + "configdrive2", + "nocloud", + "opennebula" + ], + "optional" : 1, + "type" : "string" + }, + "ciupgrade" : { + "default" : 1, + "description" : "cloud-init: do an automatic package upgrade after the first boot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ciuser" : { + "description" : "cloud-init: User name to change ssh keys and password for instead of the image's configured default user.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cores" : { + "default" : 1, + "description" : "The number of cores per socket.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "cpu" : { + "description" : "Emulated CPU type.", + "format" : "pve-vm-cpu-conf", + "optional" : 1, + "type" : "string", + "typetext" : "[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 128)", + "verbose_description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit." + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 262144, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 262144)", + "verbose_description" : "CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs." + }, + "description" : { + "description" : "Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "efidisk0" : { + "description" : "Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "efitype" : { + "default" : "2m", + "description" : "Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarch64 (ARM).", + "enum" : [ + "2m", + "4m" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "pre-enrolled-keys" : { + "default" : 0, + "description" : "Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,pre-enrolled-keys=<1|0>] [,size=]" + }, + "force" : { + "description" : "Allow to overwrite existing VM.", + "optional" : 1, + "requires" : "archive", + "type" : "boolean", + "typetext" : "" + }, + "freeze" : { + "description" : "Freeze CPU at startup (use 'c' monitor command to start execution).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the vms lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostpci[n]" : { + "description" : "Map host PCI devices into guest.", + "format" : "pve-qm-hostpci", + "optional" : 1, + "type" : "string", + "typetext" : "[[host=]] [,device-id=] [,legacy-igd=<1|0>] [,mapping=] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]", + "verbose_description" : "Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "hotplug" : { + "default" : "network,disk,usb", + "description" : "Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.", + "format" : "pve-hotplug-features", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hugepages" : { + "description" : "Enable/disable hugepages memory.", + "enum" : [ + "any", + "2", + "1024" + ], + "optional" : 1, + "type" : "string" + }, + "ide[n]" : { + "description" : "Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "model" : { + "description" : "The drive's reported model name, url-encoded, up to 40 bytes long.", + "format" : "urlencoded", + "format_description" : "model", + "maxLength" : 120, + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "import-working-storage" : { + "description" : "A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ipconfig[n]" : { + "description" : "cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n", + "format" : "pve-qm-ipconfig", + "optional" : 1, + "type" : "string", + "typetext" : "[gw=] [,gw6=] [,ip=] [,ip6=]" + }, + "ivshmem" : { + "description" : "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + "format" : { + "name" : { + "description" : "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + "format_description" : "string", + "optional" : 1, + "pattern" : "[a-zA-Z0-9\\-]+", + "type" : "string" + }, + "size" : { + "description" : "The size of the file in MB.", + "minimum" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "size= [,name=]" + }, + "keephugepages" : { + "default" : 0, + "description" : "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "keyboard" : { + "default" : null, + "description" : "Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.", + "enum" : [ + "de", + "de-ch", + "da", + "en-gb", + "en-us", + "es", + "fi", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hu", + "is", + "it", + "ja", + "lt", + "mk", + "nl", + "no", + "pl", + "pt", + "pt-br", + "sv", + "sl", + "tr" + ], + "optional" : 1, + "type" : "string" + }, + "kvm" : { + "default" : 1, + "description" : "Enable/disable KVM hardware virtualization.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "live-restore" : { + "description" : "Start the VM immediately while importing or restoring in the background.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "localtime" : { + "description" : "Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the VM.", + "enum" : [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ], + "optional" : 1, + "type" : "string" + }, + "machine" : { + "description" : "Specify the QEMU machine.", + "format" : { + "enable-s3" : { + "description" : "Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "enable-s4" : { + "description" : "Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.", + "optional" : 1, + "type" : "boolean" + }, + "type" : { + "default_key" : 1, + "description" : "Specifies the QEMU machine type.", + "format_description" : "machine type", + "maxLength" : 40, + "optional" : 1, + "pattern" : "(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)", + "type" : "string" + }, + "viommu" : { + "description" : "Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).", + "enum" : [ + "intel", + "virtio" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,enable-s3=<1|0>] [,enable-s4=<1|0>] [,viommu=]" + }, + "memory" : { + "description" : "Memory properties.", + "format" : { + "current" : { + "default" : 512, + "default_key" : 1, + "description" : "Current amount of online RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.", + "minimum" : 16, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[current=]" + }, + "migrate_downtime" : { + "default" : 0.1, + "description" : "Set maximum tolerated downtime (in seconds) for migrations. Should the migration not be able to converge in the very end, because too much newly dirtied RAM needs to be transferred, the limit will be increased automatically step-by-step until migration can converge.", + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "migrate_speed" : { + "default" : 0, + "description" : "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "name" : { + "description" : "Set a name for the VM. Only used on the configuration web interface.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nameserver" : { + "description" : "cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "format" : "address-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specify network devices.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n", + "format" : "pve-bridge-id", + "format_description" : "bridge", + "optional" : 1, + "type" : "string" + }, + "e1000" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82540em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82544gc" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000-82545em" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "e1000e" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "firewall" : { + "description" : "Whether this interface should be protected by the firewall.", + "optional" : 1, + "type" : "boolean" + }, + "i82551" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82557b" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "i82559er" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "macaddr" : { + "description" : "MAC address. That address must be unique within your network. This is automatically generated if not specified.", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "model" : { + "default_key" : 1, + "description" : "Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.", + "enum" : [ + "e1000", + "e1000-82540em", + "e1000-82544gc", + "e1000-82545em", + "e1000e", + "i82551", + "i82557b", + "i82559er", + "ne2k_isa", + "ne2k_pci", + "pcnet", + "rtl8139", + "virtio", + "vmxnet3" + ], + "type" : "string" + }, + "mtu" : { + "description" : "Force MTU, for VirtIO only. Set to '1' to use the bridge MTU", + "maximum" : 65520, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "ne2k_isa" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "ne2k_pci" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "pcnet" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "queues" : { + "description" : "Number of packet queues to be used on the device.", + "maximum" : 64, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "rate" : { + "description" : "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "rtl8139" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "tag" : { + "description" : "VLAN tag to apply to packets on this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN trunks to pass through this interface.", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "virtio" : { + "alias" : "macaddr", + "keyAlias" : "model" + }, + "vmxnet3" : { + "alias" : "macaddr", + "keyAlias" : "model" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "numa" : { + "default" : 0, + "description" : "Enable/disable NUMA.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "numa[n]" : { + "description" : "NUMA topology.", + "format" : { + "cpus" : { + "description" : "CPUs accessing this NUMA node.", + "format_description" : "id[-id];...", + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "hostnodes" : { + "description" : "Host NUMA nodes to use.", + "format_description" : "id[-id];...", + "optional" : 1, + "pattern" : "(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)", + "type" : "string" + }, + "memory" : { + "description" : "Amount of memory this NUMA node provides.", + "optional" : 1, + "type" : "number" + }, + "policy" : { + "description" : "NUMA allocation policy.", + "enum" : [ + "preferred", + "bind", + "interleave" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "cpus= [,hostnodes=] [,memory=] [,policy=]" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a VM will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostype" : { + "description" : "Specify guest operating system.", + "enum" : [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "win11", + "l24", + "l26", + "solaris" + ], + "optional" : 1, + "type" : "string", + "verbose_description" : "Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022/2025\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 6.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n" + }, + "parallel[n]" : { + "description" : "Map host parallel devices (n is 0 to 2).", + "optional" : 1, + "pattern" : "/dev/parport\\d+|/dev/usb/lp\\d+", + "type" : "string", + "verbose_description" : "Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "pool" : { + "description" : "Add the VM to the specified pool.", + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "reboot" : { + "default" : 1, + "description" : "Allow reboot. If set to '0' the VM exit on reboot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "rng0" : { + "description" : "Configure a VirtIO-based Random Number Generator.", + "format" : "pve-qm-rng", + "optional" : 1, + "type" : "string", + "typetext" : "[source=] [,max_bytes=] [,period=]" + }, + "sata[n]" : { + "description" : "Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]" + }, + "scsi[n]" : { + "description" : "Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "product" : { + "description" : "The drive's product name, up to 16 bytes long.", + "format_description" : "product", + "optional" : 1, + "pattern" : "[A-Za-z0-9\\-_\\s]{,16}", + "type" : "string" + }, + "queues" : { + "description" : "Number of queues.", + "minimum" : 2, + "optional" : 1, + "type" : "integer" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "scsiblock" : { + "default" : 0, + "description" : "whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "ssd" : { + "description" : "Whether to expose this drive as an SSD, rather than a rotational hard disk.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "vendor" : { + "description" : "The drive's vendor name, up to 8 bytes long.", + "format_description" : "vendor", + "optional" : 1, + "pattern" : "[A-Za-z0-9\\-_\\s]{,8}", + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "description" : "The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.", + "format_description" : "wwn", + "optional" : 1, + "pattern" : "(?^:^(0x)[0-9a-fA-F]{16})", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,product=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,vendor=] [,werror=] [,wwn=]" + }, + "scsihw" : { + "default" : "lsi", + "description" : "SCSI controller model", + "enum" : [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "serial[n]" : { + "description" : "Create a serial device inside the VM (n is 0 to 3)", + "optional" : 1, + "pattern" : "(/dev/.+|socket)", + "type" : "string", + "verbose_description" : "Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n" + }, + "shares" : { + "default" : 1000, + "description" : "Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.", + "maximum" : 50000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 50000)" + }, + "smbios1" : { + "description" : "Specify SMBIOS type 1 fields.", + "format" : "pve-qm-smbios1", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]" + }, + "smp" : { + "default" : 1, + "description" : "The number of CPUs. Please use option -sockets instead.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "sockets" : { + "default" : 1, + "description" : "The number of CPU sockets.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "spice_enhancements" : { + "description" : "Configure additional enhancements for SPICE.", + "format" : { + "foldersharing" : { + "default" : "0", + "description" : "Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.", + "optional" : 1, + "type" : "boolean" + }, + "videostreaming" : { + "default" : "off", + "description" : "Enable video streaming. Uses compression for detected video streams.", + "enum" : [ + "off", + "all", + "filter" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[foldersharing=<1|0>] [,videostreaming=]" + }, + "sshkeys" : { + "description" : "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format" : "urlencoded", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Start VM after it was created successfully.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "startdate" : { + "default" : "now", + "description" : "Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.", + "optional" : 1, + "pattern" : "(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)", + "type" : "string", + "typetext" : "(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "storage" : { + "description" : "Default storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tablet" : { + "default" : 1, + "description" : "Enable/disable the USB tablet device.", + "optional" : 1, + "type" : "boolean", + "typetext" : "", + "verbose_description" : "Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)." + }, + "tags" : { + "description" : "Tags of the VM. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tdf" : { + "default" : 0, + "description" : "Enable/disable time drift fix.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tpmstate0" : { + "description" : "Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "version" : { + "default" : "v1.2", + "description" : "The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.", + "enum" : [ + "v1.2", + "v2.0" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,import-from=] [,size=] [,version=]" + }, + "unique" : { + "description" : "Assign a unique random ethernet address.", + "optional" : 1, + "requires" : "archive", + "type" : "boolean", + "typetext" : "" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + }, + "volume" : { + "alias" : "file" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=]" + }, + "usb[n]" : { + "description" : "Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).", + "format" : { + "host" : { + "default_key" : 1, + "description" : "The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadecimal numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n\nEither this or the 'mapping' key must be set.\n", + "format_description" : "HOSTUSBDEVICE|spice", + "optional" : 1, + "pattern" : "(?^:(?:(?:(?^:(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})))|(?:(?^:(\\d+)\\-(\\d+(\\.\\d+)*)))|[Ss][Pp][Ii][Cc][Ee]))", + "type" : "string" + }, + "mapping" : { + "description" : "The ID of a cluster wide mapping. Either this or the default-key 'host' must be set.", + "format" : "pve-configid", + "format_description" : "mapping-id", + "optional" : 1, + "type" : "string" + }, + "usb3" : { + "default" : 0, + "description" : "Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[host=]] [,mapping=] [,usb3=<1|0>]" + }, + "vcpus" : { + "default" : 0, + "description" : "Number of hotplugged vcpus.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "vga" : { + "description" : "Configure the VGA hardware.", + "format" : { + "clipboard" : { + "description" : "Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Migration with VNC clipboard is not yet supported!", + "enum" : [ + "vnc" + ], + "optional" : 1, + "type" : "string" + }, + "memory" : { + "description" : "Sets the VGA memory (in MiB). Has no effect with serial display.", + "maximum" : 512, + "minimum" : 4, + "optional" : 1, + "type" : "integer" + }, + "type" : { + "default" : "std", + "default_key" : 1, + "description" : "Select the VGA type. Using type 'cirrus' is not recommended.", + "enum" : [ + "cirrus", + "qxl", + "qxl2", + "qxl3", + "qxl4", + "none", + "serial0", + "serial1", + "serial2", + "serial3", + "std", + "virtio", + "virtio-gl", + "vmware" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[type=]] [,clipboard=] [,memory=]", + "verbose_description" : "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal." + }, + "virtio[n]" : { + "description" : "Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.", + "format" : { + "aio" : { + "description" : "AIO type to use.", + "enum" : [ + "native", + "threads", + "io_uring" + ], + "optional" : 1, + "type" : "string" + }, + "backup" : { + "description" : "Whether the drive should be included when making backups.", + "optional" : 1, + "type" : "boolean" + }, + "bps" : { + "description" : "Maximum r/w speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_rd" : { + "description" : "Maximum read speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_rd_length" : { + "alias" : "bps_rd_max_length" + }, + "bps_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "bps_wr" : { + "description" : "Maximum write speed in bytes per second.", + "format_description" : "bps", + "optional" : 1, + "type" : "integer" + }, + "bps_wr_length" : { + "alias" : "bps_wr_max_length" + }, + "bps_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cache" : { + "description" : "The drive's cache mode", + "enum" : [ + "none", + "writethrough", + "writeback", + "unsafe", + "directsync" + ], + "optional" : 1, + "type" : "string" + }, + "cyls" : { + "description" : "Force the drive's physical geometry to have a specific cylinder count.", + "optional" : 1, + "type" : "integer" + }, + "detect_zeroes" : { + "description" : "Controls whether to detect and try to optimize writes of zeroes.", + "optional" : 1, + "type" : "boolean" + }, + "discard" : { + "description" : "Controls whether to pass discard/trim requests to the underlying storage.", + "enum" : [ + "ignore", + "on" + ], + "optional" : 1, + "type" : "string" + }, + "file" : { + "default_key" : 1, + "description" : "The drive's backing volume.", + "format" : "pve-volume-id-or-qm-path", + "format_description" : "volume", + "type" : "string" + }, + "format" : { + "description" : "The drive's backing file's data format.", + "enum" : [ + "raw", + "qcow", + "qed", + "qcow2", + "vmdk", + "cloop" + ], + "optional" : 1, + "type" : "string" + }, + "heads" : { + "description" : "Force the drive's physical geometry to have a specific head count.", + "optional" : 1, + "type" : "integer" + }, + "import-from" : { + "description" : "Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!", + "format" : "pve-volume-id-or-absolute-path", + "format_description" : "source volume", + "optional" : 1, + "type" : "string" + }, + "iops" : { + "description" : "Maximum r/w I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max" : { + "description" : "Maximum unthrottled r/w I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_max_length" : { + "description" : "Maximum length of I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_rd" : { + "description" : "Maximum read I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_length" : { + "alias" : "iops_rd_max_length" + }, + "iops_rd_max" : { + "description" : "Maximum unthrottled read I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_rd_max_length" : { + "description" : "Maximum length of read I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iops_wr" : { + "description" : "Maximum write I/O in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_length" : { + "alias" : "iops_wr_max_length" + }, + "iops_wr_max" : { + "description" : "Maximum unthrottled write I/O pool in operations per second.", + "format_description" : "iops", + "optional" : 1, + "type" : "integer" + }, + "iops_wr_max_length" : { + "description" : "Maximum length of write I/O bursts in seconds.", + "format_description" : "seconds", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "iothread" : { + "description" : "Whether to use iothreads for this drive", + "optional" : 1, + "type" : "boolean" + }, + "mbps" : { + "description" : "Maximum r/w speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_max" : { + "description" : "Maximum unthrottled r/w pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd" : { + "description" : "Maximum read speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_rd_max" : { + "description" : "Maximum unthrottled read pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr" : { + "description" : "Maximum write speed in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "mbps_wr_max" : { + "description" : "Maximum unthrottled write pool in megabytes per second.", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "media" : { + "default" : "disk", + "description" : "The drive's media type.", + "enum" : [ + "cdrom", + "disk" + ], + "optional" : 1, + "type" : "string" + }, + "replicate" : { + "default" : 1, + "description" : "Whether the drive should considered for replication jobs.", + "optional" : 1, + "type" : "boolean" + }, + "rerror" : { + "description" : "Read error action.", + "enum" : [ + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "ro" : { + "description" : "Whether the drive is read-only.", + "optional" : 1, + "type" : "boolean" + }, + "secs" : { + "description" : "Force the drive's physical geometry to have a specific sector count.", + "optional" : 1, + "type" : "integer" + }, + "serial" : { + "description" : "The drive's reported serial number, url-encoded, up to 20 bytes long.", + "format" : "urlencoded", + "format_description" : "serial", + "maxLength" : 60, + "optional" : 1, + "type" : "string" + }, + "shared" : { + "default" : 0, + "description" : "Mark this locally-managed volume as available on all nodes", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Disk size. This is purely informational and has no effect.", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "snapshot" : { + "description" : "Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.", + "optional" : 1, + "type" : "boolean" + }, + "trans" : { + "description" : "Force disk geometry bios translation mode.", + "enum" : [ + "none", + "lba", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "volume" : { + "alias" : "file" + }, + "werror" : { + "description" : "Write error action.", + "enum" : [ + "enospc", + "ignore", + "report", + "stop" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]" + }, + "virtiofs[n]" : { + "description" : "Configuration for sharing a directory between host and guest using Virtio-fs.", + "format" : { + "cache" : { + "default" : "auto", + "description" : "The caching policy the file system should use (auto, always, metadata, never).", + "enum" : [ + "auto", + "always", + "metadata", + "never" + ], + "optional" : 1, + "type" : "string" + }, + "direct-io" : { + "default" : 0, + "description" : "Honor the O_DIRECT flag passed down by guest applications.", + "optional" : 1, + "type" : "boolean" + }, + "dirid" : { + "default_key" : 1, + "description" : "Mapping identifier of the directory mapping to be shared with the guest. Also used as a mount tag inside the VM.", + "format" : "pve-configid", + "format_description" : "mapping-id", + "type" : "string" + }, + "expose-acl" : { + "default" : 0, + "description" : "Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.", + "optional" : 1, + "type" : "boolean" + }, + "expose-xattr" : { + "default" : 0, + "description" : "Enable support for extended attributes for this mount.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[dirid=] [,cache=] [,direct-io=<1|0>] [,expose-acl=<1|0>] [,expose-xattr=<1|0>]" + }, + "vmgenid" : { + "default" : "1 (autogenerated)", + "description" : "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "format_description" : "UUID", + "optional" : 1, + "pattern" : "(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])", + "type" : "string", + "verbose_description" : "The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file." + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vmstatestorage" : { + "description" : "Default storage for VM state volumes/files.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "watchdog" : { + "description" : "Create a virtual hardware watchdog device.", + "format" : "pve-qm-watchdog", + "optional" : 1, + "type" : "string", + "typetext" : "[[model=]] [,action=]", + "verbose_description" : "Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)" + } + } + }, + "permissions" : { + "description" : "You need 'VM.Allocate' permissions on /vms/{vmid} or on the VM pool /pool/{pool}. For restore (option 'archive'), it is enough if the user has 'VM.Backup' permission and the VM already exists. If you create disks you need 'Datastore.AllocateSpace' on any used storage.If you use a bridge/vlan, you need 'SDN.Use' on any used bridge/vlan.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/qemu", + "text" : "qemu" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get container configuration.", + "method" : "GET", + "name" : "vm_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "current" : { + "default" : 0, + "description" : "Get current values (instead of pending values).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapshot" : { + "description" : "Fetch config values from given snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "arch" : { + "default" : "amd64", + "description" : "OS architecture type.", + "enum" : [ + "amd64", + "i386", + "arm64", + "armhf", + "riscv32", + "riscv64" + ], + "optional" : 1, + "type" : "string" + }, + "cmode" : { + "default" : "tty", + "description" : "Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).", + "enum" : [ + "shell", + "console", + "tty" + ], + "optional" : 1, + "type" : "string" + }, + "console" : { + "default" : 1, + "description" : "Attach a console device (/dev/console) to the container.", + "optional" : 1, + "type" : "boolean" + }, + "cores" : { + "description" : "The number of cores assigned to the container. A container can use all available cores by default.", + "maximum" : 8192, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.", + "maximum" : 8192, + "minimum" : 0, + "optional" : 1, + "type" : "number" + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 500000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "verbose_description" : "CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests." + }, + "debug" : { + "default" : 0, + "description" : "Try to be more verbose. For now this only enables debug log-level on start.", + "optional" : 1, + "type" : "boolean" + }, + "description" : { + "description" : "Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string" + }, + "dev[n]" : { + "description" : "Device to pass through to the container", + "format" : { + "deny-write" : { + "default" : 0, + "description" : "Deny the container to write to the device", + "optional" : 1, + "type" : "boolean" + }, + "gid" : { + "description" : "Group ID to be assigned to the device node", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "mode" : { + "description" : "Access mode to be set on the device node", + "format_description" : "Octal access mode", + "optional" : 1, + "pattern" : "0[0-7]{3}", + "type" : "string" + }, + "path" : { + "default_key" : 1, + "description" : "Device to pass through to the container", + "format" : "pve-lxc-dev-string", + "format_description" : "Path", + "optional" : 1, + "type" : "string", + "verbose_description" : "Path to the device to pass through to the container" + }, + "uid" : { + "description" : "User ID to be assigned to the device node", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "SHA1 digest of configuration file. This can be used to prevent concurrent modifications.", + "type" : "string" + }, + "features" : { + "description" : "Allow containers access to advanced features.", + "format" : { + "force_rw_sys" : { + "default" : 0, + "description" : "Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.", + "optional" : 1, + "type" : "boolean" + }, + "fuse" : { + "default" : 0, + "description" : "Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.", + "optional" : 1, + "type" : "boolean" + }, + "keyctl" : { + "default" : 0, + "description" : "For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.", + "optional" : 1, + "type" : "boolean" + }, + "mknod" : { + "default" : 0, + "description" : "Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.", + "optional" : 1, + "type" : "boolean" + }, + "mount" : { + "description" : "Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.", + "format_description" : "fstype;fstype;...", + "optional" : 1, + "pattern" : "(?^:[a-zA-Z0-9_; ]+)", + "type" : "string" + }, + "nesting" : { + "default" : 0, + "description" : "Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the containers lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string" + }, + "hostname" : { + "description" : "Set a host name for the container.", + "format" : "dns-name", + "maxLength" : 255, + "optional" : 1, + "type" : "string" + }, + "lock" : { + "description" : "Lock/unlock the container.", + "enum" : [ + "backup", + "create", + "destroyed", + "disk", + "fstrim", + "migrate", + "mounted", + "rollback", + "snapshot", + "snapshot-delete" + ], + "optional" : 1, + "type" : "string" + }, + "lxc" : { + "description" : "Array of lxc low-level configurations ([[key1, value1], [key2, value2] ...]).", + "items" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "optional" : 1, + "type" : "array" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the container in MB.", + "minimum" : 16, + "optional" : 1, + "type" : "integer" + }, + "mp[n]" : { + "description" : "Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "backup" : { + "description" : "Whether to include the mount point in backups.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Whether to include the mount point in backups (only used for volume mount points)." + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)", + "type" : "string" + }, + "mp" : { + "description" : "Path to the mount point as seen from inside the container (must not contain symlinks).", + "format" : "pve-lxc-mp-string", + "format_description" : "Path", + "type" : "string", + "verbose_description" : "Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons." + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "nameserver" : { + "description" : "Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "lxc-ip-with-ll-iface-list", + "optional" : 1, + "type" : "string" + }, + "net[n]" : { + "description" : "Specifies network interfaces for the container.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to.", + "format_description" : "bridge", + "optional" : 1, + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "firewall" : { + "description" : "Controls whether this interface's firewall rules should be used.", + "optional" : 1, + "type" : "boolean" + }, + "gw" : { + "description" : "Default gateway for IPv4 traffic.", + "format" : "ipv4", + "format_description" : "GatewayIPv4", + "optional" : 1, + "type" : "string" + }, + "gw6" : { + "description" : "Default gateway for IPv6 traffic.", + "format" : "ipv6", + "format_description" : "GatewayIPv6", + "optional" : 1, + "type" : "string" + }, + "hwaddr" : { + "description" : "The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "ip" : { + "description" : "IPv4 address in CIDR format.", + "format" : "pve-ipv4-config", + "format_description" : "(IPv4/CIDR|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address in CIDR format.", + "format" : "pve-ipv6-config", + "format_description" : "(IPv6/CIDR|auto|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "mtu" : { + "description" : "Maximum transfer unit of the interface. (lxc.network.mtu)", + "maximum" : 65535, + "minimum" : 64, + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "Name of the network device as seen from inside the container. (lxc.network.name)", + "format_description" : "string", + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "rate" : { + "description" : "Apply rate limiting to the interface", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "tag" : { + "description" : "VLAN tag for this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN ids to pass through the interface", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:;\\d+)*)", + "type" : "string" + }, + "type" : { + "description" : "Network interface type.", + "enum" : [ + "veth" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a container will be started during system bootup.", + "optional" : 1, + "type" : "boolean" + }, + "ostype" : { + "description" : "OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.", + "enum" : [ + "debian", + "devuan", + "ubuntu", + "centos", + "fedora", + "opensuse", + "archlinux", + "alpine", + "gentoo", + "nixos", + "unmanaged" + ], + "optional" : 1, + "type" : "string" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.", + "optional" : 1, + "type" : "boolean" + }, + "rootfs" : { + "description" : "Use volume as container root.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)", + "type" : "string" + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "searchdomain" : { + "description" : "Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "dns-name-list", + "optional" : 1, + "type" : "string" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "swap" : { + "default" : 512, + "description" : "Amount of SWAP for the container in MB.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "tags" : { + "description" : "Tags of the Container. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean" + }, + "timezone" : { + "description" : "Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab", + "format" : "pve-ct-timezone", + "optional" : 1, + "type" : "string" + }, + "tty" : { + "default" : 2, + "description" : "Specify the number of tty available to the container", + "maximum" : 6, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "unprivileged" : { + "default" : 0, + "description" : "Makes the container run as unprivileged user. (Should not be modified manually.)", + "optional" : 1, + "type" : "boolean" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "volume" : { + "default_key" : 1, + "description" : "The volume that is not used currently.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set container options.", + "method" : "PUT", + "name" : "update_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "arch" : { + "default" : "amd64", + "description" : "OS architecture type.", + "enum" : [ + "amd64", + "i386", + "arm64", + "armhf", + "riscv32", + "riscv64" + ], + "optional" : 1, + "type" : "string" + }, + "cmode" : { + "default" : "tty", + "description" : "Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).", + "enum" : [ + "shell", + "console", + "tty" + ], + "optional" : 1, + "type" : "string" + }, + "console" : { + "default" : 1, + "description" : "Attach a console device (/dev/console) to the container.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cores" : { + "description" : "The number of cores assigned to the container. A container can use all available cores by default.", + "maximum" : 8192, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 8192)" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.", + "maximum" : 8192, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 8192)" + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 500000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 500000)", + "verbose_description" : "CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests." + }, + "debug" : { + "default" : 0, + "description" : "Try to be more verbose. For now this only enables debug log-level on start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dev[n]" : { + "description" : "Device to pass through to the container", + "format" : { + "deny-write" : { + "default" : 0, + "description" : "Deny the container to write to the device", + "optional" : 1, + "type" : "boolean" + }, + "gid" : { + "description" : "Group ID to be assigned to the device node", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "mode" : { + "description" : "Access mode to be set on the device node", + "format_description" : "Octal access mode", + "optional" : 1, + "pattern" : "0[0-7]{3}", + "type" : "string" + }, + "path" : { + "default_key" : 1, + "description" : "Device to pass through to the container", + "format" : "pve-lxc-dev-string", + "format_description" : "Path", + "optional" : 1, + "type" : "string", + "verbose_description" : "Path to the device to pass through to the container" + }, + "uid" : { + "description" : "User ID to be assigned to the device node", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[path=]] [,deny-write=<1|0>] [,gid=] [,mode=] [,uid=]" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "features" : { + "description" : "Allow containers access to advanced features.", + "format" : { + "force_rw_sys" : { + "default" : 0, + "description" : "Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.", + "optional" : 1, + "type" : "boolean" + }, + "fuse" : { + "default" : 0, + "description" : "Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.", + "optional" : 1, + "type" : "boolean" + }, + "keyctl" : { + "default" : 0, + "description" : "For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.", + "optional" : 1, + "type" : "boolean" + }, + "mknod" : { + "default" : 0, + "description" : "Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.", + "optional" : 1, + "type" : "boolean" + }, + "mount" : { + "description" : "Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.", + "format_description" : "fstype;fstype;...", + "optional" : 1, + "pattern" : "(?^:[a-zA-Z0-9_; ]+)", + "type" : "string" + }, + "nesting" : { + "default" : 0, + "description" : "Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[force_rw_sys=<1|0>] [,fuse=<1|0>] [,keyctl=<1|0>] [,mknod=<1|0>] [,mount=] [,nesting=<1|0>]" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the containers lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostname" : { + "description" : "Set a host name for the container.", + "format" : "dns-name", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the container.", + "enum" : [ + "backup", + "create", + "destroyed", + "disk", + "fstrim", + "migrate", + "mounted", + "rollback", + "snapshot", + "snapshot-delete" + ], + "optional" : 1, + "type" : "string" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the container in MB.", + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - N)" + }, + "mp[n]" : { + "description" : "Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "backup" : { + "description" : "Whether to include the mount point in backups.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Whether to include the mount point in backups (only used for volume mount points)." + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)", + "type" : "string" + }, + "mp" : { + "description" : "Path to the mount point as seen from inside the container (must not contain symlinks).", + "format" : "pve-lxc-mp-string", + "format_description" : "Path", + "type" : "string", + "verbose_description" : "Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons." + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=] ,mp= [,acl=<1|0>] [,backup=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]" + }, + "nameserver" : { + "description" : "Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "lxc-ip-with-ll-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specifies network interfaces for the container.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to.", + "format_description" : "bridge", + "optional" : 1, + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "firewall" : { + "description" : "Controls whether this interface's firewall rules should be used.", + "optional" : 1, + "type" : "boolean" + }, + "gw" : { + "description" : "Default gateway for IPv4 traffic.", + "format" : "ipv4", + "format_description" : "GatewayIPv4", + "optional" : 1, + "type" : "string" + }, + "gw6" : { + "description" : "Default gateway for IPv6 traffic.", + "format" : "ipv6", + "format_description" : "GatewayIPv6", + "optional" : 1, + "type" : "string" + }, + "hwaddr" : { + "description" : "The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "ip" : { + "description" : "IPv4 address in CIDR format.", + "format" : "pve-ipv4-config", + "format_description" : "(IPv4/CIDR|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address in CIDR format.", + "format" : "pve-ipv6-config", + "format_description" : "(IPv6/CIDR|auto|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "mtu" : { + "description" : "Maximum transfer unit of the interface. (lxc.network.mtu)", + "maximum" : 65535, + "minimum" : 64, + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "Name of the network device as seen from inside the container. (lxc.network.name)", + "format_description" : "string", + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "rate" : { + "description" : "Apply rate limiting to the interface", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "tag" : { + "description" : "VLAN tag for this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN ids to pass through the interface", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:;\\d+)*)", + "type" : "string" + }, + "type" : { + "description" : "Network interface type.", + "enum" : [ + "veth" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "name= [,bridge=] [,firewall=<1|0>] [,gw=] [,gw6=] [,hwaddr=] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=<(IPv6/CIDR|auto|dhcp|manual)>] [,link_down=<1|0>] [,mtu=] [,rate=] [,tag=] [,trunks=] [,type=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a container will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostype" : { + "description" : "OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.", + "enum" : [ + "debian", + "devuan", + "ubuntu", + "centos", + "fedora", + "opensuse", + "archlinux", + "alpine", + "gentoo", + "nixos", + "unmanaged" + ], + "optional" : 1, + "type" : "string" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "revert" : { + "description" : "Revert a pending change.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "rootfs" : { + "description" : "Use volume as container root.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)", + "type" : "string" + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=] [,acl=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]" + }, + "searchdomain" : { + "description" : "Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "dns-name-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "swap" : { + "default" : 512, + "description" : "Amount of SWAP for the container in MB.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "tags" : { + "description" : "Tags of the Container. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "timezone" : { + "description" : "Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab", + "format" : "pve-ct-timezone", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tty" : { + "default" : 2, + "description" : "Specify the number of tty available to the container", + "maximum" : 6, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 6)" + }, + "unprivileged" : { + "default" : 0, + "description" : "Makes the container run as unprivileged user. (Should not be modified manually.)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "volume" : { + "default_key" : 1, + "description" : "The volume that is not used currently.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=]" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk", + "VM.Config.CPU", + "VM.Config.Memory", + "VM.Config.Network", + "VM.Config.Options" + ], + "any", + 1 + ], + "description" : "non-volume mount points in rootfs and mp[n] are restricted to root@pam" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/config", + "text" : "config" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get virtual machine status.", + "method" : "GET", + "name" : "vm_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "cpu" : { + "description" : "Current CPU usage.", + "optional" : 1, + "type" : "number" + }, + "cpus" : { + "description" : "Maximum usable CPUs.", + "optional" : 1, + "type" : "number" + }, + "disk" : { + "description" : "Root disk image space-usage in bytes.", + "minimum" : 0, + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "diskread" : { + "description" : "The amount of bytes the guest read from it's block devices since the guest was started. (Note: This info is not available for all storage types.)", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "diskwrite" : { + "description" : "The amount of bytes the guest wrote from it's block devices since the guest was started. (Note: This info is not available for all storage types.)", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "ha" : { + "description" : "HA manager service status.", + "type" : "object" + }, + "lock" : { + "description" : "The current config lock, if any.", + "optional" : 1, + "type" : "string" + }, + "maxdisk" : { + "description" : "Root disk image size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Maximum memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxswap" : { + "description" : "Maximum SWAP memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "mem" : { + "description" : "Currently used memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "Container name.", + "optional" : 1, + "type" : "string" + }, + "netin" : { + "description" : "The amount of traffic in bytes that was sent to the guest over the network since it was started.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "netout" : { + "description" : "The amount of traffic in bytes that was sent from the guest over the network since it was started.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "status" : { + "description" : "LXC Container status.", + "enum" : [ + "stopped", + "running" + ], + "type" : "string" + }, + "tags" : { + "description" : "The current configured tags, if any.", + "optional" : 1, + "type" : "string" + }, + "template" : { + "default" : 0, + "description" : "Determines if the guest is a template.", + "optional" : 1, + "type" : "boolean" + }, + "uptime" : { + "description" : "Uptime in seconds.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/current", + "text" : "current" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start the container.", + "method" : "POST", + "name" : "vm_start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "debug" : { + "default" : 0, + "description" : "If set, enables very verbose debug log-level on start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop the container. This will abruptly stop all processes running in the container.", + "method" : "POST", + "name" : "vm_stop", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "overrule-shutdown" : { + "default" : 0, + "description" : "Try to abort active 'vzshutdown' tasks before stopping.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "skiplock" : { + "description" : "Ignore locks - only root is allowed to use this option.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/stop", + "text" : "stop" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Shutdown the container. This will trigger a clean shutdown of the container, see lxc-stop(1) for details.", + "method" : "POST", + "name" : "vm_shutdown", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "forceStop" : { + "default" : 0, + "description" : "Make sure the Container stops.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 60, + "description" : "Wait maximal timeout seconds.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/shutdown", + "text" : "shutdown" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Suspend the container. This is experimental.", + "method" : "POST", + "name" : "vm_suspend", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/suspend", + "text" : "suspend" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Resume the container.", + "method" : "POST", + "name" : "vm_resume", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/resume", + "text" : "resume" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Reboot the container by shutting it down, and starting it again. Applies pending changes.", + "method" : "POST", + "name" : "vm_reboot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "description" : "Wait maximal timeout seconds for the shutdown.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/status/reboot", + "text" : "reboot" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "vmcmdidx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/status", + "text" : "status" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Rollback LXC state to specified snapshot.", + "method" : "POST", + "name" : "rollback", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Whether the container should get started after rolling back successfully", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback", + "text" : "rollback" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get snapshot configuration", + "method" : "GET", + "name" : "get_snapshot_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback", + "VM.Audit" + ], + "any", + 1 + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update snapshot metadata.", + "method" : "PUT", + "name" : "update_snapshot_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A textual description or comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "text" : "config" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete a LXC snapshot.", + "method" : "DELETE", + "name" : "delsnapshot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "For removal from config file, even if removing disk snapshots fails.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "snapshot_cmd_idx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{cmd}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "text" : "{snapname}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all snapshots.", + "method" : "GET", + "name" : "list", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "description" : { + "description" : "Snapshot description.", + "type" : "string" + }, + "name" : { + "description" : "Snapshot identifier. Value 'current' identifies the current VM.", + "type" : "string" + }, + "parent" : { + "description" : "Parent snapshot identifier.", + "optional" : 1, + "type" : "string" + }, + "snaptime" : { + "description" : "Snapshot creation time", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Snapshot a container.", + "method" : "POST", + "name" : "snapshot", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A textual description or comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/snapshot", + "text" : "snapshot" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "properties" : { + "action" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "dest" : { + "optional" : 1, + "type" : "string" + }, + "dport" : { + "optional" : 1, + "type" : "string" + }, + "enable" : { + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "optional" : 1, + "type" : "string" + }, + "iface" : { + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "optional" : 1, + "type" : "string" + }, + "pos" : { + "type" : "integer" + }, + "proto" : { + "optional" : 1, + "type" : "string" + }, + "source" : { + "optional" : 1, + "type" : "string" + }, + "sport" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : null, + "returns" : { + "items" : { + "properties" : { + "pos" : { + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 0, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : null, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/rules", + "text" : "rules" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network alias.", + "method" : "DELETE", + "name" : "remove_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read alias.", + "method" : "GET", + "name" : "read_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network alias.", + "method" : "PUT", + "name" : "update_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "rename" : { + "description" : "Rename an existing alias.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List aliases", + "method" : "GET", + "name" : "get_aliases", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "name" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create IP or Network Alias.", + "method" : "POST", + "name" : "create_alias", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDR", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "Alias name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/aliases", + "text" : "aliases" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove IP or Network from IPSet.", + "method" : "DELETE", + "name" : "remove_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read IP or Network settings from IPSet.", + "method" : "GET", + "name" : "read_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update IP or Network settings", + "method" : "PUT", + "name" : "update_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "text" : "{cidr}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete IPSet", + "method" : "DELETE", + "name" : "delete_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "description" : "Delete all members of the IPSet, if there are any.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List IPSet content", + "method" : "GET", + "name" : "get_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "cidr" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{cidr}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add IP or Network to IPSet.", + "method" : "POST", + "name" : "create_ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cidr" : { + "description" : "Network/IP specification in CIDR format.", + "format" : "IPorCIDRorAlias", + "type" : "string", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nomatch" : { + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List IPSets", + "method" : "GET", + "name" : "ipset_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 0, + "type" : "string" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new IPSet", + "method" : "POST", + "name" : "create_ipset", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "IP set name.", + "maxLength" : 64, + "minLength" : 2, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "rename" : { + "description" : "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.", + "maxLength" : 64, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/ipset", + "text" : "ipset" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get VM firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "dhcp" : { + "default" : 0, + "description" : "Enable DHCP.", + "optional" : 1, + "type" : "boolean" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean" + }, + "ipfilter" : { + "description" : "Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.", + "optional" : 1, + "type" : "boolean" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macfilter" : { + "default" : 1, + "description" : "Enable/disable MAC address filter.", + "optional" : 1, + "type" : "boolean" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "radv" : { + "description" : "Allow sending Router Advertisement.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dhcp" : { + "default" : 0, + "description" : "Enable DHCP.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 0, + "description" : "Enable/disable firewall rules.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ipfilter" : { + "description" : "Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macfilter" : { + "default" : 1, + "description" : "Enable/disable MAC address filter.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "policy_in" : { + "description" : "Input policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "policy_out" : { + "description" : "Output policy.", + "enum" : [ + "ACCEPT", + "REJECT", + "DROP" + ], + "optional" : 1, + "type" : "string" + }, + "radv" : { + "description" : "Allow sending Router Advertisement.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read firewall log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display log since this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "until" : { + "description" : "Display log until this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Lists possible IPSet/Alias reference which are allowed in source/dest properties.", + "method" : "GET", + "name" : "refs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Only list references of specified type.", + "enum" : [ + "alias", + "ipset" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "ref" : { + "type" : "string" + }, + "scope" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "alias", + "ipset" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/firewall/refs", + "text" : "refs" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}/firewall", + "text" : "firewall" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read VM RRD statistics (returns PNG)", + "method" : "GET", + "name" : "rrd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "ds" : { + "description" : "The list of datasources you want to display.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "filename" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/rrd", + "text" : "rrd" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read VM RRD statistics", + "method" : "GET", + "name" : "rrddata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/rrddata", + "text" : "rrddata" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a TCP VNC proxy connections.", + "method" : "POST", + "name" : "vncproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "height" : { + "description" : "sets the height of the console in pixels.", + "maximum" : 2160, + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - 2160)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "websocket" : { + "description" : "use websocket instead of standard VNC.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "width" : { + "description" : "sets the width of the console in pixels.", + "maximum" : 4096, + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - 4096)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "cert" : { + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/vncproxy", + "text" : "vncproxy" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a TCP proxy connection.", + "method" : "POST", + "name" : "termproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/termproxy", + "text" : "termproxy" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Opens a weksocket for VNC traffic.", + "method" : "GET", + "name" : "vncwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Port number returned by previous vncproxy call.", + "maximum" : 5999, + "minimum" : 5900, + "type" : "integer", + "typetext" : " (5900 - 5999)" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "vncticket" : { + "description" : "Ticket from previous call to vncproxy.", + "maxLength" : 512, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ], + "description" : "You also need to pass a valid ticket (vncticket)." + }, + "returns" : { + "properties" : { + "port" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/vncwebsocket", + "text" : "vncwebsocket" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Returns a SPICE configuration to connect to the CT.", + "method" : "POST", + "name" : "spiceproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "proxy" : { + "description" : "SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).", + "format" : "address", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 1, + "description" : "Returned values can be directly passed to the 'remote-viewer' application.", + "properties" : { + "host" : { + "type" : "string" + }, + "password" : { + "type" : "string" + }, + "proxy" : { + "type" : "string" + }, + "tls-port" : { + "type" : "integer" + }, + "type" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/spiceproxy", + "text" : "spiceproxy" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migrate the container to another cluster. Creates a new migration task. EXPERIMENTAL feature!", + "method" : "POST", + "name" : "remote_migrate_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "migrate limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "delete" : { + "default" : 0, + "description" : "Delete the original CT and related data after successful migration. By default the original CT is kept on the source cluster in a stopped state.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "online" : { + "description" : "Use online/live migration.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restart" : { + "description" : "Use restart migration", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target-bridge" : { + "description" : "Mapping from source to target bridges. Providing only a single bridge ID maps all source bridges to that bridge. Providing the special value '1' will map each source bridge to itself.", + "format" : "bridge-pair-list", + "type" : "string", + "typetext" : "" + }, + "target-endpoint" : { + "description" : "Remote target endpoint", + "format" : "proxmox-remote", + "type" : "string", + "typetext" : "apitoken= ,host=
[,fingerprint=] [,port=]" + }, + "target-storage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storage-pair-list", + "optional" : 0, + "type" : "string", + "typetext" : "" + }, + "target-vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "timeout" : { + "default" : 180, + "description" : "Timeout in seconds for shutdown for restart migration", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/remote_migrate", + "text" : "remote_migrate" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migrate the container to another node. Creates a new migration task.", + "method" : "POST", + "name" : "migrate_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "migrate limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "online" : { + "description" : "Use online/live migration.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restart" : { + "description" : "Use restart migration", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "target-storage" : { + "description" : "Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.", + "format" : "storage-pair-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 180, + "description" : "Timeout in seconds for shutdown for restart migration", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/migrate", + "text" : "migrate" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Check if feature for virtual machine is available.", + "method" : "GET", + "name" : "vm_feature", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "feature" : { + "description" : "Feature to check.", + "enum" : [ + "snapshot", + "clone", + "copy" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "hasFeature" : { + "type" : "boolean" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/feature", + "text" : "feature" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a Template.", + "method" : "POST", + "name" : "template", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + "description" : "You need 'VM.Allocate' permissions on /vms/{vmid}" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/template", + "text" : "template" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a container clone/copy", + "method" : "POST", + "name" : "clone_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "clone limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "description" : { + "description" : "Description for the new CT.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "full" : { + "description" : "Create a full copy of all disks. This is always done when you clone a normal CT. For CT templates, we try to create a linked clone by default.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hostname" : { + "description" : "Set a hostname for the new CT.", + "format" : "dns-name", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "newid" : { + "description" : "VMID for the clone.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Add the new CT to the specified pool.", + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "snapname" : { + "description" : "The name of the snapshot.", + "format" : "pve-configid", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Target storage for full clone.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node. Only allowed if the original VM is on shared storage.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/vms/{vmid}", + [ + "VM.Clone" + ] + ], + [ + "or", + [ + "perm", + "/vms/{newid}", + [ + "VM.Allocate" + ] + ], + [ + "perm", + "/pool/{pool}", + [ + "VM.Allocate" + ], + "require_param", + "pool" + ] + ] + ], + "description" : "You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions on /vms/{newid} (or on the VM pool /pool/{pool}). You also need 'Datastore.AllocateSpace' on any used storage, and 'SDN.Use' on any bridge." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/clone", + "text" : "clone" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Resize a container mount point.", + "method" : "PUT", + "name" : "resize_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disk" : { + "description" : "The disk you want to resize.", + "enum" : [ + "rootfs", + "mp0", + "mp1", + "mp2", + "mp3", + "mp4", + "mp5", + "mp6", + "mp7", + "mp8", + "mp9", + "mp10", + "mp11", + "mp12", + "mp13", + "mp14", + "mp15", + "mp16", + "mp17", + "mp18", + "mp19", + "mp20", + "mp21", + "mp22", + "mp23", + "mp24", + "mp25", + "mp26", + "mp27", + "mp28", + "mp29", + "mp30", + "mp31", + "mp32", + "mp33", + "mp34", + "mp35", + "mp36", + "mp37", + "mp38", + "mp39", + "mp40", + "mp41", + "mp42", + "mp43", + "mp44", + "mp45", + "mp46", + "mp47", + "mp48", + "mp49", + "mp50", + "mp51", + "mp52", + "mp53", + "mp54", + "mp55", + "mp56", + "mp57", + "mp58", + "mp59", + "mp60", + "mp61", + "mp62", + "mp63", + "mp64", + "mp65", + "mp66", + "mp67", + "mp68", + "mp69", + "mp70", + "mp71", + "mp72", + "mp73", + "mp74", + "mp75", + "mp76", + "mp77", + "mp78", + "mp79", + "mp80", + "mp81", + "mp82", + "mp83", + "mp84", + "mp85", + "mp86", + "mp87", + "mp88", + "mp89", + "mp90", + "mp91", + "mp92", + "mp93", + "mp94", + "mp95", + "mp96", + "mp97", + "mp98", + "mp99", + "mp100", + "mp101", + "mp102", + "mp103", + "mp104", + "mp105", + "mp106", + "mp107", + "mp108", + "mp109", + "mp110", + "mp111", + "mp112", + "mp113", + "mp114", + "mp115", + "mp116", + "mp117", + "mp118", + "mp119", + "mp120", + "mp121", + "mp122", + "mp123", + "mp124", + "mp125", + "mp126", + "mp127", + "mp128", + "mp129", + "mp130", + "mp131", + "mp132", + "mp133", + "mp134", + "mp135", + "mp136", + "mp137", + "mp138", + "mp139", + "mp140", + "mp141", + "mp142", + "mp143", + "mp144", + "mp145", + "mp146", + "mp147", + "mp148", + "mp149", + "mp150", + "mp151", + "mp152", + "mp153", + "mp154", + "mp155", + "mp156", + "mp157", + "mp158", + "mp159", + "mp160", + "mp161", + "mp162", + "mp163", + "mp164", + "mp165", + "mp166", + "mp167", + "mp168", + "mp169", + "mp170", + "mp171", + "mp172", + "mp173", + "mp174", + "mp175", + "mp176", + "mp177", + "mp178", + "mp179", + "mp180", + "mp181", + "mp182", + "mp183", + "mp184", + "mp185", + "mp186", + "mp187", + "mp188", + "mp189", + "mp190", + "mp191", + "mp192", + "mp193", + "mp194", + "mp195", + "mp196", + "mp197", + "mp198", + "mp199", + "mp200", + "mp201", + "mp202", + "mp203", + "mp204", + "mp205", + "mp206", + "mp207", + "mp208", + "mp209", + "mp210", + "mp211", + "mp212", + "mp213", + "mp214", + "mp215", + "mp216", + "mp217", + "mp218", + "mp219", + "mp220", + "mp221", + "mp222", + "mp223", + "mp224", + "mp225", + "mp226", + "mp227", + "mp228", + "mp229", + "mp230", + "mp231", + "mp232", + "mp233", + "mp234", + "mp235", + "mp236", + "mp237", + "mp238", + "mp239", + "mp240", + "mp241", + "mp242", + "mp243", + "mp244", + "mp245", + "mp246", + "mp247", + "mp248", + "mp249", + "mp250", + "mp251", + "mp252", + "mp253", + "mp254", + "mp255" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "size" : { + "description" : "The new size. With the '+' sign the value is added to the actual size of the volume and without it, the value is taken as an absolute one. Shrinking disk size is not supported.", + "pattern" : "\\+?\\d+(\\.\\d+)?[KMGT]?", + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "the task ID.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/resize", + "text" : "resize" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Move a rootfs-/mp-volume to a different storage or to a different container.", + "method" : "POST", + "name" : "move_volume", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bwlimit" : { + "default" : "clone limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "delete" : { + "default" : 0, + "description" : "Delete the original volume after successful copy. By default the original is kept as an unused volume entry.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 \" .\n\t\t \"digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Target Storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target-digest" : { + "description" : "Prevent changes if current configuration file of the target \" .\n\t\t \"container has a different SHA1 digest. This can be used to prevent \" .\n\t\t \"concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target-vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "target-volume" : { + "description" : "The config key the volume will be moved to. Default is the source volume key.", + "enum" : [ + "rootfs", + "mp0", + "mp1", + "mp2", + "mp3", + "mp4", + "mp5", + "mp6", + "mp7", + "mp8", + "mp9", + "mp10", + "mp11", + "mp12", + "mp13", + "mp14", + "mp15", + "mp16", + "mp17", + "mp18", + "mp19", + "mp20", + "mp21", + "mp22", + "mp23", + "mp24", + "mp25", + "mp26", + "mp27", + "mp28", + "mp29", + "mp30", + "mp31", + "mp32", + "mp33", + "mp34", + "mp35", + "mp36", + "mp37", + "mp38", + "mp39", + "mp40", + "mp41", + "mp42", + "mp43", + "mp44", + "mp45", + "mp46", + "mp47", + "mp48", + "mp49", + "mp50", + "mp51", + "mp52", + "mp53", + "mp54", + "mp55", + "mp56", + "mp57", + "mp58", + "mp59", + "mp60", + "mp61", + "mp62", + "mp63", + "mp64", + "mp65", + "mp66", + "mp67", + "mp68", + "mp69", + "mp70", + "mp71", + "mp72", + "mp73", + "mp74", + "mp75", + "mp76", + "mp77", + "mp78", + "mp79", + "mp80", + "mp81", + "mp82", + "mp83", + "mp84", + "mp85", + "mp86", + "mp87", + "mp88", + "mp89", + "mp90", + "mp91", + "mp92", + "mp93", + "mp94", + "mp95", + "mp96", + "mp97", + "mp98", + "mp99", + "mp100", + "mp101", + "mp102", + "mp103", + "mp104", + "mp105", + "mp106", + "mp107", + "mp108", + "mp109", + "mp110", + "mp111", + "mp112", + "mp113", + "mp114", + "mp115", + "mp116", + "mp117", + "mp118", + "mp119", + "mp120", + "mp121", + "mp122", + "mp123", + "mp124", + "mp125", + "mp126", + "mp127", + "mp128", + "mp129", + "mp130", + "mp131", + "mp132", + "mp133", + "mp134", + "mp135", + "mp136", + "mp137", + "mp138", + "mp139", + "mp140", + "mp141", + "mp142", + "mp143", + "mp144", + "mp145", + "mp146", + "mp147", + "mp148", + "mp149", + "mp150", + "mp151", + "mp152", + "mp153", + "mp154", + "mp155", + "mp156", + "mp157", + "mp158", + "mp159", + "mp160", + "mp161", + "mp162", + "mp163", + "mp164", + "mp165", + "mp166", + "mp167", + "mp168", + "mp169", + "mp170", + "mp171", + "mp172", + "mp173", + "mp174", + "mp175", + "mp176", + "mp177", + "mp178", + "mp179", + "mp180", + "mp181", + "mp182", + "mp183", + "mp184", + "mp185", + "mp186", + "mp187", + "mp188", + "mp189", + "mp190", + "mp191", + "mp192", + "mp193", + "mp194", + "mp195", + "mp196", + "mp197", + "mp198", + "mp199", + "mp200", + "mp201", + "mp202", + "mp203", + "mp204", + "mp205", + "mp206", + "mp207", + "mp208", + "mp209", + "mp210", + "mp211", + "mp212", + "mp213", + "mp214", + "mp215", + "mp216", + "mp217", + "mp218", + "mp219", + "mp220", + "mp221", + "mp222", + "mp223", + "mp224", + "mp225", + "mp226", + "mp227", + "mp228", + "mp229", + "mp230", + "mp231", + "mp232", + "mp233", + "mp234", + "mp235", + "mp236", + "mp237", + "mp238", + "mp239", + "mp240", + "mp241", + "mp242", + "mp243", + "mp244", + "mp245", + "mp246", + "mp247", + "mp248", + "mp249", + "mp250", + "mp251", + "mp252", + "mp253", + "mp254", + "mp255", + "unused0", + "unused1", + "unused2", + "unused3", + "unused4", + "unused5", + "unused6", + "unused7", + "unused8", + "unused9", + "unused10", + "unused11", + "unused12", + "unused13", + "unused14", + "unused15", + "unused16", + "unused17", + "unused18", + "unused19", + "unused20", + "unused21", + "unused22", + "unused23", + "unused24", + "unused25", + "unused26", + "unused27", + "unused28", + "unused29", + "unused30", + "unused31", + "unused32", + "unused33", + "unused34", + "unused35", + "unused36", + "unused37", + "unused38", + "unused39", + "unused40", + "unused41", + "unused42", + "unused43", + "unused44", + "unused45", + "unused46", + "unused47", + "unused48", + "unused49", + "unused50", + "unused51", + "unused52", + "unused53", + "unused54", + "unused55", + "unused56", + "unused57", + "unused58", + "unused59", + "unused60", + "unused61", + "unused62", + "unused63", + "unused64", + "unused65", + "unused66", + "unused67", + "unused68", + "unused69", + "unused70", + "unused71", + "unused72", + "unused73", + "unused74", + "unused75", + "unused76", + "unused77", + "unused78", + "unused79", + "unused80", + "unused81", + "unused82", + "unused83", + "unused84", + "unused85", + "unused86", + "unused87", + "unused88", + "unused89", + "unused90", + "unused91", + "unused92", + "unused93", + "unused94", + "unused95", + "unused96", + "unused97", + "unused98", + "unused99", + "unused100", + "unused101", + "unused102", + "unused103", + "unused104", + "unused105", + "unused106", + "unused107", + "unused108", + "unused109", + "unused110", + "unused111", + "unused112", + "unused113", + "unused114", + "unused115", + "unused116", + "unused117", + "unused118", + "unused119", + "unused120", + "unused121", + "unused122", + "unused123", + "unused124", + "unused125", + "unused126", + "unused127", + "unused128", + "unused129", + "unused130", + "unused131", + "unused132", + "unused133", + "unused134", + "unused135", + "unused136", + "unused137", + "unused138", + "unused139", + "unused140", + "unused141", + "unused142", + "unused143", + "unused144", + "unused145", + "unused146", + "unused147", + "unused148", + "unused149", + "unused150", + "unused151", + "unused152", + "unused153", + "unused154", + "unused155", + "unused156", + "unused157", + "unused158", + "unused159", + "unused160", + "unused161", + "unused162", + "unused163", + "unused164", + "unused165", + "unused166", + "unused167", + "unused168", + "unused169", + "unused170", + "unused171", + "unused172", + "unused173", + "unused174", + "unused175", + "unused176", + "unused177", + "unused178", + "unused179", + "unused180", + "unused181", + "unused182", + "unused183", + "unused184", + "unused185", + "unused186", + "unused187", + "unused188", + "unused189", + "unused190", + "unused191", + "unused192", + "unused193", + "unused194", + "unused195", + "unused196", + "unused197", + "unused198", + "unused199", + "unused200", + "unused201", + "unused202", + "unused203", + "unused204", + "unused205", + "unused206", + "unused207", + "unused208", + "unused209", + "unused210", + "unused211", + "unused212", + "unused213", + "unused214", + "unused215", + "unused216", + "unused217", + "unused218", + "unused219", + "unused220", + "unused221", + "unused222", + "unused223", + "unused224", + "unused225", + "unused226", + "unused227", + "unused228", + "unused229", + "unused230", + "unused231", + "unused232", + "unused233", + "unused234", + "unused235", + "unused236", + "unused237", + "unused238", + "unused239", + "unused240", + "unused241", + "unused242", + "unused243", + "unused244", + "unused245", + "unused246", + "unused247", + "unused248", + "unused249", + "unused250", + "unused251", + "unused252", + "unused253", + "unused254", + "unused255" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "volume" : { + "description" : "Volume which will be moved.", + "enum" : [ + "rootfs", + "mp0", + "mp1", + "mp2", + "mp3", + "mp4", + "mp5", + "mp6", + "mp7", + "mp8", + "mp9", + "mp10", + "mp11", + "mp12", + "mp13", + "mp14", + "mp15", + "mp16", + "mp17", + "mp18", + "mp19", + "mp20", + "mp21", + "mp22", + "mp23", + "mp24", + "mp25", + "mp26", + "mp27", + "mp28", + "mp29", + "mp30", + "mp31", + "mp32", + "mp33", + "mp34", + "mp35", + "mp36", + "mp37", + "mp38", + "mp39", + "mp40", + "mp41", + "mp42", + "mp43", + "mp44", + "mp45", + "mp46", + "mp47", + "mp48", + "mp49", + "mp50", + "mp51", + "mp52", + "mp53", + "mp54", + "mp55", + "mp56", + "mp57", + "mp58", + "mp59", + "mp60", + "mp61", + "mp62", + "mp63", + "mp64", + "mp65", + "mp66", + "mp67", + "mp68", + "mp69", + "mp70", + "mp71", + "mp72", + "mp73", + "mp74", + "mp75", + "mp76", + "mp77", + "mp78", + "mp79", + "mp80", + "mp81", + "mp82", + "mp83", + "mp84", + "mp85", + "mp86", + "mp87", + "mp88", + "mp89", + "mp90", + "mp91", + "mp92", + "mp93", + "mp94", + "mp95", + "mp96", + "mp97", + "mp98", + "mp99", + "mp100", + "mp101", + "mp102", + "mp103", + "mp104", + "mp105", + "mp106", + "mp107", + "mp108", + "mp109", + "mp110", + "mp111", + "mp112", + "mp113", + "mp114", + "mp115", + "mp116", + "mp117", + "mp118", + "mp119", + "mp120", + "mp121", + "mp122", + "mp123", + "mp124", + "mp125", + "mp126", + "mp127", + "mp128", + "mp129", + "mp130", + "mp131", + "mp132", + "mp133", + "mp134", + "mp135", + "mp136", + "mp137", + "mp138", + "mp139", + "mp140", + "mp141", + "mp142", + "mp143", + "mp144", + "mp145", + "mp146", + "mp147", + "mp148", + "mp149", + "mp150", + "mp151", + "mp152", + "mp153", + "mp154", + "mp155", + "mp156", + "mp157", + "mp158", + "mp159", + "mp160", + "mp161", + "mp162", + "mp163", + "mp164", + "mp165", + "mp166", + "mp167", + "mp168", + "mp169", + "mp170", + "mp171", + "mp172", + "mp173", + "mp174", + "mp175", + "mp176", + "mp177", + "mp178", + "mp179", + "mp180", + "mp181", + "mp182", + "mp183", + "mp184", + "mp185", + "mp186", + "mp187", + "mp188", + "mp189", + "mp190", + "mp191", + "mp192", + "mp193", + "mp194", + "mp195", + "mp196", + "mp197", + "mp198", + "mp199", + "mp200", + "mp201", + "mp202", + "mp203", + "mp204", + "mp205", + "mp206", + "mp207", + "mp208", + "mp209", + "mp210", + "mp211", + "mp212", + "mp213", + "mp214", + "mp215", + "mp216", + "mp217", + "mp218", + "mp219", + "mp220", + "mp221", + "mp222", + "mp223", + "mp224", + "mp225", + "mp226", + "mp227", + "mp228", + "mp229", + "mp230", + "mp231", + "mp232", + "mp233", + "mp234", + "mp235", + "mp236", + "mp237", + "mp238", + "mp239", + "mp240", + "mp241", + "mp242", + "mp243", + "mp244", + "mp245", + "mp246", + "mp247", + "mp248", + "mp249", + "mp250", + "mp251", + "mp252", + "mp253", + "mp254", + "mp255", + "unused0", + "unused1", + "unused2", + "unused3", + "unused4", + "unused5", + "unused6", + "unused7", + "unused8", + "unused9", + "unused10", + "unused11", + "unused12", + "unused13", + "unused14", + "unused15", + "unused16", + "unused17", + "unused18", + "unused19", + "unused20", + "unused21", + "unused22", + "unused23", + "unused24", + "unused25", + "unused26", + "unused27", + "unused28", + "unused29", + "unused30", + "unused31", + "unused32", + "unused33", + "unused34", + "unused35", + "unused36", + "unused37", + "unused38", + "unused39", + "unused40", + "unused41", + "unused42", + "unused43", + "unused44", + "unused45", + "unused46", + "unused47", + "unused48", + "unused49", + "unused50", + "unused51", + "unused52", + "unused53", + "unused54", + "unused55", + "unused56", + "unused57", + "unused58", + "unused59", + "unused60", + "unused61", + "unused62", + "unused63", + "unused64", + "unused65", + "unused66", + "unused67", + "unused68", + "unused69", + "unused70", + "unused71", + "unused72", + "unused73", + "unused74", + "unused75", + "unused76", + "unused77", + "unused78", + "unused79", + "unused80", + "unused81", + "unused82", + "unused83", + "unused84", + "unused85", + "unused86", + "unused87", + "unused88", + "unused89", + "unused90", + "unused91", + "unused92", + "unused93", + "unused94", + "unused95", + "unused96", + "unused97", + "unused98", + "unused99", + "unused100", + "unused101", + "unused102", + "unused103", + "unused104", + "unused105", + "unused106", + "unused107", + "unused108", + "unused109", + "unused110", + "unused111", + "unused112", + "unused113", + "unused114", + "unused115", + "unused116", + "unused117", + "unused118", + "unused119", + "unused120", + "unused121", + "unused122", + "unused123", + "unused124", + "unused125", + "unused126", + "unused127", + "unused128", + "unused129", + "unused130", + "unused131", + "unused132", + "unused133", + "unused134", + "unused135", + "unused136", + "unused137", + "unused138", + "unused139", + "unused140", + "unused141", + "unused142", + "unused143", + "unused144", + "unused145", + "unused146", + "unused147", + "unused148", + "unused149", + "unused150", + "unused151", + "unused152", + "unused153", + "unused154", + "unused155", + "unused156", + "unused157", + "unused158", + "unused159", + "unused160", + "unused161", + "unused162", + "unused163", + "unused164", + "unused165", + "unused166", + "unused167", + "unused168", + "unused169", + "unused170", + "unused171", + "unused172", + "unused173", + "unused174", + "unused175", + "unused176", + "unused177", + "unused178", + "unused179", + "unused180", + "unused181", + "unused182", + "unused183", + "unused184", + "unused185", + "unused186", + "unused187", + "unused188", + "unused189", + "unused190", + "unused191", + "unused192", + "unused193", + "unused194", + "unused195", + "unused196", + "unused197", + "unused198", + "unused199", + "unused200", + "unused201", + "unused202", + "unused203", + "unused204", + "unused205", + "unused206", + "unused207", + "unused208", + "unused209", + "unused210", + "unused211", + "unused212", + "unused213", + "unused214", + "unused215", + "unused216", + "unused217", + "unused218", + "unused219", + "unused220", + "unused221", + "unused222", + "unused223", + "unused224", + "unused225", + "unused226", + "unused227", + "unused228", + "unused229", + "unused230", + "unused231", + "unused232", + "unused233", + "unused234", + "unused235", + "unused236", + "unused237", + "unused238", + "unused239", + "unused240", + "unused241", + "unused242", + "unused243", + "unused244", + "unused245", + "unused246", + "unused247", + "unused248", + "unused249", + "unused250", + "unused251", + "unused252", + "unused253", + "unused254", + "unused255" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ], + "description" : "You need 'VM.Config.Disk' permissions on /vms/{vmid}, and 'Datastore.AllocateSpace' permissions on the storage. To move a volume to another container, you need the permissions on the target container as well." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/move_volume", + "text" : "move_volume" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get container configuration, including pending changes.", + "method" : "GET", + "name" : "vm_pending", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "delete" : { + "description" : "Indicates a pending delete request if present and not 0.", + "maximum" : 2, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "key" : { + "description" : "Configuration option name.", + "type" : "string" + }, + "pending" : { + "description" : "Pending value.", + "optional" : 1, + "type" : "string" + }, + "value" : { + "description" : "Current value.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/pending", + "text" : "pending" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get IP addresses of the specified container interface.", + "method" : "GET", + "name" : "ip", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "hardware-address" : { + "description" : "The MAC address of the interface", + "optional" : 0, + "type" : "string" + }, + "hwaddr" : { + "description" : "The MAC address of the interface", + "optional" : 0, + "type" : "string" + }, + "inet" : { + "description" : "The IPv4 address of the interface", + "optional" : 1, + "type" : "string" + }, + "inet6" : { + "description" : "The IPv6 address of the interface", + "optional" : 1, + "type" : "string" + }, + "ip-addresses" : { + "description" : "The addresses of the interface", + "items" : { + "properties" : { + "ip-address" : { + "description" : "IP-Address", + "optional" : 1, + "type" : "string" + }, + "ip-address-type" : { + "description" : "IP-Family", + "optional" : 1, + "type" : "string" + }, + "prefix" : { + "description" : "IP-Prefix", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "optional" : 0, + "type" : "array" + }, + "name" : { + "description" : "The name of the interface", + "optional" : 0, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/interfaces", + "text" : "interfaces" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migration tunnel endpoint - only for internal use by CT migration.", + "method" : "POST", + "name" : "mtunnel", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "bridges" : { + "description" : "List of network bridges to check availability. Will be checked again for actually used bridges during migration.", + "format" : "pve-bridge-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storages" : { + "description" : "List of storages to check permission and availability. Will be checked again for all actually used storages during migration.", + "format" : "pve-storage-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + [ + "perm", + "/", + [ + "Sys.Incoming" + ] + ] + ], + "description" : "You need 'VM.Allocate' permissions on '/vms/{vmid}' and Sys.Incoming on '/'. Further permission checks happen during the actual migration." + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "socket" : { + "type" : "string" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/mtunnel", + "text" : "mtunnel" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration.", + "method" : "GET", + "name" : "mtunnelwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "socket" : { + "description" : "unix socket to forward to", + "type" : "string", + "typetext" : "" + }, + "ticket" : { + "description" : "ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "description" : "You need to pass a ticket valid for the selected socket. Tickets can be created via the mtunnel API call, which will check permissions accordingly.", + "user" : "all" + }, + "returns" : { + "properties" : { + "port" : { + "optional" : 1, + "type" : "string" + }, + "socket" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/lxc/{vmid}/mtunnelwebsocket", + "text" : "mtunnelwebsocket" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy the container (also delete all uses files).", + "method" : "DELETE", + "name" : "destroy_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "destroy-unreferenced-disks" : { + "description" : "If set, destroy additionally all disks with the VMID from all enabled storages which are not referenced in the config.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "force" : { + "default" : 0, + "description" : "Force destroy, even if running.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "purge" : { + "default" : 0, + "description" : "Remove container from all related configurations. For example, backup jobs, replication jobs or HA. Related ACLs and Firewall entries will *always* be removed.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "vmdiridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc/{vmid}", + "text" : "{vmid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "LXC container index (per node).", + "method" : "GET", + "name" : "vmlist", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list CTs where you have VM.Audit permission on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "cpu" : { + "description" : "Current CPU usage.", + "optional" : 1, + "type" : "number" + }, + "cpus" : { + "description" : "Maximum usable CPUs.", + "optional" : 1, + "type" : "number" + }, + "disk" : { + "description" : "Root disk image space-usage in bytes.", + "minimum" : 0, + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "diskread" : { + "description" : "The amount of bytes the guest read from it's block devices since the guest was started. (Note: This info is not available for all storage types.)", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "diskwrite" : { + "description" : "The amount of bytes the guest wrote from it's block devices since the guest was started. (Note: This info is not available for all storage types.)", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "lock" : { + "description" : "The current config lock, if any.", + "optional" : 1, + "type" : "string" + }, + "maxdisk" : { + "description" : "Root disk image size in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxmem" : { + "description" : "Maximum memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "maxswap" : { + "description" : "Maximum SWAP memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "mem" : { + "description" : "Currently used memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "name" : { + "description" : "Container name.", + "optional" : 1, + "type" : "string" + }, + "netin" : { + "description" : "The amount of traffic in bytes that was sent to the guest over the network since it was started.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "netout" : { + "description" : "The amount of traffic in bytes that was sent from the guest over the network since it was started.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "status" : { + "description" : "LXC Container status.", + "enum" : [ + "stopped", + "running" + ], + "type" : "string" + }, + "tags" : { + "description" : "The current configured tags, if any.", + "optional" : 1, + "type" : "string" + }, + "template" : { + "default" : 0, + "description" : "Determines if the guest is a template.", + "optional" : 1, + "type" : "boolean" + }, + "uptime" : { + "description" : "Uptime in seconds.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{vmid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create or restore a container.", + "method" : "POST", + "name" : "create_vm", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "arch" : { + "default" : "amd64", + "description" : "OS architecture type.", + "enum" : [ + "amd64", + "i386", + "arm64", + "armhf", + "riscv32", + "riscv64" + ], + "optional" : 1, + "type" : "string" + }, + "bwlimit" : { + "default" : "restore limit from datacenter or storage config", + "description" : "Override I/O bandwidth limit (in KiB/s).", + "minimum" : "0", + "optional" : 1, + "type" : "number", + "typetext" : " (0 - N)" + }, + "cmode" : { + "default" : "tty", + "description" : "Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).", + "enum" : [ + "shell", + "console", + "tty" + ], + "optional" : 1, + "type" : "string" + }, + "console" : { + "default" : 1, + "description" : "Attach a console device (/dev/console) to the container.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cores" : { + "description" : "The number of cores assigned to the container. A container can use all available cores by default.", + "maximum" : 8192, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 8192)" + }, + "cpulimit" : { + "default" : 0, + "description" : "Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.", + "maximum" : 8192, + "minimum" : 0, + "optional" : 1, + "type" : "number", + "typetext" : " (0 - 8192)" + }, + "cpuunits" : { + "default" : "cgroup v1: 1024, cgroup v2: 100", + "description" : "CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.", + "maximum" : 500000, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 500000)", + "verbose_description" : "CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests." + }, + "debug" : { + "default" : 0, + "description" : "Try to be more verbose. For now this only enables debug log-level on start.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "description" : { + "description" : "Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.", + "maxLength" : 8192, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dev[n]" : { + "description" : "Device to pass through to the container", + "format" : { + "deny-write" : { + "default" : 0, + "description" : "Deny the container to write to the device", + "optional" : 1, + "type" : "boolean" + }, + "gid" : { + "description" : "Group ID to be assigned to the device node", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "mode" : { + "description" : "Access mode to be set on the device node", + "format_description" : "Octal access mode", + "optional" : 1, + "pattern" : "0[0-7]{3}", + "type" : "string" + }, + "path" : { + "default_key" : 1, + "description" : "Device to pass through to the container", + "format" : "pve-lxc-dev-string", + "format_description" : "Path", + "optional" : 1, + "type" : "string", + "verbose_description" : "Path to the device to pass through to the container" + }, + "uid" : { + "description" : "User ID to be assigned to the device node", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[[path=]] [,deny-write=<1|0>] [,gid=] [,mode=] [,uid=]" + }, + "features" : { + "description" : "Allow containers access to advanced features.", + "format" : { + "force_rw_sys" : { + "default" : 0, + "description" : "Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.", + "optional" : 1, + "type" : "boolean" + }, + "fuse" : { + "default" : 0, + "description" : "Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.", + "optional" : 1, + "type" : "boolean" + }, + "keyctl" : { + "default" : 0, + "description" : "For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.", + "optional" : 1, + "type" : "boolean" + }, + "mknod" : { + "default" : 0, + "description" : "Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.", + "optional" : 1, + "type" : "boolean" + }, + "mount" : { + "description" : "Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.", + "format_description" : "fstype;fstype;...", + "optional" : 1, + "pattern" : "(?^:[a-zA-Z0-9_; ]+)", + "type" : "string" + }, + "nesting" : { + "default" : 0, + "description" : "Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.", + "optional" : 1, + "type" : "boolean" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[force_rw_sys=<1|0>] [,fuse=<1|0>] [,keyctl=<1|0>] [,mknod=<1|0>] [,mount=] [,nesting=<1|0>]" + }, + "force" : { + "description" : "Allow to overwrite existing container.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "hookscript" : { + "description" : "Script that will be executed during various steps in the containers lifetime.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "hostname" : { + "description" : "Set a host name for the container.", + "format" : "dns-name", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ignore-unpack-errors" : { + "description" : "Ignore errors when extracting the template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lock" : { + "description" : "Lock/unlock the container.", + "enum" : [ + "backup", + "create", + "destroyed", + "disk", + "fstrim", + "migrate", + "mounted", + "rollback", + "snapshot", + "snapshot-delete" + ], + "optional" : 1, + "type" : "string" + }, + "memory" : { + "default" : 512, + "description" : "Amount of RAM for the container in MB.", + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - N)" + }, + "mp[n]" : { + "description" : "Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "backup" : { + "description" : "Whether to include the mount point in backups.", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Whether to include the mount point in backups (only used for volume mount points)." + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)", + "type" : "string" + }, + "mp" : { + "description" : "Path to the mount point as seen from inside the container (must not contain symlinks).", + "format" : "pve-lxc-mp-string", + "format_description" : "Path", + "type" : "string", + "verbose_description" : "Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons." + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=] ,mp= [,acl=<1|0>] [,backup=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]" + }, + "nameserver" : { + "description" : "Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "lxc-ip-with-ll-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "net[n]" : { + "description" : "Specifies network interfaces for the container.", + "format" : { + "bridge" : { + "description" : "Bridge to attach the network device to.", + "format_description" : "bridge", + "optional" : 1, + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "firewall" : { + "description" : "Controls whether this interface's firewall rules should be used.", + "optional" : 1, + "type" : "boolean" + }, + "gw" : { + "description" : "Default gateway for IPv4 traffic.", + "format" : "ipv4", + "format_description" : "GatewayIPv4", + "optional" : 1, + "type" : "string" + }, + "gw6" : { + "description" : "Default gateway for IPv6 traffic.", + "format" : "ipv6", + "format_description" : "GatewayIPv6", + "optional" : 1, + "type" : "string" + }, + "hwaddr" : { + "description" : "The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)", + "format" : "mac-addr", + "format_description" : "XX:XX:XX:XX:XX:XX", + "optional" : 1, + "type" : "string", + "verbose_description" : "A common MAC address with the I/G (Individual/Group) bit not set." + }, + "ip" : { + "description" : "IPv4 address in CIDR format.", + "format" : "pve-ipv4-config", + "format_description" : "(IPv4/CIDR|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "ip6" : { + "description" : "IPv6 address in CIDR format.", + "format" : "pve-ipv6-config", + "format_description" : "(IPv6/CIDR|auto|dhcp|manual)", + "optional" : 1, + "type" : "string" + }, + "link_down" : { + "description" : "Whether this interface should be disconnected (like pulling the plug).", + "optional" : 1, + "type" : "boolean" + }, + "mtu" : { + "description" : "Maximum transfer unit of the interface. (lxc.network.mtu)", + "maximum" : 65535, + "minimum" : 64, + "optional" : 1, + "type" : "integer" + }, + "name" : { + "description" : "Name of the network device as seen from inside the container. (lxc.network.name)", + "format_description" : "string", + "pattern" : "[-_.\\w\\d]+", + "type" : "string" + }, + "rate" : { + "description" : "Apply rate limiting to the interface", + "format_description" : "mbps", + "optional" : 1, + "type" : "number" + }, + "tag" : { + "description" : "VLAN tag for this interface.", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "trunks" : { + "description" : "VLAN ids to pass through the interface", + "format_description" : "vlanid[;vlanid...]", + "optional" : 1, + "pattern" : "(?^:\\d+(?:;\\d+)*)", + "type" : "string" + }, + "type" : { + "description" : "Network interface type.", + "enum" : [ + "veth" + ], + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "name= [,bridge=] [,firewall=<1|0>] [,gw=] [,gw6=] [,hwaddr=] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=<(IPv6/CIDR|auto|dhcp|manual)>] [,link_down=<1|0>] [,mtu=] [,rate=] [,tag=] [,trunks=] [,type=]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "onboot" : { + "default" : 0, + "description" : "Specifies whether a container will be started during system bootup.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ostemplate" : { + "description" : "The OS template or backup file.", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + }, + "ostype" : { + "description" : "OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.", + "enum" : [ + "debian", + "devuan", + "ubuntu", + "centos", + "fedora", + "opensuse", + "archlinux", + "alpine", + "gentoo", + "nixos", + "unmanaged" + ], + "optional" : 1, + "type" : "string" + }, + "password" : { + "description" : "Sets root password inside container.", + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Add the VM to the specified pool.", + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protection" : { + "default" : 0, + "description" : "Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "restore" : { + "description" : "Mark this as restore task.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "rootfs" : { + "description" : "Use volume as container root.", + "format" : { + "acl" : { + "description" : "Explicitly enable or disable ACL support.", + "optional" : 1, + "type" : "boolean" + }, + "mountoptions" : { + "description" : "Extra mount options for rootfs/mps.", + "format_description" : "opt[;opt...]", + "optional" : 1, + "pattern" : "(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)", + "type" : "string" + }, + "quota" : { + "description" : "Enable user quotas inside the container (not supported with zfs subvolumes)", + "optional" : 1, + "type" : "boolean" + }, + "replicate" : { + "default" : 1, + "description" : "Will include this volume to a storage replica job.", + "optional" : 1, + "type" : "boolean" + }, + "ro" : { + "description" : "Read-only mount point", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "default" : 0, + "description" : "Mark this non-volume mount point as available on multiple nodes (see 'nodes')", + "optional" : 1, + "type" : "boolean", + "verbose_description" : "Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!" + }, + "size" : { + "description" : "Volume size (read only value).", + "format" : "disk-size", + "format_description" : "DiskSize", + "optional" : 1, + "type" : "string" + }, + "volume" : { + "default_key" : 1, + "description" : "Volume, device or directory to mount into the container.", + "format" : "pve-lxc-mp-string", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=] [,acl=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]" + }, + "searchdomain" : { + "description" : "Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.", + "format" : "dns-name-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ssh-public-keys" : { + "description" : "Setup public SSH keys (one key per line, OpenSSH format).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Start the CT after its creation finished successfully.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "startup" : { + "description" : "Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.", + "format" : "pve-startup-order", + "optional" : 1, + "type" : "string", + "typetext" : "[[order=]\\d+] [,up=\\d+] [,down=\\d+] " + }, + "storage" : { + "default" : "local", + "description" : "Default Storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "swap" : { + "default" : 512, + "description" : "Amount of SWAP for the container in MB.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "tags" : { + "description" : "Tags of the Container. This is only meta information.", + "format" : "pve-tag-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "template" : { + "default" : 0, + "description" : "Enable/disable Template.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "timezone" : { + "description" : "Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab", + "format" : "pve-ct-timezone", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tty" : { + "default" : 2, + "description" : "Specify the number of tty available to the container", + "maximum" : 6, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 6)" + }, + "unique" : { + "description" : "Assign a unique random ethernet address.", + "optional" : 1, + "requires" : "restore", + "type" : "boolean", + "typetext" : "" + }, + "unprivileged" : { + "default" : 0, + "description" : "Makes the container run as unprivileged user. (Should not be modified manually.)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "unused[n]" : { + "description" : "Reference to unused volumes. This is used internally, and should not be modified manually.", + "format" : { + "volume" : { + "default_key" : 1, + "description" : "The volume that is not used currently.", + "format" : "pve-volume-id", + "format_description" : "volume", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[volume=]" + }, + "vmid" : { + "description" : "The (unique) ID of the VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "description" : "You need 'VM.Allocate' permission on /vms/{vmid} or on the VM pool /pool/{pool}. For restore, it is enough if the user has 'VM.Backup' permission and the VM already exists. You also need 'Datastore.AllocateSpace' permissions on the storage.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/lxc", + "text" : "lxc" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the Ceph configuration file.", + "method" : "GET", + "name" : "raw", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/cfg/raw", + "text" : "raw" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the Ceph configuration database.", + "method" : "GET", + "name" : "db", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "can_update_at_runtime" : { + "type" : "boolean" + }, + "level" : { + "type" : "string" + }, + "mask" : { + "type" : "string" + }, + "name" : { + "type" : "string" + }, + "section" : { + "type" : "string" + }, + "value" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/cfg/db", + "text" : "db" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get configured values from either the config file or config DB.", + "method" : "GET", + "name" : "value", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "config-keys" : { + "description" : "List of
: items.", + "pattern" : "(?^:^(:?(?^i:[0-9a-z\\-_\\.]+:[0-9a-zA-Z\\-_]+))(:?[;, ](?^i:[0-9a-z\\-_\\.]+:[0-9a-zA-Z\\-_]+))*$)", + "type" : "string", + "typetext" : "
:[;
:]" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Contains {section}->{key} children with the values", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/cfg/value", + "text" : "value" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/cfg", + "text" : "cfg" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get OSD details", + "method" : "GET", + "name" : "osddetails", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "devices" : { + "description" : "Array containing data about devices", + "items" : { + "properties" : { + "dev_node" : { + "description" : "Device node", + "type" : "string" + }, + "device" : { + "description" : "Kind of OSD device", + "enum" : [ + "block", + "db", + "wal" + ], + "type" : "string" + }, + "devices" : { + "description" : "Physical disks used", + "type" : "string" + }, + "size" : { + "description" : "Size in bytes", + "type" : "integer" + }, + "support_discard" : { + "description" : "Discard support of the physical device", + "type" : "boolean" + }, + "type" : { + "description" : "Type of device. For example, hdd or ssd", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "osd" : { + "description" : "General information about the OSD", + "properties" : { + "back_addr" : { + "description" : "Address and port used to talk to other OSDs.", + "type" : "string" + }, + "front_addr" : { + "description" : "Address and port used to talk to clients and monitors.", + "type" : "string" + }, + "hb_back_addr" : { + "description" : "Heartbeat address and port for other OSDs.", + "type" : "string" + }, + "hb_front_addr" : { + "description" : "Heartbeat address and port for clients and monitors.", + "type" : "string" + }, + "hostname" : { + "description" : "Name of the host containing the OSD.", + "type" : "string" + }, + "id" : { + "description" : "ID of the OSD.", + "type" : "integer" + }, + "mem_usage" : { + "description" : "Memory usage of the OSD service.", + "type" : "integer" + }, + "osd_data" : { + "description" : "Path to the OSD's data directory.", + "type" : "string" + }, + "osd_objectstore" : { + "description" : "The type of object store used.", + "type" : "string" + }, + "pid" : { + "description" : "OSD process ID.", + "type" : "integer" + }, + "version" : { + "description" : "Ceph version of the OSD service.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/metadata", + "text" : "metadata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get OSD volume details", + "method" : "GET", + "name" : "osdvolume", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + }, + "type" : { + "default" : "block", + "description" : "OSD device type", + "enum" : [ + "block", + "db", + "wal" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "creation_time" : { + "description" : "Creation time as reported by `lvs`.", + "type" : "string" + }, + "lv_name" : { + "description" : "Name of the logical volume (LV).", + "type" : "string" + }, + "lv_path" : { + "description" : "Path to the logical volume (LV).", + "type" : "string" + }, + "lv_size" : { + "description" : "Size of the logical volume (LV).", + "type" : "integer" + }, + "lv_uuid" : { + "description" : "UUID of the logical volume (LV).", + "type" : "string" + }, + "vg_name" : { + "description" : "Name of the volume group (VG).", + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/lv-info", + "text" : "lv-info" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "ceph osd in", + "method" : "POST", + "name" : "in", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/in", + "text" : "in" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "ceph osd out", + "method" : "POST", + "name" : "out", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/out", + "text" : "out" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Instruct the OSD to scrub.", + "method" : "POST", + "name" : "scrub", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "deep" : { + "default" : 0, + "description" : "If set, instructs a deep scrub instead of a normal one.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/osd/{osdid}/scrub", + "text" : "scrub" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy OSD", + "method" : "DELETE", + "name" : "destroyosd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cleanup" : { + "default" : 0, + "description" : "If set, we remove partition table entries.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "OSD index.", + "method" : "GET", + "name" : "osdindex", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osdid" : { + "description" : "OSD ID", + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/osd/{osdid}", + "text" : "{osdid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Ceph osd list/tree.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "flags" : { + "type" : "string" + }, + "root" : { + "description" : "Tree with OSDs in the CRUSH map structure.", + "type" : "object" + } + }, + "type" : "object" + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create OSD", + "method" : "POST", + "name" : "createosd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "crush-device-class" : { + "description" : "Set the device class of the OSD in crush.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "db_dev" : { + "description" : "Block device name for block.db.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "db_dev_size" : { + "default" : "bluestore_block_db_size or 10% of OSD size", + "description" : "Size in GiB for block.db.", + "minimum" : 1, + "optional" : 1, + "requires" : "db_dev", + "type" : "number", + "typetext" : " (1 - N)", + "verbose_description" : "If a block.db is requested but the size is not given, will be automatically selected by: bluestore_block_db_size from the ceph database (osd or global section) or config (osd or global section) in that order. If this is not available, it will be sized 10% of the size of the OSD device. Fails if the available size is not enough." + }, + "dev" : { + "description" : "Block device name.", + "type" : "string", + "typetext" : "" + }, + "encrypted" : { + "default" : 0, + "description" : "Enables encryption of the OSD.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "osds-per-device" : { + "description" : "OSD services per physical device. Only useful for fast NVMe devices\"\n\t\t .\" to utilize their performance better.", + "minimum" : "1", + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "wal_dev" : { + "description" : "Block device name for block.wal.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "wal_dev_size" : { + "default" : "bluestore_block_wal_size or 1% of OSD size", + "description" : "Size in GiB for block.wal.", + "minimum" : 0.5, + "optional" : 1, + "requires" : "wal_dev", + "type" : "number", + "typetext" : " (0.5 - N)", + "verbose_description" : "If a block.wal is requested but the size is not given, will be automatically selected by: bluestore_block_wal_size from the ceph database (osd or global section) or config (osd or global section) in that order. If this is not available, it will be sized 1% of the size of the OSD device. Fails if the available size is not enough." + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/osd", + "text" : "osd" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy Ceph Metadata Server", + "method" : "DELETE", + "name" : "destroymds", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The name (ID) of the mds", + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Ceph Metadata Server (MDS)", + "method" : "POST", + "name" : "createmds", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "hotstandby" : { + "default" : "0", + "description" : "Determines whether a ceph-mds daemon should poll and replay the log of an active MDS. Faster switch on MDS failure, but needs more idle resources.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "default" : "nodename", + "description" : "The ID for the mds, when omitted the same as the nodename", + "maxLength" : 200, + "optional" : 1, + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/mds/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "MDS directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "addr" : { + "optional" : 1, + "type" : "string" + }, + "host" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name (ID) for the MDS" + }, + "rank" : { + "optional" : 1, + "type" : "integer" + }, + "standby_replay" : { + "description" : "If true, the standby MDS is polling the active MDS for faster recovery (hot standby).", + "optional" : 1, + "type" : "boolean" + }, + "state" : { + "description" : "State of the MDS", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/mds", + "text" : "mds" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy Ceph Manager.", + "method" : "DELETE", + "name" : "destroymgr", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The ID of the manager", + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Ceph Manager", + "method" : "POST", + "name" : "createmgr", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "The ID for the manager, when omitted the same as the nodename", + "maxLength" : 200, + "optional" : 1, + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/mgr/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "MGR directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "addr" : { + "optional" : 1, + "type" : "string" + }, + "host" : { + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The name (ID) for the MGR" + }, + "state" : { + "description" : "State of the MGR", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/mgr", + "text" : "mgr" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy Ceph Monitor and Manager.", + "method" : "DELETE", + "name" : "destroymon", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "monid" : { + "description" : "Monitor ID", + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Ceph Monitor and Manager", + "method" : "POST", + "name" : "createmon", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "mon-address" : { + "description" : "Overwrites autodetected monitor IP address(es). Must be in the public network(s) of Ceph.", + "format" : "ip-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "monid" : { + "description" : "The ID for the monitor, when omitted the same as the nodename", + "maxLength" : 200, + "optional" : 1, + "pattern" : "[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/mon/{monid}", + "text" : "{monid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Ceph monitor list.", + "method" : "GET", + "name" : "listmon", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "addr" : { + "optional" : 1, + "type" : "string" + }, + "ceph_version" : { + "optional" : 1, + "type" : "string" + }, + "ceph_version_short" : { + "optional" : 1, + "type" : "string" + }, + "direxists" : { + "optional" : 1, + "type" : "string" + }, + "host" : { + "optional" : 1, + "type" : "boolean" + }, + "name" : { + "type" : "string" + }, + "quorum" : { + "optional" : 1, + "type" : "boolean" + }, + "rank" : { + "optional" : 1, + "type" : "integer" + }, + "service" : { + "optional" : 1, + "type" : "integer" + }, + "state" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/mon", + "text" : "mon" + }, + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create a Ceph filesystem", + "method" : "POST", + "name" : "createfs", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add-storage" : { + "default" : 0, + "description" : "Configure the created CephFS as storage for this cluster.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "default" : "cephfs", + "description" : "The ceph filesystem name.", + "optional" : 1, + "pattern" : "(?^:^[^:/\\s]+$)", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_num" : { + "default" : 128, + "description" : "Number of placement groups for the backing data pool. The metadata pool will use a quarter of this.", + "maximum" : 32768, + "minimum" : 8, + "optional" : 1, + "type" : "integer", + "typetext" : " (8 - 32768)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/fs/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "data_pool" : { + "description" : "The name of the data pool.", + "type" : "string" + }, + "metadata_pool" : { + "description" : "The name of the metadata pool.", + "type" : "string" + }, + "name" : { + "description" : "The ceph filesystem name.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/fs", + "text" : "fs" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Show the current pool status.", + "method" : "GET", + "name" : "getpool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The name of the pool. It must be unique.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "verbose" : { + "default" : 0, + "description" : "If enabled, will display additional data(eg. statistics).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "application" : { + "default" : "rbd", + "description" : "The application of the pool.", + "enum" : [ + "rbd", + "cephfs", + "rgw" + ], + "optional" : 1, + "title" : "Application", + "type" : "string" + }, + "application_list" : { + "optional" : 1, + "title" : "Application", + "type" : "array" + }, + "autoscale_status" : { + "optional" : 1, + "title" : "Autoscale Status", + "type" : "object" + }, + "crush_rule" : { + "description" : "The rule to use for mapping object placement in the cluster.", + "optional" : 1, + "title" : "Crush Rule Name", + "type" : "string" + }, + "fast_read" : { + "title" : "Fast Read", + "type" : "boolean" + }, + "hashpspool" : { + "title" : "hashpspool", + "type" : "boolean" + }, + "id" : { + "title" : "ID", + "type" : "integer" + }, + "min_size" : { + "default" : 2, + "description" : "Minimum number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Min Size", + "type" : "integer" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "pattern" : "(?^:^[^:/\\s]+$)", + "title" : "Name", + "type" : "string" + }, + "nodeep-scrub" : { + "title" : "nodeep-scrub", + "type" : "boolean" + }, + "nodelete" : { + "title" : "nodelete", + "type" : "boolean" + }, + "nopgchange" : { + "title" : "nopgchange", + "type" : "boolean" + }, + "noscrub" : { + "title" : "noscrub", + "type" : "boolean" + }, + "nosizechange" : { + "title" : "nosizechange", + "type" : "boolean" + }, + "pg_autoscale_mode" : { + "default" : "warn", + "description" : "The automatic PG scaling mode of the pool.", + "enum" : [ + "on", + "off", + "warn" + ], + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "default" : 128, + "description" : "Number of placement groups.", + "maximum" : 32768, + "minimum" : 1, + "optional" : 1, + "title" : "PG Num", + "type" : "integer" + }, + "pg_num_min" : { + "description" : "Minimal number of placement groups.", + "maximum" : 32768, + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer" + }, + "pgp_num" : { + "title" : "PGP num", + "type" : "integer" + }, + "size" : { + "default" : 3, + "description" : "Number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Size", + "type" : "integer" + }, + "statistics" : { + "optional" : 1, + "title" : "Statistics", + "type" : "object" + }, + "target_size" : { + "description" : "The estimated target size of the pool for the PG autoscaler.", + "optional" : 1, + "pattern" : "^(\\d+(\\.\\d+)?)([KMGT])?$", + "title" : "PG Autoscale Target Size", + "type" : "string" + }, + "target_size_ratio" : { + "description" : "The estimated target ratio of the pool for the PG autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number" + }, + "use_gmt_hitset" : { + "title" : "use_gmt_hitset", + "type" : "boolean" + }, + "write_fadvise_dontneed" : { + "title" : "write_fadvise_dontneed", + "type" : "boolean" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/pool/{name}/status", + "text" : "status" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy pool", + "method" : "DELETE", + "name" : "destroypool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "If true, destroys pool even if in use", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "remove_ecprofile" : { + "default" : 1, + "description" : "Remove the erasure code profile. Defaults to true, if applicable.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove_storages" : { + "default" : 0, + "description" : "Remove all pveceph-managed storages configured for this pool", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Pool index.", + "method" : "GET", + "name" : "poolindex", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The name of the pool.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Change POOL settings", + "method" : "PUT", + "name" : "setpool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "application" : { + "description" : "The application of the pool.", + "enum" : [ + "rbd", + "cephfs", + "rgw" + ], + "optional" : 1, + "title" : "Application", + "type" : "string" + }, + "crush_rule" : { + "description" : "The rule to use for mapping object placement in the cluster.", + "optional" : 1, + "title" : "Crush Rule Name", + "type" : "string", + "typetext" : "" + }, + "min_size" : { + "description" : "Minimum number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Min Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "pattern" : "(?^:^[^:/\\s]+$)", + "title" : "Name", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_autoscale_mode" : { + "description" : "The automatic PG scaling mode of the pool.", + "enum" : [ + "on", + "off", + "warn" + ], + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "description" : "Number of placement groups.", + "maximum" : 32768, + "minimum" : 1, + "optional" : 1, + "title" : "PG Num", + "type" : "integer", + "typetext" : " (1 - 32768)" + }, + "pg_num_min" : { + "description" : "Minimal number of placement groups.", + "maximum" : 32768, + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer", + "typetext" : " (-N - 32768)" + }, + "size" : { + "description" : "Number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "target_size" : { + "description" : "The estimated target size of the pool for the PG autoscaler.", + "optional" : 1, + "pattern" : "^(\\d+(\\.\\d+)?)([KMGT])?$", + "title" : "PG Autoscale Target Size", + "type" : "string" + }, + "target_size_ratio" : { + "description" : "The estimated target ratio of the pool for the PG autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/pool/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all pools and their settings (which are settable by the POST/PUT endpoints).", + "method" : "GET", + "name" : "lspools", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "application_metadata" : { + "optional" : 1, + "title" : "Associated Applications", + "type" : "object" + }, + "autoscale_status" : { + "optional" : 1, + "title" : "Autoscale Status", + "type" : "object" + }, + "bytes_used" : { + "title" : "Used", + "type" : "integer" + }, + "crush_rule" : { + "title" : "Crush Rule", + "type" : "integer" + }, + "crush_rule_name" : { + "title" : "Crush Rule Name", + "type" : "string" + }, + "min_size" : { + "title" : "Min Size", + "type" : "integer" + }, + "percent_used" : { + "title" : "%-Used", + "type" : "number" + }, + "pg_autoscale_mode" : { + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "title" : "PG Num", + "type" : "integer" + }, + "pg_num_final" : { + "optional" : 1, + "title" : "Optimal PG Num", + "type" : "integer" + }, + "pg_num_min" : { + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer" + }, + "pool" : { + "title" : "ID", + "type" : "integer" + }, + "pool_name" : { + "title" : "Name", + "type" : "string" + }, + "size" : { + "title" : "Size", + "type" : "integer" + }, + "target_size" : { + "optional" : 1, + "title" : "PG Autoscale Target Size", + "type" : "integer" + }, + "target_size_ratio" : { + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number" + }, + "type" : { + "enum" : [ + "replicated", + "erasure", + "unknown" + ], + "title" : "Type", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pool_name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create Ceph pool", + "method" : "POST", + "name" : "createpool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storages" : { + "default" : "0; for erasure coded pools: 1", + "description" : "Configure VM and CT storage using the new pool.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "application" : { + "default" : "rbd", + "description" : "The application of the pool.", + "enum" : [ + "rbd", + "cephfs", + "rgw" + ], + "optional" : 1, + "title" : "Application", + "type" : "string" + }, + "crush_rule" : { + "description" : "The rule to use for mapping object placement in the cluster.", + "optional" : 1, + "title" : "Crush Rule Name", + "type" : "string", + "typetext" : "" + }, + "erasure-coding" : { + "description" : "Create an erasure coded pool for RBD with an accompaning replicated pool for metadata storage. With EC, the common ceph options 'size', 'min_size' and 'crush_rule' parameters will be applied to the metadata pool.", + "format" : { + "device-class" : { + "description" : "CRUSH device class. Will create an erasure coded pool plus a replicated pool for metadata.", + "format_description" : "class", + "optional" : 1, + "type" : "string" + }, + "failure-domain" : { + "default" : "host", + "description" : "CRUSH failure domain. Default is 'host'. Will create an erasure coded pool plus a replicated pool for metadata.", + "format_description" : "domain", + "optional" : 1, + "type" : "string" + }, + "k" : { + "description" : "Number of data chunks. Will create an erasure coded pool plus a replicated pool for metadata.", + "minimum" : 2, + "type" : "integer" + }, + "m" : { + "description" : "Number of coding chunks. Will create an erasure coded pool plus a replicated pool for metadata.", + "minimum" : 1, + "type" : "integer" + }, + "profile" : { + "description" : "Override the erasure code (EC) profile to use. Will create an erasure coded pool plus a replicated pool for metadata.", + "format_description" : "profile", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "k= ,m= [,device-class=] [,failure-domain=] [,profile=]" + }, + "min_size" : { + "default" : 2, + "description" : "Minimum number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Min Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "name" : { + "description" : "The name of the pool. It must be unique.", + "pattern" : "(?^:^[^:/\\s]+$)", + "title" : "Name", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_autoscale_mode" : { + "default" : "warn", + "description" : "The automatic PG scaling mode of the pool.", + "enum" : [ + "on", + "off", + "warn" + ], + "optional" : 1, + "title" : "PG Autoscale Mode", + "type" : "string" + }, + "pg_num" : { + "default" : 128, + "description" : "Number of placement groups.", + "maximum" : 32768, + "minimum" : 1, + "optional" : 1, + "title" : "PG Num", + "type" : "integer", + "typetext" : " (1 - 32768)" + }, + "pg_num_min" : { + "description" : "Minimal number of placement groups.", + "maximum" : 32768, + "optional" : 1, + "title" : "min. PG Num", + "type" : "integer", + "typetext" : " (-N - 32768)" + }, + "size" : { + "default" : 3, + "description" : "Number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "title" : "Size", + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "target_size" : { + "description" : "The estimated target size of the pool for the PG autoscaler.", + "optional" : 1, + "pattern" : "^(\\d+(\\.\\d+)?)([KMGT])?$", + "title" : "PG Autoscale Target Size", + "type" : "string" + }, + "target_size_ratio" : { + "description" : "The estimated target ratio of the pool for the PG autoscaler.", + "optional" : 1, + "title" : "PG Autoscale Target Ratio", + "type" : "number", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph/pool", + "text" : "pool" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create initial ceph default configuration and setup symlinks.", + "method" : "POST", + "name" : "init", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cluster-network" : { + "description" : "Declare a separate cluster network, OSDs will routeheartbeat, object replication and recovery traffic over it", + "format" : "CIDR", + "maxLength" : 128, + "optional" : 1, + "requires" : "network", + "type" : "string", + "typetext" : "" + }, + "disable_cephx" : { + "default" : 0, + "description" : "Disable cephx authentication.\n\nWARNING: cephx is a security feature protecting against man-in-the-middle attacks. Only consider disabling cephx if your network is private!", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "min_size" : { + "default" : 2, + "description" : "Minimum number of available replicas per object to allow I/O", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 7)" + }, + "network" : { + "description" : "Use specific network for all ceph related traffic", + "format" : "CIDR", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pg_bits" : { + "default" : 6, + "description" : "Placement group bits, used to specify the default number of placement groups.\n\nDepreacted. This setting was deprecated in recent Ceph versions.", + "maximum" : 14, + "minimum" : 6, + "optional" : 1, + "type" : "integer", + "typetext" : " (6 - 14)" + }, + "size" : { + "default" : 3, + "description" : "Targeted number of replicas per object", + "maximum" : 7, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 7)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/init", + "text" : "init" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop ceph services.", + "method" : "POST", + "name" : "stop", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "default" : "ceph.target", + "description" : "Ceph service name.", + "optional" : 1, + "pattern" : "(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/stop", + "text" : "stop" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start ceph services.", + "method" : "POST", + "name" : "start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "default" : "ceph.target", + "description" : "Ceph service name.", + "optional" : 1, + "pattern" : "(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Restart ceph services.", + "method" : "POST", + "name" : "restart", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "default" : "ceph.target", + "description" : "Ceph service name.", + "optional" : 1, + "pattern" : "(mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/restart", + "text" : "restart" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get ceph status.", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get OSD crush map", + "method" : "GET", + "name" : "crush", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/crush", + "text" : "crush" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read ceph log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List ceph rules.", + "method" : "GET", + "name" : "rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "name" : { + "description" : "Name of the CRUSH rule.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/rules", + "text" : "rules" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Heuristical check if it is safe to perform an action.", + "method" : "GET", + "name" : "cmd_safety", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Action to check", + "enum" : [ + "stop", + "destroy" + ], + "type" : "string" + }, + "id" : { + "description" : "ID of the service", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service type", + "enum" : [ + "osd", + "mon", + "mds" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "safe" : { + "description" : "If it is safe to run the command.", + "type" : "boolean" + }, + "status" : { + "description" : "Status message given by Ceph.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/ceph/cmd-safety", + "text" : "cmd-safety" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/ceph", + "text" : "ceph" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the currently configured vzdump defaults.", + "method" : "GET", + "name" : "defaults", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions for the specified storage (or default storage if none specified). Some properties are only returned when the user has 'Sys.Audit' permissions for the node.", + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (in KiB/s).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "fleecing" : { + "description" : "Options for backup fleecing (VM only).", + "format" : "backup-fleecing", + "optional" : 1, + "type" : "string" + }, + "ionice" : { + "default" : 7, + "description" : "Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "mailnotification" : { + "default" : "always", + "description" : "Deprecated: use notification targets/matchers instead. Specify when to send a notification mail", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string" + }, + "maxfiles" : { + "description" : "Deprecated: use 'prune-backups' instead. Maximal number of backup files per guest system.", + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string" + }, + "notes-template" : { + "description" : "Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.", + "maxLength" : 1024, + "optional" : 1, + "requires" : "storage", + "type" : "string" + }, + "notification-mode" : { + "default" : "auto", + "description" : "Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.", + "enum" : [ + "auto", + "legacy-sendmail", + "notification-system" + ], + "optional" : 1, + "type" : "string" + }, + "notification-policy" : { + "default" : "always", + "description" : "Deprecated: Do not use", + "enum" : [ + "always", + "failure", + "never" + ], + "optional" : 1, + "type" : "string" + }, + "notification-target" : { + "description" : "Deprecated: Do not use", + "format" : "pve-configid", + "optional" : 1, + "type" : "string" + }, + "pbs-change-detection-mode" : { + "description" : "PBS mode used to detect file changes and switch encoding format for container backups.", + "enum" : [ + "legacy", + "data", + "metadata" + ], + "optional" : 1, + "type" : "string" + }, + "performance" : { + "description" : "Other performance-related settings.", + "format" : "backup-performance", + "optional" : 1, + "type" : "string" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string" + }, + "protected" : { + "description" : "If true, mark backup(s) as protected.", + "optional" : 1, + "requires" : "storage", + "type" : "boolean" + }, + "prune-backups" : { + "default" : "keep-all=1", + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean" + }, + "remove" : { + "default" : 1, + "description" : "Prune older backups according to 'prune-backups'.", + "optional" : 1, + "type" : "boolean" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.", + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/vzdump/defaults", + "text" : "defaults" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Extract configuration from vzdump backup archive.", + "method" : "GET", + "name" : "extractconfig", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'VM.Backup' permissions on the backed up guest ID, and 'Datastore.AllocateSpace' on the backup storage.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/vzdump/extractconfig", + "text" : "extractconfig" + } + ], + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Create backup.", + "method" : "POST", + "name" : "vzdump", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "all" : { + "default" : 0, + "description" : "Backup all known guest systems on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bwlimit" : { + "default" : 0, + "description" : "Limit I/O bandwidth (in KiB/s).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "compress" : { + "default" : "0", + "description" : "Compress dump file.", + "enum" : [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "dumpdir" : { + "description" : "Store resulting files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exclude" : { + "description" : "Exclude specified guest systems (assumes --all)", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "exclude-path" : { + "description" : "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array", + "typetext" : "" + }, + "fleecing" : { + "description" : "Options for backup fleecing (VM only).", + "format" : "backup-fleecing", + "optional" : 1, + "type" : "string", + "typetext" : "[[enabled=]<1|0>] [,storage=]" + }, + "ionice" : { + "default" : 7, + "description" : "Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.", + "maximum" : 8, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 8)" + }, + "job-id" : { + "description" : "The ID of the backup job. If set, the 'backup-job' metadata field of the backup notification will be set to this value. Only root@pam can set this parameter.", + "maxLength" : 50, + "optional" : 1, + "pattern" : "\\S+", + "type" : "string" + }, + "lockwait" : { + "default" : 180, + "description" : "Maximal time to wait for the global lock (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mailnotification" : { + "default" : "always", + "description" : "Deprecated: use notification targets/matchers instead. Specify when to send a notification mail", + "enum" : [ + "always", + "failure" + ], + "optional" : 1, + "type" : "string" + }, + "mailto" : { + "description" : "Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.", + "format" : "email-or-username-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "maxfiles" : { + "description" : "Deprecated: use 'prune-backups' instead. Maximal number of backup files per guest system.", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "mode" : { + "default" : "snapshot", + "description" : "Backup mode.", + "enum" : [ + "snapshot", + "suspend", + "stop" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "Only run if executed on this node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "notes-template" : { + "description" : "Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.", + "maxLength" : 1024, + "optional" : 1, + "requires" : "storage", + "type" : "string", + "typetext" : "" + }, + "notification-mode" : { + "default" : "auto", + "description" : "Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.", + "enum" : [ + "auto", + "legacy-sendmail", + "notification-system" + ], + "optional" : 1, + "type" : "string" + }, + "notification-policy" : { + "default" : "always", + "description" : "Deprecated: Do not use", + "enum" : [ + "always", + "failure", + "never" + ], + "optional" : 1, + "type" : "string" + }, + "notification-target" : { + "description" : "Deprecated: Do not use", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pbs-change-detection-mode" : { + "description" : "PBS mode used to detect file changes and switch encoding format for container backups.", + "enum" : [ + "legacy", + "data", + "metadata" + ], + "optional" : 1, + "type" : "string" + }, + "performance" : { + "description" : "Other performance-related settings.", + "format" : "backup-performance", + "optional" : 1, + "type" : "string", + "typetext" : "[max-workers=] [,pbs-entries-max=]" + }, + "pigz" : { + "default" : 0, + "description" : "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "pool" : { + "description" : "Backup all known guest systems included in the specified pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protected" : { + "description" : "If true, mark backup(s) as protected.", + "optional" : 1, + "requires" : "storage", + "type" : "boolean", + "typetext" : "" + }, + "prune-backups" : { + "default" : "keep-all=1", + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "quiet" : { + "default" : 0, + "description" : "Be quiet.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "remove" : { + "default" : 1, + "description" : "Prune older backups according to 'prune-backups'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "script" : { + "description" : "Use specified hook script.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "stdexcludes" : { + "default" : 1, + "description" : "Exclude temporary files and logs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stdout" : { + "description" : "Write tar to stdout, not to a file.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stop" : { + "default" : 0, + "description" : "Stop running backup jobs on this host.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "stopwait" : { + "default" : 10, + "description" : "Maximal time to wait until a guest system is stopped (minutes).", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "storage" : { + "description" : "Store resulting file to this storage.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tmpdir" : { + "description" : "Store temporary files to specified directory.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "The ID of the guest system you want to backup.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "zstd" : { + "default" : 1, + "description" : "Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'VM.Backup' permissions on any VM, and 'Datastore.AllocateSpace' on the backup storage (and fleecing storage when fleecing is used). The 'tmpdir', 'dumpdir', 'script' and 'job-id' parameters are restricted to the 'root@pam' user. The 'maxfiles' and 'prune-backups' settings require 'Datastore.Allocate' on the backup storage. The 'bwlimit', 'performance' and 'ionice' parameters require 'Sys.Modify' on '/'.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/vzdump", + "text" : "vzdump" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read service properties", + "method" : "GET", + "name" : "service_state", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "postfix", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/state", + "text" : "state" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start service.", + "method" : "POST", + "name" : "service_start", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "postfix", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/start", + "text" : "start" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop service.", + "method" : "POST", + "name" : "service_stop", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "postfix", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/stop", + "text" : "stop" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Hard restart service. Use reload if you want to reduce interruptions.", + "method" : "POST", + "name" : "service_restart", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "postfix", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/restart", + "text" : "restart" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Reload service. Falls back to restart if service cannot be reloaded.", + "method" : "POST", + "name" : "service_reload", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "postfix", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/services/{service}/reload", + "text" : "reload" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index", + "method" : "GET", + "name" : "srvcmdidx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "enum" : [ + "chrony", + "corosync", + "cron", + "ksmtuned", + "postfix", + "pve-cluster", + "pve-firewall", + "pve-ha-crm", + "pve-ha-lrm", + "pvedaemon", + "pvefw-logger", + "pveproxy", + "pvescheduler", + "pvestatd", + "spiceproxy", + "sshd", + "syslog", + "systemd-journald", + "systemd-timesyncd" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/services/{service}", + "text" : "{service}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Service list.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{service}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/services", + "text" : "services" + }, + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete subscription key of this node.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read subscription info.", + "method" : "GET", + "name" : "get", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "properties" : { + "checktime" : { + "description" : "Timestamp of the last check done.", + "optional" : 1, + "type" : "integer" + }, + "key" : { + "description" : "The subscription key, if set and permitted to access.", + "optional" : 1, + "type" : "string" + }, + "level" : { + "description" : "A short code for the subscription level.", + "optional" : 1, + "type" : "string" + }, + "message" : { + "description" : "A more human readable status message.", + "optional" : 1, + "type" : "string" + }, + "nextduedate" : { + "description" : "Next due date of the set subscription.", + "optional" : 1, + "type" : "string" + }, + "productname" : { + "description" : "Human readable productname of the set subscription.", + "optional" : 1, + "type" : "string" + }, + "regdate" : { + "description" : "Register date of the set subscription.", + "optional" : 1, + "type" : "string" + }, + "serverid" : { + "description" : "The server ID, if permitted to access.", + "optional" : 1, + "type" : "string" + }, + "signature" : { + "description" : "Signature for offline keys", + "optional" : 1, + "type" : "string" + }, + "sockets" : { + "description" : "The number of sockets for this host.", + "optional" : 1, + "type" : "integer" + }, + "status" : { + "description" : "The current subscription status.", + "enum" : [ + "new", + "notfound", + "active", + "invalid", + "expired", + "suspended" + ], + "type" : "string" + }, + "url" : { + "description" : "URL to the web shop.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Update subscription info.", + "method" : "POST", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "Always connect to server, even if local cache is still valid.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set subscription key.", + "method" : "PUT", + "name" : "set", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "key" : { + "description" : "Proxmox VE subscription key", + "maxLength" : 32, + "pattern" : "\\s*pve([1248])([cbsp])-[0-9a-f]{10}\\s*", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/subscription", + "text" : "subscription" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete network device configuration", + "method" : "DELETE", + "name" : "delete_network", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read network device configuration", + "method" : "GET", + "name" : "network_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "method" : { + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update network device configuration", + "method" : "PUT", + "name" : "update_network", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "address" : { + "description" : "IP address.", + "format" : "ipv4", + "optional" : 1, + "requires" : "netmask", + "type" : "string", + "typetext" : "" + }, + "address6" : { + "description" : "IP address.", + "format" : "ipv6", + "optional" : 1, + "requires" : "netmask6", + "type" : "string", + "typetext" : "" + }, + "autostart" : { + "description" : "Automatically start interface on boot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bond-primary" : { + "description" : "Specify the primary interface for active-backup bond.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bond_mode" : { + "description" : "Bonding mode.", + "enum" : [ + "balance-rr", + "active-backup", + "balance-xor", + "broadcast", + "802.3ad", + "balance-tlb", + "balance-alb", + "balance-slb", + "lacp-balance-slb", + "lacp-balance-tcp" + ], + "optional" : 1, + "type" : "string" + }, + "bond_xmit_hash_policy" : { + "description" : "Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.", + "enum" : [ + "layer2", + "layer2+3", + "layer3+4" + ], + "optional" : 1, + "type" : "string" + }, + "bridge_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge_vids" : { + "description" : "Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.", + "format" : "pve-vlan-id-or-range-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge_vlan_aware" : { + "description" : "Enable bridge vlan support.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cidr" : { + "description" : "IPv4 CIDR.", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cidr6" : { + "description" : "IPv6 CIDR.", + "format" : "CIDRv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comments" : { + "description" : "Comments", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comments6" : { + "description" : "Comments", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway" : { + "description" : "Default gateway address.", + "format" : "ipv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway6" : { + "description" : "Default ipv6 gateway address.", + "format" : "ipv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string", + "typetext" : "" + }, + "mtu" : { + "description" : "MTU.", + "maximum" : 65520, + "minimum" : 1280, + "optional" : 1, + "type" : "integer", + "typetext" : " (1280 - 65520)" + }, + "netmask" : { + "description" : "Network mask.", + "format" : "ipv4mask", + "optional" : 1, + "requires" : "address", + "type" : "string", + "typetext" : "" + }, + "netmask6" : { + "description" : "Network mask.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "requires" : "address6", + "type" : "integer", + "typetext" : " (0 - 128)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "ovs_bonds" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_bridge" : { + "description" : "The OVS bridge associated with a OVS port. This is required when you create an OVS port.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_options" : { + "description" : "OVS interface options.", + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_tag" : { + "description" : "Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4094)" + }, + "slaves" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Network interface type", + "enum" : [ + "bridge", + "bond", + "eth", + "alias", + "vlan", + "OVSBridge", + "OVSBond", + "OVSPort", + "OVSIntPort", + "vnet", + "unknown" + ], + "type" : "string" + }, + "vlan-id" : { + "description" : "vlan-id for a custom named vlan interface (ifupdown2 only).", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4094)" + }, + "vlan-raw-device" : { + "description" : "Specify the raw interface for the vlan interface.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/network/{iface}", + "text" : "{iface}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Revert network configuration changes.", + "method" : "DELETE", + "name" : "revert_network_changes", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List available networks", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Only list specific interface types.", + "enum" : [ + "bridge", + "bond", + "eth", + "alias", + "vlan", + "OVSBridge", + "OVSBond", + "OVSPort", + "OVSIntPort", + "vnet", + "any_bridge", + "any_local_bridge" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "active" : { + "description" : "Set to true if the interface is active.", + "optional" : 1, + "type" : "boolean" + }, + "address" : { + "description" : "IP address.", + "format" : "ipv4", + "optional" : 1, + "requires" : "netmask", + "type" : "string" + }, + "address6" : { + "description" : "IP address.", + "format" : "ipv6", + "optional" : 1, + "requires" : "netmask6", + "type" : "string" + }, + "autostart" : { + "description" : "Automatically start interface on boot.", + "optional" : 1, + "type" : "boolean" + }, + "bond-primary" : { + "description" : "Specify the primary interface for active-backup bond.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string" + }, + "bond_mode" : { + "description" : "Bonding mode.", + "enum" : [ + "balance-rr", + "active-backup", + "balance-xor", + "broadcast", + "802.3ad", + "balance-tlb", + "balance-alb", + "balance-slb", + "lacp-balance-slb", + "lacp-balance-tcp" + ], + "optional" : 1, + "type" : "string" + }, + "bond_xmit_hash_policy" : { + "description" : "Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.", + "enum" : [ + "layer2", + "layer2+3", + "layer3+4" + ], + "optional" : 1, + "type" : "string" + }, + "bridge-access" : { + "description" : "The bridge port access VLAN.", + "optional" : 1, + "type" : "integer" + }, + "bridge-arp-nd-suppress" : { + "description" : "Bridge port ARP/ND suppress flag.", + "optional" : 1, + "type" : "boolean" + }, + "bridge-learning" : { + "description" : "Bridge port learning flag.", + "optional" : 1, + "type" : "boolean" + }, + "bridge-multicast-flood" : { + "description" : "Bridge port multicast flood flag.", + "optional" : 1, + "type" : "boolean" + }, + "bridge-unicast-flood" : { + "description" : "Bridge port unicast flood flag.", + "optional" : 1, + "type" : "boolean" + }, + "bridge_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string" + }, + "bridge_vids" : { + "description" : "Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.", + "format" : "pve-vlan-id-or-range-list", + "optional" : 1, + "type" : "string" + }, + "bridge_vlan_aware" : { + "description" : "Enable bridge vlan support.", + "optional" : 1, + "type" : "boolean" + }, + "cidr" : { + "description" : "IPv4 CIDR.", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string" + }, + "cidr6" : { + "description" : "IPv6 CIDR.", + "format" : "CIDRv6", + "optional" : 1, + "type" : "string" + }, + "comments" : { + "description" : "Comments", + "optional" : 1, + "type" : "string" + }, + "comments6" : { + "description" : "Comments", + "optional" : 1, + "type" : "string" + }, + "exists" : { + "description" : "Set to true if the interface physically exists.", + "optional" : 1, + "type" : "boolean" + }, + "families" : { + "description" : "The network families.", + "items" : { + "description" : "A network family.", + "enum" : [ + "inet", + "inet6" + ], + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "gateway" : { + "description" : "Default gateway address.", + "format" : "ipv4", + "optional" : 1, + "type" : "string" + }, + "gateway6" : { + "description" : "Default ipv6 gateway address.", + "format" : "ipv6", + "optional" : 1, + "type" : "string" + }, + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string" + }, + "link-type" : { + "description" : "The link type.", + "optional" : 1, + "type" : "string" + }, + "method" : { + "description" : "The network configuration method for IPv4.", + "enum" : [ + "loopback", + "dhcp", + "manual", + "static", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "method6" : { + "description" : "The network configuration method for IPv6.", + "enum" : [ + "loopback", + "dhcp", + "manual", + "static", + "auto" + ], + "optional" : 1, + "type" : "string" + }, + "mtu" : { + "description" : "MTU.", + "maximum" : 65520, + "minimum" : 1280, + "optional" : 1, + "type" : "integer" + }, + "netmask" : { + "description" : "Network mask.", + "format" : "ipv4mask", + "optional" : 1, + "requires" : "address", + "type" : "string" + }, + "netmask6" : { + "description" : "Network mask.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "requires" : "address6", + "type" : "integer" + }, + "options" : { + "description" : "A list of additional interface options for IPv4.", + "items" : { + "description" : "An interface property.", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "options6" : { + "description" : "A list of additional interface options for IPv6.", + "items" : { + "description" : "An interface property.", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "ovs_bonds" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string" + }, + "ovs_bridge" : { + "description" : "The OVS bridge associated with a OVS port. This is required when you create an OVS port.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string" + }, + "ovs_options" : { + "description" : "OVS interface options.", + "maxLength" : 1024, + "optional" : 1, + "type" : "string" + }, + "ovs_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string" + }, + "ovs_tag" : { + "description" : "Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "priority" : { + "description" : "The order of the interface.", + "optional" : 1, + "type" : "integer" + }, + "slaves" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Network interface type", + "enum" : [ + "bridge", + "bond", + "eth", + "alias", + "vlan", + "OVSBridge", + "OVSBond", + "OVSPort", + "OVSIntPort", + "vnet", + "unknown" + ], + "type" : "string" + }, + "uplink-id" : { + "description" : "The uplink ID.", + "optional" : 1, + "type" : "string" + }, + "vlan-id" : { + "description" : "vlan-id for a custom named vlan interface (ifupdown2 only).", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer" + }, + "vlan-protocol" : { + "description" : "The VLAN protocol.", + "enum" : [ + "802.1ad", + "802.1q" + ], + "optional" : 1, + "type" : "string" + }, + "vlan-raw-device" : { + "description" : "Specify the raw interface for the vlan interface.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string" + }, + "vxlan-id" : { + "description" : "The VXLAN ID.", + "optional" : 1, + "type" : "integer" + }, + "vxlan-local-tunnelip" : { + "description" : "The VXLAN local tunnel IP.", + "optional" : 1, + "type" : "string" + }, + "vxlan-physdev" : { + "description" : "The physical device for the VXLAN tunnel.", + "optional" : 1, + "type" : "string" + }, + "vxlan-svcnodeip" : { + "description" : "The VXLAN SVC node IP.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{iface}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create network device configuration", + "method" : "POST", + "name" : "create_network", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "address" : { + "description" : "IP address.", + "format" : "ipv4", + "optional" : 1, + "requires" : "netmask", + "type" : "string", + "typetext" : "" + }, + "address6" : { + "description" : "IP address.", + "format" : "ipv6", + "optional" : 1, + "requires" : "netmask6", + "type" : "string", + "typetext" : "" + }, + "autostart" : { + "description" : "Automatically start interface on boot.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "bond-primary" : { + "description" : "Specify the primary interface for active-backup bond.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bond_mode" : { + "description" : "Bonding mode.", + "enum" : [ + "balance-rr", + "active-backup", + "balance-xor", + "broadcast", + "802.3ad", + "balance-tlb", + "balance-alb", + "balance-slb", + "lacp-balance-slb", + "lacp-balance-tcp" + ], + "optional" : 1, + "type" : "string" + }, + "bond_xmit_hash_policy" : { + "description" : "Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.", + "enum" : [ + "layer2", + "layer2+3", + "layer3+4" + ], + "optional" : 1, + "type" : "string" + }, + "bridge_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge_vids" : { + "description" : "Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.", + "format" : "pve-vlan-id-or-range-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bridge_vlan_aware" : { + "description" : "Enable bridge vlan support.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cidr" : { + "description" : "IPv4 CIDR.", + "format" : "CIDRv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "cidr6" : { + "description" : "IPv6 CIDR.", + "format" : "CIDRv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comments" : { + "description" : "Comments", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comments6" : { + "description" : "Comments", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway" : { + "description" : "Default gateway address.", + "format" : "ipv4", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "gateway6" : { + "description" : "Default ipv6 gateway address.", + "format" : "ipv6", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "type" : "string", + "typetext" : "" + }, + "mtu" : { + "description" : "MTU.", + "maximum" : 65520, + "minimum" : 1280, + "optional" : 1, + "type" : "integer", + "typetext" : " (1280 - 65520)" + }, + "netmask" : { + "description" : "Network mask.", + "format" : "ipv4mask", + "optional" : 1, + "requires" : "address", + "type" : "string", + "typetext" : "" + }, + "netmask6" : { + "description" : "Network mask.", + "maximum" : 128, + "minimum" : 0, + "optional" : 1, + "requires" : "address6", + "type" : "integer", + "typetext" : " (0 - 128)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "ovs_bonds" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_bridge" : { + "description" : "The OVS bridge associated with a OVS port. This is required when you create an OVS port.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_options" : { + "description" : "OVS interface options.", + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_ports" : { + "description" : "Specify the interfaces you want to add to your bridge.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "ovs_tag" : { + "description" : "Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4094)" + }, + "slaves" : { + "description" : "Specify the interfaces used by the bonding device.", + "format" : "pve-iface-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Network interface type", + "enum" : [ + "bridge", + "bond", + "eth", + "alias", + "vlan", + "OVSBridge", + "OVSBond", + "OVSPort", + "OVSIntPort", + "vnet", + "unknown" + ], + "type" : "string" + }, + "vlan-id" : { + "description" : "vlan-id for a custom named vlan interface (ifupdown2 only).", + "maximum" : 4094, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 4094)" + }, + "vlan-raw-device" : { + "description" : "Specify the raw interface for the vlan interface.", + "format" : "pve-iface", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Reload network configuration", + "method" : "PUT", + "name" : "reload_network_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/network", + "text" : "network" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read task log.", + "download_allowed" : 1, + "method" : "GET", + "name" : "read_task_log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "download" : { + "description" : "Whether the tasklog file should be downloaded. This parameter can't be used in conjunction with other parameters", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "limit" : { + "default" : 50, + "description" : "The amount of lines to read from the tasklog.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "start" : { + "default" : 0, + "description" : "Start at this line when reading the tasklog", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "upid" : { + "description" : "The task's unique ID.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'Sys.Audit' permissions on '/nodes/' if they aren't the owner of the task.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/tasks/{upid}/log", + "text" : "log" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read task status.", + "method" : "GET", + "name" : "read_task_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "upid" : { + "description" : "The task's unique ID.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'Sys.Audit' permissions on '/nodes/' if they are not the owner of the task.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "exitstatus" : { + "optional" : 1, + "type" : "string" + }, + "id" : { + "type" : "string" + }, + "node" : { + "type" : "string" + }, + "pid" : { + "type" : "integer" + }, + "pstart" : { + "type" : "integer" + }, + "starttime" : { + "type" : "integer" + }, + "status" : { + "enum" : [ + "running", + "stopped" + ], + "type" : "string" + }, + "type" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/tasks/{upid}/status", + "text" : "status" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Stop a task.", + "method" : "DELETE", + "name" : "stop_task", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "upid" : { + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The user needs 'Sys.Modify' permissions on '/nodes/' if they aren't the owner of the task.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "upid_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "upid" : { + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/tasks/{upid}", + "text" : "{upid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read task list for one node (finished tasks).", + "method" : "GET", + "name" : "node_tasks", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "errors" : { + "default" : 0, + "description" : "Only list tasks with a status of ERROR.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "limit" : { + "default" : 50, + "description" : "Only list this amount of tasks.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Only list tasks since this UNIX epoch.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "source" : { + "default" : "archive", + "description" : "List archived, active or all tasks.", + "enum" : [ + "archive", + "active", + "all" + ], + "optional" : 1, + "type" : "string" + }, + "start" : { + "default" : 0, + "description" : "List tasks beginning from this offset.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "statusfilter" : { + "description" : "List of Task States that should be returned.", + "format" : "pve-task-status-type-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "typefilter" : { + "description" : "Only list tasks of this type (e.g., vzstart, vzdump).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "until" : { + "description" : "Only list tasks until this UNIX epoch.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "userfilter" : { + "description" : "Only list tasks from this user.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "Only list tasks for this VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "description" : "List task associated with the current user, or all task the user has 'Sys.Audit' permissions on /nodes/ (the the task runs on).", + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "endtime" : { + "optional" : 1, + "title" : "Endtime", + "type" : "integer" + }, + "id" : { + "title" : "ID", + "type" : "string" + }, + "node" : { + "title" : "Node", + "type" : "string" + }, + "pid" : { + "title" : "PID", + "type" : "integer" + }, + "pstart" : { + "type" : "integer" + }, + "starttime" : { + "title" : "Starttime", + "type" : "integer" + }, + "status" : { + "optional" : 1, + "title" : "Status", + "type" : "string" + }, + "type" : { + "title" : "Type", + "type" : "string" + }, + "upid" : { + "title" : "UPID", + "type" : "string" + }, + "user" : { + "title" : "User", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{upid}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/tasks", + "text" : "tasks" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote NFS server.", + "method" : "GET", + "name" : "nfsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "The server address (name or IP).", + "format" : "pve-storage-server", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "options" : { + "description" : "NFS export options.", + "type" : "string" + }, + "path" : { + "description" : "The exported path.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/nfs", + "text" : "nfs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote CIFS server.", + "method" : "GET", + "name" : "cifsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "domain" : { + "description" : "SMB domain (Workgroup).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "User password.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "The server address (name or IP).", + "format" : "pve-storage-server", + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "User name.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "description" : { + "description" : "Descriptive text from server.", + "type" : "string" + }, + "share" : { + "description" : "The cifs share name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/cifs", + "text" : "cifs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote Proxmox Backup Server.", + "method" : "GET", + "name" : "pbsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "User password or API token secret.", + "type" : "string", + "typetext" : "" + }, + "port" : { + "default" : 8007, + "description" : "Optional port.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "server" : { + "description" : "The server address (name or IP).", + "format" : "pve-storage-server", + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "User-name or API token-ID.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "Comment from server.", + "optional" : 1, + "type" : "string" + }, + "store" : { + "description" : "The datastore name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/pbs", + "text" : "pbs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote GlusterFS server.", + "method" : "GET", + "name" : "glusterfsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "The server address (name or IP).", + "format" : "pve-storage-server", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "volname" : { + "description" : "The volume name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/glusterfs", + "text" : "glusterfs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan remote iSCSI server.", + "method" : "GET", + "name" : "iscsiscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "portal" : { + "description" : "The iSCSI portal (IP or DNS name with optional port).", + "format" : "pve-storage-portal-dns", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "portal" : { + "description" : "The iSCSI portal name.", + "type" : "string" + }, + "target" : { + "description" : "The iSCSI target name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/iscsi", + "text" : "iscsi" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local LVM volume groups.", + "method" : "GET", + "name" : "lvmscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "vg" : { + "description" : "The LVM logical volume group name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/lvm", + "text" : "lvm" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local LVM Thin Pools.", + "method" : "GET", + "name" : "lvmthinscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vg" : { + "maxLength" : 100, + "pattern" : "[a-zA-Z0-9\\.\\+\\_][a-zA-Z0-9\\.\\+\\_\\-]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "lv" : { + "description" : "The LVM Thin Pool name (LVM logical volume).", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/lvmthin", + "text" : "lvmthin" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Scan zfs pool list on local node.", + "method" : "GET", + "name" : "zfsscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "pool" : { + "description" : "ZFS pool name.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/scan/zfs", + "text" : "zfs" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index of available scan methods", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "method" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{method}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/scan", + "text" : "scan" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List mediated device types for given PCI device.", + "method" : "GET", + "name" : "mdevscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pci-id-or-mapping" : { + "description" : "The PCI ID or mapping to list the mdev types for.", + "pattern" : "(?:(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\\.[0-9a-fA-F])|([a-zA-Z][a-zA-Z0-9_-]+)", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "available" : { + "description" : "The number of still available instances of this type.", + "type" : "integer" + }, + "description" : { + "description" : "Additional description of the type.", + "type" : "string" + }, + "name" : { + "description" : "A human readable name for the type.", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "The name of the mdev type.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev", + "text" : "mdev" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index of available pci methods", + "method" : "GET", + "name" : "pci_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pci-id-or-mapping" : { + "pattern" : "(?:(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\\.[0-9a-fA-F])|([a-zA-Z][a-zA-Z0-9_-]+)", + "type" : "string" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "method" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{method}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/hardware/pci/{pci-id-or-mapping}", + "text" : "{pci-id-or-mapping}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local PCI devices.", + "method" : "GET", + "name" : "pci_scan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pci-class-blacklist" : { + "default" : "05;06;0b", + "description" : "A list of blacklisted PCI classes, which will not be returned. Following are filtered by default: Memory Controller (05), Bridge (06) and Processor (0b).", + "format" : "string-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "verbose" : { + "default" : 1, + "description" : "If disabled, does only print the PCI IDs. Otherwise, additional information like vendor and device will be returned.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "class" : { + "description" : "The PCI Class of the device.", + "type" : "string" + }, + "device" : { + "description" : "The Device ID.", + "type" : "string" + }, + "device_name" : { + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "The PCI ID.", + "type" : "string" + }, + "iommugroup" : { + "description" : "The IOMMU group in which the device is in. If no IOMMU group is detected, it is set to -1.", + "type" : "integer" + }, + "mdev" : { + "description" : "If set, marks that the device is capable of creating mediated devices.", + "optional" : 1, + "type" : "boolean" + }, + "subsystem_device" : { + "description" : "The Subsystem Device ID.", + "optional" : 1, + "type" : "string" + }, + "subsystem_device_name" : { + "optional" : 1, + "type" : "string" + }, + "subsystem_vendor" : { + "description" : "The Subsystem Vendor ID.", + "optional" : 1, + "type" : "string" + }, + "subsystem_vendor_name" : { + "optional" : 1, + "type" : "string" + }, + "vendor" : { + "description" : "The Vendor ID.", + "type" : "string" + }, + "vendor_name" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/hardware/pci", + "text" : "pci" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local USB devices.", + "method" : "GET", + "name" : "usbscan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "busnum" : { + "type" : "integer" + }, + "class" : { + "type" : "integer" + }, + "devnum" : { + "type" : "integer" + }, + "level" : { + "type" : "integer" + }, + "manufacturer" : { + "optional" : 1, + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "prodid" : { + "type" : "string" + }, + "product" : { + "optional" : 1, + "type" : "string" + }, + "serial" : { + "optional" : 1, + "type" : "string" + }, + "speed" : { + "type" : "string" + }, + "usbpath" : { + "optional" : 1, + "type" : "string" + }, + "vendid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/hardware/usb", + "text" : "usb" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Index of hardware types", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{type}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/hardware", + "text" : "hardware" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List all custom and default CPU models.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only returns custom models when the current user has Sys.Audit on /nodes.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "custom" : { + "description" : "True if this is a custom CPU model.", + "type" : "boolean" + }, + "name" : { + "description" : "Name of the CPU model. Identifies it for subsequent API calls. Prefixed with 'custom-' for custom models.", + "type" : "string" + }, + "vendor" : { + "description" : "CPU vendor visible to the guest when this model is selected. Vendor of 'reported-model' in case of custom models.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/capabilities/qemu/cpu", + "text" : "cpu" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get available QEMU/KVM machine types.", + "method" : "GET", + "name" : "types", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "changes" : { + "description" : "Notable changes of a version, currently only set for +pveX versions.", + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "Full name of machine type and version.", + "type" : "string" + }, + "type" : { + "description" : "The machine type.", + "enum" : [ + "q35", + "i440fx" + ], + "type" : "string" + }, + "version" : { + "description" : "The machine version.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/capabilities/qemu/machines", + "text" : "machines" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "QEMU capabilities index.", + "method" : "GET", + "name" : "qemu_caps_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/capabilities/qemu", + "text" : "qemu" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Node capabilities index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/capabilities", + "text" : "capabilities" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Prune backups. Only those using the standard naming scheme are considered.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "prune-backups" : { + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Either 'qemu' or 'lxc'. Only consider backups for guests of this type.", + "enum" : [ + "qemu", + "lxc" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "Only prune backups for this VM.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "description" : "You need the 'Datastore.Allocate' privilege on the storage (or if a VM ID is specified, 'Datastore.AllocateSpace' and 'VM.Backup' for the VM).", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get prune information for backups. NOTE: this is only a preview and might not be what a subsequent prune call does if backups are removed/added in the meantime.", + "method" : "GET", + "name" : "dryrun", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "prune-backups" : { + "description" : "Use these retention options instead of those from the storage configuration.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Either 'qemu' or 'lxc'. Only consider backups for guests of this type.", + "enum" : [ + "qemu", + "lxc" + ], + "optional" : 1, + "type" : "string" + }, + "vmid" : { + "description" : "Only consider backups for this guest.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "ctime" : { + "description" : "Creation time of the backup (seconds since the UNIX epoch).", + "type" : "integer" + }, + "mark" : { + "description" : "Whether the backup would be kept or removed. Backups that are protected or don't use the standard naming scheme are not removed.", + "enum" : [ + "keep", + "remove", + "protected", + "renamed" + ], + "type" : "string" + }, + "type" : { + "description" : "One of 'qemu', 'lxc', 'openvz' or 'unknown'.", + "type" : "string" + }, + "vmid" : { + "description" : "The VM the backup belongs to.", + "optional" : 1, + "type" : "integer" + }, + "volid" : { + "description" : "Backup volume ID.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/prunebackups", + "text" : "prunebackups" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete volume", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delay" : { + "description" : "Time to wait for the task to finish. We return 'null' if the task finish within that time.", + "maximum" : 30, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 30)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need 'Datastore.Allocate' privilege on the storage (or 'Datastore.AllocateSpace' for backup volumes if you have VM.Backup privilege on the VM).", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "optional" : 1, + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get volume attributes", + "method" : "GET", + "name" : "info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "format" : { + "description" : "Format identifier ('raw', 'qcow2', 'subvol', 'iso', 'tgz' ...)", + "type" : "string" + }, + "notes" : { + "description" : "Optional notes.", + "optional" : 1, + "type" : "string" + }, + "path" : { + "description" : "The Path", + "type" : "string" + }, + "protected" : { + "description" : "Protection status. Currently only supported for backups.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Volume size in bytes.", + "renderer" : "bytes", + "type" : "integer" + }, + "used" : { + "description" : "Used space. Please note that most storage plugins do not report anything useful here.", + "renderer" : "bytes", + "type" : "integer" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Copy a volume. This is experimental code - do not use.", + "method" : "POST", + "name" : "copy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target volume identifier", + "type" : "string", + "typetext" : "" + }, + "target_node" : { + "description" : "Target node. Default is local node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Source volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update volume attributes", + "method" : "PUT", + "name" : "updateattributes", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "notes" : { + "description" : "The new notes.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "protected" : { + "description" : "Protection status. Currently only supported for backups.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/content/{volume}", + "text" : "{volume}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List storage content.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "content" : { + "description" : "Only list content of this type.", + "format" : "pve-storage-content", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "Only list images for this VM", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "ctime" : { + "description" : "Creation time (seconds since the UNIX Epoch).", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "encrypted" : { + "description" : "If whole backup is encrypted, value is the fingerprint or '1' if encrypted. Only useful for the Proxmox Backup Server storage type.", + "optional" : 1, + "type" : "string" + }, + "format" : { + "description" : "Format identifier ('raw', 'qcow2', 'subvol', 'iso', 'tgz' ...)", + "type" : "string" + }, + "notes" : { + "description" : "Optional notes. If they contain multiple lines, only the first one is returned here.", + "optional" : 1, + "type" : "string" + }, + "parent" : { + "description" : "Volume identifier of parent (for linked cloned).", + "optional" : 1, + "type" : "string" + }, + "protected" : { + "description" : "Protection status. Currently only supported for backups.", + "optional" : 1, + "type" : "boolean" + }, + "size" : { + "description" : "Volume size in bytes.", + "renderer" : "bytes", + "type" : "integer" + }, + "used" : { + "description" : "Used space. Please note that most storage plugins do not report anything useful here.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "verification" : { + "description" : "Last backup verification result, only useful for PBS storages.", + "optional" : 1, + "properties" : { + "state" : { + "description" : "Last backup verification state.", + "type" : "string" + }, + "upid" : { + "description" : "Last backup verification UPID.", + "type" : "string" + } + }, + "type" : "object" + }, + "vmid" : { + "description" : "Associated Owner VMID.", + "optional" : 1, + "type" : "integer" + }, + "volid" : { + "description" : "Volume identifier.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{volid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Allocate disk images.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "filename" : { + "description" : "The name of the file to create.", + "type" : "string", + "typetext" : "" + }, + "format" : { + "description" : "Format of the image.", + "enum" : [ + "raw", + "qcow2", + "subvol", + "vmdk" + ], + "optional" : 1, + "requires" : "size", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "size" : { + "description" : "Size in kilobyte (1024 bytes). Optional suffixes 'M' (megabyte, 1024K) and 'G' (gigabyte, 1024M)", + "pattern" : "\\d+[MG]?", + "type" : "string" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "vmid" : { + "description" : "Specify owner VM", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "type" : "integer", + "typetext" : " (100 - 999999999)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateSpace" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "description" : "Volume identifier", + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/storage/{storage}/content", + "text" : "content" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List files and directories for single file restore under the given path.", + "method" : "GET", + "name" : "list", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "filepath" : { + "description" : "base64-path to the directory or file being listed, or \"/\".", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Backup volume ID or name. Currently only PBS snapshots are supported.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "filepath" : { + "description" : "base64 path of the current entry", + "type" : "string" + }, + "leaf" : { + "description" : "If this entry is a leaf in the directory graph.", + "type" : "boolean" + }, + "mtime" : { + "description" : "Entry last-modified time (unix timestamp).", + "optional" : 1, + "type" : "integer" + }, + "size" : { + "description" : "Entry file size.", + "optional" : 1, + "type" : "integer" + }, + "text" : { + "description" : "Entry display text.", + "type" : "string" + }, + "type" : { + "description" : "Entry type.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/file-restore/list", + "text" : "list" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Extract a file or directory (as zip archive) from a PBS backup.", + "download_allowed" : 1, + "method" : "GET", + "name" : "download", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "filepath" : { + "description" : "base64-path to the directory or file to download.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "tar" : { + "default" : 0, + "description" : "Download dirs as 'tar.zst' instead of 'zip'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "volume" : { + "description" : "Backup volume ID or name. Currently only PBS snapshots are supported.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "any" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/file-restore/download", + "text" : "download" + } + ], + "leaf" : 0, + "path" : "/nodes/{node}/storage/{storage}/file-restore", + "text" : "file-restore" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read storage status.", + "method" : "GET", + "name" : "read_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read storage RRD statistics (returns PNG).", + "method" : "GET", + "name" : "rrd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "ds" : { + "description" : "The list of datasources you want to display.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "filename" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/rrd", + "text" : "rrd" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read storage RRD statistics.", + "method" : "GET", + "name" : "rrddata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/rrddata", + "text" : "rrddata" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Upload templates, ISO images, OVAs and VM images.", + "method" : "POST", + "name" : "upload", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "checksum" : { + "description" : "The expected checksum of the file.", + "optional" : 1, + "requires" : "checksum-algorithm", + "type" : "string", + "typetext" : "" + }, + "checksum-algorithm" : { + "description" : "The algorithm to calculate the checksum of the file.", + "enum" : [ + "md5", + "sha1", + "sha224", + "sha256", + "sha384", + "sha512" + ], + "optional" : 1, + "requires" : "checksum", + "type" : "string" + }, + "content" : { + "description" : "Content type.", + "enum" : [ + "iso", + "vztmpl", + "import" + ], + "format" : "pve-storage-content", + "type" : "string" + }, + "filename" : { + "description" : "The name of the file to create. Caution: This will be normalized!", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "tmpfilename" : { + "description" : "The source file name. This parameter is usually set by the REST handler. You can only overwrite it when connecting to the trusted port on localhost.", + "optional" : 1, + "pattern" : "/var/tmp/pveupload-[0-9a-f]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/upload", + "text" : "upload" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Download templates, ISO images, OVAs and VM images by using an URL.", + "method" : "POST", + "name" : "download_url", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "checksum" : { + "description" : "The expected checksum of the file.", + "optional" : 1, + "requires" : "checksum-algorithm", + "type" : "string", + "typetext" : "" + }, + "checksum-algorithm" : { + "description" : "The algorithm to calculate the checksum of the file.", + "enum" : [ + "md5", + "sha1", + "sha224", + "sha256", + "sha384", + "sha512" + ], + "optional" : 1, + "requires" : "checksum", + "type" : "string" + }, + "compression" : { + "description" : "Decompress the downloaded file using the specified compression algorithm.", + "enum" : null, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "content" : { + "description" : "Content type.", + "enum" : [ + "iso", + "vztmpl", + "import" + ], + "format" : "pve-storage-content", + "type" : "string" + }, + "filename" : { + "description" : "The name of the file to create. Caution: This will be normalized!", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "url" : { + "description" : "The URL to download the file from.", + "pattern" : "https?://.*", + "type" : "string" + }, + "verify-certificates" : { + "default" : 1, + "description" : "If false, no SSL/TLS certificates will be verified.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.AccessNetwork" + ] + ] + ] + ], + "description" : "Requires allocation access on the storage and as this allows one to probe the (local!) host network indirectly it also requires one of Sys.Modify on / (for backwards compatibility) or the newer Sys.AccessNetwork privilege on the node." + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/download-url", + "text" : "download-url" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the base parameters for creating a guest which imports data from a foreign importable guest, like an ESXi VM", + "method" : "GET", + "name" : "get_import_metadata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Volume identifier for the guest archive/entry.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need read access for the volume.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "description" : "Information about how to import a guest.", + "properties" : { + "create-args" : { + "additionalProperties" : 1, + "description" : "Parameters which can be used in a call to create a VM or container.", + "type" : "object" + }, + "disks" : { + "additionalProperties" : 1, + "description" : "Recognised disk volumes as `$bus$id` => `$storeid:$path` map.", + "optional" : 1, + "type" : "object" + }, + "net" : { + "additionalProperties" : 1, + "description" : "Recognised network interfaces as `net$id` => { ...params } object.", + "optional" : 1, + "type" : "object" + }, + "source" : { + "description" : "The type of the import-source of this guest volume.", + "enum" : [ + "esxi" + ], + "type" : "string" + }, + "type" : { + "description" : "The type of guest this is going to produce.", + "enum" : [ + "vm" + ], + "type" : "string" + }, + "warnings" : { + "description" : "List of known issues that can affect the import of a guest. Note that lack of warning does not imply that there cannot be any problems.", + "items" : { + "additionalProperties" : 1, + "properties" : { + "key" : { + "description" : "Related subject (config) key of warning.", + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "What this warning is about.", + "enum" : [ + "cdrom-image-ignored", + "efi-state-lost", + "guest-is-running", + "nvme-unsupported", + "ova-needs-extracting", + "ovmf-with-lsi-unsupported", + "serial-port-socket-only" + ], + "type" : "string" + }, + "value" : { + "description" : "Related subject (config) value of warning.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/storage/{storage}/import-metadata", + "text" : "import-metadata" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "diridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/storage/{storage}", + "text" : "{storage}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get status for all datastores.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "content" : { + "description" : "Only list stores which support this content type.", + "format" : "pve-storage-content-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enabled" : { + "default" : 0, + "description" : "Only list stores which are enabled (not disabled in config).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "format" : { + "default" : 0, + "description" : "Include information about formats", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "Only list status for specified storage", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "If target is different to 'node', we only lists shared storages which content is accessible on this 'node' and the specified 'target' node.", + "format" : "pve-node", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "active" : { + "description" : "Set when storage is accessible.", + "optional" : 1, + "type" : "boolean" + }, + "avail" : { + "description" : "Available storage space in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "content" : { + "description" : "Allowed storage content types.", + "format" : "pve-storage-content-list", + "type" : "string" + }, + "enabled" : { + "description" : "Set when storage is enabled (not disabled).", + "optional" : 1, + "type" : "boolean" + }, + "shared" : { + "description" : "Shared flag from storage configuration.", + "optional" : 1, + "type" : "boolean" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string" + }, + "total" : { + "description" : "Total storage space in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "type" : { + "description" : "Storage type.", + "type" : "string" + }, + "used" : { + "description" : "Used storage space in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "used_fraction" : { + "description" : "Used fraction (used/total).", + "optional" : 1, + "renderer" : "fraction_as_percentage", + "type" : "number" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{storage}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/storage", + "text" : "storage" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove an LVM Volume Group.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cleanup-config" : { + "default" : 0, + "description" : "Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cleanup-disks" : { + "default" : 0, + "description" : "Also wipe disks so they can be repurposed afterwards.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/lvm/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List LVM Volume Groups", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "children" : { + "items" : { + "properties" : { + "children" : { + "description" : "The underlying physical volumes", + "items" : { + "properties" : { + "free" : { + "description" : "The free bytes in the physical volume", + "type" : "integer" + }, + "leaf" : { + "type" : "boolean" + }, + "name" : { + "description" : "The name of the physical volume", + "type" : "string" + }, + "size" : { + "description" : "The size of the physical volume in bytes", + "type" : "integer" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "free" : { + "description" : "The free bytes in the volume group", + "type" : "integer" + }, + "leaf" : { + "type" : "boolean" + }, + "name" : { + "description" : "The name of the volume group", + "type" : "string" + }, + "size" : { + "description" : "The size of the volume group in bytes", + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "leaf" : { + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create an LVM Volume Group", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storage" : { + "default" : 0, + "description" : "Configure storage using the Volume Group", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "device" : { + "description" : "The block device you want to create the volume group on", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks/lvm", + "text" : "lvm" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove an LVM thin pool.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cleanup-config" : { + "default" : 0, + "description" : "Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cleanup-disks" : { + "default" : 0, + "description" : "Also wipe disks so they can be repurposed afterwards.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "volume-group" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/lvmthin/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List LVM thinpools", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "lv" : { + "description" : "The name of the thinpool.", + "type" : "string" + }, + "lv_size" : { + "description" : "The size of the thinpool in bytes.", + "type" : "integer" + }, + "metadata_size" : { + "description" : "The size of the metadata lv in bytes.", + "type" : "integer" + }, + "metadata_used" : { + "description" : "The used bytes of the metadata lv.", + "type" : "integer" + }, + "used" : { + "description" : "The used bytes of the thinpool.", + "type" : "integer" + }, + "vg" : { + "description" : "The associated volume group.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create an LVM thinpool", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storage" : { + "default" : 0, + "description" : "Configure storage using the thinpool.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "device" : { + "description" : "The block device you want to create the thinpool on.", + "type" : "string", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks/lvmthin", + "text" : "lvmthin" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Unmounts the storage and removes the mount unit.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cleanup-config" : { + "default" : 0, + "description" : "Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cleanup-disks" : { + "default" : 0, + "description" : "Also wipe disk so it can be repurposed afterwards.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/directory/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "PVE Managed Directory storages.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "device" : { + "description" : "The mounted device.", + "type" : "string" + }, + "options" : { + "description" : "The mount options.", + "type" : "string" + }, + "path" : { + "description" : "The mount path.", + "type" : "string" + }, + "type" : { + "description" : "The filesystem type.", + "type" : "string" + }, + "unitfile" : { + "description" : "The path of the mount unit.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a Filesystem on an unused disk. Will be mounted under '/mnt/pve/NAME'.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storage" : { + "default" : 0, + "description" : "Configure storage using the directory.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "device" : { + "description" : "The block device you want to create the filesystem on.", + "type" : "string", + "typetext" : "" + }, + "filesystem" : { + "default" : "ext4", + "description" : "The desired filesystem.", + "enum" : [ + "ext4", + "xfs" + ], + "optional" : 1, + "type" : "string" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks/directory", + "text" : "directory" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Destroy a ZFS pool.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cleanup-config" : { + "default" : 0, + "description" : "Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cleanup-disks" : { + "default" : 0, + "description" : "Also wipe disks so they can be repurposed afterwards.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get details about a zpool.", + "method" : "GET", + "name" : "detail", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "action" : { + "description" : "Information about the recommended action to fix the state.", + "optional" : 1, + "type" : "string" + }, + "children" : { + "description" : "The pool configuration information, including the vdevs for each section (e.g. spares, cache), may be nested.", + "items" : { + "properties" : { + "cksum" : { + "optional" : 1, + "type" : "number" + }, + "msg" : { + "description" : "An optional message about the vdev.", + "type" : "string" + }, + "name" : { + "description" : "The name of the vdev or section.", + "type" : "string" + }, + "read" : { + "optional" : 1, + "type" : "number" + }, + "state" : { + "description" : "The state of the vdev.", + "optional" : 1, + "type" : "string" + }, + "write" : { + "optional" : 1, + "type" : "number" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "errors" : { + "description" : "Information about the errors on the zpool.", + "type" : "string" + }, + "name" : { + "description" : "The name of the zpool.", + "type" : "string" + }, + "scan" : { + "description" : "Information about the last/current scrub.", + "optional" : 1, + "type" : "string" + }, + "state" : { + "description" : "The state of the zpool.", + "type" : "string" + }, + "status" : { + "description" : "Information about the state of the zpool.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/zfs/{name}", + "text" : "{name}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List Zpools.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "alloc" : { + "description" : "", + "type" : "integer" + }, + "dedup" : { + "description" : "", + "type" : "number" + }, + "frag" : { + "description" : "", + "type" : "integer" + }, + "free" : { + "description" : "", + "type" : "integer" + }, + "health" : { + "description" : "", + "type" : "string" + }, + "name" : { + "description" : "", + "type" : "string" + }, + "size" : { + "description" : "", + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a ZFS pool.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "add_storage" : { + "default" : 0, + "description" : "Configure storage using the zpool.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ashift" : { + "default" : 12, + "description" : "Pool sector size exponent.", + "maximum" : 16, + "minimum" : 9, + "optional" : 1, + "type" : "integer", + "typetext" : " (9 - 16)" + }, + "compression" : { + "default" : "on", + "description" : "The compression algorithm to use.", + "enum" : [ + "on", + "off", + "gzip", + "lz4", + "lzjb", + "zle", + "zstd" + ], + "optional" : 1, + "type" : "string" + }, + "devices" : { + "description" : "The block devices you want to create the zpool on.", + "format" : "string-list", + "type" : "string", + "typetext" : "" + }, + "draid-config" : { + "format" : { + "data" : { + "description" : "The number of data devices per redundancy group. (dRAID)", + "minimum" : 1, + "type" : "integer" + }, + "spares" : { + "description" : "Number of dRAID spares.", + "minimum" : 0, + "type" : "integer" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "data= ,spares=" + }, + "name" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "raidlevel" : { + "description" : "The RAID level to use.", + "enum" : [ + "single", + "mirror", + "raid10", + "raidz", + "raidz2", + "raidz3", + "draid", + "draid2", + "draid3" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description" : "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks/zfs", + "text" : "zfs" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List local disks.", + "method" : "GET", + "name" : "list", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "include-partitions" : { + "default" : 0, + "description" : "Also include partitions.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "skipsmart" : { + "default" : 0, + "description" : "Skip smart checks.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "type" : { + "description" : "Only list specific types of disks.", + "enum" : [ + "unused", + "journal_disks" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit" + ] + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "devpath" : { + "description" : "The device path", + "type" : "string" + }, + "gpt" : { + "type" : "boolean" + }, + "health" : { + "optional" : 1, + "type" : "string" + }, + "model" : { + "optional" : 1, + "type" : "string" + }, + "mounted" : { + "type" : "boolean" + }, + "osdid" : { + "type" : "integer" + }, + "osdid-list" : { + "items" : { + "type" : "integer" + }, + "type" : "array" + }, + "parent" : { + "description" : "For partitions only. The device path of the disk the partition resides on.", + "optional" : 1, + "type" : "string" + }, + "serial" : { + "optional" : 1, + "type" : "string" + }, + "size" : { + "type" : "integer" + }, + "used" : { + "optional" : 1, + "type" : "string" + }, + "vendor" : { + "optional" : 1, + "type" : "string" + }, + "wwn" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/list", + "text" : "list" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get SMART Health of a disk.", + "method" : "GET", + "name" : "smart", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "disk" : { + "description" : "Block device name", + "pattern" : "^/dev/[a-zA-Z0-9\\/]+$", + "type" : "string" + }, + "healthonly" : { + "description" : "If true returns only the health status", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "attributes" : { + "optional" : 1, + "type" : "array" + }, + "health" : { + "type" : "string" + }, + "text" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/smart", + "text" : "smart" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Initialize Disk with GPT", + "method" : "POST", + "name" : "initgpt", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "disk" : { + "description" : "Block device name", + "pattern" : "^/dev/[a-zA-Z0-9\\/]+$", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "uuid" : { + "description" : "UUID for the GPT table", + "maxLength" : 36, + "optional" : 1, + "pattern" : "[a-fA-F0-9\\-]+", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/initgpt", + "text" : "initgpt" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Wipe a disk or partition.", + "method" : "PUT", + "name" : "wipe_disk", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "disk" : { + "description" : "Block device name", + "pattern" : "^/dev/[a-zA-Z0-9\\/]+$", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/disks/wipedisk", + "text" : "wipedisk" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Node index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/disks", + "text" : "disks" + }, + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List available updates.", + "method" : "GET", + "name" : "list_updates", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "This is used to resynchronize the package index files from their sources (apt-get update).", + "method" : "POST", + "name" : "update_database", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "notify" : { + "default" : 0, + "description" : "Send notification about new packages.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "quiet" : { + "default" : 0, + "description" : "Only produces output suitable for logging, omitting progress indicators.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/apt/update", + "text" : "update" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get package changelogs.", + "method" : "GET", + "name" : "changelog", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "name" : { + "description" : "Package name.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "version" : { + "description" : "Package version.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/apt/changelog", + "text" : "changelog" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get APT repository information.", + "method" : "GET", + "name" : "repositories", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "description" : "Result from parsing the APT repository files in /etc/apt/.", + "properties" : { + "digest" : { + "description" : "Common digest of all files.", + "type" : "string" + }, + "errors" : { + "description" : "List of problematic repository files.", + "items" : { + "properties" : { + "error" : { + "description" : "The error message", + "type" : "string" + }, + "path" : { + "description" : "Path to the problematic file.", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "files" : { + "description" : "List of parsed repository files.", + "items" : { + "properties" : { + "digest" : { + "description" : "Digest of the file as bytes.", + "items" : { + "type" : "integer" + }, + "type" : "array" + }, + "file-type" : { + "description" : "Format of the file.", + "enum" : [ + "list", + "sources" + ], + "type" : "string" + }, + "path" : { + "description" : "Path to the problematic file.", + "type" : "string" + }, + "repositories" : { + "description" : "The parsed repositories.", + "items" : { + "properties" : { + "Comment" : { + "description" : "Associated comment", + "optional" : 1, + "type" : "string" + }, + "Components" : { + "description" : "List of repository components", + "items" : { + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "Enabled" : { + "description" : "Whether the repository is enabled or not", + "type" : "boolean" + }, + "FileType" : { + "description" : "Format of the defining file.", + "enum" : [ + "list", + "sources" + ], + "type" : "string" + }, + "Options" : { + "description" : "Additional options", + "items" : { + "properties" : { + "Key" : { + "type" : "string" + }, + "Values" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "Suites" : { + "description" : "List of package distribuitions", + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "Types" : { + "description" : "List of package types.", + "items" : { + "enum" : [ + "deb", + "deb-src" + ], + "type" : "string" + }, + "type" : "array" + }, + "URIs" : { + "description" : "List of repository URIs.", + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "infos" : { + "description" : "Additional information/warnings for APT repositories.", + "items" : { + "properties" : { + "index" : { + "description" : "Index of the associated repository within the file.", + "type" : "string" + }, + "kind" : { + "description" : "Kind of the information (e.g. warning).", + "type" : "string" + }, + "message" : { + "description" : "Information message.", + "type" : "string" + }, + "path" : { + "description" : "Path to the associated file.", + "type" : "string" + }, + "property" : { + "description" : "Property from which the info originates.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "standard-repos" : { + "description" : "List of standard repositories and their configuration status", + "items" : { + "properties" : { + "handle" : { + "description" : "Handle to identify the repository.", + "type" : "string" + }, + "name" : { + "description" : "Full name of the repository.", + "type" : "string" + }, + "status" : { + "description" : "Indicating enabled/disabled status, if the repository is configured.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Change the properties of a repository. Currently only allows enabling/disabling.", + "method" : "POST", + "name" : "change_repository", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Digest to detect modifications.", + "maxLength" : 80, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enabled" : { + "description" : "Whether the repository should be enabled or not.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "index" : { + "description" : "Index within the file (starting from 0).", + "type" : "integer", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "Path to the containing file.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Add a standard repository to the configuration", + "method" : "PUT", + "name" : "add_repository", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Digest to detect modifications.", + "maxLength" : 80, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "handle" : { + "description" : "Handle that identifies a repository.", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/apt/repositories", + "text" : "repositories" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get package information for important Proxmox packages.", + "method" : "GET", + "name" : "versions", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/apt/versions", + "text" : "versions" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index for apt (Advanced Package Tool).", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/apt", + "text" : "apt" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete rule.", + "method" : "DELETE", + "name" : "delete_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get single rule data.", + "method" : "GET", + "name" : "get_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "action" : { + "type" : "string" + }, + "comment" : { + "optional" : 1, + "type" : "string" + }, + "dest" : { + "optional" : 1, + "type" : "string" + }, + "dport" : { + "optional" : 1, + "type" : "string" + }, + "enable" : { + "optional" : 1, + "type" : "integer" + }, + "icmp-type" : { + "optional" : 1, + "type" : "string" + }, + "iface" : { + "optional" : 1, + "type" : "string" + }, + "ipversion" : { + "optional" : 1, + "type" : "integer" + }, + "log" : { + "description" : "Log level for firewall rule", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "optional" : 1, + "type" : "string" + }, + "pos" : { + "type" : "integer" + }, + "proto" : { + "optional" : 1, + "type" : "string" + }, + "source" : { + "optional" : 1, + "type" : "string" + }, + "sport" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Modify rule data.", + "method" : "PUT", + "name" : "update_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "moveto" : { + "description" : "Move rule to new position . Other arguments are ignored.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/firewall/rules/{pos}", + "text" : "{pos}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List rules.", + "method" : "GET", + "name" : "get_rules", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "pos" : { + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{pos}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new rule.", + "method" : "POST", + "name" : "create_rule", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "action" : { + "description" : "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.", + "maxLength" : 20, + "minLength" : 2, + "optional" : 0, + "pattern" : "[A-Za-z][A-Za-z0-9\\-\\_]+", + "type" : "string" + }, + "comment" : { + "description" : "Descriptive comment.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dest" : { + "description" : "Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dport" : { + "description" : "Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-dport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Flag to enable/disable a rule.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "icmp-type" : { + "description" : "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format" : "pve-fw-icmp-type-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iface" : { + "description" : "Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.", + "format" : "pve-iface", + "maxLength" : 20, + "minLength" : 2, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "log" : { + "description" : "Log level for firewall rule.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "macro" : { + "description" : "Use predefined standard macro.", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "pos" : { + "description" : "Update rule at position .", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "proto" : { + "description" : "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format" : "pve-fw-protocol-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "source" : { + "description" : "Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.", + "format" : "pve-fw-addr-spec", + "maxLength" : 512, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sport" : { + "description" : "Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.", + "format" : "pve-fw-sport-spec", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "Rule type.", + "enum" : [ + "in", + "out", + "forward", + "group" + ], + "optional" : 0, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/firewall/rules", + "text" : "rules" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get host firewall options.", + "method" : "GET", + "name" : "get_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "enable" : { + "description" : "Enable host firewall rules.", + "optional" : 1, + "type" : "boolean" + }, + "log_level_forward" : { + "description" : "Log level for forwarded traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_nf_conntrack" : { + "default" : 0, + "description" : "Enable logging of conntrack information.", + "optional" : 1, + "type" : "boolean" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean" + }, + "nf_conntrack_allow_invalid" : { + "default" : 0, + "description" : "Allow invalid packets on connection tracking.", + "optional" : 1, + "type" : "boolean" + }, + "nf_conntrack_helpers" : { + "default" : "", + "description" : "Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp", + "format" : "pve-fw-conntrack-helper", + "optional" : 1, + "type" : "string" + }, + "nf_conntrack_max" : { + "default" : 262144, + "description" : "Maximum number of tracked connections.", + "minimum" : 32768, + "optional" : 1, + "type" : "integer" + }, + "nf_conntrack_tcp_timeout_established" : { + "default" : 432000, + "description" : "Conntrack established timeout.", + "minimum" : 7875, + "optional" : 1, + "type" : "integer" + }, + "nf_conntrack_tcp_timeout_syn_recv" : { + "default" : 60, + "description" : "Conntrack syn recv timeout.", + "maximum" : 60, + "minimum" : 30, + "optional" : 1, + "type" : "integer" + }, + "nftables" : { + "default" : 0, + "description" : "Enable nftables based firewall (tech preview)", + "optional" : 1, + "type" : "boolean" + }, + "nosmurfs" : { + "description" : "Enable SMURFS filter.", + "optional" : 1, + "type" : "boolean" + }, + "protection_synflood" : { + "default" : 0, + "description" : "Enable synflood protection", + "optional" : 1, + "type" : "boolean" + }, + "protection_synflood_burst" : { + "default" : 1000, + "description" : "Synflood protection rate burst by ip src.", + "optional" : 1, + "type" : "integer" + }, + "protection_synflood_rate" : { + "default" : 200, + "description" : "Synflood protection rate syn/sec by ip src.", + "optional" : 1, + "type" : "integer" + }, + "smurf_log_level" : { + "description" : "Log level for SMURFS filter.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "tcp_flags_log_level" : { + "description" : "Log level for illegal tcp flags filter.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "tcpflags" : { + "default" : 0, + "description" : "Filter illegal combinations of TCP flags.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set Firewall options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Enable host firewall rules.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "log_level_forward" : { + "description" : "Log level for forwarded traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_in" : { + "description" : "Log level for incoming traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_level_out" : { + "description" : "Log level for outgoing traffic.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "log_nf_conntrack" : { + "default" : 0, + "description" : "Enable logging of conntrack information.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "ndp" : { + "default" : 0, + "description" : "Enable NDP (Neighbor Discovery Protocol).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nf_conntrack_allow_invalid" : { + "default" : 0, + "description" : "Allow invalid packets on connection tracking.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nf_conntrack_helpers" : { + "default" : "", + "description" : "Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp", + "format" : "pve-fw-conntrack-helper", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nf_conntrack_max" : { + "default" : 262144, + "description" : "Maximum number of tracked connections.", + "minimum" : 32768, + "optional" : 1, + "type" : "integer", + "typetext" : " (32768 - N)" + }, + "nf_conntrack_tcp_timeout_established" : { + "default" : 432000, + "description" : "Conntrack established timeout.", + "minimum" : 7875, + "optional" : 1, + "type" : "integer", + "typetext" : " (7875 - N)" + }, + "nf_conntrack_tcp_timeout_syn_recv" : { + "default" : 60, + "description" : "Conntrack syn recv timeout.", + "maximum" : 60, + "minimum" : 30, + "optional" : 1, + "type" : "integer", + "typetext" : " (30 - 60)" + }, + "nftables" : { + "default" : 0, + "description" : "Enable nftables based firewall (tech preview)", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "nosmurfs" : { + "description" : "Enable SMURFS filter.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "protection_synflood" : { + "default" : 0, + "description" : "Enable synflood protection", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "protection_synflood_burst" : { + "default" : 1000, + "description" : "Synflood protection rate burst by ip src.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "protection_synflood_rate" : { + "default" : 200, + "description" : "Synflood protection rate syn/sec by ip src.", + "optional" : 1, + "type" : "integer", + "typetext" : "" + }, + "smurf_log_level" : { + "description" : "Log level for SMURFS filter.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "tcp_flags_log_level" : { + "description" : "Log level for illegal tcp flags filter.", + "enum" : [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ], + "optional" : 1, + "type" : "string" + }, + "tcpflags" : { + "default" : 0, + "description" : "Filter illegal combinations of TCP flags.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/firewall/options", + "text" : "options" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read firewall log", + "method" : "GET", + "name" : "log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display log since this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "until" : { + "description" : "Display log until this UNIX epoch.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/firewall/log", + "text" : "log" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/firewall", + "text" : "firewall" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get replication job status.", + "method" : "GET", + "name" : "job_status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/replication/{id}/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read replication job log.", + "method" : "GET", + "name" : "read_job_log", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/, or 'Sys.Audit' on '/nodes/'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/replication/{id}/log", + "text" : "log" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Schedule replication job to start as soon as possible.", + "method" : "POST", + "name" : "schedule_now", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/replication/{id}/schedule_now", + "text" : "schedule_now" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.", + "format" : "pve-replication-job-id", + "pattern" : "[1-9][0-9]{2,8}-\\d{1,9}", + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/replication/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List status of all replication jobs on this node.", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "guest" : { + "description" : "Only list replication jobs for this guest.", + "format" : "pve-vmid", + "maximum" : 999999999, + "minimum" : 100, + "optional" : 1, + "type" : "integer", + "typetext" : " (100 - 999999999)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Requires the VM.Audit permission on /vms/.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "id" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/replication", + "text" : "replication" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Revoke existing certificate from CA.", + "method" : "DELETE", + "name" : "revoke_certificate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Order a new certificate from ACME-compatible CA.", + "method" : "POST", + "name" : "new_certificate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "Overwrite existing custom certificate.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Renew existing certificate from CA.", + "method" : "PUT", + "name" : "renew_certificate", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : 0, + "description" : "Force renewal even if expiry is more than 30 days away.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/certificates/acme/certificate", + "text" : "certificate" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "ACME index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/certificates/acme", + "text" : "acme" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get information about node's certificates.", + "method" : "GET", + "name" : "info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "filename" : { + "optional" : 1, + "type" : "string" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "issuer" : { + "description" : "Certificate issuer name.", + "optional" : 1, + "type" : "string" + }, + "notafter" : { + "description" : "Certificate's notAfter timestamp (UNIX epoch).", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "notbefore" : { + "description" : "Certificate's notBefore timestamp (UNIX epoch).", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "pem" : { + "description" : "Certificate in PEM format", + "format" : "pem-certificate", + "optional" : 1, + "type" : "string" + }, + "public-key-bits" : { + "description" : "Certificate's public key size", + "optional" : 1, + "type" : "integer" + }, + "public-key-type" : { + "description" : "Certificate's public key algorithm", + "optional" : 1, + "type" : "string" + }, + "san" : { + "description" : "List of Certificate's SubjectAlternativeName entries.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "renderer" : "yaml", + "type" : "array" + }, + "subject" : { + "description" : "Certificate subject name.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/certificates/info", + "text" : "info" + }, + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "DELETE custom certificate chain and key.", + "method" : "DELETE", + "name" : "remove_custom_cert", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "restart" : { + "default" : 0, + "description" : "Restart pveproxy.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Upload or update custom certificate chain and key.", + "method" : "POST", + "name" : "upload_custom_cert", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "certificates" : { + "description" : "PEM encoded certificate (chain).", + "format" : "pem-certificate-chain", + "type" : "string", + "typetext" : "" + }, + "force" : { + "default" : 0, + "description" : "Overwrite existing custom or ACME certificate files.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "key" : { + "description" : "PEM encoded private key.", + "format" : "pem-string", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "restart" : { + "default" : 0, + "description" : "Restart pveproxy.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "filename" : { + "optional" : 1, + "type" : "string" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "issuer" : { + "description" : "Certificate issuer name.", + "optional" : 1, + "type" : "string" + }, + "notafter" : { + "description" : "Certificate's notAfter timestamp (UNIX epoch).", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "notbefore" : { + "description" : "Certificate's notBefore timestamp (UNIX epoch).", + "optional" : 1, + "renderer" : "timestamp", + "type" : "integer" + }, + "pem" : { + "description" : "Certificate in PEM format", + "format" : "pem-certificate", + "optional" : 1, + "type" : "string" + }, + "public-key-bits" : { + "description" : "Certificate's public key size", + "optional" : 1, + "type" : "integer" + }, + "public-key-type" : { + "description" : "Certificate's public key algorithm", + "optional" : 1, + "type" : "string" + }, + "san" : { + "description" : "List of Certificate's SubjectAlternativeName entries.", + "items" : { + "type" : "string" + }, + "optional" : 1, + "renderer" : "yaml", + "type" : "array" + }, + "subject" : { + "description" : "Certificate subject name.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/certificates/custom", + "text" : "custom" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Node index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/certificates", + "text" : "certificates" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get node configuration options.", + "method" : "GET", + "name" : "get_config", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "property" : { + "default" : "all", + "description" : "Return only a specific property from the node configuration.", + "enum" : [ + "acme", + "acmedomain0", + "acmedomain1", + "acmedomain2", + "acmedomain3", + "acmedomain4", + "acmedomain5", + "ballooning-target", + "description", + "startall-onboot-delay", + "wakeonlan" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "acme" : { + "description" : "Node specific ACME settings.", + "format" : { + "account" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string" + }, + "domains" : { + "description" : "List of domains for this node's ACME certificate", + "format" : "pve-acme-domain-list", + "format_description" : "domain[;domain;...]", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "acmedomain[n]" : { + "description" : "ACME domain and validation plugin", + "format" : { + "alias" : { + "description" : "Alias for the Domain to verify ACME Challenge over DNS", + "format" : "pve-acme-alias", + "format_description" : "domain", + "optional" : 1, + "type" : "string" + }, + "domain" : { + "default_key" : 1, + "description" : "domain for this node's ACME certificate", + "format" : "pve-acme-domain", + "format_description" : "domain", + "type" : "string" + }, + "plugin" : { + "default" : "standalone", + "description" : "The ACME plugin ID", + "format" : "pve-configid", + "format_description" : "name of the plugin configuration", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + }, + "ballooning-target" : { + "default" : 80, + "description" : "RAM usage target for ballooning (in percent of total memory)", + "maximum" : 100, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "description" : { + "description" : "Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.", + "maxLength" : 65536, + "optional" : 1, + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string" + }, + "startall-onboot-delay" : { + "default" : 0, + "description" : "Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.", + "maximum" : 300, + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "wakeonlan" : { + "description" : "Node specific wake on LAN settings.", + "format" : { + "bind-interface" : { + "default" : "The interface carrying the default route", + "description" : "Bind to this interface when sending wake on LAN packet", + "format" : "pve-iface", + "format_description" : "bind interface", + "optional" : 1, + "type" : "string" + }, + "broadcast-address" : { + "default" : "255.255.255.255", + "description" : "IPv4 broadcast address to use when sending wake on LAN packet", + "format" : "ipv4", + "format_description" : "IPv4 broadcast address", + "optional" : 1, + "type" : "string" + }, + "mac" : { + "default_key" : 1, + "description" : "MAC address for wake on LAN", + "format" : "mac-addr", + "format_description" : "MAC address", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set node configuration options.", + "method" : "PUT", + "name" : "set_options", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acme" : { + "description" : "Node specific ACME settings.", + "format" : { + "account" : { + "default" : "default", + "description" : "ACME account config file name.", + "format" : "pve-configid", + "format_description" : "name", + "optional" : 1, + "type" : "string" + }, + "domains" : { + "description" : "List of domains for this node's ACME certificate", + "format" : "pve-acme-domain-list", + "format_description" : "domain[;domain;...]", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[account=] [,domains=]" + }, + "acmedomain[n]" : { + "description" : "ACME domain and validation plugin", + "format" : { + "alias" : { + "description" : "Alias for the Domain to verify ACME Challenge over DNS", + "format" : "pve-acme-alias", + "format_description" : "domain", + "optional" : 1, + "type" : "string" + }, + "domain" : { + "default_key" : 1, + "description" : "domain for this node's ACME certificate", + "format" : "pve-acme-domain", + "format_description" : "domain", + "type" : "string" + }, + "plugin" : { + "default" : "standalone", + "description" : "The ACME plugin ID", + "format" : "pve-configid", + "format_description" : "name of the plugin configuration", + "optional" : 1, + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[domain=] [,alias=] [,plugin=]" + }, + "ballooning-target" : { + "default" : 80, + "description" : "RAM usage target for ballooning (in percent of total memory)", + "maximum" : 100, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 100)" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.", + "maxLength" : 65536, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.", + "maxLength" : 40, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "startall-onboot-delay" : { + "default" : 0, + "description" : "Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.", + "maximum" : 300, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 300)" + }, + "wakeonlan" : { + "description" : "Node specific wake on LAN settings.", + "format" : { + "bind-interface" : { + "default" : "The interface carrying the default route", + "description" : "Bind to this interface when sending wake on LAN packet", + "format" : "pve-iface", + "format_description" : "bind interface", + "optional" : 1, + "type" : "string" + }, + "broadcast-address" : { + "default" : "255.255.255.255", + "description" : "IPv4 broadcast address to use when sending wake on LAN packet", + "format" : "ipv4", + "format_description" : "IPv4 broadcast address", + "optional" : 1, + "type" : "string" + }, + "mac" : { + "default_key" : 1, + "description" : "MAC address for wake on LAN", + "format" : "mac-addr", + "format_description" : "MAC address", + "type" : "string" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[mac=] [,bind-interface=] [,broadcast-address=]" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/config", + "text" : "config" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List zone content.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ], + "any", + 1 + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "status" : { + "description" : "Status.", + "optional" : 1, + "type" : "string" + }, + "statusmsg" : { + "description" : "Status details", + "optional" : 1, + "type" : "string" + }, + "vnet" : { + "description" : "Vnet identifier.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{vnet}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/sdn/zones/{zone}/content", + "text" : "content" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "", + "method" : "GET", + "name" : "diridx", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ], + "any", + 1 + ] + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/sdn/zones/{zone}", + "text" : "{zone}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get status for all zones.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'SDN.Audit'", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "status" : { + "description" : "Status of zone", + "enum" : [ + "available", + "pending", + "error" + ], + "type" : "string" + }, + "zone" : { + "description" : "The SDN zone object identifier.", + "format" : "pve-sdn-zone-id", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{zone}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/sdn/zones", + "text" : "zones" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "SDN index.", + "method" : "GET", + "name" : "sdnindex", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}/sdn", + "text" : "sdn" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "API version details", + "method" : "GET", + "name" : "version", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "release" : { + "description" : "The current installed Proxmox VE Release", + "type" : "string" + }, + "repoid" : { + "description" : "The short git commit hash ID from which this version was build", + "type" : "string" + }, + "version" : { + "description" : "The current installed pve-manager package version", + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/version", + "text" : "version" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read node status", + "method" : "GET", + "name" : "status", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 1, + "properties" : { + "boot-info" : { + "description" : "Meta-information about the boot mode.", + "properties" : { + "mode" : { + "description" : "Through which firmware the system got booted.", + "enum" : [ + "efi", + "legacy-bios" + ], + "type" : "string" + }, + "secureboot" : { + "description" : "System is booted in secure mode, only applicable for the \"efi\" mode.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "cpu" : { + "description" : "The current cpu usage.", + "type" : "number" + }, + "cpuinfo" : { + "properties" : { + "cores" : { + "description" : "The number of physical cores of the CPU.", + "type" : "integer" + }, + "cpus" : { + "description" : "The number of logical threads of the CPU.", + "type" : "integer" + }, + "model" : { + "description" : "The CPU model", + "type" : "string" + }, + "sockets" : { + "description" : "The number of logical threads of the CPU.", + "type" : "integer" + } + }, + "type" : "object" + }, + "current-kernel" : { + "description" : "Meta-information about the currently booted kernel of this node.", + "properties" : { + "machine" : { + "description" : "Hardware (architecture) type", + "type" : "string" + }, + "release" : { + "description" : "OS kernel release (e.g., \"6.8.0\")", + "type" : "string" + }, + "sysname" : { + "description" : "OS kernel name (e.g., \"Linux\")", + "type" : "string" + }, + "version" : { + "description" : "OS kernel version with build info", + "type" : "string" + } + }, + "type" : "object" + }, + "loadavg" : { + "description" : "An array of load avg for 1, 5 and 15 minutes respectively.", + "items" : { + "description" : "The value of the load.", + "type" : "string" + }, + "type" : "array" + }, + "memory" : { + "properties" : { + "free" : { + "description" : "The free memory in bytes.", + "type" : "integer" + }, + "total" : { + "description" : "The total memory in bytes.", + "type" : "integer" + }, + "used" : { + "description" : "The used memory in bytes.", + "type" : "integer" + } + }, + "type" : "object" + }, + "pveversion" : { + "description" : "The PVE version string.", + "type" : "string" + }, + "rootfs" : { + "properties" : { + "avail" : { + "description" : "The available bytes in the root filesystem.", + "type" : "integer" + }, + "free" : { + "description" : "The free bytes on the root filesystem.", + "type" : "integer" + }, + "total" : { + "description" : "The total size of the root filesystem in bytes.", + "type" : "integer" + }, + "used" : { + "description" : "The used bytes in the root filesystem.", + "type" : "integer" + } + }, + "type" : "object" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Reboot or shutdown a node.", + "method" : "POST", + "name" : "node_cmd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "command" : { + "description" : "Specify the command.", + "enum" : [ + "reboot", + "shutdown" + ], + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.PowerMgmt" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/status", + "text" : "status" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read tap/vm network device interface counters", + "method" : "GET", + "name" : "netstat", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/netstat", + "text" : "netstat" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Execute multiple commands in order, root only.", + "method" : "POST", + "name" : "execute", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "commands" : { + "description" : "JSON encoded array of commands.", + "format" : "pve-command-batch", + "type" : "string", + "typetext" : "", + "verbose_description" : "JSON encoded array of commands, where each command is an object with the following properties:\n args: \n\t A set of parameter names and their values.\n\n method: (GET|POST|PUT|DELETE)\n\t A method related to the API endpoint (GET, POST etc.).\n\n path: \n\t A relative path to an API endpoint on this node.\n\n" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/execute", + "text" : "execute" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Try to wake a node via 'wake on LAN' network packet.", + "method" : "POST", + "name" : "wakeonlan", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "target node for wake on LAN packet", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.PowerMgmt" + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "MAC address used to assemble the WoL magic packet.", + "format" : "mac-addr", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/wakeonlan", + "text" : "wakeonlan" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read node RRD statistics (returns PNG)", + "method" : "GET", + "name" : "rrd", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "ds" : { + "description" : "The list of datasources you want to display.", + "format" : "pve-configid-list", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "filename" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/rrd", + "text" : "rrd" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read node RRD statistics", + "method" : "GET", + "name" : "rrddata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cf" : { + "description" : "The RRD consolidation function", + "enum" : [ + "AVERAGE", + "MAX" + ], + "optional" : 1, + "type" : "string" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeframe" : { + "description" : "Specify the time frame you are interested in.", + "enum" : [ + "hour", + "day", + "week", + "month", + "year" + ], + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/rrddata", + "text" : "rrddata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read system log", + "method" : "GET", + "name" : "syslog", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "limit" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "service" : { + "description" : "Service ID", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display all log since this date-time string.", + "optional" : 1, + "pattern" : "^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$", + "type" : "string" + }, + "start" : { + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "until" : { + "description" : "Display all log until this date-time string.", + "optional" : 1, + "pattern" : "^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : { + "n" : { + "description" : "Line number", + "type" : "integer" + }, + "t" : { + "description" : "Line text", + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/syslog", + "text" : "syslog" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read Journal", + "download_allowed" : 1, + "method" : "GET", + "name" : "journal", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "endcursor" : { + "description" : "End before the given Cursor. Conflicts with 'until'", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "lastentries" : { + "description" : "Limit to the last X lines. Conflicts with a range.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "since" : { + "description" : "Display all log since this UNIX epoch. Conflicts with 'startcursor'.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "startcursor" : { + "description" : "Start after the given Cursor. Conflicts with 'since'", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "until" : { + "description" : "Display all log until this UNIX epoch. Conflicts with 'endcursor'.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/journal", + "text" : "journal" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a VNC Shell proxy.", + "method" : "POST", + "name" : "vncshell", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cmd" : { + "default" : "login", + "description" : "Run specific command or default to login (requires 'root@pam')", + "enum" : [ + "ceph_install", + "upgrade", + "login" + ], + "optional" : 1, + "type" : "string" + }, + "cmd-opts" : { + "default" : "", + "description" : "Add parameters to a command. Encoded as null terminated strings.", + "optional" : 1, + "requires" : "cmd", + "type" : "string", + "typetext" : "" + }, + "height" : { + "description" : "sets the height of the console in pixels.", + "maximum" : 2160, + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - 2160)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "websocket" : { + "description" : "use websocket instead of standard vnc.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "width" : { + "description" : "sets the width of the console in pixels.", + "maximum" : 4096, + "minimum" : 16, + "optional" : 1, + "type" : "integer", + "typetext" : " (16 - 4096)" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "cert" : { + "type" : "string" + }, + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/vncshell", + "text" : "vncshell" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a VNC Shell proxy.", + "method" : "POST", + "name" : "termproxy", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cmd" : { + "default" : "login", + "description" : "Run specific command or default to login (requires 'root@pam')", + "enum" : [ + "ceph_install", + "upgrade", + "login" + ], + "optional" : 1, + "type" : "string" + }, + "cmd-opts" : { + "default" : "", + "description" : "Add parameters to a command. Encoded as null terminated strings.", + "optional" : 1, + "requires" : "cmd", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "port" : { + "type" : "integer" + }, + "ticket" : { + "type" : "string" + }, + "upid" : { + "type" : "string" + }, + "user" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/termproxy", + "text" : "termproxy" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Opens a websocket for VNC traffic.", + "method" : "GET", + "name" : "vncwebsocket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Port number returned by previous vncproxy call.", + "maximum" : 5999, + "minimum" : 5900, + "type" : "integer", + "typetext" : " (5900 - 5999)" + }, + "vncticket" : { + "description" : "Ticket from previous call to vncproxy.", + "maxLength" : 512, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ], + "description" : "You also need to pass a valid ticket (vncticket)." + }, + "returns" : { + "properties" : { + "port" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/vncwebsocket", + "text" : "vncwebsocket" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Creates a SPICE shell.", + "method" : "POST", + "name" : "spiceshell", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "cmd" : { + "default" : "login", + "description" : "Run specific command or default to login (requires 'root@pam')", + "enum" : [ + "ceph_install", + "upgrade", + "login" + ], + "optional" : 1, + "type" : "string" + }, + "cmd-opts" : { + "default" : "", + "description" : "Add parameters to a command. Encoded as null terminated strings.", + "optional" : 1, + "requires" : "cmd", + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "proxy" : { + "description" : "SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).", + "format" : "address", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 1, + "description" : "Returned values can be directly passed to the 'remote-viewer' application.", + "properties" : { + "host" : { + "type" : "string" + }, + "password" : { + "type" : "string" + }, + "proxy" : { + "type" : "string" + }, + "tls-port" : { + "type" : "integer" + }, + "type" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/spiceshell", + "text" : "spiceshell" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read DNS settings.", + "method" : "GET", + "name" : "dns", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "properties" : { + "dns1" : { + "description" : "First name server IP address.", + "optional" : 1, + "type" : "string" + }, + "dns2" : { + "description" : "Second name server IP address.", + "optional" : 1, + "type" : "string" + }, + "dns3" : { + "description" : "Third name server IP address.", + "optional" : 1, + "type" : "string" + }, + "search" : { + "description" : "Search domain for host-name lookup.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Write DNS settings.", + "method" : "PUT", + "name" : "update_dns", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dns1" : { + "description" : "First name server IP address.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dns2" : { + "description" : "Second name server IP address.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "dns3" : { + "description" : "Third name server IP address.", + "format" : "ip", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "search" : { + "description" : "Search domain for host-name lookup.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/dns", + "text" : "dns" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Read server time and time zone settings.", + "method" : "GET", + "name" : "time", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "proxyto" : "node", + "returns" : { + "additionalProperties" : 0, + "properties" : { + "localtime" : { + "description" : "Seconds since 1970-01-01 00:00:00 (local time)", + "minimum" : 1297163644, + "renderer" : "timestamp_gmt", + "type" : "integer" + }, + "time" : { + "description" : "Seconds since 1970-01-01 00:00:00 UTC.", + "minimum" : 1297163644, + "renderer" : "timestamp", + "type" : "integer" + }, + "timezone" : { + "description" : "Time zone", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Set time zone.", + "method" : "PUT", + "name" : "set_timezone", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timezone" : { + "description" : "Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names.", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/time", + "text" : "time" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get list of appliances.", + "method" : "GET", + "name" : "aplinfo", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "proxyto" : "node", + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Download appliance templates.", + "method" : "POST", + "name" : "apl_download", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "The storage where the template will be stored", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "template" : { + "description" : "The template which will downloaded", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/aplinfo", + "text" : "aplinfo" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Query metadata of an URL: file size, file name and mime type.", + "method" : "GET", + "name" : "query_url_metadata", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "url" : { + "description" : "The URL to query the metadata from.", + "pattern" : "https?://.*", + "type" : "string" + }, + "verify-certificates" : { + "default" : 1, + "description" : "If false, no SSL/TLS certificates will be verified.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.AccessNetwork" + ] + ] + ] + }, + "proxyto" : "node", + "returns" : { + "properties" : { + "filename" : { + "optional" : 1, + "type" : "string" + }, + "mimetype" : { + "optional" : 1, + "type" : "string" + }, + "size" : { + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/query-url-metadata", + "text" : "query-url-metadata" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Gather various systems information about a node", + "method" : "GET", + "name" : "report", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/report", + "text" : "report" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Start all VMs and containers located on this node (by default only those with onboot=1).", + "method" : "POST", + "name" : "startall", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force" : { + "default" : "off", + "description" : "Issue start command even if virtual guest have 'onboot' not set or set to off.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "Only consider guests from this comma separated list of VMIDs.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/startall", + "text" : "startall" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Stop all VMs and Containers.", + "method" : "POST", + "name" : "stopall", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "force-stop" : { + "default" : 1, + "description" : "Force a hard-stop after the timeout.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "timeout" : { + "default" : 180, + "description" : "Timeout for each guest shutdown task. Depending on `force-stop`, the shutdown gets then simply aborted or a hard-stop is forced.", + "maximum" : 7200, + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - 7200)" + }, + "vms" : { + "description" : "Only consider Guests with these IDs.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/stopall", + "text" : "stopall" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Suspend all VMs.", + "method" : "POST", + "name" : "suspendall", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "Only consider Guests with these IDs.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter. Additionally, you need 'VM.Config.Disk' on the '/vms/{vmid}' path and 'Datastore.AllocateSpace' for the configured state-storage(s)", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/suspendall", + "text" : "suspendall" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Migrate all VMs and Containers.", + "method" : "POST", + "name" : "migrateall", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "maxworkers" : { + "description" : "Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg. One of both must be set!", + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - N)" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "target" : { + "description" : "Target node.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "Only consider Guests with these IDs.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "with-local-disks" : { + "description" : "Enable live storage migration for local disk", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The 'VM.Migrate' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user" : "all" + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/migrateall", + "text" : "migrateall" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get the content of /etc/hosts.", + "method" : "GET", + "name" : "get_etc_hosts", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "properties" : { + "data" : { + "description" : "The content of /etc/hosts.", + "type" : "string" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Write /etc/hosts.", + "method" : "POST", + "name" : "write_etc_hosts", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "data" : { + "description" : "The target content of /etc/hosts.", + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "proxyto" : "node", + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/nodes/{node}/hosts", + "text" : "hosts" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Node index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : {}, + "type" : "object" + }, + "links" : [ + { + "href" : "{name}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes/{node}", + "text" : "{node}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Cluster node index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "cpu" : { + "description" : "CPU utilization.", + "optional" : 1, + "renderer" : "fraction_as_percentage", + "type" : "number" + }, + "level" : { + "description" : "Support level.", + "optional" : 1, + "type" : "string" + }, + "maxcpu" : { + "description" : "Number of available CPUs.", + "optional" : 1, + "type" : "integer" + }, + "maxmem" : { + "description" : "Number of available memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "mem" : { + "description" : "Used memory in bytes.", + "optional" : 1, + "renderer" : "bytes", + "type" : "integer" + }, + "node" : { + "description" : "The cluster node name.", + "format" : "pve-node", + "type" : "string" + }, + "ssl_fingerprint" : { + "description" : "The SSL fingerprint for the node certificate.", + "optional" : 1, + "type" : "string" + }, + "status" : { + "description" : "Node status.", + "enum" : [ + "unknown", + "online", + "offline" + ], + "type" : "string" + }, + "uptime" : { + "description" : "Node uptime in seconds.", + "optional" : 1, + "renderer" : "duration", + "type" : "integer" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{node}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/nodes", + "text" : "nodes" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete storage configuration.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Read storage configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/storage/{storage}", + [ + "Datastore.Allocate" + ] + ] + }, + "returns" : { + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update storage configuration.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "blocksize" : { + "description" : "block size", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bwlimit" : { + "description" : "Set I/O bandwidth limit for various operations (in KiB/s).", + "format" : { + "clone" : { + "description" : "bandwidth limit in KiB/s for cloning disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "default" : { + "description" : "default bandwidth limit in KiB/s", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "migration" : { + "description" : "bandwidth limit in KiB/s for migrating guests (including moving local disks)", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "move" : { + "description" : "bandwidth limit in KiB/s for moving disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "restore" : { + "description" : "bandwidth limit in KiB/s for restoring guests from backups", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[clone=] [,default=] [,migration=] [,move=] [,restore=]" + }, + "comstar_hg" : { + "description" : "host group for comstar views", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comstar_tg" : { + "description" : "target group for comstar views", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "content" : { + "description" : "Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n", + "format" : "pve-storage-content-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "content-dirs" : { + "description" : "Overrides for default content type directories.", + "format" : "pve-dir-override-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "create-base-path" : { + "default" : "yes", + "description" : "Create the base directory if it doesn't exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "create-subdirs" : { + "default" : "yes", + "description" : "Populate the directory with the default structure.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "data-pool" : { + "description" : "Data Pool (for erasure coding only)", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the storage.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "domain" : { + "description" : "CIFS domain.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "encryption-key" : { + "description" : "Encryption key. Use 'autogen' to generate one automatically without passphrase.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "format" : { + "description" : "Default image format.", + "enum" : [ + "raw", + "qcow2", + "subvol", + "vmdk" + ], + "optional" : 1, + "type" : "string" + }, + "fs-name" : { + "description" : "The Ceph filesystem name.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fuse" : { + "description" : "Mount CephFS through FUSE.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "is_mountpoint" : { + "default" : "no", + "description" : "Assume the given path is an externally managed mountpoint and consider the storage offline if it is not mounted. Using a boolean (yes/no) value serves as a shortcut to using the target path in this field.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "keyring" : { + "description" : "Client keyring contents (for external clusters).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "krbd" : { + "default" : 0, + "description" : "Always access rbd through krbd kernel module.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lio_tpg" : { + "description" : "target portal group for Linux LIO targets", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "master-pubkey" : { + "description" : "Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "max-protected-backups" : { + "default" : "Unlimited for users with Datastore.Allocate privilege, 5 for other users", + "description" : "Maximal number of protected backups per guest. Use '-1' for unlimited.", + "minimum" : -1, + "optional" : 1, + "type" : "integer", + "typetext" : " (-1 - N)" + }, + "maxfiles" : { + "description" : "Deprecated: use 'prune-backups' instead. Maximal number of backup files per VM. Use '0' for unlimited.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mkdir" : { + "default" : "yes", + "description" : "Create the directory if it doesn't exist and populate it with default sub-dirs. NOTE: Deprecated, use the 'create-base-path' and 'create-subdirs' options instead.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "monhost" : { + "description" : "IP addresses of monitors (for external clusters).", + "format" : "pve-storage-portal-dns-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mountpoint" : { + "description" : "mount point", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "namespace" : { + "description" : "Namespace.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nocow" : { + "default" : 0, + "description" : "Set the NOCOW flag on files. Disables data checksumming and causes data errors to be unrecoverable from while allowing direct I/O. Only use this if data does not need to be any more safe than on a single ext4 formatted disk with no underlying raid system.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nodes" : { + "description" : "List of nodes for which the storage configuration applies.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nowritecache" : { + "description" : "disable write caching on the target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "options" : { + "description" : "NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')", + "format" : "pve-storage-options", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "Password for accessing the share/datastore.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Use this port to connect to the storage instead of the default one (for example, with PBS or ESXi). For NFS and CIFS, use the 'options' option to configure the port via the mount options.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "preallocation" : { + "default" : "metadata", + "description" : "Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off.", + "enum" : [ + "off", + "metadata", + "falloc", + "full" + ], + "optional" : 1, + "type" : "string" + }, + "prune-backups" : { + "description" : "The retention options with shorter intervals are processed first with --keep-last being the very first one. Each option covers a specific period of time. We say that backups within this period are covered by this option. The next option does not take care of already covered backups and only considers older backups.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "saferemove" : { + "description" : "Zero-out data when removing LVs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "saferemove_throughput" : { + "description" : "Wipe throughput (cstream -t parameter value).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "Server IP or DNS name.", + "format" : "pve-storage-server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server2" : { + "description" : "Backup volfile server IP or DNS name.", + "format" : "pve-storage-server", + "optional" : 1, + "requires" : "server", + "type" : "string", + "typetext" : "" + }, + "shared" : { + "description" : "Indicate that this is a single storage with the same contents on all nodes (or all listed in the 'nodes' option). It will not make the contents of a local storage automatically accessible to other nodes, it just marks an already shared storage as such!", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "skip-cert-verification" : { + "default" : "false", + "description" : "Disable TLS certificate verification, only enable on fully trusted networks!", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "smbversion" : { + "default" : "default", + "description" : "SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server.", + "enum" : [ + "default", + "2.0", + "2.1", + "3", + "3.0", + "3.11" + ], + "optional" : 1, + "type" : "string" + }, + "sparse" : { + "description" : "use sparse volumes", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "subdir" : { + "description" : "Subdir to mount.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tagged_only" : { + "description" : "Only use logical volumes tagged with 'pve-vm-ID'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "transport" : { + "description" : "Gluster transport: tcp or rdma", + "enum" : [ + "tcp", + "rdma", + "unix" + ], + "optional" : 1, + "type" : "string" + }, + "username" : { + "description" : "RBD Id.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "config" : { + "additionalProperties" : 1, + "description" : "Partial, possible server generated, configuration properties.", + "optional" : 1, + "properties" : { + "encryption-key" : { + "description" : "The, possible auto-generated, encryption-key.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "storage" : { + "description" : "The ID of the created storage.", + "type" : "string" + }, + "type" : { + "description" : "The type of the created storage.", + "enum" : [ + "btrfs", + "cephfs", + "cifs", + "dir", + "esxi", + "glusterfs", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/storage/{storage}", + "text" : "{storage}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Storage index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "type" : { + "description" : "Only list storage of specific type", + "enum" : [ + "btrfs", + "cephfs", + "cifs", + "dir", + "esxi", + "glusterfs", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "storage" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{storage}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create a new storage.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "authsupported" : { + "description" : "Authsupported.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "base" : { + "description" : "Base volume. This volume is automatically activated.", + "format" : "pve-volume-id", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "blocksize" : { + "description" : "block size", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bwlimit" : { + "description" : "Set I/O bandwidth limit for various operations (in KiB/s).", + "format" : { + "clone" : { + "description" : "bandwidth limit in KiB/s for cloning disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "default" : { + "description" : "default bandwidth limit in KiB/s", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "migration" : { + "description" : "bandwidth limit in KiB/s for migrating guests (including moving local disks)", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "move" : { + "description" : "bandwidth limit in KiB/s for moving disks", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + }, + "restore" : { + "description" : "bandwidth limit in KiB/s for restoring guests from backups", + "format_description" : "LIMIT", + "minimum" : "0", + "optional" : 1, + "type" : "number" + } + }, + "optional" : 1, + "type" : "string", + "typetext" : "[clone=] [,default=] [,migration=] [,move=] [,restore=]" + }, + "comstar_hg" : { + "description" : "host group for comstar views", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comstar_tg" : { + "description" : "target group for comstar views", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "content" : { + "description" : "Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n", + "format" : "pve-storage-content-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "content-dirs" : { + "description" : "Overrides for default content type directories.", + "format" : "pve-dir-override-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "create-base-path" : { + "default" : "yes", + "description" : "Create the base directory if it doesn't exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "create-subdirs" : { + "default" : "yes", + "description" : "Populate the directory with the default structure.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "data-pool" : { + "description" : "Data Pool (for erasure coding only)", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "datastore" : { + "description" : "Proxmox Backup Server datastore name.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "disable" : { + "description" : "Flag to disable the storage.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "domain" : { + "description" : "CIFS domain.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "encryption-key" : { + "description" : "Encryption key. Use 'autogen' to generate one automatically without passphrase.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "export" : { + "description" : "NFS export path.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fingerprint" : { + "description" : "Certificate SHA 256 fingerprint.", + "optional" : 1, + "pattern" : "([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}", + "type" : "string" + }, + "format" : { + "description" : "Default image format.", + "enum" : [ + "raw", + "qcow2", + "subvol", + "vmdk" + ], + "optional" : 1, + "type" : "string" + }, + "fs-name" : { + "description" : "The Ceph filesystem name.", + "format" : "pve-configid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "fuse" : { + "description" : "Mount CephFS through FUSE.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "is_mountpoint" : { + "default" : "no", + "description" : "Assume the given path is an externally managed mountpoint and consider the storage offline if it is not mounted. Using a boolean (yes/no) value serves as a shortcut to using the target path in this field.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "iscsiprovider" : { + "description" : "iscsi provider", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "keyring" : { + "description" : "Client keyring contents (for external clusters).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "krbd" : { + "default" : 0, + "description" : "Always access rbd through krbd kernel module.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "lio_tpg" : { + "description" : "target portal group for Linux LIO targets", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "master-pubkey" : { + "description" : "Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "max-protected-backups" : { + "default" : "Unlimited for users with Datastore.Allocate privilege, 5 for other users", + "description" : "Maximal number of protected backups per guest. Use '-1' for unlimited.", + "minimum" : -1, + "optional" : 1, + "type" : "integer", + "typetext" : " (-1 - N)" + }, + "maxfiles" : { + "description" : "Deprecated: use 'prune-backups' instead. Maximal number of backup files per VM. Use '0' for unlimited.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "mkdir" : { + "default" : "yes", + "description" : "Create the directory if it doesn't exist and populate it with default sub-dirs. NOTE: Deprecated, use the 'create-base-path' and 'create-subdirs' options instead.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "monhost" : { + "description" : "IP addresses of monitors (for external clusters).", + "format" : "pve-storage-portal-dns-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mountpoint" : { + "description" : "mount point", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "namespace" : { + "description" : "Namespace.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nocow" : { + "default" : 0, + "description" : "Set the NOCOW flag on files. Disables data checksumming and causes data errors to be unrecoverable from while allowing direct I/O. Only use this if data does not need to be any more safe than on a single ext4 formatted disk with no underlying raid system.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "nodes" : { + "description" : "List of nodes for which the storage configuration applies.", + "format" : "pve-node-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "nowritecache" : { + "description" : "disable write caching on the target", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "options" : { + "description" : "NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')", + "format" : "pve-storage-options", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "Password for accessing the share/datastore.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "File system path.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "pool" : { + "description" : "Pool.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Use this port to connect to the storage instead of the default one (for example, with PBS or ESXi). For NFS and CIFS, use the 'options' option to configure the port via the mount options.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "portal" : { + "description" : "iSCSI portal (IP or DNS name with optional port).", + "format" : "pve-storage-portal-dns", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "preallocation" : { + "default" : "metadata", + "description" : "Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off.", + "enum" : [ + "off", + "metadata", + "falloc", + "full" + ], + "optional" : 1, + "type" : "string" + }, + "prune-backups" : { + "description" : "The retention options with shorter intervals are processed first with --keep-last being the very first one. Each option covers a specific period of time. We say that backups within this period are covered by this option. The next option does not take care of already covered backups and only considers older backups.", + "format" : "prune-backups", + "optional" : 1, + "type" : "string", + "typetext" : "[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]" + }, + "saferemove" : { + "description" : "Zero-out data when removing LVs.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "saferemove_throughput" : { + "description" : "Wipe throughput (cstream -t parameter value).", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server" : { + "description" : "Server IP or DNS name.", + "format" : "pve-storage-server", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server2" : { + "description" : "Backup volfile server IP or DNS name.", + "format" : "pve-storage-server", + "optional" : 1, + "requires" : "server", + "type" : "string", + "typetext" : "" + }, + "share" : { + "description" : "CIFS share.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "shared" : { + "description" : "Indicate that this is a single storage with the same contents on all nodes (or all listed in the 'nodes' option). It will not make the contents of a local storage automatically accessible to other nodes, it just marks an already shared storage as such!", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "skip-cert-verification" : { + "default" : "false", + "description" : "Disable TLS certificate verification, only enable on fully trusted networks!", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "smbversion" : { + "default" : "default", + "description" : "SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server.", + "enum" : [ + "default", + "2.0", + "2.1", + "3", + "3.0", + "3.11" + ], + "optional" : 1, + "type" : "string" + }, + "sparse" : { + "description" : "use sparse volumes", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "storage" : { + "description" : "The storage identifier.", + "format" : "pve-storage-id", + "format_description" : "storage ID", + "type" : "string", + "typetext" : "" + }, + "subdir" : { + "description" : "Subdir to mount.", + "format" : "pve-storage-path", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tagged_only" : { + "description" : "Only use logical volumes tagged with 'pve-vm-ID'.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "target" : { + "description" : "iSCSI target.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "thinpool" : { + "description" : "LVM thin pool LV name.", + "format" : "pve-storage-vgname", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "transport" : { + "description" : "Gluster transport: tcp or rdma", + "enum" : [ + "tcp", + "rdma", + "unix" + ], + "optional" : 1, + "type" : "string" + }, + "type" : { + "description" : "Storage type.", + "enum" : [ + "btrfs", + "cephfs", + "cifs", + "dir", + "esxi", + "glusterfs", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "type" : "string" + }, + "username" : { + "description" : "RBD Id.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vgname" : { + "description" : "Volume group name.", + "format" : "pve-storage-vgname", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "volume" : { + "description" : "Glusterfs Volume.", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "config" : { + "additionalProperties" : 1, + "description" : "Partial, possible server generated, configuration properties.", + "optional" : 1, + "properties" : { + "encryption-key" : { + "description" : "The, possible auto-generated, encryption-key.", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "storage" : { + "description" : "The ID of the created storage.", + "type" : "string" + }, + "type" : { + "description" : "The type of the created storage.", + "enum" : [ + "btrfs", + "cephfs", + "cifs", + "dir", + "esxi", + "glusterfs", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ], + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 0, + "path" : "/storage", + "text" : "storage" + }, + { + "children" : [ + { + "children" : [ + { + "children" : [ + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get user TFA types (Personal and Realm).", + "method" : "GET", + "name" : "read_user_tfa_type", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "multiple" : { + "default" : 0, + "description" : "Request all entries as an array.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "realm" : { + "description" : "The type of TFA the users realm has set, if any.", + "enum" : [ + "oath", + "yubico" + ], + "optional" : 1, + "type" : "string" + }, + "types" : { + "description" : "Array of the user configured TFA types, if any. Only available if 'multiple' was not passed.", + "items" : { + "description" : "A TFA type.", + "enum" : [ + "totp", + "u2f", + "yubico", + "webauthn", + "recovedry" + ], + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "user" : { + "description" : "The type of TFA the user has set, if any. Only set if 'multiple' was not passed.", + "enum" : [ + "oath", + "u2f" + ], + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/users/{userid}/tfa", + "text" : "tfa" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 1, + "description" : "Unlock a user's TFA authentication.", + "method" : "PUT", + "name" : "unlock_tfa", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "userid-group", + [ + "User.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "boolean" + } + } + }, + "leaf" : 1, + "path" : "/access/users/{userid}/unlock-tfa", + "text" : "unlock-tfa" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Remove API token for a specific user.", + "method" : "DELETE", + "name" : "remove_token", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get specific API token information.", + "method" : "GET", + "name" : "read_token", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "returns" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Generate a new API token for a specific user. NOTE: returns API token value, which needs to be stored as it cannot be retrieved afterwards!", + "method" : "POST", + "name" : "generate_token", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "full-tokenid" : { + "description" : "The full token id.", + "format_description" : "!", + "type" : "string" + }, + "info" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "value" : { + "description" : "API token value used for authentication.", + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update API token for a specific user.", + "method" : "PUT", + "name" : "update_token_info", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "Updated token information.", + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/users/{userid}/token/{tokenid}", + "text" : "{tokenid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get user API tokens.", + "method" : "GET", + "name" : "token_index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + }, + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{tokenid}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/access/users/{userid}/token", + "text" : "token" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete user.", + "method" : "DELETE", + "name" : "delete_user", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get user configuration.", + "method" : "GET", + "name" : "read_user", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "maxLength" : 2048, + "optional" : 1, + "type" : "string" + }, + "email" : { + "format" : "email-opt", + "maxLength" : 254, + "optional" : 1, + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Enable the account (default). You can set this to '0' to disable the account", + "optional" : 1, + "type" : "boolean" + }, + "expire" : { + "description" : "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "firstname" : { + "maxLength" : 1024, + "optional" : 1, + "type" : "string" + }, + "groups" : { + "items" : { + "format" : "pve-groupid", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + }, + "keys" : { + "description" : "Keys for two factor auth (yubico).", + "optional" : 1, + "pattern" : "[0-9a-zA-Z!=]{0,4096}", + "type" : "string" + }, + "lastname" : { + "maxLength" : 1024, + "optional" : 1, + "type" : "string" + }, + "tokens" : { + "additionalProperties" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "object" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update user configuration.", + "method" : "PUT", + "name" : "update_user", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "append" : { + "optional" : 1, + "requires" : "groups", + "type" : "boolean", + "typetext" : "" + }, + "comment" : { + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "email" : { + "format" : "email-opt", + "maxLength" : 254, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 1, + "description" : "Enable the account (default). You can set this to '0' to disable the account", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "expire" : { + "description" : "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "firstname" : { + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groups" : { + "format" : "pve-groupid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "keys" : { + "description" : "Keys for two factor auth (yubico).", + "optional" : 1, + "pattern" : "[0-9a-zA-Z!=]{0,4096}", + "type" : "string" + }, + "lastname" : { + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "userid-group", + [ + "User.Modify" + ], + "groups_param", + "update" + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/users/{userid}", + "text" : "{userid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "User index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "enabled" : { + "description" : "Optional filter for enable property.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "full" : { + "default" : 0, + "description" : "Include group and token information.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "The returned list is restricted to users where you have 'User.Modify' or 'Sys.Audit' permissions on '/access/groups' or on a group the user belongs too. But it always includes the current (authenticated) user.", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "maxLength" : 2048, + "optional" : 1, + "type" : "string" + }, + "email" : { + "format" : "email-opt", + "maxLength" : 254, + "optional" : 1, + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Enable the account (default). You can set this to '0' to disable the account", + "optional" : 1, + "type" : "boolean" + }, + "expire" : { + "description" : "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "firstname" : { + "maxLength" : 1024, + "optional" : 1, + "type" : "string" + }, + "groups" : { + "format" : "pve-groupid-list", + "optional" : 1, + "type" : "string" + }, + "keys" : { + "description" : "Keys for two factor auth (yubico).", + "optional" : 1, + "pattern" : "[0-9a-zA-Z!=]{0,4096}", + "type" : "string" + }, + "lastname" : { + "maxLength" : 1024, + "optional" : 1, + "type" : "string" + }, + "realm-type" : { + "description" : "The type of the users realm", + "format" : "pve-realm", + "optional" : 1, + "type" : "string" + }, + "tfa-locked-until" : { + "description" : "Contains a timestamp until when a user is locked out of 2nd factors.", + "optional" : 1, + "type" : "integer" + }, + "tokens" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "expire" : { + "default" : "same as user", + "description" : "API token expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer" + }, + "privsep" : { + "default" : 1, + "description" : "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "optional" : 1, + "type" : "boolean" + }, + "tokenid" : { + "description" : "User-specific token identifier.", + "pattern" : "(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)", + "type" : "string" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "totp-locked" : { + "description" : "True if the user is currently locked out of TOTP factors.", + "optional" : 1, + "type" : "boolean" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{userid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new user.", + "method" : "POST", + "name" : "create_user", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "email" : { + "format" : "email-opt", + "maxLength" : 254, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "default" : 1, + "description" : "Enable the account (default). You can set this to '0' to disable the account", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "expire" : { + "description" : "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum" : 0, + "optional" : 1, + "type" : "integer", + "typetext" : " (0 - N)" + }, + "firstname" : { + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groups" : { + "format" : "pve-groupid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "keys" : { + "description" : "Keys for two factor auth (yubico).", + "optional" : 1, + "pattern" : "[0-9a-zA-Z!=]{0,4096}", + "type" : "string" + }, + "lastname" : { + "maxLength" : 1024, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "Initial password.", + "maxLength" : 64, + "minLength" : 8, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ], + "groups_param", + "create" + ] + ], + "description" : "You need 'Realm.AllocateUser' on '/access/realm/' on the realm of user , and 'User.Modify' permissions to '/access/groups/' for any group specified (or 'User.Modify' on '/access/groups' if you pass no groups." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/users", + "text" : "users" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete group.", + "method" : "DELETE", + "name" : "delete_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "groupid" : { + "format" : "pve-groupid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get group configuration.", + "method" : "GET", + "name" : "read_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "groupid" : { + "format" : "pve-groupid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/groups", + [ + "Sys.Audit", + "Group.Allocate" + ], + "any", + 1 + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "members" : { + "items" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update group data.", + "method" : "PUT", + "name" : "update_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groupid" : { + "format" : "pve-groupid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/groups/{groupid}", + "text" : "{groupid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Group index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "The returned list is restricted to groups where you have 'User.Modify', 'Sys.Audit' or 'Group.Allocate' permissions on /access/groups/.", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "groupid" : { + "format" : "pve-groupid", + "type" : "string" + }, + "users" : { + "description" : "list of users which form this group", + "format" : "pve-userid-list", + "optional" : 1, + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{groupid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new group.", + "method" : "POST", + "name" : "create_group", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groupid" : { + "format" : "pve-groupid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/groups", + "text" : "groups" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete role.", + "method" : "DELETE", + "name" : "delete_role", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "roleid" : { + "format" : "pve-roleid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get role configuration.", + "method" : "GET", + "name" : "read_role", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "roleid" : { + "format" : "pve-roleid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "Datastore.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "Datastore.AllocateSpace" : { + "optional" : 1, + "type" : "boolean" + }, + "Datastore.AllocateTemplate" : { + "optional" : 1, + "type" : "boolean" + }, + "Datastore.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "Group.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "Mapping.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "Mapping.Modify" : { + "optional" : 1, + "type" : "boolean" + }, + "Mapping.Use" : { + "optional" : 1, + "type" : "boolean" + }, + "Permissions.Modify" : { + "optional" : 1, + "type" : "boolean" + }, + "Pool.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "Pool.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "Realm.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "Realm.AllocateUser" : { + "optional" : 1, + "type" : "boolean" + }, + "SDN.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "SDN.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "SDN.Use" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.AccessNetwork" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Console" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Incoming" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Modify" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.PowerMgmt" : { + "optional" : 1, + "type" : "boolean" + }, + "Sys.Syslog" : { + "optional" : 1, + "type" : "boolean" + }, + "User.Modify" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Allocate" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Audit" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Backup" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Clone" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.CDROM" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.CPU" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Cloudinit" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Disk" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.HWType" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Memory" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Network" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Config.Options" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Console" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Migrate" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Monitor" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.PowerMgmt" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Snapshot" : { + "optional" : 1, + "type" : "boolean" + }, + "VM.Snapshot.Rollback" : { + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update an existing role.", + "method" : "PUT", + "name" : "update_role", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "append" : { + "optional" : 1, + "requires" : "privs", + "type" : "boolean", + "typetext" : "" + }, + "privs" : { + "format" : "pve-priv-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "roleid" : { + "format" : "pve-roleid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/roles/{roleid}", + "text" : "{roleid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Role index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "privs" : { + "format" : "pve-priv-list", + "optional" : 1, + "type" : "string" + }, + "roleid" : { + "format" : "pve-roleid", + "type" : "string" + }, + "special" : { + "default" : 0, + "optional" : 1, + "type" : "boolean" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{roleid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new role.", + "method" : "POST", + "name" : "create_role", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "privs" : { + "format" : "pve-priv-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "roleid" : { + "format" : "pve-roleid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/roles", + "text" : "roles" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Get Access Control List (ACLs).", + "method" : "GET", + "name" : "read_acl", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "The returned list is restricted to objects where you have rights to modify permissions.", + "user" : "all" + }, + "returns" : { + "items" : { + "additionalProperties" : 0, + "properties" : { + "path" : { + "description" : "Access control path", + "type" : "string" + }, + "propagate" : { + "default" : 1, + "description" : "Allow to propagate (inherit) permissions.", + "optional" : 1, + "type" : "boolean" + }, + "roleid" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "user", + "group", + "token" + ], + "type" : "string" + }, + "ugid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update Access Control List (add or remove permissions).", + "method" : "PUT", + "name" : "update_acl", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "delete" : { + "description" : "Remove permissions (instead of adding it).", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "groups" : { + "description" : "List of groups.", + "format" : "pve-groupid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "Access control path", + "type" : "string", + "typetext" : "" + }, + "propagate" : { + "default" : 1, + "description" : "Allow to propagate (inherit) permissions.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "roles" : { + "description" : "List of roles.", + "format" : "pve-roleid-list", + "type" : "string", + "typetext" : "" + }, + "tokens" : { + "description" : "List of API tokens.", + "format" : "pve-tokenid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "users" : { + "description" : "List of users.", + "format" : "pve-userid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm-modify", + "{path}" + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/acl", + "text" : "acl" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Syncs users and/or groups from the configured LDAP to user.cfg. NOTE: Synced groups will have the name 'name-$realm', so make sure those groups do not exist to prevent overwriting.", + "method" : "POST", + "name" : "sync", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "dry-run" : { + "default" : 0, + "description" : "If set, does not write anything.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "enable-new" : { + "default" : "1", + "description" : "Enable newly synced users immediately.", + "optional" : "1", + "type" : "boolean", + "typetext" : "" + }, + "full" : { + "description" : "DEPRECATED: use 'remove-vanished' instead. If set, uses the LDAP Directory as source of truth, deleting users or groups not returned from the sync and removing all locally modified properties of synced users. If not set, only syncs information which is present in the synced data, and does not delete or modify anything else.", + "optional" : "1", + "type" : "boolean", + "typetext" : "" + }, + "purge" : { + "description" : "DEPRECATED: use 'remove-vanished' instead. Remove ACLs for users or groups which were removed from the config during a sync.", + "optional" : "1", + "type" : "boolean", + "typetext" : "" + }, + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + }, + "remove-vanished" : { + "default" : "none", + "description" : "A semicolon-separated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).", + "optional" : "1", + "pattern" : "(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none", + "type" : "string", + "typetext" : "([acl];[properties];[entry])|none" + }, + "scope" : { + "description" : "Select what to sync.", + "enum" : [ + "users", + "groups", + "both" + ], + "optional" : "1", + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "and", + [ + "perm", + "/access/realm/{realm}", + [ + "Realm.AllocateUser" + ] + ], + [ + "perm", + "/access/groups", + [ + "User.Modify" + ] + ] + ], + "description" : "'Realm.AllocateUser' on '/access/realm/' and 'User.Modify' permissions to '/access/groups/'." + }, + "protected" : 1, + "returns" : { + "description" : "Worker Task-UPID", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/access/domains/{realm}/sync", + "text" : "sync" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete an authentication server.", + "method" : "DELETE", + "name" : "delete", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get auth server configuration.", + "method" : "GET", + "name" : "read", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/access/realm", + [ + "Realm.Allocate", + "Sys.Audit" + ], + "any", + 1 + ] + }, + "returns" : {} + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update authentication server settings.", + "method" : "PUT", + "name" : "update", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acr-values" : { + "description" : "Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.", + "optional" : 1, + "pattern" : "^[^\\x00-\\x1F\\x7F <>#\"]*$", + "type" : "string" + }, + "autocreate" : { + "default" : 0, + "description" : "Automatically create users if they do not exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "base_dn" : { + "description" : "LDAP base domain name", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bind_dn" : { + "description" : "LDAP bind domain name", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "capath" : { + "default" : "/etc/ssl/certs", + "description" : "Path to the CA certificate store", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "case-sensitive" : { + "default" : 1, + "description" : "username is case-sensitive", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cert" : { + "description" : "Path to the client certificate", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "certkey" : { + "description" : "Path to the client certificate key", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "check-connection" : { + "default" : 0, + "description" : "Check bind connection to the server.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "client-id" : { + "description" : "OpenID Client ID", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "client-key" : { + "description" : "OpenID Client Key", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "default" : { + "description" : "Use this as default realm", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "delete" : { + "description" : "A list of settings you want to delete.", + "format" : "pve-configid-list", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "digest" : { + "description" : "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.", + "maxLength" : 64, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "domain" : { + "description" : "AD domain name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\S+", + "type" : "string" + }, + "filter" : { + "description" : "LDAP filter for user sync.", + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_classes" : { + "default" : "groupOfNames, group, univentionGroup, ipausergroup", + "description" : "The objectclasses for groups.", + "format" : "ldap-simple-attr-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_dn" : { + "description" : "LDAP base domain name for group sync. If not set, the base_dn will be used.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_filter" : { + "description" : "LDAP filter for group sync.", + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_name_attr" : { + "description" : "LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.", + "format" : "ldap-simple-attr", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groups-autocreate" : { + "default" : 0, + "description" : "Automatically create groups if they do not exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "groups-claim" : { + "description" : "OpenID claim used to retrieve groups with.", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^:[A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "groups-overwrite" : { + "default" : 0, + "description" : "All groups will be overwritten for the user on login.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "issuer-url" : { + "description" : "OpenID Issuer Url", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mode" : { + "default" : "ldap", + "description" : "LDAP protocol mode.", + "enum" : [ + "ldap", + "ldaps", + "ldap+starttls" + ], + "optional" : 1, + "type" : "string" + }, + "password" : { + "description" : "LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Server port.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "prompt" : { + "description" : "Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.", + "optional" : 1, + "pattern" : "(?:none|login|consent|select_account|\\S+)", + "type" : "string" + }, + "query-userinfo" : { + "default" : 1, + "description" : "Enables querying the userinfo endpoint for claims values.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + }, + "scopes" : { + "default" : "email profile", + "description" : "Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "secure" : { + "description" : "Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "server1" : { + "description" : "Server IP address (or DNS name)", + "format" : "address", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server2" : { + "description" : "Fallback Server IP address (or DNS name)", + "format" : "address", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sslversion" : { + "description" : "LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!", + "enum" : [ + "tlsv1", + "tlsv1_1", + "tlsv1_2", + "tlsv1_3" + ], + "optional" : 1, + "type" : "string" + }, + "sync-defaults-options" : { + "description" : "The default options for behavior of synchronizations.", + "format" : "realm-sync-options", + "optional" : 1, + "type" : "string", + "typetext" : "[enable-new=<1|0>] [,full=<1|0>] [,purge=<1|0>] [,remove-vanished=([acl];[properties];[entry])|none] [,scope=]" + }, + "sync_attributes" : { + "description" : "Comma separated list of key=value pairs for specifying which LDAP attributes map to which PVE user field. For example, to map the LDAP attribute 'mail' to PVEs 'email', write 'email=mail'. By default, each PVE user field is represented by an LDAP attribute of the same name.", + "optional" : 1, + "pattern" : "\\w+=[^,]+(,\\s*\\w+=[^,]+)*", + "type" : "string" + }, + "tfa" : { + "description" : "Use Two-factor authentication.", + "format" : "pve-tfa-config", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "type= [,digits=] [,id=] [,key=] [,step=] [,url=]" + }, + "user_attr" : { + "description" : "LDAP user attribute name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\S{2,}", + "type" : "string" + }, + "user_classes" : { + "default" : "inetorgperson, posixaccount, person, user", + "description" : "The objectclasses for users.", + "format" : "ldap-simple-attr-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "verify" : { + "default" : 0, + "description" : "Verify the server's SSL certificate", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/domains/{realm}", + "text" : "{realm}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Authentication domain index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "Anyone can access that, because we need that list for the login box (before the user is authenticated).", + "user" : "world" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "description" : "A comment. The GUI use this text when you select a domain (Realm) on the login window.", + "optional" : 1, + "type" : "string" + }, + "realm" : { + "type" : "string" + }, + "tfa" : { + "description" : "Two-factor authentication provider.", + "enum" : [ + "yubico", + "oath" + ], + "optional" : 1, + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{realm}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Add an authentication server.", + "method" : "POST", + "name" : "create", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "acr-values" : { + "description" : "Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.", + "optional" : 1, + "pattern" : "^[^\\x00-\\x1F\\x7F <>#\"]*$", + "type" : "string" + }, + "autocreate" : { + "default" : 0, + "description" : "Automatically create users if they do not exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "base_dn" : { + "description" : "LDAP base domain name", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "bind_dn" : { + "description" : "LDAP bind domain name", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "capath" : { + "default" : "/etc/ssl/certs", + "description" : "Path to the CA certificate store", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "case-sensitive" : { + "default" : 1, + "description" : "username is case-sensitive", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "cert" : { + "description" : "Path to the client certificate", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "certkey" : { + "description" : "Path to the client certificate key", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "check-connection" : { + "default" : 0, + "description" : "Check bind connection to the server.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "client-id" : { + "description" : "OpenID Client ID", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "client-key" : { + "description" : "OpenID Client Key", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "comment" : { + "description" : "Description.", + "maxLength" : 4096, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "default" : { + "description" : "Use this as default realm", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "domain" : { + "description" : "AD domain name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\S+", + "type" : "string" + }, + "filter" : { + "description" : "LDAP filter for user sync.", + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_classes" : { + "default" : "groupOfNames, group, univentionGroup, ipausergroup", + "description" : "The objectclasses for groups.", + "format" : "ldap-simple-attr-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_dn" : { + "description" : "LDAP base domain name for group sync. If not set, the base_dn will be used.", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_filter" : { + "description" : "LDAP filter for group sync.", + "maxLength" : 2048, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "group_name_attr" : { + "description" : "LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.", + "format" : "ldap-simple-attr", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "groups-autocreate" : { + "default" : 0, + "description" : "Automatically create groups if they do not exist.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "groups-claim" : { + "description" : "OpenID claim used to retrieve groups with.", + "maxLength" : 256, + "optional" : 1, + "pattern" : "(?^:[A-Za-z0-9\\.\\-_]+)", + "type" : "string" + }, + "groups-overwrite" : { + "default" : 0, + "description" : "All groups will be overwritten for the user on login.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "issuer-url" : { + "description" : "OpenID Issuer Url", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "mode" : { + "default" : "ldap", + "description" : "LDAP protocol mode.", + "enum" : [ + "ldap", + "ldaps", + "ldap+starttls" + ], + "optional" : 1, + "type" : "string" + }, + "password" : { + "description" : "LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "port" : { + "description" : "Server port.", + "maximum" : 65535, + "minimum" : 1, + "optional" : 1, + "type" : "integer", + "typetext" : " (1 - 65535)" + }, + "prompt" : { + "description" : "Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.", + "optional" : 1, + "pattern" : "(?:none|login|consent|select_account|\\S+)", + "type" : "string" + }, + "query-userinfo" : { + "default" : 1, + "description" : "Enables querying the userinfo endpoint for claims values.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + }, + "scopes" : { + "default" : "email profile", + "description" : "Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "secure" : { + "description" : "Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "server1" : { + "description" : "Server IP address (or DNS name)", + "format" : "address", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "server2" : { + "description" : "Fallback Server IP address (or DNS name)", + "format" : "address", + "maxLength" : 256, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "sslversion" : { + "description" : "LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!", + "enum" : [ + "tlsv1", + "tlsv1_1", + "tlsv1_2", + "tlsv1_3" + ], + "optional" : 1, + "type" : "string" + }, + "sync-defaults-options" : { + "description" : "The default options for behavior of synchronizations.", + "format" : "realm-sync-options", + "optional" : 1, + "type" : "string", + "typetext" : "[enable-new=<1|0>] [,full=<1|0>] [,purge=<1|0>] [,remove-vanished=([acl];[properties];[entry])|none] [,scope=]" + }, + "sync_attributes" : { + "description" : "Comma separated list of key=value pairs for specifying which LDAP attributes map to which PVE user field. For example, to map the LDAP attribute 'mail' to PVEs 'email', write 'email=mail'. By default, each PVE user field is represented by an LDAP attribute of the same name.", + "optional" : 1, + "pattern" : "\\w+=[^,]+(,\\s*\\w+=[^,]+)*", + "type" : "string" + }, + "tfa" : { + "description" : "Use Two-factor authentication.", + "format" : "pve-tfa-config", + "maxLength" : 128, + "optional" : 1, + "type" : "string", + "typetext" : "type= [,digits=] [,id=] [,key=] [,step=] [,url=]" + }, + "type" : { + "description" : "Realm type.", + "enum" : [ + "ad", + "ldap", + "openid", + "pam", + "pve" + ], + "type" : "string" + }, + "user_attr" : { + "description" : "LDAP user attribute name", + "maxLength" : 256, + "optional" : 1, + "pattern" : "\\S{2,}", + "type" : "string" + }, + "user_classes" : { + "default" : "inetorgperson, posixaccount, person, user", + "description" : "The objectclasses for users.", + "format" : "ldap-simple-attr-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "username-claim" : { + "description" : "OpenID claim used to generate the unique username.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "verify" : { + "default" : 0, + "description" : "Verify the server's SSL certificate", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + } + }, + "type" : "object" + }, + "permissions" : { + "check" : [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/access/domains", + "text" : "domains" + }, + { + "children" : [ + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : "Get the OpenId Authorization Url for the specified realm.", + "method" : "POST", + "name" : "auth_url", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "realm" : { + "description" : "Authentication domain ID", + "format" : "pve-realm", + "maxLength" : 32, + "type" : "string", + "typetext" : "" + }, + "redirect-url" : { + "description" : "Redirection Url. The client should set this to the used server url (location.origin).", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "world" + }, + "protected" : 1, + "returns" : { + "description" : "Redirection URL.", + "type" : "string" + } + } + }, + "leaf" : 1, + "path" : "/access/openid/auth-url", + "text" : "auth-url" + }, + { + "info" : { + "POST" : { + "allowtoken" : 1, + "description" : " Verify OpenID authorization code and create a ticket.", + "method" : "POST", + "name" : "login", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "code" : { + "description" : "OpenId authorization code.", + "maxLength" : 4096, + "type" : "string", + "typetext" : "" + }, + "redirect-url" : { + "description" : "Redirection Url. The client should set this to the used server url (location.origin).", + "maxLength" : 255, + "type" : "string", + "typetext" : "" + }, + "state" : { + "description" : "OpenId state.", + "maxLength" : 1024, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "user" : "world" + }, + "protected" : 1, + "returns" : { + "properties" : { + "CSRFPreventionToken" : { + "type" : "string" + }, + "cap" : { + "type" : "object" + }, + "clustername" : { + "optional" : 1, + "type" : "string" + }, + "ticket" : { + "type" : "string" + }, + "username" : { + "type" : "string" + } + } + } + } + }, + "leaf" : 1, + "path" : "/access/openid/login", + "text" : "login" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/access/openid", + "text" : "openid" + }, + { + "children" : [ + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 0, + "description" : "Delete a TFA entry by ID.", + "method" : "DELETE", + "name" : "delete_tfa", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "A TFA entry id.", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The current password of the user performing the change.", + "maxLength" : 64, + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Fetch a requested TFA entry if present.", + "method" : "GET", + "name" : "get_tfa_entry", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "id" : { + "description" : "A TFA entry id.", + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "TFA Entry.", + "properties" : { + "created" : { + "description" : "Creation time of this entry as unix epoch.", + "type" : "integer" + }, + "description" : { + "description" : "User chosen description for this entry.", + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Whether this TFA entry is currently enabled.", + "optional" : 1, + "type" : "boolean" + }, + "id" : { + "description" : "The id used to reference this entry.", + "type" : "string" + }, + "type" : { + "description" : "TFA Entry Type.", + "enum" : [ + "totp", + "u2f", + "webauthn", + "recovery", + "yubico" + ], + "type" : "string" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 0, + "description" : "Add a TFA entry for a user.", + "method" : "PUT", + "name" : "update_tfa_entry", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "description" : { + "description" : "A description to distinguish multiple entries from one another", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "enable" : { + "description" : "Whether the entry should be enabled for login.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "id" : { + "description" : "A TFA entry id.", + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The current password of the user performing the change.", + "maxLength" : 64, + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/tfa/{userid}/{id}", + "text" : "{id}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List TFA configurations of users.", + "method" : "GET", + "name" : "list_user_tfa", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "description" : "A list of the user's TFA entries.", + "items" : { + "description" : "TFA Entry.", + "properties" : { + "created" : { + "description" : "Creation time of this entry as unix epoch.", + "type" : "integer" + }, + "description" : { + "description" : "User chosen description for this entry.", + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Whether this TFA entry is currently enabled.", + "optional" : 1, + "type" : "boolean" + }, + "id" : { + "description" : "The id used to reference this entry.", + "type" : "string" + }, + "type" : { + "description" : "TFA Entry Type.", + "enum" : [ + "totp", + "u2f", + "webauthn", + "recovery", + "yubico" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{id}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 0, + "description" : "Add a TFA entry for a user.", + "method" : "POST", + "name" : "add_tfa_entry", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "challenge" : { + "description" : "When responding to a u2f challenge: the original challenge string", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "description" : { + "description" : "A description to distinguish multiple entries from one another", + "maxLength" : 255, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The current password of the user performing the change.", + "maxLength" : 64, + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "totp" : { + "description" : "A totp URI.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "description" : "TFA Entry Type.", + "enum" : [ + "totp", + "u2f", + "webauthn", + "recovery", + "yubico" + ], + "type" : "string" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + }, + "value" : { + "description" : "The current value for the provided totp URI, or a Webauthn/U2F challenge response", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "protected" : 1, + "returns" : { + "properties" : { + "challenge" : { + "description" : "When adding u2f entries, this contains a challenge the user must respond to in order to finish the registration.", + "optional" : 1, + "type" : "string" + }, + "id" : { + "description" : "The id of a newly added TFA entry.", + "type" : "string" + }, + "recovery" : { + "description" : "When adding recovery codes, this contains the list of codes to be displayed to the user", + "items" : { + "description" : "A recovery entry.", + "type" : "string" + }, + "optional" : 1, + "type" : "array" + } + }, + "type" : "object" + } + } + }, + "leaf" : 0, + "path" : "/access/tfa/{userid}", + "text" : "{userid}" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "List TFA configurations of users.", + "method" : "GET", + "name" : "list_tfa", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "description" : "Returns all or just the logged-in user, depending on privileges.", + "user" : "all" + }, + "protected" : 1, + "returns" : { + "description" : "The list tuples of user and TFA entries.", + "items" : { + "properties" : { + "entries" : { + "items" : { + "description" : "TFA Entry.", + "properties" : { + "created" : { + "description" : "Creation time of this entry as unix epoch.", + "type" : "integer" + }, + "description" : { + "description" : "User chosen description for this entry.", + "type" : "string" + }, + "enable" : { + "default" : 1, + "description" : "Whether this TFA entry is currently enabled.", + "optional" : 1, + "type" : "boolean" + }, + "id" : { + "description" : "The id used to reference this entry.", + "type" : "string" + }, + "type" : { + "description" : "TFA Entry Type.", + "enum" : [ + "totp", + "u2f", + "webauthn", + "recovery", + "yubico" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "type" : "array" + }, + "tfa-locked-until" : { + "description" : "Contains a timestamp until when a user is locked out of 2nd factors.", + "optional" : 1, + "type" : "integer" + }, + "totp-locked" : { + "description" : "True if the user is currently locked out of TOTP factors.", + "optional" : 1, + "type" : "boolean" + }, + "userid" : { + "description" : "User this entry belongs to.", + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{userid}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/access/tfa", + "text" : "tfa" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Dummy. Useful for formatters which want to provide a login page.", + "method" : "GET", + "name" : "get_ticket", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "world" + }, + "returns" : { + "type" : "null" + } + }, + "POST" : { + "allowtoken" : 0, + "description" : "Create or verify authentication ticket.", + "method" : "POST", + "name" : "create_ticket", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "new-format" : { + "default" : 1, + "description" : "This parameter is now ignored and assumed to be 1.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "otp" : { + "description" : "One-time password for Two-factor authentication.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The secret password. This can also be a valid ticket.", + "type" : "string", + "typetext" : "" + }, + "path" : { + "description" : "Verify ticket, and check if user have access 'privs' on 'path'", + "maxLength" : 64, + "optional" : 1, + "requires" : "privs", + "type" : "string", + "typetext" : "" + }, + "privs" : { + "description" : "Verify ticket, and check if user have access 'privs' on 'path'", + "format" : "pve-priv-list", + "maxLength" : 64, + "optional" : 1, + "requires" : "path", + "type" : "string", + "typetext" : "" + }, + "realm" : { + "description" : "You can optionally pass the realm using this parameter. Normally the realm is simply added to the username @.", + "format" : "pve-realm", + "maxLength" : 32, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "tfa-challenge" : { + "description" : "The signed TFA challenge string the user wants to respond to.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "username" : { + "description" : "User name", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "description" : "You need to pass valid credientials.", + "user" : "world" + }, + "protected" : 1, + "returns" : { + "properties" : { + "CSRFPreventionToken" : { + "optional" : 1, + "type" : "string" + }, + "clustername" : { + "optional" : 1, + "type" : "string" + }, + "ticket" : { + "optional" : 1, + "type" : "string" + }, + "username" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/ticket", + "text" : "ticket" + }, + { + "info" : { + "PUT" : { + "allowtoken" : 0, + "description" : "Change user password.", + "method" : "PUT", + "name" : "change_password", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "confirmation-password" : { + "description" : "The current password of the user performing the change.", + "maxLength" : 64, + "minLength" : 5, + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "password" : { + "description" : "The new password.", + "maxLength" : 64, + "minLength" : 8, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "Full User ID, in the `name@realm` format.", + "format" : "pve-userid", + "maxLength" : 64, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "or", + [ + "userid-param", + "self" + ], + [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + ], + "description" : "Each user is allowed to change their own password. A user can change the password of another user if they have 'Realm.AllocateUser' (on the realm of user ) and 'User.Modify' permission on /access/groups/ on a group where user is member of. For the PAM realm, a password change does not take effect cluster-wide, but only applies to the local node." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/access/password", + "text" : "password" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Retrieve effective permissions of given user/token.", + "method" : "GET", + "name" : "permissions", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "path" : { + "description" : "Only dump this specific path, not the whole tree.", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "userid" : { + "description" : "User ID or full API token ID", + "optional" : 1, + "pattern" : "(?^:^(?^:[^\\s:/]+)\\@(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)(?:!(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+))?$)", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "Each user/token is allowed to dump their own permissions (or that of owned tokens). A user can dump the permissions of another user or their tokens if they have 'Sys.Audit' permission on /access.", + "user" : "all" + }, + "returns" : { + "description" : "Map of \"path\" => (Map of \"privilege\" => \"propagate boolean\").", + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/access/permissions", + "text" : "permissions" + } + ], + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "Directory index.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "subdir" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{subdir}", + "rel" : "child" + } + ], + "type" : "array" + } + } + }, + "leaf" : 0, + "path" : "/access", + "text" : "access" + }, + { + "children" : [ + { + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete pool (deprecated, no support for nested pools, use 'DELETE /pools/?poolid={poolid}').", + "method" : "DELETE", + "name" : "delete_pool_deprecated", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description" : "You can only delete empty pools (no members)." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "Get pool configuration (deprecated, no support for nested pools, use 'GET /pools/?poolid={poolid}').", + "method" : "GET", + "name" : "read_pool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + }, + "type" : { + "enum" : [ + "qemu", + "lxc", + "storage" + ], + "optional" : 1, + "type" : "string" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Audit" + ] + ] + }, + "returns" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "members" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "id" : { + "type" : "string" + }, + "node" : { + "type" : "string" + }, + "storage" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "enum" : [ + "qemu", + "lxc", + "openvz", + "storage" + ], + "type" : "string" + }, + "vmid" : { + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "type" : "array" + } + }, + "type" : "object" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update pool data (deprecated, no support for nested pools - use 'PUT /pools/?poolid={poolid}' instead).", + "method" : "PUT", + "name" : "update_pool_deprecated", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "allow-move" : { + "default" : 0, + "description" : "Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "default" : 0, + "description" : "Remove the passed VMIDs and/or storage IDs instead of adding them.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "List of storage IDs to add or remove from this pool.", + "format" : "pve-storage-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "List of guest VMIDs to add or remove from this pool.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description" : "You also need the right to modify permissions on any object you add/delete." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 1, + "path" : "/pools/{poolid}", + "text" : "{poolid}" + } + ], + "info" : { + "DELETE" : { + "allowtoken" : 1, + "description" : "Delete pool.", + "method" : "DELETE", + "name" : "delete_pool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description" : "You can only delete empty pools (no members)." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "GET" : { + "allowtoken" : 1, + "description" : "List pools or get pool configuration.", + "method" : "GET", + "name" : "index", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "poolid" : { + "format" : "pve-poolid", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "type" : { + "enum" : [ + "qemu", + "lxc", + "storage" + ], + "optional" : 1, + "requires" : "poolid", + "type" : "string" + } + } + }, + "permissions" : { + "description" : "List all pools where you have Pool.Audit permissions on /pool/, or the pool specific with {poolid}", + "user" : "all" + }, + "returns" : { + "items" : { + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string" + }, + "members" : { + "items" : { + "additionalProperties" : 1, + "properties" : { + "id" : { + "type" : "string" + }, + "node" : { + "type" : "string" + }, + "storage" : { + "optional" : 1, + "type" : "string" + }, + "type" : { + "enum" : [ + "qemu", + "lxc", + "openvz", + "storage" + ], + "type" : "string" + }, + "vmid" : { + "optional" : 1, + "type" : "integer" + } + }, + "type" : "object" + }, + "optional" : 1, + "type" : "array" + }, + "poolid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "links" : [ + { + "href" : "{poolid}", + "rel" : "child" + } + ], + "type" : "array" + } + }, + "POST" : { + "allowtoken" : 1, + "description" : "Create new pool.", + "method" : "POST", + "name" : "create_pool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ] + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + }, + "PUT" : { + "allowtoken" : 1, + "description" : "Update pool.", + "method" : "PUT", + "name" : "update_pool", + "parameters" : { + "additionalProperties" : 0, + "properties" : { + "allow-move" : { + "default" : 0, + "description" : "Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "comment" : { + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "delete" : { + "default" : 0, + "description" : "Remove the passed VMIDs and/or storage IDs instead of adding them.", + "optional" : 1, + "type" : "boolean", + "typetext" : "" + }, + "poolid" : { + "format" : "pve-poolid", + "type" : "string", + "typetext" : "" + }, + "storage" : { + "description" : "List of storage IDs to add or remove from this pool.", + "format" : "pve-storage-id-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + }, + "vms" : { + "description" : "List of guest VMIDs to add or remove from this pool.", + "format" : "pve-vmid-list", + "optional" : 1, + "type" : "string", + "typetext" : "" + } + } + }, + "permissions" : { + "check" : [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description" : "You also need the right to modify permissions on any object you add/delete." + }, + "protected" : 1, + "returns" : { + "type" : "null" + } + } + }, + "leaf" : 0, + "path" : "/pools", + "text" : "pools" + }, + { + "info" : { + "GET" : { + "allowtoken" : 1, + "description" : "API version details, including some parts of the global datacenter config.", + "method" : "GET", + "name" : "version", + "parameters" : { + "additionalProperties" : 0 + }, + "permissions" : { + "user" : "all" + }, + "returns" : { + "properties" : { + "console" : { + "description" : "The default console viewer to use.", + "enum" : [ + "applet", + "vv", + "html5", + "xtermjs" + ], + "optional" : 1, + "type" : "string" + }, + "release" : { + "description" : "The current Proxmox VE point release in `x.y` format.", + "type" : "string" + }, + "repoid" : { + "description" : "The short git revision from which this version was build.", + "pattern" : "[0-9a-fA-F]{8,64}", + "type" : "string" + }, + "version" : { + "description" : "The full pve-manager package version of this node.", + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "leaf" : 1, + "path" : "/version", + "text" : "version" + } +] +; + +let method2cmd = { + GET: 'get', + POST: 'create', + PUT: 'set', + DELETE: 'delete' +}; + +function cliUsageRenderer(method, path) { + return `
HTTP:   `; + usage += `${method} /api2/json${endpoint}
 
CLI:pvesh ${method2cmd[method]} ${path}
`; +} +/*global apiSchema*/ + +Ext.onReady(function() { + Ext.define('pmx-param-schema', { + extend: 'Ext.data.Model', + fields: [ + 'name', 'type', 'typetext', 'description', 'verbose_description', + 'enum', 'minimum', 'maximum', 'minLength', 'maxLength', + 'pattern', 'title', 'requires', 'format', 'default', + 'disallow', 'extends', 'links', 'instance-types', + { + name: 'optional', + type: 'boolean', + }, + ], + }); + + let store = Ext.define('pmx-updated-treestore', { + extend: 'Ext.data.TreeStore', + model: Ext.define('pmx-api-doc', { + extend: 'Ext.data.Model', + fields: [ + 'path', 'info', 'text', + ], + }), + proxy: { + type: 'memory', + data: apiSchema, + }, + sorters: [{ + property: 'leaf', + direction: 'ASC', + }, { + property: 'text', + direction: 'ASC', + }], + filterer: 'bottomup', + doFilter: function(node) { + this.filterNodes(node, this.getFilters().getFilterFn(), true); + }, + + filterNodes: function(node, filterFn, parentVisible) { + let me = this; + + let match = filterFn(node) && (parentVisible || (node.isRoot() && !me.getRootVisible())); + + if (node.childNodes && node.childNodes.length) { + let bottomUpFiltering = me.filterer === 'bottomup'; + let childMatch; + for (const child of node.childNodes) { + childMatch = me.filterNodes(child, filterFn, match || bottomUpFiltering) || childMatch; + } + if (bottomUpFiltering) { + match = childMatch || match; + } + } + + node.set("visible", match, me._silentOptions); + return match; + }, + + }).create(); + + let render_description = function(value, metaData, record) { + let pdef = record.data; + + value = pdef.verbose_description || value; + + // TODO: try to render asciidoc correctly + + metaData.style = 'white-space:pre-wrap;'; + + return Ext.htmlEncode(value); + }; + + let render_type = function(value, metaData, record) { + let pdef = record.data; + + return pdef.enum ? 'enum' : pdef.type || 'string'; + }; + + const renderFormatString = function(obj) { + if (!Ext.isObject(obj)) { + return obj; + } + const mandatory = []; + const optional = []; + Object.entries(obj).forEach(function([name, param]) { + let list = param.optional ? optional : mandatory; + let str = param.default_key ? `[${name}=]` : `${name}=`; + if (param.alias) { + return; + } else if (param.enum) { + str += `(${param.enum?.join(' | ')})`; + } else { + str += `<${param.format_description || param.pattern || param.type}>`; + } + list.push(str); + }); + return mandatory.join(", ") + ' ' + optional.map(each => `[,${each}]`).join(' '); + }; + + let render_simple_format = function(pdef, type_fallback) { + if (pdef.typetext) { + return pdef.typetext; + } + if (pdef.enum) { + return pdef.enum.join(' | '); + } + if (pdef.format) { + return renderFormatString(pdef.format); + } + if (pdef.pattern) { + return pdef.pattern; + } + if (pdef.type === 'boolean') { + return ``; + } + if (type_fallback && pdef.type) { + return `<${pdef.type}>`; + } + if (pdef.minimum || pdef.maximum) { + return `${pdef.minimum || 'N'} - ${pdef.maximum || 'N'}`; + } + return ''; + }; + + let render_format = function(value, metaData, record) { + let pdef = record.data; + + metaData.style = 'white-space:normal;'; + + if (pdef.type === 'array' && pdef.items) { + let format = render_simple_format(pdef.items, true); + return `[${Ext.htmlEncode(format)}, ...]`; + } + + return Ext.htmlEncode(render_simple_format(pdef)); + }; + + let real_path = function(path) { + if (!path.match(/^[/]/)) { + path = `/${path}`; + } + return path.replace(/^.*\/_upgrade_(\/)?/, "/"); + }; + + let permission_text = function(permission) { + let permhtml = ""; + + if (permission.user) { + if (!permission.description) { + if (permission.user === 'world') { + permhtml += "Accessible without any authentication."; + } else if (permission.user === 'all') { + permhtml += "Accessible by all authenticated users."; + } else { + permhtml += `Only accessible by user "${permission.user}"`; + } + } + } else if (permission.check) { + permhtml += `
Check: ${Ext.htmlEncode(JSON.stringify(permission.check))}
`; + } else if (permission.userParam) { + permhtml += `
Check if user matches parameter '${permission.userParam}'`; + } else if (permission.or) { + permhtml += "
Or
"; + permhtml += permission.or.map(v => permission_text(v)).join(''); + permhtml += "
"; + } else if (permission.and) { + permhtml += "
And
"; + permhtml += permission.and.map(v => permission_text(v)).join(''); + permhtml += "
"; + } else { + permhtml += "Unknown syntax!"; + } + + return permhtml; + }; + + let render_docu = function(data) { + let md = data.info; + + let items = []; + + Ext.Array.each(['GET', 'POST', 'PUT', 'DELETE'], function(method) { + let info = md[method]; + if (info) { + let endpoint = real_path(data.path); + let usage = ``; + + if (typeof cliUsageRenderer === 'function') { + usage += cliUsageRenderer(method, endpoint); // eslint-disable-line no-undef + } + + let sections = [ + { + title: 'Description', + html: Ext.htmlEncode(info.description), + bodyPadding: 10, + }, + { + title: 'Usage', + html: usage, + bodyPadding: 10, + }, + ]; + + if (info.parameters && info.parameters.properties) { + let pstore = Ext.create('Ext.data.Store', { + model: 'pmx-param-schema', + proxy: { + type: 'memory', + }, + groupField: 'optional', + sorters: [ + { + property: 'instance-types', + direction: 'ASC', + }, + { + property: 'name', + direction: 'ASC', + }, + ], + }); + + let has_type_properties = false; + + Ext.Object.each(info.parameters.properties, function(name, pdef) { + if (pdef.oneOf) { + pdef.oneOf.forEach((alternative) => { + alternative.name = name; + pstore.add(alternative); + has_type_properties = true; + }); + } else if (pdef['instance-types']) { + pdef['instance-types'].forEach((type) => { + let typePdef = Ext.apply({}, pdef); + typePdef.name = name; + typePdef['instance-types'] = [type]; + pstore.add(typePdef); + has_type_properties = true; + }); + } else { + pdef.name = name; + pstore.add(pdef); + } + }); + + pstore.sort(); + + let groupingFeature = Ext.create('Ext.grid.feature.Grouping', { + enableGroupingMenu: false, + groupHeaderTpl: 'OptionalRequired', + }); + + sections.push({ + xtype: 'gridpanel', + title: 'Parameters', + features: [groupingFeature], + store: pstore, + viewConfig: { + trackOver: false, + stripeRows: true, + enableTextSelection: true, + }, + columns: [ + { + header: 'Name', + dataIndex: 'name', + flex: 1, + }, + { + header: 'Type', + dataIndex: 'type', + renderer: render_type, + flex: 1, + }, + { + header: 'For Types', + dataIndex: 'instance-types', + hidden: !has_type_properties, + flex: 1, + }, + { + header: 'Default', + dataIndex: 'default', + flex: 1, + }, + { + header: 'Format', + dataIndex: 'type', + renderer: render_format, + flex: 2, + }, + { + header: 'Description', + dataIndex: 'description', + renderer: render_description, + flex: 6, + }, + ], + }); + } + + if (info.returns) { + let retinf = info.returns; + let rtype = retinf.type; + if (!rtype && retinf.items) {rtype = 'array';} + if (!rtype) {rtype = 'object';} + + let rpstore = Ext.create('Ext.data.Store', { + model: 'pmx-param-schema', + proxy: { + type: 'memory', + }, + groupField: 'optional', + sorters: [ + { + property: 'name', + direction: 'ASC', + }, + ], + }); + + let properties; + if (rtype === 'array' && retinf.items.properties) { + properties = retinf.items.properties; + } + + if (rtype === 'object' && retinf.properties) { + properties = retinf.properties; + } + + Ext.Object.each(properties, function(name, pdef) { + pdef.name = name; + rpstore.add(pdef); + }); + + rpstore.sort(); + + let groupingFeature = Ext.create('Ext.grid.feature.Grouping', { + enableGroupingMenu: false, + groupHeaderTpl: 'OptionalObligatory', + }); + let returnhtml; + if (retinf.items) { + returnhtml = '
items: ' + Ext.htmlEncode(JSON.stringify(retinf.items, null, 4)) + '
'; + } + + if (retinf.properties) { + returnhtml = returnhtml || ''; + returnhtml += '
properties:' + Ext.htmlEncode(JSON.stringify(retinf.properties, null, 4)) + '
'; + } + + let rawSection = Ext.create('Ext.panel.Panel', { + bodyPadding: '0px 10px 10px 10px', + html: returnhtml, + hidden: true, + }); + + sections.push({ + xtype: 'gridpanel', + title: 'Returns: ' + rtype, + features: [groupingFeature], + store: rpstore, + viewConfig: { + trackOver: false, + stripeRows: true, + enableTextSelection: true, + }, + columns: [ + { + header: 'Name', + dataIndex: 'name', + flex: 1, + }, + { + header: 'Type', + dataIndex: 'type', + renderer: render_type, + flex: 1, + }, + { + header: 'Default', + dataIndex: 'default', + flex: 1, + }, + { + header: 'Format', + dataIndex: 'type', + renderer: render_format, + flex: 2, + }, + { + header: 'Description', + dataIndex: 'description', + renderer: render_description, + flex: 6, + }, + ], + bbar: [ + { + xtype: 'button', + text: 'Show RAW', + handler: function(btn) { + rawSection.setVisible(!rawSection.isVisible()); + btn.setText(rawSection.isVisible() ? 'Hide RAW' : 'Show RAW'); + }, + }, + ], + }); + + sections.push(rawSection); + } + + if (!data.path.match(/\/_upgrade_/)) { + let permhtml = ''; + + if (!info.permissions) { + permhtml = "Root only."; + } else { + if (info.permissions.description) { + permhtml += "
" + + Ext.htmlEncode(info.permissions.description) + "
"; + } + permhtml += permission_text(info.permissions); + } + + if (info.allowtoken !== undefined && !info.allowtoken) { + permhtml += "
This API endpoint is not available for API tokens."; + } + + sections.push({ + title: 'Required permissions', + bodyPadding: 10, + html: permhtml, + }); + } + + items.push({ + title: method, + autoScroll: true, + defaults: { + border: false, + }, + items: sections, + }); + } + }); + + let ct = Ext.getCmp('docview'); + ct.setTitle("Path: " + real_path(data.path)); + ct.removeAll(true); + ct.add(items); + ct.setActiveTab(0); + }; + + Ext.define('Ext.form.SearchField', { + extend: 'Ext.form.field.Text', + alias: 'widget.searchfield', + + emptyText: 'Search...', + + flex: 1, + + inputType: 'search', + listeners: { + 'change': function() { + let value = this.getValue(); + if (!Ext.isEmpty(value)) { + store.filter({ + property: 'path', + value: value, + anyMatch: true, + }); + } else { + store.clearFilter(); + } + }, + }, + }); + + let treePanel = Ext.create('Ext.tree.Panel', { + title: 'Resource Tree', + tbar: [ + { + xtype: 'searchfield', + }, + ], + tools: [ + { + type: 'expand', + tooltip: 'Expand all', + tooltipType: 'title', + callback: tree => tree.expandAll(), + }, + { + type: 'collapse', + tooltip: 'Collapse all', + tooltipType: 'title', + callback: tree => tree.collapseAll(), + }, + ], + store: store, + width: 200, + region: 'west', + split: true, + margins: '5 0 5 5', + rootVisible: false, + listeners: { + selectionchange: function(v, selections) { + if (!selections[0]) {return;} + let rec = selections[0]; + render_docu(rec.data); + location.hash = '#' + rec.data.path; + }, + }, + }); + + Ext.create('Ext.container.Viewport', { + layout: 'border', + renderTo: Ext.getBody(), + items: [ + treePanel, + { + xtype: 'tabpanel', + title: 'Documentation', + id: 'docview', + region: 'center', + margins: '5 5 5 0', + layout: 'fit', + items: [], + }, + ], + }); + + let deepLink = function() { + let path = window.location.hash.substring(1).replace(/\/\s*$/, ''); + let endpoint = store.findNode('path', path); + + if (endpoint) { + treePanel.getSelectionModel().select(endpoint); + treePanel.expandPath(endpoint.getPath()); + render_docu(endpoint.data); + } + }; + window.onhashchange = deepLink; + + deepLink(); +}); diff --git a/contracts/fce6db0a784b3a9b447895895fc6ff4b4437c2dce82e5f3db99227af217726fa/snapshot.json b/contracts/fce6db0a784b3a9b447895895fc6ff4b4437c2dce82e5f3db99227af217726fa/snapshot.json new file mode 100644 index 0000000..29e9105 --- /dev/null +++ b/contracts/fce6db0a784b3a9b447895895fc6ff4b4437c2dce82e5f3db99227af217726fa/snapshot.json @@ -0,0 +1 @@ +{"extra":{"warning_count":0},"format_version":1,"method_count":605,"path_count":398,"paths":[{"extra":{},"methods":[{"allow_token":true,"checksum":"381dbe2603a3fe4644aef5716358b57a8c8df69ae5476d4204ec50da62e28f19","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/access"},{"extra":{},"methods":[{"allow_token":true,"checksum":"69d1196ad983a4e9b6440c4dc7050a74d305be5327ff2b7231df69a5f7300f0a","description":"Get Access Control List (ACLs).","extra":{},"name":"read_acl","parameters":[],"permissions":{"description":"The returned list is restricted to objects where you have rights to modify permissions.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":0},"properties":{"path":{"description":"Access control path","enum":[],"extra":{},"properties":{},"type":"string"},"propagate":{"default":1,"description":"Allow to propagate (inherit) permissions.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"roleid":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":["user","group","token"],"extra":{},"properties":{},"type":"string"},"ugid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f303163fa6559541cc81fcd57689b33e3ed216ea236d34d63cd9d35e3fce947a","description":"Update Access Control List (add or remove permissions).","extra":{},"name":"update_acl","parameters":[{"definition":{"description":"Remove permissions (instead of adding it).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"List of groups.","enum":[],"extra":{"typetext":""},"format":"pve-groupid-list","optional":true,"properties":{},"type":"string"},"name":"groups"},{"definition":{"description":"Access control path","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"path"},{"definition":{"default":1,"description":"Allow to propagate (inherit) permissions.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"propagate"},{"definition":{"description":"List of roles.","enum":[],"extra":{"typetext":""},"format":"pve-roleid-list","properties":{},"type":"string"},"name":"roles"},{"definition":{"description":"List of API tokens.","enum":[],"extra":{"typetext":""},"format":"pve-tokenid-list","optional":true,"properties":{},"type":"string"},"name":"tokens"},{"definition":{"description":"List of users.","enum":[],"extra":{"typetext":""},"format":"pve-userid-list","optional":true,"properties":{},"type":"string"},"name":"users"}],"permissions":{"expression":{"check":["perm-modify","{path}"]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/acl"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f6bd08a792d4f4d22aac7aaddba3d623b96b8333f6e0e464a8782c3ebc6c764b","description":"Authentication domain index.","extra":{},"name":"index","parameters":[],"permissions":{"description":"Anyone can access that, because we need that list for the login box (before the user is authenticated).","expression":{},"extra":{},"user":"world"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{realm}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"A comment. The GUI use this text when you select a domain (Realm) on the login window.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"realm":{"enum":[],"extra":{},"properties":{},"type":"string"},"tfa":{"description":"Two-factor authentication provider.","enum":["yubico","oath"],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"955f2975d7d902d74b2d5a4695291bd962ca860b50ab35684653dc68bb0c988c","description":"Add an authentication server.","extra":{},"name":"create","parameters":[{"definition":{"description":"Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.","enum":[],"extra":{},"optional":true,"pattern":"^[^\\x00-\\x1F\\x7F <>#\"]*$","properties":{},"type":"string"},"name":"acr-values"},{"definition":{"default":0,"description":"Automatically create users if they do not exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autocreate"},{"definition":{"description":"LDAP base domain name","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"base_dn"},{"definition":{"description":"LDAP bind domain name","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"bind_dn"},{"definition":{"default":"/etc/ssl/certs","description":"Path to the CA certificate store","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"capath"},{"definition":{"default":1,"description":"username is case-sensitive","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"case-sensitive"},{"definition":{"description":"Path to the client certificate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cert"},{"definition":{"description":"Path to the client certificate key","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"certkey"},{"definition":{"default":0,"description":"Check bind connection to the server.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"check-connection"},{"definition":{"description":"OpenID Client ID","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"client-id"},{"definition":{"description":"OpenID Client Key","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"client-key"},{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Use this as default realm","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"default"},{"definition":{"description":"AD domain name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\S+","properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"LDAP filter for user sync.","enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"filter"},{"definition":{"default":"groupOfNames, group, univentionGroup, ipausergroup","description":"The objectclasses for groups.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr-list","optional":true,"properties":{},"type":"string"},"name":"group_classes"},{"definition":{"description":"LDAP base domain name for group sync. If not set, the base_dn will be used.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"group_dn"},{"definition":{"description":"LDAP filter for group sync.","enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"group_filter"},{"definition":{"description":"LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"group_name_attr"},{"definition":{"default":0,"description":"Automatically create groups if they do not exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"groups-autocreate"},{"definition":{"description":"OpenID claim used to retrieve groups with.","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^:[A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"groups-claim"},{"definition":{"default":0,"description":"All groups will be overwritten for the user on login.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"groups-overwrite"},{"definition":{"description":"OpenID Issuer Url","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"issuer-url"},{"definition":{"default":"ldap","description":"LDAP protocol mode.","enum":["ldap","ldaps","ldap+starttls"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Server port.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.","enum":[],"extra":{},"optional":true,"pattern":"(?:none|login|consent|select_account|\\S+)","properties":{},"type":"string"},"name":"prompt"},{"definition":{"default":1,"description":"Enables querying the userinfo endpoint for claims values.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"query-userinfo"},{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"},{"definition":{"default":"email profile","description":"Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"scopes"},{"definition":{"description":"Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"secure"},{"definition":{"description":"Server IP address (or DNS name)","enum":[],"extra":{"typetext":""},"format":"address","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"server1"},{"definition":{"description":"Fallback Server IP address (or DNS name)","enum":[],"extra":{"typetext":""},"format":"address","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"server2"},{"definition":{"description":"LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!","enum":["tlsv1","tlsv1_1","tlsv1_2","tlsv1_3"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"sslversion"},{"definition":{"description":"The default options for behavior of synchronizations.","enum":[],"extra":{"typetext":"[enable-new=<1|0>] [,full=<1|0>] [,purge=<1|0>] [,remove-vanished=([acl];[properties];[entry])|none] [,scope=]"},"format":"realm-sync-options","optional":true,"properties":{},"type":"string"},"name":"sync-defaults-options"},{"definition":{"description":"Comma separated list of key=value pairs for specifying which LDAP attributes map to which PVE user field. For example, to map the LDAP attribute 'mail' to PVEs 'email', write 'email=mail'. By default, each PVE user field is represented by an LDAP attribute of the same name.","enum":[],"extra":{},"optional":true,"pattern":"\\w+=[^,]+(,\\s*\\w+=[^,]+)*","properties":{},"type":"string"},"name":"sync_attributes"},{"definition":{"description":"Use Two-factor authentication.","enum":[],"extra":{"typetext":"type= [,digits=] [,id=] [,key=] [,step=] [,url=]"},"format":"pve-tfa-config","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"tfa"},{"definition":{"description":"Realm type.","enum":["ad","ldap","openid","pam","pve"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"LDAP user attribute name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\S{2,}","properties":{},"type":"string"},"name":"user_attr"},{"definition":{"default":"inetorgperson, posixaccount, person, user","description":"The objectclasses for users.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr-list","optional":true,"properties":{},"type":"string"},"name":"user_classes"},{"definition":{"description":"OpenID claim used to generate the unique username.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username-claim"},{"definition":{"default":0,"description":"Verify the server's SSL certificate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify"}],"permissions":{"expression":{"check":["perm","/access/realm",["Realm.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/domains"},{"extra":{},"methods":[{"allow_token":true,"checksum":"67ef2d8bf073fff13e3d81cd559ffa0c8d70b56f153a1a682bf52b5e6068f2ee","description":"Delete an authentication server.","extra":{},"name":"delete","parameters":[{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"}],"permissions":{"expression":{"check":["perm","/access/realm",["Realm.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"68ad3629142a043ace8f38217d65a6ecf29d34a83d21ff690c0def6efcdabd7c","description":"Get auth server configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"}],"permissions":{"expression":{"check":["perm","/access/realm",["Realm.Allocate","Sys.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{}},"verb":"GET"},{"allow_token":true,"checksum":"da31103b160d435c8348e4f409759306074282b4e6367556a24e2f5e087ff797","description":"Update authentication server settings.","extra":{},"name":"update","parameters":[{"definition":{"description":"Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.","enum":[],"extra":{},"optional":true,"pattern":"^[^\\x00-\\x1F\\x7F <>#\"]*$","properties":{},"type":"string"},"name":"acr-values"},{"definition":{"default":0,"description":"Automatically create users if they do not exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autocreate"},{"definition":{"description":"LDAP base domain name","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"base_dn"},{"definition":{"description":"LDAP bind domain name","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"bind_dn"},{"definition":{"default":"/etc/ssl/certs","description":"Path to the CA certificate store","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"capath"},{"definition":{"default":1,"description":"username is case-sensitive","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"case-sensitive"},{"definition":{"description":"Path to the client certificate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cert"},{"definition":{"description":"Path to the client certificate key","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"certkey"},{"definition":{"default":0,"description":"Check bind connection to the server.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"check-connection"},{"definition":{"description":"OpenID Client ID","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"client-id"},{"definition":{"description":"OpenID Client Key","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"client-key"},{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Use this as default realm","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"default"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"AD domain name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\S+","properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"LDAP filter for user sync.","enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"filter"},{"definition":{"default":"groupOfNames, group, univentionGroup, ipausergroup","description":"The objectclasses for groups.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr-list","optional":true,"properties":{},"type":"string"},"name":"group_classes"},{"definition":{"description":"LDAP base domain name for group sync. If not set, the base_dn will be used.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"group_dn"},{"definition":{"description":"LDAP filter for group sync.","enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"group_filter"},{"definition":{"description":"LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"group_name_attr"},{"definition":{"default":0,"description":"Automatically create groups if they do not exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"groups-autocreate"},{"definition":{"description":"OpenID claim used to retrieve groups with.","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^:[A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"groups-claim"},{"definition":{"default":0,"description":"All groups will be overwritten for the user on login.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"groups-overwrite"},{"definition":{"description":"OpenID Issuer Url","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"issuer-url"},{"definition":{"default":"ldap","description":"LDAP protocol mode.","enum":["ldap","ldaps","ldap+starttls"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Server port.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.","enum":[],"extra":{},"optional":true,"pattern":"(?:none|login|consent|select_account|\\S+)","properties":{},"type":"string"},"name":"prompt"},{"definition":{"default":1,"description":"Enables querying the userinfo endpoint for claims values.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"query-userinfo"},{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"},{"definition":{"default":"email profile","description":"Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"scopes"},{"definition":{"description":"Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"secure"},{"definition":{"description":"Server IP address (or DNS name)","enum":[],"extra":{"typetext":""},"format":"address","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"server1"},{"definition":{"description":"Fallback Server IP address (or DNS name)","enum":[],"extra":{"typetext":""},"format":"address","max_length":256,"optional":true,"properties":{},"type":"string"},"name":"server2"},{"definition":{"description":"LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!","enum":["tlsv1","tlsv1_1","tlsv1_2","tlsv1_3"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"sslversion"},{"definition":{"description":"The default options for behavior of synchronizations.","enum":[],"extra":{"typetext":"[enable-new=<1|0>] [,full=<1|0>] [,purge=<1|0>] [,remove-vanished=([acl];[properties];[entry])|none] [,scope=]"},"format":"realm-sync-options","optional":true,"properties":{},"type":"string"},"name":"sync-defaults-options"},{"definition":{"description":"Comma separated list of key=value pairs for specifying which LDAP attributes map to which PVE user field. For example, to map the LDAP attribute 'mail' to PVEs 'email', write 'email=mail'. By default, each PVE user field is represented by an LDAP attribute of the same name.","enum":[],"extra":{},"optional":true,"pattern":"\\w+=[^,]+(,\\s*\\w+=[^,]+)*","properties":{},"type":"string"},"name":"sync_attributes"},{"definition":{"description":"Use Two-factor authentication.","enum":[],"extra":{"typetext":"type= [,digits=] [,id=] [,key=] [,step=] [,url=]"},"format":"pve-tfa-config","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"tfa"},{"definition":{"description":"LDAP user attribute name","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"\\S{2,}","properties":{},"type":"string"},"name":"user_attr"},{"definition":{"default":"inetorgperson, posixaccount, person, user","description":"The objectclasses for users.","enum":[],"extra":{"typetext":""},"format":"ldap-simple-attr-list","optional":true,"properties":{},"type":"string"},"name":"user_classes"},{"definition":{"default":0,"description":"Verify the server's SSL certificate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify"}],"permissions":{"expression":{"check":["perm","/access/realm",["Realm.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/domains/{realm}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a1767738c2b9bc0ac0f8cd38d7d39bc6a0aa139bfc06fc7f92b6d6fce313c81f","description":"Syncs users and/or groups from the configured LDAP to user.cfg. NOTE: Synced groups will have the name 'name-$realm', so make sure those groups do not exist to prevent overwriting.","extra":{},"name":"sync","parameters":[{"definition":{"default":0,"description":"If set, does not write anything.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"dry-run"},{"definition":{"default":"1","description":"Enable newly synced users immediately.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable-new"},{"definition":{"description":"DEPRECATED: use 'remove-vanished' instead. If set, uses the LDAP Directory as source of truth, deleting users or groups not returned from the sync and removing all locally modified properties of synced users. If not set, only syncs information which is present in the synced data, and does not delete or modify anything else.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"},{"definition":{"description":"DEPRECATED: use 'remove-vanished' instead. Remove ACLs for users or groups which were removed from the config during a sync.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"purge"},{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"},{"definition":{"default":"none","description":"A semicolon-separated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).","enum":[],"extra":{"typetext":"([acl];[properties];[entry])|none"},"optional":true,"pattern":"(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none","properties":{},"type":"string"},"name":"remove-vanished"},{"definition":{"description":"Select what to sync.","enum":["users","groups","both"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scope"}],"permissions":{"description":"'Realm.AllocateUser' on '/access/realm/' and 'User.Modify' permissions to '/access/groups/'.","expression":{"check":["and",["perm","/access/realm/{realm}",["Realm.AllocateUser"]],["perm","/access/groups",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"description":"Worker Task-UPID","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/access/domains/{realm}/sync"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4c91cdccabc91aef686778145ca3abfc7c583221f55d71a6a63742c0c9e8620e","description":"Group index.","extra":{},"name":"index","parameters":[],"permissions":{"description":"The returned list is restricted to groups where you have 'User.Modify', 'Sys.Audit' or 'Group.Allocate' permissions on /access/groups/.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{groupid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"groupid":{"enum":[],"extra":{},"format":"pve-groupid","properties":{},"type":"string"},"users":{"description":"list of users which form this group","enum":[],"extra":{},"format":"pve-userid-list","optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f98ce64f3980dff63659bf39b78cfd90bc57491d5a6b16adf211ad89cb5bacbf","description":"Create new group.","extra":{},"name":"create_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid","properties":{},"type":"string"},"name":"groupid"}],"permissions":{"expression":{"check":["perm","/access/groups",["Group.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/groups"},{"extra":{},"methods":[{"allow_token":true,"checksum":"da8c8fd5b71fd2ffb0d9a877a6a55bf3fece5793e6e84103fd32ce8393b143a9","description":"Delete group.","extra":{},"name":"delete_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid","properties":{},"type":"string"},"name":"groupid"}],"permissions":{"expression":{"check":["perm","/access/groups",["Group.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"97141e0ff4c0c701de5667b1695e08f82f1c7ca0457b431a4544c6b1b2ebf164","description":"Get group configuration.","extra":{},"name":"read_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid","properties":{},"type":"string"},"name":"groupid"}],"permissions":{"expression":{"check":["perm","/access/groups",["Sys.Audit","Group.Allocate"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"members":{"enum":[],"extra":{},"items":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"acae7739337fa0edb0e0a31549c4d29be7fdf80fd872c3b0e65f946d447c8570","description":"Update group data.","extra":{},"name":"update_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid","properties":{},"type":"string"},"name":"groupid"}],"permissions":{"expression":{"check":["perm","/access/groups",["Group.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/groups/{groupid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"381dbe2603a3fe4644aef5716358b57a8c8df69ae5476d4204ec50da62e28f19","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/access/openid"},{"extra":{},"methods":[{"allow_token":true,"checksum":"11698bf61b11bf04b51047fbad48466f21c0e0de4d90d25ed9650486cab24fdb","description":"Get the OpenId Authorization Url for the specified realm.","extra":{},"name":"auth_url","parameters":[{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"name":"realm"},{"definition":{"description":"Redirection Url. The client should set this to the used server url (location.origin).","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"redirect-url"}],"permissions":{"expression":{},"extra":{},"user":"world"},"protected":true,"returns":{"description":"Redirection URL.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/access/openid/auth-url"},{"extra":{},"methods":[{"allow_token":true,"checksum":"19ede18ffcfecdd547ec697670a70a44b18fe1b9f0160ba1e02d8446072ad21d","description":" Verify OpenID authorization code and create a ticket.","extra":{},"name":"login","parameters":[{"definition":{"description":"OpenId authorization code.","enum":[],"extra":{"typetext":""},"max_length":4096,"properties":{},"type":"string"},"name":"code"},{"definition":{"description":"Redirection Url. The client should set this to the used server url (location.origin).","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"redirect-url"},{"definition":{"description":"OpenId state.","enum":[],"extra":{"typetext":""},"max_length":1024,"properties":{},"type":"string"},"name":"state"}],"permissions":{"expression":{},"extra":{},"user":"world"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"CSRFPreventionToken":{"enum":[],"extra":{},"properties":{},"type":"string"},"cap":{"enum":[],"extra":{},"properties":{},"type":"object"},"clustername":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"username":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/access/openid/login"},{"extra":{},"methods":[{"allow_token":false,"checksum":"89105df2fc31d5ef94c2383c01872c011a634de7c0e3241dc325311de9f11fa1","description":"Change user password.","extra":{},"name":"change_password","parameters":[{"definition":{"description":"The current password of the user performing the change.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"confirmation-password"},{"definition":{"description":"The new password.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":8,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"description":"Each user is allowed to change their own password. A user can change the password of another user if they have 'Realm.AllocateUser' (on the realm of user ) and 'User.Modify' permission on /access/groups/ on a group where user is member of. For the PAM realm, a password change does not take effect cluster-wide, but only applies to the local node.","expression":{"check":["or",["userid-param","self"],["and",["userid-param","Realm.AllocateUser"],["userid-group",["User.Modify"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/password"},{"extra":{},"methods":[{"allow_token":true,"checksum":"581500cf55715c5906b69cd6691c20d1372de35b8e557a473e8351db9bf8feb8","description":"Retrieve effective permissions of given user/token.","extra":{},"name":"permissions","parameters":[{"definition":{"description":"Only dump this specific path, not the whole tree.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"User ID or full API token ID","enum":[],"extra":{},"optional":true,"pattern":"(?^:^(?^:[^\\s:/]+)\\@(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)(?:!(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+))?$)","properties":{},"type":"string"},"name":"userid"}],"permissions":{"description":"Each user/token is allowed to dump their own permissions (or that of owned tokens). A user can dump the permissions of another user or their tokens if they have 'Sys.Audit' permission on /access.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"Map of \"path\" => (Map of \"privilege\" => \"propagate boolean\").","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/access/permissions"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7d4735a632ce33c51d1e2e47102b18f3b391b730e88f11993ab2319447462466","description":"Role index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{roleid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"privs":{"enum":[],"extra":{},"format":"pve-priv-list","optional":true,"properties":{},"type":"string"},"roleid":{"enum":[],"extra":{},"format":"pve-roleid","properties":{},"type":"string"},"special":{"default":0,"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f57a81b3de7e8d88ea26453fd9bf5d26eb5b707474daa5d903df0fd5883860d5","description":"Create new role.","extra":{},"name":"create_role","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-priv-list","optional":true,"properties":{},"type":"string"},"name":"privs"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-roleid","properties":{},"type":"string"},"name":"roleid"}],"permissions":{"expression":{"check":["perm","/access",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/roles"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f1877684ae2970429259e20a70086722eda0e3fbd75ec22dc770adfed8cdad01","description":"Delete role.","extra":{},"name":"delete_role","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-roleid","properties":{},"type":"string"},"name":"roleid"}],"permissions":{"expression":{"check":["perm","/access",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"1882fe9448027396019be3743c55c29ec631a06654f216b7b1a57c9de338c1fe","description":"Get role configuration.","extra":{},"name":"read_role","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-roleid","properties":{},"type":"string"},"name":"roleid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"Datastore.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Datastore.AllocateSpace":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Datastore.AllocateTemplate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Datastore.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Group.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Mapping.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Mapping.Modify":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Mapping.Use":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Permissions.Modify":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Pool.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Pool.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Realm.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Realm.AllocateUser":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"SDN.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"SDN.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"SDN.Use":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.AccessNetwork":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Console":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Incoming":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Modify":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.PowerMgmt":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"Sys.Syslog":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"User.Modify":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Allocate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Audit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Backup":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Clone":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.CDROM":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.CPU":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Cloudinit":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Disk":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.HWType":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Memory":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Network":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Config.Options":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Console":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Migrate":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Monitor":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.PowerMgmt":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Snapshot":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"VM.Snapshot.Rollback":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"de543d90c405a031a8d83dba37eaf7b9faa4301cd0cac388ad12bc18dfdeb306","description":"Update an existing role.","extra":{},"name":"update_role","parameters":[{"definition":{"enum":[],"extra":{"requires":"privs","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"append"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-priv-list","optional":true,"properties":{},"type":"string"},"name":"privs"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-roleid","properties":{},"type":"string"},"name":"roleid"}],"permissions":{"expression":{"check":["perm","/access",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/roles/{roleid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f91fc5c12c7b0b199c7707aac6752be2449378befab94de333882d63e260cb78","description":"List TFA configurations of users.","extra":{},"name":"list_tfa","parameters":[],"permissions":{"description":"Returns all or just the logged-in user, depending on privileges.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"description":"The list tuples of user and TFA entries.","enum":[],"extra":{"links":[{"href":"{userid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"entries":{"enum":[],"extra":{},"items":{"description":"TFA Entry.","enum":[],"extra":{},"properties":{"created":{"description":"Creation time of this entry as unix epoch.","enum":[],"extra":{},"properties":{},"type":"integer"},"description":{"description":"User chosen description for this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"enable":{"default":1,"description":"Whether this TFA entry is currently enabled.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"id":{"description":"The id used to reference this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"TFA Entry Type.","enum":["totp","u2f","webauthn","recovery","yubico"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"tfa-locked-until":{"description":"Contains a timestamp until when a user is locked out of 2nd factors.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"totp-locked":{"description":"True if the user is currently locked out of TOTP factors.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"userid":{"description":"User this entry belongs to.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/access/tfa"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9e9514c7d979e99e219e52f97e01d8dde204978341882b3b25607e285fa80386","description":"List TFA configurations of users.","extra":{},"name":"list_user_tfa","parameters":[{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify","Sys.Audit"]]]},"extra":{}},"protected":true,"returns":{"description":"A list of the user's TFA entries.","enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"description":"TFA Entry.","enum":[],"extra":{},"properties":{"created":{"description":"Creation time of this entry as unix epoch.","enum":[],"extra":{},"properties":{},"type":"integer"},"description":{"description":"User chosen description for this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"enable":{"default":1,"description":"Whether this TFA entry is currently enabled.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"id":{"description":"The id used to reference this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"TFA Entry Type.","enum":["totp","u2f","webauthn","recovery","yubico"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":false,"checksum":"25a61e1b13613dab8ffbddc3d215b6e902d7ca2074ffb050f4435f2196444f86","description":"Add a TFA entry for a user.","extra":{},"name":"add_tfa_entry","parameters":[{"definition":{"description":"When responding to a u2f challenge: the original challenge string","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"challenge"},{"definition":{"description":"A description to distinguish multiple entries from one another","enum":[],"extra":{"typetext":""},"max_length":255,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The current password of the user performing the change.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"A totp URI.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"totp"},{"definition":{"description":"TFA Entry Type.","enum":["totp","u2f","webauthn","recovery","yubico"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"},{"definition":{"description":"The current value for the provided totp URI, or a Webauthn/U2F challenge response","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"value"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"challenge":{"description":"When adding u2f entries, this contains a challenge the user must respond to in order to finish the registration.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"description":"The id of a newly added TFA entry.","enum":[],"extra":{},"properties":{},"type":"string"},"recovery":{"description":"When adding recovery codes, this contains the list of codes to be displayed to the user","enum":[],"extra":{},"items":{"description":"A recovery entry.","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"verb":"POST"}],"path":"/access/tfa/{userid}"},{"extra":{},"methods":[{"allow_token":false,"checksum":"7f5a4a103f311d4bd0cda2596ae1b4ac5a454f02629ef26f23055c1eca449482","description":"Delete a TFA entry by ID.","extra":{},"name":"delete_tfa","parameters":[{"definition":{"description":"A TFA entry id.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The current password of the user performing the change.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"0980e358fcccf5906073e67987deaae92d2c610d396aa4988af5b8356c102847","description":"Fetch a requested TFA entry if present.","extra":{},"name":"get_tfa_entry","parameters":[{"definition":{"description":"A TFA entry id.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"id"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify","Sys.Audit"]]]},"extra":{}},"protected":true,"returns":{"description":"TFA Entry.","enum":[],"extra":{},"properties":{"created":{"description":"Creation time of this entry as unix epoch.","enum":[],"extra":{},"properties":{},"type":"integer"},"description":{"description":"User chosen description for this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"enable":{"default":1,"description":"Whether this TFA entry is currently enabled.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"id":{"description":"The id used to reference this entry.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"TFA Entry Type.","enum":["totp","u2f","webauthn","recovery","yubico"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":false,"checksum":"de5fbd256e20fa2c51750debf25afd3f80b7f1faf154d09718ae976814751769","description":"Add a TFA entry for a user.","extra":{},"name":"update_tfa_entry","parameters":[{"definition":{"description":"A description to distinguish multiple entries from one another","enum":[],"extra":{"typetext":""},"max_length":255,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Whether the entry should be enabled for login.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"A TFA entry id.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The current password of the user performing the change.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/tfa/{userid}/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b7321acfd13335fc9d66fb47358fa1b8f0ec6775a3c1733a8cdc617c3f9778b8","description":"Dummy. Useful for formatters which want to provide a login page.","extra":{},"name":"get_ticket","parameters":[],"permissions":{"expression":{},"extra":{},"user":"world"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"GET"},{"allow_token":false,"checksum":"ca41840815da5a2a32ab134298fee34856eb743cd283bc6eb453437982d6d7fc","description":"Create or verify authentication ticket.","extra":{},"name":"create_ticket","parameters":[{"definition":{"default":1,"description":"This parameter is now ignored and assumed to be 1.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"new-format"},{"definition":{"description":"One-time password for Two-factor authentication.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"otp"},{"definition":{"description":"The secret password. This can also be a valid ticket.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Verify ticket, and check if user have access 'privs' on 'path'","enum":[],"extra":{"requires":"privs","typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"Verify ticket, and check if user have access 'privs' on 'path'","enum":[],"extra":{"requires":"path","typetext":""},"format":"pve-priv-list","max_length":64,"optional":true,"properties":{},"type":"string"},"name":"privs"},{"definition":{"description":"You can optionally pass the realm using this parameter. Normally the realm is simply added to the username @.","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"optional":true,"properties":{},"type":"string"},"name":"realm"},{"definition":{"description":"The signed TFA challenge string the user wants to respond to.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tfa-challenge"},{"definition":{"description":"User name","enum":[],"extra":{"typetext":""},"max_length":64,"properties":{},"type":"string"},"name":"username"}],"permissions":{"description":"You need to pass valid credientials.","expression":{},"extra":{},"user":"world"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"CSRFPreventionToken":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"clustername":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ticket":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"username":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"POST"}],"path":"/access/ticket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c408f011c77c4c09143ff66a9a8318b74d1213818930e28ab8b349ee1a9dbc47","description":"User index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Optional filter for enable property.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"default":0,"description":"Include group and token information.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"}],"permissions":{"description":"The returned list is restricted to users where you have 'User.Modify' or 'Sys.Audit' permissions on '/access/groups' or on a group the user belongs too. But it always includes the current (authenticated) user.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{userid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"max_length":2048,"optional":true,"properties":{},"type":"string"},"email":{"enum":[],"extra":{},"format":"email-opt","max_length":254,"optional":true,"properties":{},"type":"string"},"enable":{"default":1,"description":"Enable the account (default). You can set this to '0' to disable the account","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"expire":{"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"firstname":{"enum":[],"extra":{},"max_length":1024,"optional":true,"properties":{},"type":"string"},"groups":{"enum":[],"extra":{},"format":"pve-groupid-list","optional":true,"properties":{},"type":"string"},"keys":{"description":"Keys for two factor auth (yubico).","enum":[],"extra":{},"optional":true,"pattern":"[0-9a-zA-Z!=]{0,4096}","properties":{},"type":"string"},"lastname":{"enum":[],"extra":{},"max_length":1024,"optional":true,"properties":{},"type":"string"},"realm-type":{"description":"The type of the users realm","enum":[],"extra":{},"format":"pve-realm","optional":true,"properties":{},"type":"string"},"tfa-locked-until":{"description":"Contains a timestamp until when a user is locked out of 2nd factors.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"tokens":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"tokenid":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"totp-locked":{"description":"True if the user is currently locked out of TOTP factors.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"userid":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{},"format":"pve-userid","max_length":64,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"8af1d16557cf5606431678f4758a50a5ff8af95deab3885d4d6dab9ea8d28f20","description":"Create new user.","extra":{},"name":"create_user","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"email-opt","max_length":254,"optional":true,"properties":{},"type":"string"},"name":"email"},{"definition":{"default":1,"description":"Enable the account (default). You can set this to '0' to disable the account","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"expire"},{"definition":{"enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"firstname"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid-list","optional":true,"properties":{},"type":"string"},"name":"groups"},{"definition":{"description":"Keys for two factor auth (yubico).","enum":[],"extra":{},"optional":true,"pattern":"[0-9a-zA-Z!=]{0,4096}","properties":{},"type":"string"},"name":"keys"},{"definition":{"enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"lastname"},{"definition":{"description":"Initial password.","enum":[],"extra":{"typetext":""},"max_length":64,"min_length":8,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"description":"You need 'Realm.AllocateUser' on '/access/realm/' on the realm of user , and 'User.Modify' permissions to '/access/groups/' for any group specified (or 'User.Modify' on '/access/groups' if you pass no groups.","expression":{"check":["and",["userid-param","Realm.AllocateUser"],["userid-group",["User.Modify"],"groups_param","create"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/access/users"},{"extra":{},"methods":[{"allow_token":true,"checksum":"22780e2427b9f89adfddae9c96331bf99e9988faa7d41c686fb83495858757ae","description":"Delete user.","extra":{},"name":"delete_user","parameters":[{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["and",["userid-param","Realm.AllocateUser"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"c9026bc7070e532432f03a9f4c8ac6708677d2006e8e4bce17376506d7fa06a2","description":"Get user configuration.","extra":{},"name":"read_user","parameters":[{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["userid-group",["User.Modify","Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"comment":{"enum":[],"extra":{},"max_length":2048,"optional":true,"properties":{},"type":"string"},"email":{"enum":[],"extra":{},"format":"email-opt","max_length":254,"optional":true,"properties":{},"type":"string"},"enable":{"default":1,"description":"Enable the account (default). You can set this to '0' to disable the account","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"expire":{"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"firstname":{"enum":[],"extra":{},"max_length":1024,"optional":true,"properties":{},"type":"string"},"groups":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"pve-groupid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"keys":{"description":"Keys for two factor auth (yubico).","enum":[],"extra":{},"optional":true,"pattern":"[0-9a-zA-Z!=]{0,4096}","properties":{},"type":"string"},"lastname":{"enum":[],"extra":{},"max_length":1024,"optional":true,"properties":{},"type":"string"},"tokens":{"enum":[],"extra":{"additionalProperties":{"properties":{"comment":{"optional":1,"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","minimum":0,"optional":1,"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","optional":1,"type":"boolean"}},"type":"object"}},"optional":true,"properties":{},"type":"object"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"6ebb05ae9a13766bb70f67f0f179cb5fedd4ec39339a7be78af0aafaf2a517a1","description":"Update user configuration.","extra":{},"name":"update_user","parameters":[{"definition":{"enum":[],"extra":{"requires":"groups","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"append"},{"definition":{"enum":[],"extra":{"typetext":""},"max_length":2048,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"email-opt","max_length":254,"optional":true,"properties":{},"type":"string"},"name":"email"},{"definition":{"default":1,"description":"Enable the account (default). You can set this to '0' to disable the account","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"expire"},{"definition":{"enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"firstname"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-groupid-list","optional":true,"properties":{},"type":"string"},"name":"groups"},{"definition":{"description":"Keys for two factor auth (yubico).","enum":[],"extra":{},"optional":true,"pattern":"[0-9a-zA-Z!=]{0,4096}","properties":{},"type":"string"},"name":"keys"},{"definition":{"enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"lastname"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["userid-group",["User.Modify"],"groups_param","update"]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/access/users/{userid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"26f06a801f3aeabfcda58f7abde4e44ae2ea0b7d444bb45d43ab0a2b0ea914f6","description":"Get user TFA types (Personal and Realm).","extra":{},"name":"read_user_tfa_type","parameters":[{"definition":{"default":0,"description":"Request all entries as an array.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"multiple"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify","Sys.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"realm":{"description":"The type of TFA the users realm has set, if any.","enum":["oath","yubico"],"extra":{},"optional":true,"properties":{},"type":"string"},"types":{"description":"Array of the user configured TFA types, if any. Only available if 'multiple' was not passed.","enum":[],"extra":{},"items":{"description":"A TFA type.","enum":["totp","u2f","yubico","webauthn","recovedry"],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"user":{"description":"The type of TFA the user has set, if any. Only set if 'multiple' was not passed.","enum":["oath","u2f"],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/access/users/{userid}/tfa"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2360720a844aea0ccfa1e79e038d8f7e51fdbbf56b0326c4c494f6c74cda5c23","description":"Get user API tokens.","extra":{},"name":"token_index","parameters":[{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{tokenid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"tokenid":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/access/users/{userid}/token"},{"extra":{},"methods":[{"allow_token":true,"checksum":"90a204f61f32d1c0a9d7013a9d97a94ad045ddf8e8a632185529ef137603b2cf","description":"Remove API token for a specific user.","extra":{},"name":"remove_token","parameters":[{"definition":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"tokenid"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f828f02deaee05fa61e8f6f3a516e80c673e3378a5ee3207a542c04c0ec6ffeb","description":"Get specific API token information.","extra":{},"name":"read_token","parameters":[{"definition":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"tokenid"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"b49a880be0c3083d372de13e274dae7d56a3b454d854ae90924ed5ecde1cba28","description":"Generate a new API token for a specific user. NOTE: returns API token value, which needs to be stored as it cannot be retrieved afterwards!","extra":{},"name":"generate_token","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"expire"},{"definition":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"privsep"},{"definition":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"tokenid"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"full-tokenid":{"description":"The full token id.","enum":[],"extra":{"format_description":"!"},"properties":{},"type":"string"},"info":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"value":{"description":"API token value used for authentication.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"POST"},{"allow_token":true,"checksum":"479161dc3bc0e315503384e52b71a816bb68d2b8f04ad8880b76dd2b3f6c3a0d","description":"Update API token for a specific user.","extra":{},"name":"update_token_info","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"expire"},{"definition":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"privsep"},{"definition":{"description":"User-specific token identifier.","enum":[],"extra":{},"pattern":"(?^:[A-Za-z][A-Za-z0-9\\.\\-_]+)","properties":{},"type":"string"},"name":"tokenid"},{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"description":"Updated token information.","enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"expire":{"default":"same as user","description":"API token expiration date (seconds since epoch). '0' means no expiration date.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"privsep":{"default":1,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"PUT"}],"path":"/access/users/{userid}/token/{tokenid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5c931db6ab2df88bd52ec3eb4863aed7d21f91c49181ee08b7dc0c67734724ec","description":"Unlock a user's TFA authentication.","extra":{},"name":"unlock_tfa","parameters":[{"definition":{"description":"Full User ID, in the `name@realm` format.","enum":[],"extra":{"typetext":""},"format":"pve-userid","max_length":64,"properties":{},"type":"string"},"name":"userid"}],"permissions":{"expression":{"check":["userid-group",["User.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"verb":"PUT"}],"path":"/access/users/{userid}/unlock-tfa"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8208fe00dcce4afff6857aaaea1b384b09f47069978af63ec4017df08db2adc2","description":"Cluster index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster"},{"extra":{},"methods":[{"allow_token":true,"checksum":"454de9c8ff02ffa321a5cb4dec888a3a945bddc5bb7b099c0da6cca8fb62090b","description":"ACMEAccount index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/acme"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1effbffd5ff5a4763a2fe7769dff21fc58d70d542b250d7117b4d7aa2264e0ca","description":"ACMEAccount index.","extra":{},"name":"account_index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"ba9673f107c9c48f05ca853d7dd64c07a2f371b2cb565a1fd87c6dfcfa5255e3","description":"Register a new ACME account with CA.","extra":{},"name":"register_account","parameters":[{"definition":{"description":"Contact email addresses.","enum":[],"extra":{"typetext":""},"format":"email-list","properties":{},"type":"string"},"name":"contact"},{"definition":{"default":"https://acme-v02.api.letsencrypt.org/directory","description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"optional":true,"pattern":"^https?://.*","properties":{},"type":"string"},"name":"directory"},{"definition":{"description":"HMAC key for External Account Binding.","enum":[],"extra":{"requires":"eab-kid","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"eab-hmac-key"},{"definition":{"description":"Key Identifier for External Account Binding.","enum":[],"extra":{"requires":"eab-hmac-key","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"eab-kid"},{"definition":{"default":"default","description":"ACME account config file name.","enum":[],"extra":{"format_description":"name","typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"URL of CA TermsOfService - setting this indicates agreement.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tos_url"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/acme/account"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b454212b12e22548f4709a1c2a277a21c02818412eadbb2d14bd24d8352bddf8","description":"Deactivate existing ACME account at CA.","extra":{},"name":"deactivate_account","parameters":[{"definition":{"default":"default","description":"ACME account config file name.","enum":[],"extra":{"format_description":"name","typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"name"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"8a68ee3cda0d4d131277b3fe68cbea1ed1fb044dc7ecec47cb77afc513eef373","description":"Return existing ACME account information.","extra":{},"name":"get_account","parameters":[{"definition":{"default":"default","description":"ACME account config file name.","enum":[],"extra":{"format_description":"name","typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"name"}],"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"account":{"enum":[],"extra":{"renderer":"yaml"},"optional":true,"properties":{},"type":"object"},"directory":{"description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"optional":true,"pattern":"^https?://.*","properties":{},"type":"string"},"location":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"tos":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"d34253209420f70af9ce9636d062d86816aa0aaad6156da14616f0c62a52bf93","description":"Update existing ACME account information with CA. Note: not specifying any new account information triggers a refresh.","extra":{},"name":"update_account","parameters":[{"definition":{"description":"Contact email addresses.","enum":[],"extra":{"typetext":""},"format":"email-list","optional":true,"properties":{},"type":"string"},"name":"contact"},{"definition":{"default":"default","description":"ACME account config file name.","enum":[],"extra":{"format_description":"name","typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"name"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/cluster/acme/account/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bb3b64c0f654249ad36a0e6d6795943403662e273ec2511021fde72e27414433","description":"Get schema of ACME challenge types.","extra":{},"name":"challengeschema","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":0},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Human readable name, falls back to id","enum":[],"extra":{},"properties":{},"type":"string"},"schema":{"enum":[],"extra":{},"properties":{},"type":"object"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/acme/challenge-schema"},{"extra":{},"methods":[{"allow_token":true,"checksum":"83c926d16ce96312b6485852605650ec68d069e1004de1bf706cf88ce5230a8b","description":"Get named known ACME directory endpoints.","extra":{},"name":"get_directories","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":0},"properties":{"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"url":{"description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"pattern":"^https?://.*","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/acme/directories"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f2405d2a940e789c1d9b3b42f6da89d39e230861b91430071e8ea19b4446e74d","description":"Retrieve ACME Directory Meta Information","extra":{},"name":"get_meta","parameters":[{"definition":{"default":"https://acme-v02.api.letsencrypt.org/directory","description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"optional":true,"pattern":"^https?://.*","properties":{},"type":"string"},"name":"directory"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":1},"properties":{"caaIdentities":{"description":"Hostnames referring to the ACME servers.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"externalAccountRequired":{"description":"EAB Required","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"termsOfService":{"description":"ACME TermsOfService URL.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"website":{"description":"URL to more information about the ACME server.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/cluster/acme/meta"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3e96f2ad7d3b068e319a6e185995cb4727138447c78db5fb64029588946ae88d","description":"ACME plugin index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list ACME plugins of a specific type","enum":["dns","standalone"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{plugin}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"plugin":{"description":"Unique identifier for ACME plugin instance.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"6e1b56d08c938b6a112517525bb77fa723c19b564facc2d7c47b19de07bc3d58","description":"Add ACME plugin configuration.","extra":{},"name":"add_plugin","parameters":[{"definition":{"description":"API plugin name","enum":["1984hosting","acmedns","acmeproxy","active24","ad","ali","alviy","anx","artfiles","arvan","aurora","autodns","aws","azion","azure","bookmyname","bunny","cf","clouddns","cloudns","cn","conoha","constellix","cpanel","curanet","cyon","da","ddnss","desec","df","dgon","dnsexit","dnshome","dnsimple","dnsservices","doapi","domeneshop","dp","dpi","dreamhost","duckdns","durabledns","dyn","dynu","dynv6","easydns","edgedns","euserv","exoscale","fornex","freedns","gandi_livedns","gcloud","gcore","gd","geoscaling","googledomains","he","hetzner","hexonet","hostingde","huaweicloud","infoblox","infomaniak","internetbs","inwx","ionos","ionos_cloud","ipv64","ispconfig","jd","joker","kappernet","kas","kinghost","knot","la","leaseweb","lexicon","limacity","linode","linode_v4","loopia","lua","maradns","me","miab","misaka","myapi","mydevil","mydnsjp","mythic_beasts","namecheap","namecom","namesilo","nanelo","nederhost","neodigit","netcup","netlify","nic","njalla","nm","nsd","nsone","nsupdate","nw","oci","omglol","one","online","openprovider","openstack","opnsense","ovh","pdns","pleskxml","pointhq","porkbun","rackcorp","rackspace","rage4","rcode0","regru","scaleway","schlundtech","selectel","selfhost","servercow","simply","technitium","tele3","tencent","timeweb","transip","udr","ultra","unoeuro","variomedia","veesp","vercel","vscale","vultr","websupport","west_cn","world4you","yandex360","yc","zilore","zone","zoneedit","zonomi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"api"},{"definition":{"description":"DNS plugin data. (base64 encoded)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"data"},{"definition":{"description":"Flag to disable the config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"ACME Plugin ID name","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"ACME challenge type.","enum":["dns","standalone"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"default":30,"description":"Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.","enum":[],"extra":{"typetext":" (0 - 172800)"},"maximum":172800,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"validation-delay"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/acme/plugins"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e31513c49230a6793d02a258e1461555d3d724ed5007c688cdf61d6047f43335","description":"Delete ACME plugin configuration.","extra":{},"name":"delete_plugin","parameters":[{"definition":{"description":"Unique identifier for ACME plugin instance.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"75aa54b197ffabed6256c4937525a341970e630aa4ea348fa6604b00f2b14e5c","description":"Get ACME plugin configuration.","extra":{},"name":"get_plugin_config","parameters":[{"definition":{"description":"Unique identifier for ACME plugin instance.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"48281fb78eee69b5c6f4d50d35b89c64e6136e953d6611ab6e0dacacf4f78fbb","description":"Update ACME plugin configuration.","extra":{},"name":"update_plugin","parameters":[{"definition":{"description":"API plugin name","enum":["1984hosting","acmedns","acmeproxy","active24","ad","ali","alviy","anx","artfiles","arvan","aurora","autodns","aws","azion","azure","bookmyname","bunny","cf","clouddns","cloudns","cn","conoha","constellix","cpanel","curanet","cyon","da","ddnss","desec","df","dgon","dnsexit","dnshome","dnsimple","dnsservices","doapi","domeneshop","dp","dpi","dreamhost","duckdns","durabledns","dyn","dynu","dynv6","easydns","edgedns","euserv","exoscale","fornex","freedns","gandi_livedns","gcloud","gcore","gd","geoscaling","googledomains","he","hetzner","hexonet","hostingde","huaweicloud","infoblox","infomaniak","internetbs","inwx","ionos","ionos_cloud","ipv64","ispconfig","jd","joker","kappernet","kas","kinghost","knot","la","leaseweb","lexicon","limacity","linode","linode_v4","loopia","lua","maradns","me","miab","misaka","myapi","mydevil","mydnsjp","mythic_beasts","namecheap","namecom","namesilo","nanelo","nederhost","neodigit","netcup","netlify","nic","njalla","nm","nsd","nsone","nsupdate","nw","oci","omglol","one","online","openprovider","openstack","opnsense","ovh","pdns","pleskxml","pointhq","porkbun","rackcorp","rackspace","rage4","rcode0","regru","scaleway","schlundtech","selectel","selfhost","servercow","simply","technitium","tele3","tencent","timeweb","transip","udr","ultra","unoeuro","variomedia","veesp","vercel","vscale","vultr","websupport","west_cn","world4you","yandex360","yc","zilore","zone","zoneedit","zonomi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"api"},{"definition":{"description":"DNS plugin data. (base64 encoded)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"data"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Flag to disable the config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"ACME Plugin ID name","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"default":30,"description":"Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.","enum":[],"extra":{"typetext":" (0 - 172800)"},"maximum":172800,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"validation-delay"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/acme/plugins/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0a3b5b1c3e86a6bd9d319c9aab8d847e27bd335e6c58329506b77f0ada2e7b53","description":"Retrieve ACME TermsOfService URL from CA. Deprecated, please use /cluster/acme/meta.","extra":{},"name":"get_tos","parameters":[{"definition":{"default":"https://acme-v02.api.letsencrypt.org/directory","description":"URL of ACME CA directory endpoint.","enum":[],"extra":{},"optional":true,"pattern":"^https?://.*","properties":{},"type":"string"},"name":"directory"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"ACME TermsOfService URL.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"verb":"GET"}],"path":"/cluster/acme/tos"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1b3f7f33d8c5cb19ea8fac5bfb57fc86639d1cdbc0f397a99e72c4abcd53d8b2","description":"List vzdump backup schedule.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"description":"The job ID.","enum":[],"extra":{},"max_length":50,"pattern":"\\S+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"03494cef620aefb37afd8254fe683ebf46094b6b95134523a7218c6a0b3a8239","description":"Create new vzdump backup job.","extra":{},"name":"create_job","parameters":[{"definition":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"all"},{"definition":{"default":0,"description":"Limit I/O bandwidth (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"Description for the Job.","enum":[],"extra":{"typetext":""},"max_length":512,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"compress"},{"definition":{"default":"mon,tue,wed,thu,fri,sat,sun","description":"Day of week selection.","enum":[],"extra":{"requires":"starttime","typetext":""},"format":"pve-day-of-week-list","optional":true,"properties":{},"type":"string"},"name":"dow"},{"definition":{"description":"Store resulting files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dumpdir"},{"definition":{"default":"1","description":"Enable or disable the job.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"exclude"},{"definition":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"exclude-path"},{"definition":{"description":"Options for backup fleecing (VM only).","enum":[],"extra":{"typetext":"[[enabled=]<1|0>] [,storage=]"},"format":"backup-fleecing","optional":true,"properties":{},"type":"string"},"name":"fleecing"},{"definition":{"description":"Job ID (will be autogenerated).","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"id"},{"definition":{"default":7,"description":"Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.","enum":[],"extra":{"typetext":" (0 - 8)"},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"ionice"},{"definition":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"lockwait"},{"definition":{"default":"always","description":"Deprecated: use notification targets/matchers instead. Specify when to send a notification mail","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mailnotification"},{"definition":{"description":"Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{"typetext":""},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"name":"mailto"},{"definition":{"description":"Deprecated: use 'prune-backups' instead. Maximal number of backup files per guest system.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxfiles"},{"definition":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"Only run if executed on this node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.","enum":[],"extra":{"requires":"storage","typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"notes-template"},{"definition":{"default":"auto","description":"Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.","enum":["auto","legacy-sendmail","notification-system"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"notification-mode"},{"definition":{"default":"always","description":"Deprecated: Do not use","enum":["always","failure","never"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"notification-policy"},{"definition":{"description":"Deprecated: Do not use","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"notification-target"},{"definition":{"description":"PBS mode used to detect file changes and switch encoding format for container backups.","enum":["legacy","data","metadata"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"pbs-change-detection-mode"},{"definition":{"description":"Other performance-related settings.","enum":[],"extra":{"typetext":"[max-workers=] [,pbs-entries-max=]"},"format":"backup-performance","optional":true,"properties":{},"type":"string"},"name":"performance"},{"definition":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"pigz"},{"definition":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"If true, mark backup(s) as protected.","enum":[],"extra":{"requires":"storage","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protected"},{"definition":{"default":"keep-all=1","description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"default":0,"description":"Be quiet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"quiet"},{"definition":{"default":1,"description":"Prune older backups according to 'prune-backups'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove"},{"definition":{"default":0,"description":"If true, the job will be run as soon as possible if it was missed while the scheduler was not running.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"repeat-missed"},{"definition":{"description":"Backup schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"Use specified hook script.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"script"},{"definition":{"description":"Job Start time.","enum":[],"extra":{"typetext":"HH:MM"},"optional":true,"pattern":"\\d{1,2}:\\d{1,2}","properties":{},"type":"string"},"name":"starttime"},{"definition":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stdexcludes"},{"definition":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stop"},{"definition":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"stopwait"},{"definition":{"description":"Store resulting file to this storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Store temporary files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tmpdir"},{"definition":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vmid"},{"definition":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"zstd"}],"permissions":{"description":"The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user.","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/backup"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e8fa5d6fa114f069dcf59323f56dc2636286f1d895cf328de285fd9c651a1f48","description":"Index for backup info related endpoints","extra":{},"name":"index","parameters":[],"protected":false,"returns":{"description":"Directory index.","enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"description":"API sub-directory endpoint","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/backup-info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"10072ad7bf08fad7b5214622361f9bcfe52101f6e15709fc5661262557128b24","description":"Shows all guests which are not covered by any backup job.","extra":{},"name":"get_guests_not_in_backup","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"description":"Contains the guest objects.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"name":{"description":"Name of the guest","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Type of the guest.","enum":["qemu","lxc"],"extra":{},"properties":{},"type":"string"},"vmid":{"description":"VMID of the guest.","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/backup-info/not-backed-up"},{"extra":{},"methods":[{"allow_token":true,"checksum":"361a95b88e0ef40ed125d2b05ed16ffbd2617b3de31a6809f36e88e99cb2cd3b","description":"Delete vzdump backup job definition.","extra":{},"name":"delete_job","parameters":[{"definition":{"description":"The job ID.","enum":[],"extra":{},"max_length":50,"pattern":"\\S+","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"7613d9aeb0afb9480e8f21c45197b8eb6f1768174329fb95c741a409e5b8489c","description":"Read vzdump backup job definition.","extra":{},"name":"read_job","parameters":[{"definition":{"description":"The job ID.","enum":[],"extra":{},"max_length":50,"pattern":"\\S+","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"62dfccd2c07d4eeef5ec92c3b05849cc6050f9e071b604287826595fa72e0449","description":"Update vzdump backup job definition.","extra":{},"name":"update_job","parameters":[{"definition":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"all"},{"definition":{"default":0,"description":"Limit I/O bandwidth (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"Description for the Job.","enum":[],"extra":{"typetext":""},"max_length":512,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"compress"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Day of week selection.","enum":[],"extra":{"requires":"starttime","typetext":""},"format":"pve-day-of-week-list","optional":true,"properties":{},"type":"string"},"name":"dow"},{"definition":{"description":"Store resulting files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dumpdir"},{"definition":{"default":"1","description":"Enable or disable the job.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"exclude"},{"definition":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"exclude-path"},{"definition":{"description":"Options for backup fleecing (VM only).","enum":[],"extra":{"typetext":"[[enabled=]<1|0>] [,storage=]"},"format":"backup-fleecing","optional":true,"properties":{},"type":"string"},"name":"fleecing"},{"definition":{"description":"The job ID.","enum":[],"extra":{},"max_length":50,"pattern":"\\S+","properties":{},"type":"string"},"name":"id"},{"definition":{"default":7,"description":"Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.","enum":[],"extra":{"typetext":" (0 - 8)"},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"ionice"},{"definition":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"lockwait"},{"definition":{"default":"always","description":"Deprecated: use notification targets/matchers instead. Specify when to send a notification mail","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mailnotification"},{"definition":{"description":"Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{"typetext":""},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"name":"mailto"},{"definition":{"description":"Deprecated: use 'prune-backups' instead. Maximal number of backup files per guest system.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxfiles"},{"definition":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"Only run if executed on this node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.","enum":[],"extra":{"requires":"storage","typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"notes-template"},{"definition":{"default":"auto","description":"Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.","enum":["auto","legacy-sendmail","notification-system"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"notification-mode"},{"definition":{"default":"always","description":"Deprecated: Do not use","enum":["always","failure","never"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"notification-policy"},{"definition":{"description":"Deprecated: Do not use","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"notification-target"},{"definition":{"description":"PBS mode used to detect file changes and switch encoding format for container backups.","enum":["legacy","data","metadata"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"pbs-change-detection-mode"},{"definition":{"description":"Other performance-related settings.","enum":[],"extra":{"typetext":"[max-workers=] [,pbs-entries-max=]"},"format":"backup-performance","optional":true,"properties":{},"type":"string"},"name":"performance"},{"definition":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"pigz"},{"definition":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"If true, mark backup(s) as protected.","enum":[],"extra":{"requires":"storage","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protected"},{"definition":{"default":"keep-all=1","description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"default":0,"description":"Be quiet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"quiet"},{"definition":{"default":1,"description":"Prune older backups according to 'prune-backups'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove"},{"definition":{"default":0,"description":"If true, the job will be run as soon as possible if it was missed while the scheduler was not running.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"repeat-missed"},{"definition":{"description":"Backup schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"Use specified hook script.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"script"},{"definition":{"description":"Job Start time.","enum":[],"extra":{"typetext":"HH:MM"},"optional":true,"pattern":"\\d{1,2}:\\d{1,2}","properties":{},"type":"string"},"name":"starttime"},{"definition":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stdexcludes"},{"definition":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stop"},{"definition":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"stopwait"},{"definition":{"description":"Store resulting file to this storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Store temporary files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tmpdir"},{"definition":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vmid"},{"definition":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"zstd"}],"permissions":{"description":"The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user.","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/backup/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"31f6fa33dc5f9967d128553b7fa048f24df2d818f5f7f80b10687b0b6f6e2b44","description":"Returns included guests and the backup status of their disks. Optimized to be used in ExtJS tree views.","extra":{},"name":"get_volume_backup_included","parameters":[{"definition":{"description":"The job ID.","enum":[],"extra":{},"max_length":50,"pattern":"\\S+","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"description":"Root node of the tree object. Children represent guests, grandchildren represent volumes of that guest.","enum":[],"extra":{},"properties":{"children":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"children":{"description":"The volumes of the guest with the information if they will be included in backups.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"id":{"description":"Configuration key of the volume.","enum":[],"extra":{},"properties":{},"type":"string"},"included":{"description":"Whether the volume is included in the backup or not.","enum":[],"extra":{},"properties":{},"type":"boolean"},"name":{"description":"Name of the volume.","enum":[],"extra":{},"properties":{},"type":"string"},"reason":{"description":"The reason why the volume is included (or excluded).","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"id":{"description":"VMID of the guest.","enum":[],"extra":{},"properties":{},"type":"integer"},"name":{"description":"Name of the guest","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"Type of the guest, VM, CT or unknown for removed but not purged guests.","enum":["qemu","lxc","unknown"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"}],"path":"/cluster/backup/{id}/included_volumes"},{"extra":{},"methods":[{"allow_token":true,"checksum":"eba2ffcf3c2b12528c59e5ea186dccaf2c83608b8f244536294254186e44c927","description":"Cluster ceph index.","extra":{},"name":"cephindex","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/ceph"},{"extra":{},"methods":[{"allow_token":true,"checksum":"02afb14bbc8590601cd50857ea48b148df439fcd0eeb68ad743f81117830e050","description":"get the status of all ceph flags","extra":{},"name":"get_all_flags","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"description":{"description":"Flag description.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Flag name.","enum":["nobackfill","nodeep-scrub","nodown","noin","noout","norebalance","norecover","noscrub","notieragent","noup","pause"],"extra":{},"properties":{},"type":"string"},"value":{"description":"Flag value.","enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"970a0fb05e1b758fb4fdf2eb40ec7342550b919ccbc76dbfcfb001afefa4ae31","description":"Set/Unset multiple ceph flags at once.","extra":{},"name":"set_flags","parameters":[{"definition":{"description":"Backfilling of PGs is suspended.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nobackfill"},{"definition":{"description":"Deep Scrubbing is disabled.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nodeep-scrub"},{"definition":{"description":"OSD failure reports are being ignored, such that the monitors will not mark OSDs down.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nodown"},{"definition":{"description":"OSDs that were previously marked out will not be marked back in when they start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"noin"},{"definition":{"description":"OSDs will not automatically be marked out after the configured interval.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"noout"},{"definition":{"description":"Rebalancing of PGs is suspended.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"norebalance"},{"definition":{"description":"Recovery of PGs is suspended.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"norecover"},{"definition":{"description":"Scrubbing is disabled.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"noscrub"},{"definition":{"description":"Cache tiering activity is suspended.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"notieragent"},{"definition":{"description":"OSDs are not allowed to start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"noup"},{"definition":{"description":"Pauses read and writes.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pause"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/cluster/ceph/flags"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ec390749f9b3b558092a75a9d5b9a3a05a0f4d7caaba0587fbbc491a53147656","description":"Get the status of a specific ceph flag.","extra":{},"name":"get_flag","parameters":[{"definition":{"description":"The name of the flag name to get.","enum":["nobackfill","nodeep-scrub","nodown","noin","noout","norebalance","norecover","noscrub","notieragent","noup","pause"],"extra":{},"properties":{},"type":"string"},"name":"flag"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"verb":"GET"},{"allow_token":true,"checksum":"2e9c3fffaa1d7970614c7564afef27bfb7e06a951d8f2cd26e7995f90f827bf1","description":"Set or clear (unset) a specific ceph flag","extra":{},"name":"update_flag","parameters":[{"definition":{"description":"The ceph flag to update","enum":["nobackfill","nodeep-scrub","nodown","noin","noout","norebalance","norecover","noscrub","notieragent","noup","pause"],"extra":{},"properties":{},"type":"string"},"name":"flag"},{"definition":{"description":"The new value of the flag","enum":[],"extra":{"typetext":""},"properties":{},"type":"boolean"},"name":"value"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/ceph/flags/{flag}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4a403969f7330d91a3a498833fd5420b4091516e69a60e1f4047f53574320e54","description":"Get ceph metadata.","extra":{},"name":"metadata","parameters":[{"definition":{"default":"all","enum":["all","versions"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scope"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"Items for each type of service containing objects for each instance.","enum":[],"extra":{},"properties":{"mds":{"description":"Metadata servers configured in the cluster and their properties.","enum":[],"extra":{},"properties":{"{id}":{"description":"Useful properties are listed, but not the full list.","enum":[],"extra":{},"properties":{"addr":{"description":"Bind addresses and ports.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_release":{"description":"Ceph release codename currently used.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version":{"description":"Version info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version_short":{"description":"Short version (numerical) info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"hostname":{"description":"Hostname on which the service is running.","enum":[],"extra":{},"properties":{},"type":"string"},"mem_swap_kb":{"description":"Memory of the service currently in swap.","enum":[],"extra":{},"properties":{},"type":"integer"},"mem_total_kb":{"description":"Memory consumption of the service.","enum":[],"extra":{},"properties":{},"type":"integer"},"name":{"description":"Name of the service instance.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"}},"type":"object"},"mgr":{"description":"Managers configured in the cluster and their properties.","enum":[],"extra":{},"properties":{"{id}":{"description":"Useful properties are listed, but not the full list.","enum":[],"extra":{},"properties":{"addr":{"description":"Bind address","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_release":{"description":"Ceph release codename currently used.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version":{"description":"Version info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version_short":{"description":"Short version (numerical) info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"hostname":{"description":"Hostname on which the service is running.","enum":[],"extra":{},"properties":{},"type":"string"},"mem_swap_kb":{"description":"Memory of the service currently in swap.","enum":[],"extra":{},"properties":{},"type":"integer"},"mem_total_kb":{"description":"Memory consumption of the service.","enum":[],"extra":{},"properties":{},"type":"integer"},"name":{"description":"Name of the service instance.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"}},"type":"object"},"mon":{"description":"Monitors configured in the cluster and their properties.","enum":[],"extra":{},"properties":{"{id}":{"description":"Useful properties are listed, but not the full list.","enum":[],"extra":{},"properties":{"addrs":{"description":"Bind addresses and ports.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_release":{"description":"Ceph release codename currently used.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version":{"description":"Version info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version_short":{"description":"Short version (numerical) info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"hostname":{"description":"Hostname on which the service is running.","enum":[],"extra":{},"properties":{},"type":"string"},"mem_swap_kb":{"description":"Memory of the service currently in swap.","enum":[],"extra":{},"properties":{},"type":"integer"},"mem_total_kb":{"description":"Memory consumption of the service.","enum":[],"extra":{},"properties":{},"type":"integer"},"name":{"description":"Name of the service instance.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"}},"type":"object"},"node":{"description":"Ceph version installed on the nodes.","enum":[],"extra":{},"properties":{"{node}":{"enum":[],"extra":{},"properties":{"buildcommit":{"description":"GIT commit used for the build.","enum":[],"extra":{},"properties":{},"type":"string"},"version":{"description":"Version info.","enum":[],"extra":{},"properties":{"parts":{"description":"major, minor & patch","enum":[],"extra":{},"properties":{},"type":"array"},"str":{"description":"Version as single string.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"}},"type":"object"}},"type":"object"},"osd":{"description":"OSDs configured in the cluster and their properties.","enum":[],"extra":{},"properties":{"{id}":{"description":"Useful properties are listed, but not the full list.","enum":[],"extra":{},"properties":{"back_addr":{"description":"Bind addresses and ports for backend inter OSD traffic.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_release":{"description":"Ceph release codename currently used.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version":{"description":"Version info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"ceph_version_short":{"description":"Short version (numerical) info currently used by the service.","enum":[],"extra":{},"properties":{},"type":"string"},"device_id":{"description":"Devices used by the OSD.","enum":[],"extra":{},"properties":{},"type":"string"},"front_addr":{"description":"Bind addresses and ports for frontend traffic to OSDs.","enum":[],"extra":{},"properties":{},"type":"string"},"hostname":{"description":"Hostname on which the service is running.","enum":[],"extra":{},"properties":{},"type":"string"},"id":{"description":"OSD ID.","enum":[],"extra":{},"properties":{},"type":"integer"},"mem_swap_kb":{"description":"Memory of the service currently in swap.","enum":[],"extra":{},"properties":{},"type":"integer"},"mem_total_kb":{"description":"Memory consumption of the service.","enum":[],"extra":{},"properties":{},"type":"integer"},"osd_data":{"description":"Path to the OSD data directory.","enum":[],"extra":{},"properties":{},"type":"string"},"osd_objectstore":{"description":"OSD objectstore type.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"}},"type":"array"}},"type":"object"},"verb":"GET"}],"path":"/cluster/ceph/metadata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"409b59805f3b7f2541a2610e760ac490c3c6c53e2f4107c9149cc5870f3999ab","description":"Get ceph status.","extra":{},"name":"status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/ceph/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4e462b2d722b46bdaa5c6d40f69bc9f0fea21bf2b17f55764148409d7e6634a1","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"dc847d83f7fc30755b2764c4614fade64611f8f97ac8d872642a9b3fb1cadc5e","description":"Generate new cluster configuration. If no links given, default to local IP address as link0.","extra":{},"name":"create","parameters":[{"definition":{"description":"The name of the cluster.","enum":[],"extra":{"typetext":""},"format":"pve-node","max_length":15,"properties":{},"type":"string"},"name":"clustername"},{"definition":{"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)","enum":[],"extra":{"typetext":"[address=] [,priority=]"},"format":{"address":{"default_key":1,"description":"Hostname (or IP) of this corosync link address.","format":"address","format_description":"IP","type":"string"},"priority":{"default":0,"description":"The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.","maximum":255,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"link[n]"},{"definition":{"description":"Node id for this node.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"nodeid"},{"definition":{"description":"Number of votes for this node.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"votes"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5861b788cde0b7cc8e00ed4490c40cc476724fc3e74e8d888af4e2667f4fc440","description":"Return the version of the cluster join API available on this node.","extra":{},"name":"join_api_version","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"description":"Cluster Join API version, currently 1","enum":[],"extra":{},"minimum":0,"properties":{},"type":"integer"},"verb":"GET"}],"path":"/cluster/config/apiversion"},{"extra":{},"methods":[{"allow_token":true,"checksum":"27b190ca706bbf299b7db981785dc2470fa61c40ce5577145f166e14dfa5ab80","description":"Get information needed to join this cluster over the connected node.","extra":{},"name":"join_info","parameters":[{"definition":{"default":"current connected node","description":"The node for which the joinee gets the nodeinfo. ","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"config_digest":{"enum":[],"extra":{},"properties":{},"type":"string"},"nodelist":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"name":{"description":"The cluster node name.","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"nodeid":{"description":"Node id for this node.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"pve_addr":{"enum":[],"extra":{},"format":"ip","properties":{},"type":"string"},"pve_fp":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"quorum_votes":{"enum":[],"extra":{},"minimum":0,"properties":{},"type":"integer"},"ring0_addr":{"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)","enum":[],"extra":{},"format":{"address":{"default_key":1,"description":"Hostname (or IP) of this corosync link address.","format":"address","format_description":"IP","type":"string"},"priority":{"default":0,"description":"The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.","maximum":255,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"preferred_node":{"description":"The cluster node name.","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"totem":{"enum":[],"extra":{},"properties":{},"type":"object"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"b68eacfbf66e39c59302d333b33cc64f4ff8211a81f4b5e13e745569757d2229","description":"Joins this node into an existing cluster. If no links are given, default to IP resolved by node's hostname on single link (fallback fails for clusters with multiple links).","extra":{},"name":"join","parameters":[{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"Do not throw error if node already exists.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Hostname (or IP) of an existing cluster member.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"hostname"},{"definition":{"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)","enum":[],"extra":{"typetext":"[address=] [,priority=]"},"format":{"address":{"default_key":1,"description":"Hostname (or IP) of this corosync link address.","format":"address","format_description":"IP","type":"string"},"priority":{"default":0,"description":"The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.","maximum":255,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"link[n]"},{"definition":{"description":"Node id for this node.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"nodeid"},{"definition":{"description":"Superuser (root) password of peer node.","enum":[],"extra":{"typetext":""},"max_length":128,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Number of votes for this node","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"votes"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/cluster/config/join"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1f1fa8f6c73d69a06ca87952831af1858a31d439c8ce22d6db1dc91f7ca064ba","description":"Corosync node list.","extra":{},"name":"nodes","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{node}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"node":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/config/nodes"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4ad5a311d984ff153e9e2592b537f44cdcce104ab314eadbe47ce01a97c6f77c","description":"Removes a node from the cluster configuration.","extra":{},"name":"delnode","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"2304b23018ece442ff87923324c1fd7f3616f5b677fc4dc2af779b5c3da61fd7","description":"Adds a node to the cluster configuration. This call is for internal use.","extra":{},"name":"addnode","parameters":[{"definition":{"description":"The JOIN_API_VERSION of the new node.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"apiversion"},{"definition":{"description":"Do not throw error if node already exists.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)","enum":[],"extra":{"typetext":"[address=] [,priority=]"},"format":{"address":{"default_key":1,"description":"Hostname (or IP) of this corosync link address.","format":"address","format_description":"IP","type":"string"},"priority":{"default":0,"description":"The priority for the link when knet is used in 'passive' mode (default). Lower value means higher priority. Only valid for cluster create, ignored on node add.","maximum":255,"minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"link[n]"},{"definition":{"description":"IP Address of node to add. Used as fallback if no links are given.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"new_node_ip"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Node id for this node.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"nodeid"},{"definition":{"description":"Number of votes for this node","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"votes"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{"corosync_authkey":{"enum":[],"extra":{},"properties":{},"type":"string"},"corosync_conf":{"enum":[],"extra":{},"properties":{},"type":"string"},"warnings":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"verb":"POST"}],"path":"/cluster/config/nodes/{node}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"51bd45c1bad501ab6b44ef5c67e7ca632259b91909c89431696c26607bfa79ae","description":"Get QDevice status","extra":{},"name":"status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/config/qdevice"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c99926d6eacc2ee248abe8c35c3b919d67610792d6702ff22aee72db49cc4a84","description":"Get corosync totem protocol settings.","extra":{},"name":"totem","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/config/totem"},{"extra":{},"methods":[{"allow_token":true,"checksum":"74551df8a7f69c7a92251a3cae53f3fa26e51e7232e76071c74973bbbcee0c60","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b3fce23e30c9cb681a73f749ce1dcd3c5eaa6accb7deb388baf2a9aca8bee91f","description":"List aliases","extra":{},"name":"get_aliases","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f144d7afa87a39ea6a57ac4e64d062df366af072960ccdf34d6336ac2377b7f3","description":"Create IP or Network Alias.","extra":{},"name":"create_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/aliases"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ec4a41a6b5108e1fd283289d8256ef9485bbdfeb65d8d3cfc4572042cb9a677c","description":"Remove IP or Network alias.","extra":{},"name":"remove_alias","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"31f91732baef0ccfba57dfc0c349ce762ef253d020ab23770f2a16b530eb55ed","description":"Read alias.","extra":{},"name":"read_alias","parameters":[{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"056e5969ce07a362663b71db6f255296a4bb9b19c9c6e154f03ad1090c4100d2","description":"Update IP or Network alias.","extra":{},"name":"update_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Rename an existing alias.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/aliases/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b142edd1f2967146d48335be6436ef08ede6983c38c5e107ea3fe74c8c714881","description":"List security groups.","extra":{},"name":"list_security_groups","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{group}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"group":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"5f97a9521d66f8673888e63abdcd4507d17dd7692b28de5029e2e4c16fe4e53d","description":"Create new security group.","extra":{},"name":"create_security_group","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Rename/update an existing security group. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing group.","enum":[],"extra":{},"max_length":18,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/groups"},{"extra":{},"methods":[{"allow_token":true,"checksum":"acdcc8bdd19b229574d5ede528b0727f932a90c3fbb9ef47222856db9f4531d9","description":"Delete security group.","extra":{},"name":"delete_security_group","parameters":[{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"5e311b86179420cbc403ca7c6e0bb22d853c4be88b8ef0b63aab2614af61e428","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"42c0cdbaa4914a570c14a97d8e4f5d2a404dce6192f118d1f0d2241de295dba3","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/groups/{group}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6cf50307b7550a5994109ed58d36939b6fee81d72ef581b4536e22cc1f1c9fdb","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"1f3be3248486446917c63efaf928e95d33b8e383145a7ac4f9a7f4abf4b7fa19","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"c6c1eb12515b6c41f99959b8ae71473d2489301f6148eaf5920c5d013a665c4b","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Security Group name.","enum":[],"extra":{},"max_length":18,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/groups/{group}/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"02e10644e1474fe97e64060352d25dd832410fbc8ced9c0cd8b81bfd881e5f07","description":"List IPSets","extra":{},"name":"ipset_index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"name":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"d806f2879177e4ad4b25a3bd3bd8eefb291b03ceab3c4d94cc5e5d4eeed6097b","description":"Create new IPSet","extra":{},"name":"create_ipset","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/ipset"},{"extra":{},"methods":[{"allow_token":true,"checksum":"26a94d7acf918753aa6d8f5ec4155fb0e85f270e9366a91473ab924cb19cc9f0","description":"Delete IPSet","extra":{},"name":"delete_ipset","parameters":[{"definition":{"description":"Delete all members of the IPSet, if there are any.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"54fbdbe3ff6d8809dcf27bb78048fb8499eefeaba14c4bc371ea6de68a6b7cc5","description":"List IPSet content","extra":{},"name":"get_ipset","parameters":[{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cidr}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"nomatch":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"64742b376a8e3ee9b6b16b594db4e04c4b486e54165aa69f492fb0b952ea3225","description":"Add IP or Network to IPSet.","extra":{},"name":"create_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/ipset/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"35054ac0be461e02c18d2ec00e2e726f212564597638db31d0eeff1aab38415e","description":"Remove IP or Network from IPSet.","extra":{},"name":"remove_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"63a5cefffbd4607d42d80144ed58b521edc579d7778d60043f08271ec0332405","description":"Read IP or Network settings from IPSet.","extra":{},"name":"read_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"8650e84287c1ef48f83c92f08af9d31324d2409227c2ef65e8653c9f2cb2d686","description":"Update IP or Network settings","extra":{},"name":"update_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/ipset/{name}/{cidr}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8e98c5e0609b2624b64c801c530753f356fe8bd2682f5a27a745f43d6f986123","description":"List available macros","extra":{},"name":"get_macros","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"descr":{"description":"More verbose description (if available).","enum":[],"extra":{},"properties":{},"type":"string"},"macro":{"description":"Macro name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/firewall/macros"},{"extra":{},"methods":[{"allow_token":true,"checksum":"81130a305a74bdf185e994868fce1a5ce7d2f9f63424549436902d05f7168682","description":"Get Firewall options.","extra":{},"name":"get_options","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"ebtables":{"default":1,"description":"Enable ebtables rules cluster wide.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"enable":{"description":"Enable or disable the firewall cluster wide.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"log_ratelimit":{"description":"Log ratelimiting settings","enum":[],"extra":{},"format":{"burst":{"default":5,"description":"Initial burst of packages which will always get logged before the rate is applied","minimum":0,"optional":1,"type":"integer"},"enable":{"default":"1","default_key":1,"description":"Enable or disable log rate limiting","type":"boolean"},"rate":{"default":"1/second","description":"Frequency with which the burst bucket gets refilled","format_description":"rate","optional":1,"pattern":"[1-9][0-9]*\\/(second|minute|hour|day)","type":"string"}},"optional":true,"properties":{},"type":"string"},"policy_forward":{"description":"Forward policy.","enum":["ACCEPT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"policy_in":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"policy_out":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"263653df92947d3028ea8b2c3c1c25dca0e68a9139eac5c9bd7a439b021d1325","description":"Set Firewall options.","extra":{},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":1,"description":"Enable ebtables rules cluster wide.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ebtables"},{"definition":{"description":"Enable or disable the firewall cluster wide.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Log ratelimiting settings","enum":[],"extra":{"typetext":"[enable=]<1|0> [,burst=] [,rate=]"},"format":{"burst":{"default":5,"description":"Initial burst of packages which will always get logged before the rate is applied","minimum":0,"optional":1,"type":"integer"},"enable":{"default":"1","default_key":1,"description":"Enable or disable log rate limiting","type":"boolean"},"rate":{"default":"1/second","description":"Frequency with which the burst bucket gets refilled","format_description":"rate","optional":1,"pattern":"[1-9][0-9]*\\/(second|minute|hour|day)","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"log_ratelimit"},{"definition":{"description":"Forward policy.","enum":["ACCEPT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_forward"},{"definition":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_in"},{"definition":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_out"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ca62b2e7b4ef073e676faf630d69bbcec98c09d6ac4b374c701808f9225ef43d","description":"Lists possible IPSet/Alias reference which are allowed in source/dest properties.","extra":{},"name":"refs","parameters":[{"definition":{"description":"Only list references of specified type.","enum":["alias","ipset"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"ref":{"enum":[],"extra":{},"properties":{},"type":"string"},"scope":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":["alias","ipset"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/firewall/refs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9165dc3d913c799db2db301b2e535e230c212b7dbfcef2f3918b7e9c7d6408bd","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"68d04cd0b9f6de5852d41ac7745d60b3d7b85b063ec6ed05e34ddcdd8b407159","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"abca0306da7fd9aa2e4ea5d711fb76723f0fe8f7908c76ca864abe119892e3e1","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"cbc43552b6224f680019cd55a400aab123117e58e2be663243e2ffd77259b8aa","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"11ad59409653552ef6fc692b6e1ed87fd6ff77d55e44f022a38bf563343f39bc","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d001f6a38904cb5a8c874fb6d751e0a54ea9d1d75042d71b3c21dffb4e5c59ca","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/ha"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d0d28a184b53d0e953807ded4c6b2790bdae617fc6b96ff4fa1649238a2c8c13","description":"Get HA groups.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{group}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"group":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"b53609527dbca6b62c9e2b4a1366b4054348102b10a6ac691019b9da31b9242f","description":"Create a new HA group.","extra":{},"name":"create","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"List of cluster node names with optional priority.","enum":[],"extra":{"typetext":"[:]{,[:]}*","verbose_description":"List of cluster node members, where a priority can be given to each node. A resource bound to a group will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the services will get distributed to those nodes. The priorities have a relative meaning only. The higher the number, the higher the priority."},"format":"pve-ha-group-node-list","optional":false,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"default":0,"description":"The CRM tries to run services on the node with the highest priority. If a node with higher priority comes online, the CRM migrates the service to that node. Enabling nofailback prevents that behavior.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nofailback"},{"definition":{"default":0,"description":"Resources bound to restricted groups may only run on nodes defined by the group.","enum":[],"extra":{"typetext":"","verbose_description":"Resources bound to restricted groups may only run on nodes defined by the group. The resource will be placed in the stopped state if no group node member is online. Resources on unrestricted groups may run on any cluster node if all group members are offline, but they will migrate back as soon as a group member comes online. One can implement a 'preferred node' behavior using an unrestricted group with only one member."},"optional":true,"properties":{},"type":"boolean"},"name":"restricted"},{"definition":{"description":"Group type.","enum":["group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/groups"},{"extra":{},"methods":[{"allow_token":true,"checksum":"fcab72c57ac4373ef959202b673be62b63d50770dd9a16025d12a8e0f6e4a594","description":"Delete ha group configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f1dc580cb73eb7352d1f1af8768548109d5fbeee4519fb704492e9eb204c3673","description":"Read ha group configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"group"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{}},"verb":"GET"},{"allow_token":true,"checksum":"7a2d8d67a585d986cdfdf3115f37e2e618057273fb2e851d409dca9da7528e24","description":"Update ha group configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"group"},{"definition":{"description":"List of cluster node names with optional priority.","enum":[],"extra":{"typetext":"[:]{,[:]}*","verbose_description":"List of cluster node members, where a priority can be given to each node. A resource bound to a group will run on the available nodes with the highest priority. If there are more nodes in the highest priority class, the services will get distributed to those nodes. The priorities have a relative meaning only. The higher the number, the higher the priority."},"format":"pve-ha-group-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"default":0,"description":"The CRM tries to run services on the node with the highest priority. If a node with higher priority comes online, the CRM migrates the service to that node. Enabling nofailback prevents that behavior.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nofailback"},{"definition":{"default":0,"description":"Resources bound to restricted groups may only run on nodes defined by the group.","enum":[],"extra":{"typetext":"","verbose_description":"Resources bound to restricted groups may only run on nodes defined by the group. The resource will be placed in the stopped state if no group node member is online. Resources on unrestricted groups may run on any cluster node if all group members are offline, but they will migrate back as soon as a group member comes online. One can implement a 'preferred node' behavior using an unrestricted group with only one member."},"optional":true,"properties":{},"type":"boolean"},"name":"restricted"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/ha/groups/{group}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"47984f628310d0cb88a50b127b972338f4cd63248dd3c160e5200d3e7bd0cdd1","description":"List HA resources.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list resources of specific type","enum":["ct","vm"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{sid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"sid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"70fd3e7cb628f787ba3909ce16210856bb634a2b64df6e277be007cbcee9d178","description":"Create a new HA resource.","extra":{},"name":"create","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"group"},{"definition":{"default":1,"description":"Maximal number of service relocate tries when a service failes to start.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"max_relocate"},{"definition":{"default":1,"description":"Maximal number of tries to restart the service on a node after its start failed.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"max_restart"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"},{"definition":{"default":"started","description":"Requested resource state.","enum":["started","stopped","enabled","disabled","ignored"],"extra":{"verbose_description":"Requested resource state. The CRM reads this state and acts accordingly.\nPlease note that `enabled` is just an alias for `started`.\n\n`started`;;\n\nThe CRM tries to start the resource. Service state is\nset to `started` after successful start. On node failures, or when start\nfails, it tries to recover the resource. If everything fails, service\nstate it set to `error`.\n\n`stopped`;;\n\nThe CRM tries to keep the resource in `stopped` state, but it\nstill tries to relocate the resources on node failures.\n\n`disabled`;;\n\nThe CRM tries to put the resource in `stopped` state, but does not try\nto relocate the resources on node failures. The main purpose of this\nstate is error recovery, because it is the only way to move a resource out\nof the `error` state.\n\n`ignored`;;\n\nThe resource gets removed from the manager status and so the CRM and the LRM do\nnot touch the resource anymore. All {pve} API calls affecting this resource\nwill be executed, directly bypassing the HA stack. CRM commands will be thrown\naway while there source is in this state. The resource will not get relocated\non node failures.\n\n"},"optional":true,"properties":{},"type":"string"},"name":"state"},{"definition":{"description":"Resource type.","enum":["ct","vm"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/resources"},{"extra":{},"methods":[{"allow_token":true,"checksum":"abd1828ee1c6a70f7ffa5f609831cbbc19915841154fa87ae1986c48e299a35e","description":"Delete resource configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"20b2c61081918714beedef8bf2b0263c914335b03e88f592e05a48637b5ffca1","description":"Read resource configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"comment":{"description":"Description.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Can be used to prevent concurrent modifications.","enum":[],"extra":{},"properties":{},"type":"string"},"group":{"description":"The HA group identifier.","enum":[],"extra":{},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"max_relocate":{"description":"Maximal number of service relocate tries when a service failes to start.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"max_restart":{"description":"Maximal number of tries to restart the service on a node after its start failed.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"sid":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"state":{"description":"Requested resource state.","enum":["started","stopped","enabled","disabled","ignored"],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"The type of the resources.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"b4c89165684b8cbc39da73e77d290c4adb02de893090f699f123b309fc94b98c","description":"Update resource configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The HA group identifier.","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"group"},{"definition":{"default":1,"description":"Maximal number of service relocate tries when a service failes to start.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"max_relocate"},{"definition":{"default":1,"description":"Maximal number of tries to restart the service on a node after its start failed.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"max_restart"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"},{"definition":{"default":"started","description":"Requested resource state.","enum":["started","stopped","enabled","disabled","ignored"],"extra":{"verbose_description":"Requested resource state. The CRM reads this state and acts accordingly.\nPlease note that `enabled` is just an alias for `started`.\n\n`started`;;\n\nThe CRM tries to start the resource. Service state is\nset to `started` after successful start. On node failures, or when start\nfails, it tries to recover the resource. If everything fails, service\nstate it set to `error`.\n\n`stopped`;;\n\nThe CRM tries to keep the resource in `stopped` state, but it\nstill tries to relocate the resources on node failures.\n\n`disabled`;;\n\nThe CRM tries to put the resource in `stopped` state, but does not try\nto relocate the resources on node failures. The main purpose of this\nstate is error recovery, because it is the only way to move a resource out\nof the `error` state.\n\n`ignored`;;\n\nThe resource gets removed from the manager status and so the CRM and the LRM do\nnot touch the resource anymore. All {pve} API calls affecting this resource\nwill be executed, directly bypassing the HA stack. CRM commands will be thrown\naway while there source is in this state. The resource will not get relocated\non node failures.\n\n"},"optional":true,"properties":{},"type":"string"},"name":"state"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/ha/resources/{sid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0899ff908a613bc0e585e0d0ff7c3689a0290c57a6ea0a132c1736f2870ef038","description":"Request resource migration (online) to another node.","extra":{},"name":"migrate","parameters":[{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/resources/{sid}/migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0fe9da71d2503a4b046199d9088d1f15a843b739258a94575aea1eaa204385f0","description":"Request resource relocatzion to another node. This stops the service on the old node, and restarts it on the target node.","extra":{},"name":"relocate","parameters":[{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"HA resource ID. This consists of a resource type followed by a resource specific name, separated with colon (example: vm:100 / ct:100). For virtual machines and containers, you can simply use the VM or CT id as a shortcut (example: 100).","enum":[],"extra":{"typetext":":"},"format":"pve-ha-resource-or-vm-id","properties":{},"type":"string"},"name":"sid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/ha/resources/{sid}/relocate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"74551df8a7f69c7a92251a3cae53f3fa26e51e7232e76071c74973bbbcee0c60","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/ha/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6b67c501eaa5b59b77a380fe60ca2be3d8d5cc19ec5af575ff577df1a2198e24","description":"Get HA manger status.","extra":{},"name":"status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"crm_state":{"description":"For type 'service'. Service state as seen by the CRM.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"description":"Status entry ID (quorum, master, lrm:, service:).","enum":[],"extra":{},"properties":{},"type":"string"},"max_relocate":{"description":"For type 'service'.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"max_restart":{"description":"For type 'service'.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"node":{"description":"Node associated to status entry.","enum":[],"extra":{},"properties":{},"type":"string"},"quorate":{"description":"For type 'quorum'. Whether the cluster is quorate or not.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"request_state":{"description":"For type 'service'. Requested service state.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sid":{"description":"For type 'service'. Service ID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"state":{"description":"For type 'service'. Verbose service state.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"status":{"description":"Status of the entry (value depends on type).","enum":[],"extra":{},"properties":{},"type":"string"},"timestamp":{"description":"For type 'lrm','master'. Timestamp of the status information.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"type":{"description":"Type of status entry.","enum":["quorum","master","lrm","service"],"extra":{},"properties":{}}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/ha/status/current"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3a9edd6753b478f7eee2e02fa4859a8d405979a3bcff5640774bf8cd14b5d31f","description":"Get full HA manger status, including LRM status.","extra":{},"name":"manager_status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/cluster/ha/status/manager_status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e7fd541dc6bd5ac3934f5af8ff6c623fb4c63ac8f34778331904648f4ef034d9","description":"Index for jobs related endpoints.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"Directory index.","enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"description":"API sub-directory endpoint","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/jobs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6991afc8308cf7cc227211c547afaf3b3fc68d864ba698563c797f95c96f4d9d","description":"List configured realm-sync-jobs.","extra":{},"name":"syncjob_index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"A comment for the job.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enabled":{"description":"If the job is enabled or not.","enum":[],"extra":{},"properties":{},"type":"boolean"},"id":{"description":"The ID of the entry.","enum":[],"extra":{},"properties":{},"type":"string"},"last-run":{"description":"Last execution time of the job in seconds since the beginning of the UNIX epoch","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"next-run":{"description":"Next planned execution time of the job in seconds since the beginning of the UNIX epoch.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"realm":{"description":"Authentication domain ID","enum":[],"extra":{},"format":"pve-realm","max_length":32,"properties":{},"type":"string"},"remove-vanished":{"default":"none","description":"A semicolon-separated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).","enum":[],"extra":{"typetext":"([acl];[properties];[entry])|none"},"optional":true,"pattern":"(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none","properties":{},"type":"string"},"schedule":{"description":"The configured sync schedule.","enum":[],"extra":{},"properties":{},"type":"string"},"scope":{"description":"Select what to sync.","enum":["users","groups","both"],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/jobs/realm-sync"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0db7fb7f1f7c823388db4527653724add36ac3599e2857396a11dd7a637cfb46","description":"Delete realm-sync job definition.","extra":{},"name":"delete_job","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"93a9ff8182800613ae9864a6c7cce86e190587f1a55c1b0d3671c85e983d54ad","description":"Read realm-sync job definition.","extra":{},"name":"read_job","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"8295666b385b050fa4bf7fe8ca7091e37c3f32187a1d03b98c1353ffa5e1bc37","description":"Create new realm-sync job.","extra":{},"name":"create_job","parameters":[{"definition":{"description":"Description for the Job.","enum":[],"extra":{"typetext":""},"max_length":512,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":"1","description":"Enable newly synced users immediately.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable-new"},{"definition":{"default":1,"description":"Determines if the job is enabled.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"description":"The ID of the job.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":64,"properties":{},"type":"string"},"name":"id"},{"definition":{"description":"Authentication domain ID","enum":[],"extra":{"typetext":""},"format":"pve-realm","max_length":32,"optional":true,"properties":{},"type":"string"},"name":"realm"},{"definition":{"default":"none","description":"A semicolon-separated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).","enum":[],"extra":{"typetext":"([acl];[properties];[entry])|none"},"optional":true,"pattern":"(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none","properties":{},"type":"string"},"name":"remove-vanished"},{"definition":{"description":"Backup schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"Select what to sync.","enum":["users","groups","both"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scope"}],"permissions":{"description":"'Realm.AllocateUser' on '/access/realm/' and 'User.Modify' permissions to '/access/groups/'.","expression":{"check":["and",["perm","/access/realm/{realm}",["Realm.AllocateUser"]],["perm","/access/groups",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"d9421200e00b819969f44163ea78a101e356d364084cc2c5a3ec086a4f0e2578","description":"Update realm-sync job definition.","extra":{},"name":"update_job","parameters":[{"definition":{"description":"Description for the Job.","enum":[],"extra":{"typetext":""},"max_length":512,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"default":"1","description":"Enable newly synced users immediately.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable-new"},{"definition":{"default":1,"description":"Determines if the job is enabled.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"description":"The ID of the job.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":64,"properties":{},"type":"string"},"name":"id"},{"definition":{"default":"none","description":"A semicolon-separated list of things to remove when they or the user vanishes during a sync. The following values are possible: 'entry' removes the user/group when not returned from the sync. 'properties' removes the set properties on existing user/group that do not appear in the source (even custom ones). 'acl' removes acls when the user/group is not returned from the sync. Instead of a list it also can be 'none' (the default).","enum":[],"extra":{"typetext":"([acl];[properties];[entry])|none"},"optional":true,"pattern":"(?:(?:(?:acl|properties|entry);)*(?:acl|properties|entry))|none","properties":{},"type":"string"},"name":"remove-vanished"},{"definition":{"description":"Backup schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"Select what to sync.","enum":["users","groups","both"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scope"}],"permissions":{"description":"'Realm.AllocateUser' on '/access/realm/' and 'User.Modify' permissions to '/access/groups/'.","expression":{"check":["and",["perm","/access/realm/{realm}",["Realm.AllocateUser"]],["perm","/access/groups",["User.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/jobs/realm-sync/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b962117d14e12c92d1e1391addc0b51843bd1d16028ebdf260180f0585f7d628","description":"Returns a list of future schedule runtimes.","extra":{},"name":"schedule-analyze","parameters":[{"definition":{"default":10,"description":"Number of event-iteration to simulate and return.","enum":[],"extra":{"typetext":" (1 - 100)"},"maximum":100,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"iterations"},{"definition":{"description":"Job schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"UNIX timestamp to start the calculation from. Defaults to the current time.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"starttime"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"An array of the next events since .","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"timestamp":{"description":"UNIX timestamp for the run.","enum":[],"extra":{},"properties":{},"type":"integer"},"utc":{"description":"UTC timestamp for the run.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/jobs/schedule-analyze"},{"extra":{},"methods":[{"allow_token":true,"checksum":"83ec57bf65a25fea7789dc000d330836a5facedb780afa50156b1634bbf5d40a","description":"Read cluster log","extra":{},"name":"log","parameters":[{"definition":{"description":"Maximum number of entries.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0bac8b13119b633102143f35502b8d4c9d90528877d41713047d1b74f4059e37","description":"List resource types.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/mapping"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b9abd031a5cc7aefe56acc8c3f27b7ca6671ac1672d9e5f0b1d0926c7b410c52","description":"List directory mapping","extra":{},"name":"index","parameters":[{"definition":{"description":"If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the directory to the response.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"check-node"}],"permissions":{"description":"Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/dir/'.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"checks":{"description":"A list of checks, only present if 'check-node' is set.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"message":{"description":"The message of the error","enum":[],"extra":{},"properties":{},"type":"string"},"severity":{"description":"The severity of the error","enum":["warning","error"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"description":{"description":"A description of the logical mapping.","enum":[],"extra":{},"properties":{},"type":"string"},"id":{"description":"The logical ID of the mapping.","enum":[],"extra":{},"properties":{},"type":"string"},"map":{"description":"The entries of the mapping.","enum":[],"extra":{},"items":{"description":"A mapping for a node.","enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"8602f28bd41d721fe4e38c25886caef4d60cfb07cbd243a852381f43ab066516","description":"Create a new directory mapping.","extra":{},"name":"create","parameters":[{"definition":{"description":"Description of the directory mapping","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The ID of the directory mapping","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"A list of maps for the cluster nodes.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"node":{"description":"The cluster node name.","format":"pve-node","type":"string"},"path":{"description":"Absolute directory path that should be shared with the guest.","format":"pve-storage-path-in-property-string","type":"string"}},"properties":{},"type":"string"},"optional":false,"properties":{},"type":"array"},"name":"map"}],"permissions":{"expression":{"check":["perm","/mapping/dir",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/mapping/dir"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b7e8370d0c0e50d23f2a3b14f07d1d986bd27268d83d94e0ccabaa3b4928ea0f","description":"Remove directory mapping.","extra":{},"name":"delete","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/mapping/dir",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"8029154bf67479dfbe6b979b3c4b40e3d51e907e3aed0f224c4ade000b63da15","description":"Get directory mapping.","extra":{},"name":"get","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["or",["perm","/mapping/dir/{id}",["Mapping.Use"]],["perm","/mapping/dir/{id}",["Mapping.Modify"]],["perm","/mapping/dir/{id}",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"bf13a2bf62d6a1de9f615f392d402b9918b9424259b626499953698cfb1f389f","description":"Update a directory mapping.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description of the directory mapping","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The ID of the directory mapping","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"A list of maps for the cluster nodes.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"node":{"description":"The cluster node name.","format":"pve-node","type":"string"},"path":{"description":"Absolute directory path that should be shared with the guest.","format":"pve-storage-path-in-property-string","type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"map"}],"permissions":{"expression":{"check":["perm","/mapping/dir/{id}",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/mapping/dir/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d60cfe54e64682e009138eb9e5fe070b0a922286536bf55b2685cf0682b65a82","description":"List PCI Hardware Mapping","extra":{},"name":"index","parameters":[{"definition":{"description":"If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the devices to the response.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"check-node"}],"permissions":{"description":"Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/pci/'.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"checks":{"description":"A list of checks, only present if 'check_node' is set.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"message":{"description":"The message of the error","enum":[],"extra":{},"properties":{},"type":"string"},"severity":{"description":"The severity of the error","enum":["warning","error"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"description":{"description":"A description of the logical mapping.","enum":[],"extra":{},"properties":{},"type":"string"},"id":{"description":"The logical ID of the mapping.","enum":[],"extra":{},"properties":{},"type":"string"},"map":{"description":"The entries of the mapping.","enum":[],"extra":{},"items":{"description":"A mapping for a node.","enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"9e0ed761f0a2e8538cb3e98c47ffa3f2cc29b21846c06ee258e6f9fad3ffea97","description":"Create a new hardware mapping.","extra":{},"name":"create","parameters":[{"definition":{"description":"Description of the logical PCI device.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The ID of the logical PCI mapping.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"default":0,"description":"Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"live-migration-capable"},{"definition":{"description":"A list of maps for the cluster nodes.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"description":{"description":"Description of the node specific device.","maxLength":4096,"optional":1,"type":"string"},"id":{"description":"The vendor and device ID that is expected. Used for detecting hardware changes","pattern":"(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)","type":"string"},"iommugroup":{"description":"The IOMMU group in which the device is to be expected in. Used for detecting hardware changes.","optional":1,"type":"integer"},"node":{"description":"The cluster node name.","format":"pve-node","type":"string"},"path":{"description":"The path to the device. If the function is omitted, the whole device is mapped. In that case use the attributes of the first device. You can give multiple paths as a semicolon seperated list, the first available will then be chosen on guest start.","pattern":"(?:[a-f0-9]{4,}:[a-f0-9]{2}:[a-f0-9]{2}(?:.[a-f0-9])?;)*[a-f0-9]{4,}:[a-f0-9]{2}:[a-f0-9]{2}(?:.[a-f0-9])?","type":"string"},"subsystem-id":{"description":"The subsystem vendor and device ID that is expected. Used for detecting hardware changes.","optional":1,"pattern":"(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)","type":"string"}},"properties":{},"type":"string"},"optional":false,"properties":{},"type":"array"},"name":"map"},{"definition":{"default":0,"description":"Marks the device(s) as being capable of providing mediated devices.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"mdev"}],"permissions":{"expression":{"check":["perm","/mapping/pci",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/mapping/pci"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1ab38a61dfbff2d3971e6e378ac608d6b661055a418645e258a62b448e91993e","description":"Remove Hardware Mapping.","extra":{},"name":"delete","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/mapping/pci",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"4aafa5a8f922bc1569ed7fdc6dea719ad4afd335133c55508c307a788d54046f","description":"Get PCI Mapping.","extra":{},"name":"get","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["or",["perm","/mapping/pci/{id}",["Mapping.Use"]],["perm","/mapping/pci/{id}",["Mapping.Modify"]],["perm","/mapping/pci/{id}",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"3d9f546128ed9eed216493401e3c265ce206cb3a86efc112dfdcd8a8a641f39b","description":"Update a hardware mapping.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description of the logical PCI device.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The ID of the logical PCI mapping.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"default":0,"description":"Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"live-migration-capable"},{"definition":{"description":"A list of maps for the cluster nodes.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"description":{"description":"Description of the node specific device.","maxLength":4096,"optional":1,"type":"string"},"id":{"description":"The vendor and device ID that is expected. Used for detecting hardware changes","pattern":"(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)","type":"string"},"iommugroup":{"description":"The IOMMU group in which the device is to be expected in. Used for detecting hardware changes.","optional":1,"type":"integer"},"node":{"description":"The cluster node name.","format":"pve-node","type":"string"},"path":{"description":"The path to the device. If the function is omitted, the whole device is mapped. In that case use the attributes of the first device. You can give multiple paths as a semicolon seperated list, the first available will then be chosen on guest start.","pattern":"(?:[a-f0-9]{4,}:[a-f0-9]{2}:[a-f0-9]{2}(?:.[a-f0-9])?;)*[a-f0-9]{4,}:[a-f0-9]{2}:[a-f0-9]{2}(?:.[a-f0-9])?","type":"string"},"subsystem-id":{"description":"The subsystem vendor and device ID that is expected. Used for detecting hardware changes.","optional":1,"pattern":"(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)","type":"string"}},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"map"},{"definition":{"default":0,"description":"Marks the device(s) as being capable of providing mediated devices.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"mdev"}],"permissions":{"expression":{"check":["perm","/mapping/pci/{id}",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/mapping/pci/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dbd7757e06f8800f3f48e4f22c1f812e07310858bad59975b8ebc2c292ce33cd","description":"List USB Hardware Mappings","extra":{},"name":"index","parameters":[{"definition":{"description":"If given, checks the configurations on the given node for correctness, and adds relevant errors to the devices.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"check-node"}],"permissions":{"description":"Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/usb/'.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"description":{"description":"A description of the logical mapping.","enum":[],"extra":{},"properties":{},"type":"string"},"error":{"description":"A list of errors when 'check_node' is given.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"message":{"description":"The message of the error","enum":[],"extra":{},"properties":{},"type":"string"},"severity":{"description":"The severity of the error","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{}},"id":{"description":"The logical ID of the mapping.","enum":[],"extra":{},"properties":{},"type":"string"},"map":{"description":"The entries of the mapping.","enum":[],"extra":{},"items":{"description":"A mapping for a node.","enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"9067775f8baa064a5401c32739777b0d4a42d769ccae853f9a4a3316d9dfa506","description":"Create a new hardware mapping.","extra":{},"name":"create","parameters":[{"definition":{"description":"Description of the logical USB device.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The ID of the logical USB mapping.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"A list of maps for the cluster nodes.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"description":{"description":"Description of the node specific device.","maxLength":4096,"optional":1,"type":"string"},"id":{"description":"The vendor and device ID that is expected. If a USB path is given, it is only used for detecting hardware changes","pattern":"(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)","type":"string"},"node":{"description":"The cluster node name.","format":"pve-node","type":"string"},"path":{"description":"The path to the usb device.","optional":1,"pattern":"(?^:^(\\d+)\\-(\\d+(\\.\\d+)*)$)","type":"string"}},"properties":{},"type":"string"},"properties":{},"type":"array"},"name":"map"}],"permissions":{"expression":{"check":["perm","/mapping/usb",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/mapping/usb"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bdc92ea0426ed15e2364503f8ef030848f16dab636466c1f2b53686d77313087","description":"Remove Hardware Mapping.","extra":{},"name":"delete","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/mapping/usb",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"41a71a202028635b8a3019b74ca4076c50be08ee860e758541e0e49fcedc88d5","description":"Get USB Mapping.","extra":{},"name":"get","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["or",["perm","/mapping/usb/{id}",["Mapping.Audit"]],["perm","/mapping/usb/{id}",["Mapping.Use"]],["perm","/mapping/usb/{id}",["Mapping.Modify"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"10c711f5a8ebbd1366a9f6c2eaaadc7132629244f3b76089f51bb581c4d8f15b","description":"Update a hardware mapping.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description of the logical USB device.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The ID of the logical USB mapping.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"A list of maps for the cluster nodes.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":{"description":{"description":"Description of the node specific device.","maxLength":4096,"optional":1,"type":"string"},"id":{"description":"The vendor and device ID that is expected. If a USB path is given, it is only used for detecting hardware changes","pattern":"(?^:^[0-9A-Fa-f]{4}:[0-9A-Fa-f]{4}$)","type":"string"},"node":{"description":"The cluster node name.","format":"pve-node","type":"string"},"path":{"description":"The path to the usb device.","optional":1,"pattern":"(?^:^(\\d+)\\-(\\d+(\\.\\d+)*)$)","type":"string"}},"properties":{},"type":"string"},"properties":{},"type":"array"},"name":"map"}],"permissions":{"expression":{"check":["perm","/mapping/usb/{id}",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/mapping/usb/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"32e4e0d625a43113ca32f9e4eba0fba77b683c1450a608bddb7a54be11776ea3","description":"Metrics index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/metrics"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9513b28908d79747f9a7b14e6f815b5701f710de477893fbd994114329b5a9b4","description":"Retrieve metrics of the cluster.","extra":{},"name":"export","parameters":[{"definition":{"default":0,"description":"Also return historic values. Returns full available metric history unless `start-time` is also set","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"history"},{"definition":{"default":0,"description":"Only return metrics for the current node instead of the whole cluster","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"local-only"},{"definition":{"default":0,"description":"Only include metrics with a timestamp > start-time.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"start-time"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"data":{"description":"Array of system metrics. Metrics are sorted by their timestamp.","enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":0},"properties":{"id":{"description":"Unique identifier for this metric object, for instance 'node/' or 'qemu/'.","enum":[],"extra":{},"properties":{},"type":"string"},"metric":{"description":"Name of the metric.","enum":[],"extra":{},"properties":{},"type":"string"},"timestamp":{"description":"Time at which this metric was observed","enum":[],"extra":{},"properties":{},"type":"integer"},"type":{"description":"Type of the metric.","enum":["gauge","counter","derive"],"extra":{},"properties":{},"type":"string"},"value":{"description":"Metric value.","enum":[],"extra":{},"properties":{},"type":"number"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"}],"path":"/cluster/metrics/export"},{"extra":{},"methods":[{"allow_token":true,"checksum":"27149ea7f2dd2e6d37dc5ad79fe1835f771a7232d81bc38e686157565a692fc6","description":"List configured metric servers.","extra":{},"name":"server_index","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"disable":{"description":"Flag to disable the plugin.","enum":[],"extra":{},"properties":{},"type":"boolean"},"id":{"description":"The ID of the entry.","enum":[],"extra":{},"properties":{},"type":"string"},"port":{"description":"Server network port","enum":[],"extra":{},"properties":{},"type":"integer"},"server":{"description":"Server dns name or IP address","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"Plugin type.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/metrics/server"},{"extra":{},"methods":[{"allow_token":true,"checksum":"56bc7f1733b6ce3c54389c9ceed9a20983de2c44898310930261592680aa259a","description":"Remove Metric server.","extra":{},"name":"delete","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"a53d502e8ae6ee9c25effeb04789f394e23cf119b2a13a620c971ed75e925a3f","description":"Read metric server configuration.","extra":{},"name":"read","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"6312f9174ff71367ba00ae59b7472497a643ab96b470b021c08f6c6b9649dde8","description":"Create a new external metric server config","extra":{},"name":"create","parameters":[{"definition":{"description":"An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"api-path-prefix"},{"definition":{"description":"The InfluxDB bucket/db. Only necessary when using the http v2 api.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"bucket"},{"definition":{"description":"Flag to disable the plugin.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"The ID of the entry.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"default":"udp","enum":["udp","http","https"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"influxdbproto"},{"definition":{"default":25000000,"description":"InfluxDB max-body-size in bytes. Requests are batched up to this size.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max-body-size"},{"definition":{"default":1500,"description":"MTU for metrics transmission over UDP","enum":[],"extra":{"typetext":" (512 - 65536)"},"maximum":65536,"minimum":512,"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"organization"},{"definition":{"description":"root graphite path (ex: proxmox.mycluster.mykey)","enum":[],"extra":{"typetext":""},"format":"graphite-path","optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"server network port","enum":[],"extra":{"typetext":" (1 - 65536)"},"maximum":65536,"minimum":1,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Protocol to send graphite data. TCP or UDP (default)","enum":["udp","tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"server dns name or IP address","enum":[],"extra":{"typetext":""},"format":"address","properties":{},"type":"string"},"name":"server"},{"definition":{"default":1,"description":"graphite TCP socket timeout (default=1)","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"},{"definition":{"description":"Plugin type.","enum":["graphite","influxdb"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"},{"definition":{"default":1,"description":"Set to 0 to disable certificate verification for https endpoints.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify-certificate"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"54d2944b90337b365a7e20fb580348c79c341d086e14a563fe89dd020f5d010a","description":"Update metric server configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"api-path-prefix"},{"definition":{"description":"The InfluxDB bucket/db. Only necessary when using the http v2 api.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"bucket"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Flag to disable the plugin.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"The ID of the entry.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"id"},{"definition":{"default":"udp","enum":["udp","http","https"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"influxdbproto"},{"definition":{"default":25000000,"description":"InfluxDB max-body-size in bytes. Requests are batched up to this size.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max-body-size"},{"definition":{"default":1500,"description":"MTU for metrics transmission over UDP","enum":[],"extra":{"typetext":" (512 - 65536)"},"maximum":65536,"minimum":512,"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"organization"},{"definition":{"description":"root graphite path (ex: proxmox.mycluster.mykey)","enum":[],"extra":{"typetext":""},"format":"graphite-path","optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"server network port","enum":[],"extra":{"typetext":" (1 - 65536)"},"maximum":65536,"minimum":1,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Protocol to send graphite data. TCP or UDP (default)","enum":["udp","tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"server dns name or IP address","enum":[],"extra":{"typetext":""},"format":"address","properties":{},"type":"string"},"name":"server"},{"definition":{"default":1,"description":"graphite TCP socket timeout (default=1)","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"},{"definition":{"default":1,"description":"Set to 0 to disable certificate verification for https endpoints.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify-certificate"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/metrics/server/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"aa3eb10cb83557b6fcf75697ec64cec7b678f1a4450ebb9bf8ec1a20337edfa3","description":"Get next free VMID. Pass a VMID to assert that its free (at time of check).","extra":{},"name":"nextid","parameters":[{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"The next free VMID.","enum":[],"extra":{},"properties":{},"type":"integer"},"verb":"GET"}],"path":"/cluster/nextid"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7dbcb2698d0743fdaa7af4375905eaf256dcdd8b8aab222da2a96757f655c17b","description":"Index for notification-related API endpoints.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/notifications"},{"extra":{},"methods":[{"allow_token":true,"checksum":"85590b7311db3564907025d08fe26246c4cce5921df4cb13e552320becebb7b7","description":"Index for all available endpoint types.","extra":{},"name":"endpoints_index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/notifications/endpoints"},{"extra":{},"methods":[{"allow_token":true,"checksum":"aa2279f9300ffacd9067b3caf0923954a31d175a2b35e4dd55b5cdc5d6446a2d","description":"Returns a list of all gotify endpoints","extra":{},"name":"get_gotify_endpoints","parameters":[],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this target","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"name":{"description":"The name of the endpoint.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"origin":{"description":"Show if this entry was created by a user or was built-in","enum":["user-created","builtin","modified-builtin"],"extra":{},"properties":{},"type":"string"},"server":{"description":"Server URL","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"203146b6888684db9665f1eac8ba9f7c0f8badfbc80a8fb609fd9144884639d7","description":"Create a new gotify endpoint","extra":{},"name":"create_gotify_endpoint","parameters":[{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":0,"description":"Disable this target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"The name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Server URL","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"server"},{"definition":{"description":"Secret token","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"token"}],"permissions":{"expression":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/notifications/endpoints/gotify"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a6de09b94ee57a1549718ac8d08fa550e86c4f63cc58d9b87d6d5214d09114f9","description":"Remove gotify endpoint","extra":{},"name":"delete_gotify_endpoint","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"6ab08a33c312fc583f6134d2f6350bc4a95b1105b6261389b718c5240842a66e","description":"Return a specific gotify endpoint","extra":{},"name":"get_gotify_endpoint","parameters":[{"definition":{"description":"Name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this target","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"name":{"description":"The name of the endpoint.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"server":{"description":"Server URL","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"1250dacd14b1453f9e672a43ed6ae634699ac3eb7471a93d2788fc7ae609ec2f","description":"Update existing gotify endpoint","extra":{},"name":"update_gotify_endpoint","parameters":[{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Disable this target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"The name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Server URL","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"server"},{"definition":{"description":"Secret token","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"}],"permissions":{"expression":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/notifications/endpoints/gotify/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"822b8284272a3eb5b3b6b9d20fe374ac450fd09b464760fe487e6d96ff6b4ee5","description":"Returns a list of all sendmail endpoints","extra":{},"name":"get_sendmail_endpoints","parameters":[],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"author":{"description":"Author of the mail","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this target","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"from-address":{"description":"`From` address for the mail","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mailto":{"description":"List of email recipients","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"email-or-username","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"mailto-user":{"description":"List of users","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"pve-userid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":{"description":"The name of the endpoint.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"origin":{"description":"Show if this entry was created by a user or was built-in","enum":["user-created","builtin","modified-builtin"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"ff7158b8777736c611660e4a51905e8cbc619ccb80be0d565e15704dbc69efae","description":"Create a new sendmail endpoint","extra":{},"name":"create_sendmail_endpoint","parameters":[{"definition":{"description":"Author of the mail","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"author"},{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":0,"description":"Disable this target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"`From` address for the mail","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"from-address"},{"definition":{"description":"List of email recipients","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"email-or-username","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"mailto"},{"definition":{"description":"List of users","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-userid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"mailto-user"},{"definition":{"description":"The name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/notifications/endpoints/sendmail"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8b865ef7b43ac01417a73521a23175a2921b6602407180a1c687655ec120328b","description":"Remove sendmail endpoint","extra":{},"name":"delete_sendmail_endpoint","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"939df15a8a724305cca5c2b002c6546b2808542dd462d59009565a25144cf839","description":"Return a specific sendmail endpoint","extra":{},"name":"get_sendmail_endpoint","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"author":{"description":"Author of the mail","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this target","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"from-address":{"description":"`From` address for the mail","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mailto":{"description":"List of email recipients","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"email-or-username","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"mailto-user":{"description":"List of users","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"pve-userid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":{"description":"The name of the endpoint.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"918ab4f7d8ae0b6a942395375f3ffa14ec3eadcd6d38f739095057951336f9e4","description":"Update existing sendmail endpoint","extra":{},"name":"update_sendmail_endpoint","parameters":[{"definition":{"description":"Author of the mail","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"author"},{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Disable this target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"`From` address for the mail","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"from-address"},{"definition":{"description":"List of email recipients","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"email-or-username","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"mailto"},{"definition":{"description":"List of users","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-userid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"mailto-user"},{"definition":{"description":"The name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/notifications/endpoints/sendmail/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"649b926f2615be3ee77c56a411fdd943c57605f9fc8e225e545580139f1371c6","description":"Returns a list of all smtp endpoints","extra":{},"name":"get_smtp_endpoints","parameters":[],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"author":{"description":"Author of the mail. Defaults to 'Proxmox VE'.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this target","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"from-address":{"description":"`From` address for the mail","enum":[],"extra":{},"properties":{},"type":"string"},"mailto":{"description":"List of email recipients","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"email-or-username","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"mailto-user":{"description":"List of users","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"pve-userid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"mode":{"default":"tls","description":"Determine which encryption method shall be used for the connection.","enum":["insecure","starttls","tls"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"The name of the endpoint.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"origin":{"description":"Show if this entry was created by a user or was built-in","enum":["user-created","builtin","modified-builtin"],"extra":{},"properties":{},"type":"string"},"port":{"description":"The port to be used. Defaults to 465 for TLS based connections, 587 for STARTTLS based connections and port 25 for insecure plain-text connections.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"server":{"description":"The address of the SMTP server.","enum":[],"extra":{},"properties":{},"type":"string"},"username":{"description":"Username for SMTP authentication","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"50245531f58d65906617eb64a74325d81f787bde7f35ef6ce469913dfc43ef96","description":"Create a new smtp endpoint","extra":{},"name":"create_smtp_endpoint","parameters":[{"definition":{"description":"Author of the mail. Defaults to 'Proxmox VE'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"author"},{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":0,"description":"Disable this target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"`From` address for the mail","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"from-address"},{"definition":{"description":"List of email recipients","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"email-or-username","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"mailto"},{"definition":{"description":"List of users","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-userid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"mailto-user"},{"definition":{"default":"tls","description":"Determine which encryption method shall be used for the connection.","enum":["insecure","starttls","tls"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"The name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Password for SMTP authentication","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"The port to be used. Defaults to 465 for TLS based connections, 587 for STARTTLS based connections and port 25 for insecure plain-text connections.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The address of the SMTP server.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"server"},{"definition":{"description":"Username for SMTP authentication","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username"}],"permissions":{"expression":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/notifications/endpoints/smtp"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4da9aad76213e463fd077dd2994cecc67f2749fb9a67118c3db784242d3a0803","description":"Remove smtp endpoint","extra":{},"name":"delete_smtp_endpoint","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"ff151038edcae508b780b3210438ff7d62415a1fc20b2bc7f94920e1e6bd9abf","description":"Return a specific smtp endpoint","extra":{},"name":"get_smtp_endpoint","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"author":{"description":"Author of the mail. Defaults to 'Proxmox VE'.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this target","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"from-address":{"description":"`From` address for the mail","enum":[],"extra":{},"properties":{},"type":"string"},"mailto":{"description":"List of email recipients","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"email-or-username","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"mailto-user":{"description":"List of users","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"pve-userid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"mode":{"default":"tls","description":"Determine which encryption method shall be used for the connection.","enum":["insecure","starttls","tls"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"The name of the endpoint.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"port":{"description":"The port to be used. Defaults to 465 for TLS based connections, 587 for STARTTLS based connections and port 25 for insecure plain-text connections.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"server":{"description":"The address of the SMTP server.","enum":[],"extra":{},"properties":{},"type":"string"},"username":{"description":"Username for SMTP authentication","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"1007bc9cf46b936b3527c23d140212285e41624682d3cc7cbacc86bd4a1cb434","description":"Update existing smtp endpoint","extra":{},"name":"update_smtp_endpoint","parameters":[{"definition":{"description":"Author of the mail. Defaults to 'Proxmox VE'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"author"},{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Disable this target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"`From` address for the mail","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"from-address"},{"definition":{"description":"List of email recipients","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"email-or-username","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"mailto"},{"definition":{"description":"List of users","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-userid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"mailto-user"},{"definition":{"default":"tls","description":"Determine which encryption method shall be used for the connection.","enum":["insecure","starttls","tls"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"The name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Password for SMTP authentication","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"The port to be used. Defaults to 465 for TLS based connections, 587 for STARTTLS based connections and port 25 for insecure plain-text connections.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The address of the SMTP server.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"server"},{"definition":{"description":"Username for SMTP authentication","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username"}],"permissions":{"expression":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/notifications/endpoints/smtp/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f28969a47b8037821f50ecad98382ae831e9bfe571bf0f1bcf1eae8e9fcba64e","description":"Returns a list of all webhook endpoints","extra":{},"name":"get_webhook_endpoints","parameters":[],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"body":{"description":"HTTP body, base64 encoded","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this target","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"header":{"description":"HTTP headers to set. These have to be formatted as a property string in the format name=,value=","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"method":{"description":"HTTP method","enum":["post","put","get"],"extra":{},"properties":{},"type":"string"},"name":{"description":"The name of the endpoint.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"origin":{"description":"Show if this entry was created by a user or was built-in","enum":["user-created","builtin","modified-builtin"],"extra":{},"properties":{},"type":"string"},"secret":{"description":"Secrets to set. These have to be formatted as a property string in the format name=,value=","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"url":{"description":"Server URL","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"12e06ec20708e708c716f68acf165191a46721977278b1492aee8f0a87be6c05","description":"Create a new webhook endpoint","extra":{},"name":"create_webhook_endpoint","parameters":[{"definition":{"description":"HTTP body, base64 encoded","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"body"},{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":0,"description":"Disable this target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"HTTP headers to set. These have to be formatted as a property string in the format name=,value=","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"header"},{"definition":{"description":"HTTP method","enum":["post","put","get"],"extra":{},"properties":{},"type":"string"},"name":"method"},{"definition":{"description":"The name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Secrets to set. These have to be formatted as a property string in the format name=,value=","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"secret"},{"definition":{"description":"Server URL","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/notifications/endpoints/webhook"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a69d31e16174e8eeba1c3d681999308a624de1f04bededd7e80a7aef2985d39b","description":"Remove webhook endpoint","extra":{},"name":"delete_webhook_endpoint","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"872d98a658e6bda785b39c13e32ac76bd29d2619266bb1872e760e9475be1dda","description":"Return a specific webhook endpoint","extra":{},"name":"get_webhook_endpoint","parameters":[{"definition":{"description":"Name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"body":{"description":"HTTP body, base64 encoded","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this target","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"header":{"description":"HTTP headers to set. These have to be formatted as a property string in the format name=,value=","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"method":{"description":"HTTP method","enum":["post","put","get"],"extra":{},"properties":{},"type":"string"},"name":{"description":"The name of the endpoint.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"secret":{"description":"Secrets to set. These have to be formatted as a property string in the format name=,value=","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"url":{"description":"Server URL","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"8628abb1cbc8d50543fc19a45ba95f4f388d66a7a1ea108e474231a82b53baa0","description":"Update existing webhook endpoint","extra":{},"name":"update_webhook_endpoint","parameters":[{"definition":{"description":"HTTP body, base64 encoded","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"body"},{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Disable this target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"HTTP headers to set. These have to be formatted as a property string in the format name=,value=","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"header"},{"definition":{"description":"HTTP method","enum":["post","put","get"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"method"},{"definition":{"description":"The name of the endpoint.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Secrets to set. These have to be formatted as a property string in the format name=,value=","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"secret"},{"definition":{"description":"Server URL","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/notifications/endpoints/webhook/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"aa41d7e8d333bd62d93dd0d9961cc8cc1b34eaaecefb6945b796c49800978507","description":"Returns known notification metadata fields and their known values","extra":{},"name":"get_matcher_field_values","parameters":[],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"Additional comment for this value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"field":{"description":"Field this value belongs to.","enum":[],"extra":{},"properties":{},"type":"string"},"value":{"description":"Notification metadata value known by the system.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/notifications/matcher-field-values"},{"extra":{},"methods":[{"allow_token":true,"checksum":"03edb9a3636c55ce06fe6a6aec4bb99a02d3c320360e32bd7ad92736ddfc234b","description":"Returns known notification metadata fields","extra":{},"name":"get_matcher_fields","parameters":[],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"name":{"description":"Name of the field.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/notifications/matcher-fields"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2d81c639818313f8f1574cd4398c0c7573ad6fa37dc9179983f6dda5fa1ce84d","description":"Returns a list of all matchers","extra":{},"name":"get_matchers","parameters":[],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]],["perm","/mapping/notifications",["Mapping.Use"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this matcher","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"invert-match":{"description":"Invert match of the whole matcher","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"match-calendar":{"description":"Match notification timestamp","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"match-field":{"description":"Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"match-severity":{"description":"Notification severities to match","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"mode":{"default":"all","description":"Choose between 'all' and 'any' for when multiple properties are specified","enum":["all","any"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"Name of the matcher.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"origin":{"description":"Show if this entry was created by a user or was built-in","enum":["user-created","builtin","modified-builtin"],"extra":{},"properties":{},"type":"string"},"target":{"description":"Targets to notify on match","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"15c020aae8edfbf48f094c82e446b621be8b8c453a64fb68ef0b2f1f7a5d6c62","description":"Create a new matcher","extra":{},"name":"create_matcher","parameters":[{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":0,"description":"Disable this matcher","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"Invert match of the whole matcher","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"invert-match"},{"definition":{"description":"Match notification timestamp","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"match-calendar"},{"definition":{"description":"Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"match-field"},{"definition":{"description":"Notification severities to match","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"match-severity"},{"definition":{"default":"all","description":"Choose between 'all' and 'any' for when multiple properties are specified","enum":["all","any"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"Name of the matcher.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Targets to notify on match","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"target"}],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/notifications/matchers"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bc801324430c8d7fc2b03d29ea40064856138f33ee7db0dd54fd7e757a94986b","description":"Remove matcher","extra":{},"name":"delete_matcher","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"5e51e778bdb104dd9f86b83bdd60209c721601fb362521112e045bea4136140e","description":"Return a specific matcher","extra":{},"name":"get_matcher","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Disable this matcher","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"invert-match":{"description":"Invert match of the whole matcher","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"match-calendar":{"description":"Match notification timestamp","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"match-field":{"description":"Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"match-severity":{"description":"Notification severities to match","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"mode":{"default":"all","description":"Choose between 'all' and 'any' for when multiple properties are specified","enum":["all","any"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"Name of the matcher.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"target":{"description":"Targets to notify on match","enum":[],"extra":{},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"0c5c9801c81e5a52a8f5859b7253e04a23c517b90a6141e07c52e880b6be5d41","description":"Update existing matcher","extra":{},"name":"update_matcher","parameters":[{"definition":{"description":"Comment","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Disable this matcher","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"Invert match of the whole matcher","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"invert-match"},{"definition":{"description":"Match notification timestamp","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"match-calendar"},{"definition":{"description":"Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"match-field"},{"definition":{"description":"Notification severities to match","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"match-severity"},{"definition":{"default":"all","description":"Choose between 'all' and 'any' for when multiple properties are specified","enum":["all","any"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"Name of the matcher.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"Targets to notify on match","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"target"}],"permissions":{"expression":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/notifications/matchers/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6df341a23c51716542f980e768ae19f61a31ec6e92a378d86fba01c4fd3a3437","description":"Returns a list of all entities that can be used as notification targets.","extra":{},"name":"get_all_targets","parameters":[],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]],["perm","/mapping/notifications",["Mapping.Use"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"Comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"disable":{"default":0,"description":"Show if this target is disabled","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"name":{"description":"Name of the target.","enum":[],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"origin":{"description":"Show if this entry was created by a user or was built-in","enum":["user-created","builtin","modified-builtin"],"extra":{},"properties":{},"type":"string"},"type":{"description":"Type of the target.","enum":["sendmail","gotify","smtp","webhook"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/notifications/targets"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7494eacdd54979c41f1bab85951ae184cdad4ec05b2ccc76db51c7df47796558","description":"Send a test notification to a provided target.","extra":{},"name":"test_target","parameters":[{"definition":{"description":"Name of the target.","enum":[],"extra":{"typetext":""},"format":"pve-configid","properties":{},"type":"string"},"name":"name"}],"permissions":{"expression":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]],["perm","/mapping/notifications",["Mapping.Use"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/notifications/targets/{name}/test"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f25824d5aa61d78e9fdb1f99a5845b39d507b9c2093b786e95acd8d8e072ede3","description":"Get datacenter options. Without 'Sys.Audit' on '/' not all options are returned.","extra":{},"name":"get_options","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"e8c5d58161b73f14f8138734ffef248c0cc6fc32c6bf93e2c7c4f17eaccafcc0","description":"Set datacenter options.","extra":{},"name":"set_options","parameters":[{"definition":{"description":"Set I/O bandwidth limit for various operations (in KiB/s).","enum":[],"extra":{"typetext":"[clone=] [,default=] [,migration=] [,move=] [,restore=]"},"format":{"clone":{"description":"bandwidth limit in KiB/s for cloning disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"default":{"description":"default bandwidth limit in KiB/s","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"migration":{"description":"bandwidth limit in KiB/s for migrating guests (including moving local disks)","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"move":{"description":"bandwidth limit in KiB/s for moving disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"restore":{"description":"bandwidth limit in KiB/s for restoring guests from backups","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"}},"optional":true,"properties":{},"type":"string"},"name":"bwlimit"},{"definition":{"description":"Consent text that is displayed before logging in.","enum":[],"extra":{"typetext":""},"max_length":65536,"optional":true,"properties":{},"type":"string"},"name":"consent-text"},{"definition":{"description":"Select the default Console viewer. You can either use the builtin java applet (VNC; deprecated and maps to html5), an external virt-viewer comtatible application (SPICE), an HTML5 based vnc viewer (noVNC), or an HTML5 based console client (xtermjs). If the selected viewer is not available (e.g. SPICE not activated for the VM), the fallback is noVNC.","enum":["applet","vv","html5","xtermjs"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"console"},{"definition":{"description":"Cluster resource scheduling settings.","enum":[],"extra":{"typetext":"[ha=] [,ha-rebalance-on-start=<1|0>]"},"format":{"ha":{"default":"basic","description":"Use this resource scheduler mode for HA.","enum":["basic","static"],"optional":1,"type":"string","verbose_description":"Configures how the HA manager should select nodes to start or recover services. With 'basic', only the number of services is used, with 'static', static CPU and memory configuration of services is considered."},"ha-rebalance-on-start":{"default":0,"description":"Set to use CRS for selecting a suited node when a HA services request-state changes from stop to start.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"crs"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Datacenter description. Shown in the web-interface datacenter notes panel. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":65536,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Specify email address to send notification from (default is root@$hostname)","enum":[],"extra":{"typetext":""},"format":"email-opt","optional":true,"properties":{},"type":"string"},"name":"email_from"},{"definition":{"default":"watchdog","description":"Set the fencing mode of the HA cluster. Hardware mode needs a valid configuration of fence devices in /etc/pve/ha/fence.cfg. With both all two modes are used.\n\nWARNING: 'hardware' and 'both' are EXPERIMENTAL & WIP","enum":["watchdog","hardware","both"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"fencing"},{"definition":{"description":"Cluster wide HA settings.","enum":[],"extra":{"typetext":"shutdown_policy="},"format":{"shutdown_policy":{"default":"conditional","description":"The policy for HA services on node shutdown. 'freeze' disables auto-recovery, 'failover' ensures recovery, 'conditional' recovers on poweroff and freezes on reboot. 'migrate' will migrate running services to other nodes, if possible. With 'freeze' or 'failover', HA Services will always get stopped first on shutdown.","enum":["freeze","failover","conditional","migrate"],"type":"string","verbose_description":"Describes the policy for handling HA services on poweroff or reboot of a node. Freeze will always freeze services which are still located on the node on shutdown, those services won't be recovered by the HA manager. Failover will not mark the services as frozen and thus the services will get recovered to other nodes, if the shutdown node does not come up again quickly (< 1min). 'conditional' chooses automatically depending on the type of shutdown, i.e., on a reboot the service will be frozen but on a poweroff the service will stay as is, and thus get recovered after about 2 minutes. Migrate will try to move all running services to another node when a reboot or shutdown was triggered. The poweroff process will only continue once no running services are located on the node anymore. If the node comes up again, the service will be moved back to the previously powered-off node, at least if no other migration, reloaction or recovery took place."}},"optional":true,"properties":{},"type":"string"},"name":"ha"},{"definition":{"description":"Specify external http proxy which is used for downloads (example: 'http://username:password@host:port/')","enum":[],"extra":{},"optional":true,"pattern":"http://.*","properties":{},"type":"string"},"name":"http_proxy"},{"definition":{"description":"Default keybord layout for vnc server.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"keyboard"},{"definition":{"description":"Default GUI language.","enum":["ar","ca","da","de","en","es","eu","fa","fr","hr","he","it","ja","ka","kr","nb","nl","nn","pl","pt_BR","ru","sl","sv","tr","ukr","zh_CN","zh_TW"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"language"},{"definition":{"default":"BC:24:11","description":"Prefix for the auto-generated MAC addresses of virtual guests. The default 'BC:24:11' is the OUI assigned by the IEEE to Proxmox Server Solutions GmbH for a 24-bit large MAC block. You're allowed to use this in local networks, i.e., those not directly reachable by the public (e.g., in a LAN or behind NAT).","enum":[],"extra":{"typetext":"","verbose_description":"Prefix for the auto-generated MAC addresses of virtual guests. The default `BC:24:11` is the Organizationally Unique Identifier (OUI) assigned by the IEEE to Proxmox Server Solutions GmbH for a MAC Address Block Large (MA-L). You're allowed to use this in local networks, i.e., those not directly reachable by the public (e.g., in a LAN or NAT/Masquerading).\n \nNote that when you run multiple cluster that (partially) share the networks of their virtual guests, it's highly recommended that you extend the default MAC prefix, or generate a custom (valid) one, to reduce the chance of MAC collisions. For example, add a separate extra hexadecimal to the Proxmox OUI for each cluster, like `BC:24:11:0` for the first, `BC:24:11:1` for the second, and so on.\n Alternatively, you can also separate the networks of the guests logically, e.g., by using VLANs.\n\nFor publicly accessible guests it's recommended that you get your own https://standards.ieee.org/products-programs/regauth/[OUI from the IEEE] registered or coordinate with your, or your hosting providers, network admins."},"format":"mac-prefix","optional":true,"properties":{},"type":"string"},"name":"mac_prefix"},{"definition":{"description":"Defines how many workers (per node) are maximal started on actions like 'stopall VMs' or task from the ha-manager.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"max_workers"},{"definition":{"description":"For cluster wide migration settings.","enum":[],"extra":{"typetext":"[type=] [,network=]"},"format":{"network":{"description":"CIDR of the (sub) network that is used for migration.","format":"CIDR","format_description":"CIDR","optional":1,"type":"string"},"type":{"default":"secure","default_key":1,"description":"Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.","enum":["secure","insecure"],"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"migration"},{"definition":{"description":"Migration is secure using SSH tunnel by default. For secure private networks you can disable it to speed up migration. Deprecated, use the 'migration' property instead!","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"migration_unsecure"},{"definition":{"description":"Control the range for the free VMID auto-selection pool.","enum":[],"extra":{"typetext":"[lower=] [,upper=]"},"format":{"lower":{"default":100,"description":"Lower, inclusive boundary for free next-id API range.","max":999999999,"min":100,"optional":1,"type":"integer"},"upper":{"default":1000000,"description":"Upper, exclusive boundary for free next-id API range.","max":1000000000,"min":100,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"next-id"},{"definition":{"description":"Cluster-wide notification settings.","enum":[],"extra":{"typetext":"[fencing=] [,package-updates=] [,replication=] [,target-fencing=] [,target-package-updates=] [,target-replication=]"},"format":{"fencing":{"description":"UNUSED - Use datacenter notification settings instead.","enum":["always","never"],"optional":1,"type":"string"},"package-updates":{"default":"auto","description":"DEPRECATED: Use datacenter notification settings instead. Control when the daily update job should send out notifications.","enum":["auto","always","never"],"optional":1,"type":"string","verbose_description":"DEPRECATED: Use datacenter notification settings instead.\nControl how often the daily update job should send out notifications:\n* 'auto' daily for systems with a valid subscription, as those are assumed to be production-ready and thus should know about pending updates.\n* 'always' every update, if there are new pending updates.\n* 'never' never send a notification for new pending updates.\n"},"replication":{"description":"UNUSED - Use datacenter notification settings instead.","enum":["always","never"],"optional":1,"type":"string"},"target-fencing":{"description":"UNUSED - Use datacenter notification settings instead.","format_description":"TARGET","optional":1,"type":"string"},"target-package-updates":{"description":"UNUSED - Use datacenter notification settings instead.","format_description":"TARGET","optional":1,"type":"string"},"target-replication":{"description":"UNUSED - Use datacenter notification settings instead.","format_description":"TARGET","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"notify"},{"definition":{"description":"A list of tags that require a `Sys.Modify` on '/' to set and delete. Tags set here that are also in 'user-tag-access' also require `Sys.Modify`.","enum":[],"extra":{"typetext":"[;...]"},"optional":true,"pattern":"(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*);)*(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*)","properties":{},"type":"string"},"name":"registered-tags"},{"definition":{"description":"Tag style options.","enum":[],"extra":{"typetext":"[case-sensitive=<1|0>] [,color-map=:[:][;=...]] [,ordering=] [,shape=]"},"format":{"case-sensitive":{"default":0,"description":"Controls if filtering for unique tags on update should check case-sensitive.","optional":1,"type":"boolean"},"color-map":{"description":"Manual color mapping for tags (semicolon separated).","optional":1,"pattern":"(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*):[0-9a-fA-F]{6}(?::[0-9a-fA-F]{6})?)(?:;(?:(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*):[0-9a-fA-F]{6}(?::[0-9a-fA-F]{6})?))*","type":"string","typetext":":[:][;=...]"},"ordering":{"default":"alphabetical","description":"Controls the sorting of the tags in the web-interface and the API update.","enum":["config","alphabetical"],"optional":1,"type":"string"},"shape":{"default":"circle","description":"Tag shape for the web ui tree. 'full' draws the full tag. 'circle' draws only a circle with the background color. 'dense' only draws a small rectancle (useful when many tags are assigned to each guest).'none' disables showing the tags.","enum":["full","circle","dense","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"tag-style"},{"definition":{"description":"u2f","enum":[],"extra":{"typetext":"[appid=] [,origin=]"},"format":{"appid":{"description":"U2F AppId URL override. Defaults to the origin.","format_description":"APPID","optional":1,"type":"string"},"origin":{"description":"U2F Origin override. Mostly useful for single nodes with a single URL.","format_description":"URL","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"u2f"},{"definition":{"description":"Privilege options for user-settable tags","enum":[],"extra":{"typetext":"[user-allow=] [,user-allow-list=[;...]]"},"format":{"user-allow":{"default":"free","description":"Controls tag usage for users without `Sys.Modify` on `/` by either allowing `none`, a `list`, already `existing` or anything (`free`).","enum":["none","list","existing","free"],"optional":1,"type":"string","verbose_description":"Controls which tags can be set or deleted on resources a user controls (such as guests). Users with the `Sys.Modify` privilege on `/` are alwaysunrestricted.\n* 'none' no tags are usable.\n* 'list' tags from 'user-allow-list' are usable.\n* 'existing' like list, but already existing tags of resources are also usable.\n* 'free' no tag restrictions.\n"},"user-allow-list":{"description":"List of tags users are allowed to set and delete (semicolon separated) for 'user-allow' values 'list' and 'existing'.","optional":1,"pattern":"(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*)(?:;(?^i:[a-z0-9_][a-z0-9_\\-\\+\\.]*))*","type":"string","typetext":"[;...]"}},"optional":true,"properties":{},"type":"string"},"name":"user-tag-access"},{"definition":{"description":"webauthn configuration","enum":[],"extra":{"typetext":"[allow-subdomains=<1|0>] [,id=] [,origin=] [,rp=]"},"format":{"allow-subdomains":{"default":1,"description":"Whether to allow the origin to be a subdomain, rather than the exact URL.","optional":1,"type":"boolean"},"id":{"description":"Relying party ID. Must be the domain name without protocol, port or location. Changing this *will* break existing credentials.","format_description":"DOMAINNAME","optional":1,"type":"string"},"origin":{"description":"Site origin. Must be a `https://` URL (or `http://localhost`). Should contain the address users type in their browsers to access the web interface. Changing this *may* break existing credentials.","format_description":"URL","optional":1,"type":"string"},"rp":{"description":"Relying party name. Any text identifier. Changing this *may* break existing credentials.","format_description":"RELYING_PARTY","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"webauthn"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"768bcbbf1ace9e97d850e6ca5599419dd443f7a4268ffd8078113d06da086168","description":"List replication jobs.","extra":{},"name":"index","parameters":[],"permissions":{"description":"Will only return replication jobs for which the calling user has VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"6e719bf689a19e11db1c645c80b7c865cfbd44d07efa6a1dc0fef3692b58b0a2","description":"Create a new replication job","extra":{},"name":"create","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Flag to disable/deactivate the entry.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"number"},"name":"rate"},{"definition":{"description":"Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.","enum":["local","full"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"remove_job"},{"definition":{"default":"*/15","description":"Storage replication schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"For internal use, to detect if the guest was stolen.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":false,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Section type.","enum":["local"],"extra":{},"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/replication"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a755e3fc20618d34ac577bb6749b86e277a78938aafcc74d3d1ef45aee2995da","description":"Mark replication job for removal.","extra":{},"name":"delete","parameters":[{"definition":{"default":0,"description":"Will remove the jobconfig entry, but will not cleanup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"default":0,"description":"Keep replicated data at target (do not remove).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keep"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"e7ec17056fddc5bf05f3598911533fad45ff9b2eadbc69102c3ae6404a996582","description":"Read replication job configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"}],"permissions":{"description":"Requires the VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"23c934c0eade8e59c83381632100b93c0f961a7de51003cc8ee9ce0f913e676b","description":"Update replication job configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"Description.","enum":[],"extra":{"typetext":""},"max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Flag to disable/deactivate the entry.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"number"},"name":"rate"},{"definition":{"description":"Mark the replication job for removal. The job will remove all local replication snapshots. When set to 'full', it also tries to remove replicated volumes on the target. The job then removes itself from the configuration file.","enum":["local","full"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"remove_job"},{"definition":{"default":"*/15","description":"Storage replication schedule. The format is a subset of `systemd` calendar events.","enum":[],"extra":{"typetext":""},"format":"pve-calendar-event","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"schedule"},{"definition":{"description":"For internal use, to detect if the guest was stolen.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"source"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/replication/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f07e4f6b548717f100cf5149be8ce642925e602add93bc4d55cd1816ad54fb5d","description":"Resources index (cluster wide).","extra":{},"name":"resources","parameters":[{"definition":{"description":"Resource type.","enum":["vm","storage","node","sdn"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"cgroup-mode":{"description":"The cgroup mode the node operates under (for type 'node').","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"content":{"description":"Allowed storage content types (for type 'storage').","enum":[],"extra":{},"format":"pve-storage-content-list","optional":true,"properties":{},"type":"string"},"cpu":{"description":"CPU utilization (for types 'node', 'qemu' and 'lxc').","enum":[],"extra":{"renderer":"fraction_as_percentage"},"minimum":0,"optional":true,"properties":{},"type":"number"},"disk":{"description":"Used disk space in bytes (for type 'storage'), used root image space for VMs (for types 'qemu' and 'lxc').","enum":[],"extra":{"renderer":"bytes"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"diskread":{"description":"The amount of bytes the guest read from its block devices since the guest was started. This info is not available for all storage types. (for types 'qemu' and 'lxc')","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"diskwrite":{"description":"The amount of bytes the guest wrote to its block devices since the guest was started. This info is not available for all storage types. (for types 'qemu' and 'lxc')","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"hastate":{"description":"HA service status (for HA managed VMs).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"description":"Resource id.","enum":[],"extra":{},"properties":{},"type":"string"},"level":{"description":"Support level (for type 'node').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"lock":{"description":"The guest's current config lock (for types 'qemu' and 'lxc')","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxcpu":{"description":"Number of available CPUs (for types 'node', 'qemu' and 'lxc').","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"number"},"maxdisk":{"description":"Storage size in bytes (for type 'storage'), root image size for VMs (for types 'qemu' and 'lxc').","enum":[],"extra":{"renderer":"bytes"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Number of available memory in bytes (for types 'node', 'qemu' and 'lxc').","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"mem":{"description":"Used memory in bytes (for types 'node', 'qemu' and 'lxc').","enum":[],"extra":{"renderer":"bytes"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":{"description":"Name of the resource.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"netin":{"description":"The amount of traffic in bytes that was sent to the guest over the network since it was started. (for types 'qemu' and 'lxc')","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"netout":{"description":"The amount of traffic in bytes that was sent from the guest over the network since it was started. (for types 'qemu' and 'lxc')","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"node":{"description":"The cluster node name (for types 'node', 'storage', 'qemu', and 'lxc').","enum":[],"extra":{},"format":"pve-node","optional":true,"properties":{},"type":"string"},"plugintype":{"description":"More specific type, if available.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pool":{"description":"The pool name (for types 'pool', 'qemu' and 'lxc').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"status":{"description":"Resource type dependent status.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"storage":{"description":"The storage identifier (for type 'storage').","enum":[],"extra":{"format_description":"storage ID"},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"tags":{"description":"The guest's tags (for types 'qemu' and 'lxc')","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"template":{"default":0,"description":"Determines if the guest is a template. (for types 'qemu' and 'lxc')","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"type":{"description":"Resource type.","enum":["node","storage","pool","qemu","lxc","openvz","sdn"],"extra":{},"properties":{},"type":"string"},"uptime":{"description":"Uptime of node or virtual guest in seconds (for types 'node', 'qemu' and 'lxc').","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The numerical vmid (for types 'qemu' and 'lxc').","enum":[],"extra":{},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/resources"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e55fa302d4424ac9e45c59566aeab35b6fd2029e23076095e6a3fc7845483050","description":"Directory index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{"check":["perm","/sdn",["SDN.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"e3e53e99bf397ad633261a85727564ec67c8818f3f78fba390f6a9b51f809ea2","description":"Apply sdn controller changes && reload.","extra":{},"name":"reload","parameters":[],"permissions":{"expression":{"check":["perm","/sdn",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/cluster/sdn"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c19cc7c677f2cc15983d6e7a8be80ece167757e0d1131b6ffb33c4ba46728f29","description":"SDN controllers index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"Only list sdn controllers of specific type","enum":["bgp","evpn","faucet","isis"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/controllers/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{controller}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"controller":{"enum":[],"extra":{},"properties":{},"type":"string"},"pending":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"state":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"80c7f92f78a8d9cbc1c6e8fc2202eafc6c2fd7fbb42e1bce2af3d5bcd8d793a7","description":"Create a new sdn controller object.","extra":{},"name":"create","parameters":[{"definition":{"description":"autonomous system number","enum":[],"extra":{"typetext":" (0 - 4294967296)"},"maximum":4294967296,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"asn"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bgp-multipath-as-path-relax"},{"definition":{"description":"The SDN controller object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-controller-id","properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"Enable ebgp. (remote-as external)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ebgp"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"ebgp-multihop"},{"definition":{"description":"ISIS domain.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"isis-domain"},{"definition":{"description":"ISIS interface.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"isis-ifaces"},{"definition":{"description":"ISIS network entity title.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-isis-net","optional":true,"properties":{},"type":"string"},"name":"isis-net"},{"definition":{"description":"source loopback interface.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"loopback"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"peers address list.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"peers"},{"definition":{"description":"Plugin type.","enum":["bgp","evpn","faucet","isis"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/sdn/controllers",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/controllers"},{"extra":{},"methods":[{"allow_token":true,"checksum":"cd5848ee8488704f054d262616cdac7dafce590f953307860febf76eb5b924d3","description":"Delete sdn controller object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN controller object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-controller-id","properties":{},"type":"string"},"name":"controller"}],"permissions":{"expression":{"check":["perm","/sdn/controllers",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"10ce0dd020d72fc27315b708c59822eda08951a6408ee5cdf9ef59e6c77b1285","description":"Read sdn controller configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The SDN controller object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-controller-id","properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"}],"permissions":{"expression":{"check":["perm","/sdn/controllers/{controller}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"85c06c6221c9aeb56ca0de6310a91b572f4997469c4f9bfd2f12a3514d4599e4","description":"Update sdn controller object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"autonomous system number","enum":[],"extra":{"typetext":" (0 - 4294967296)"},"maximum":4294967296,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"asn"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bgp-multipath-as-path-relax"},{"definition":{"description":"The SDN controller object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-controller-id","properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Enable ebgp. (remote-as external)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ebgp"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"ebgp-multihop"},{"definition":{"description":"ISIS domain.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"isis-domain"},{"definition":{"description":"ISIS interface.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"isis-ifaces"},{"definition":{"description":"ISIS network entity title.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-isis-net","optional":true,"properties":{},"type":"string"},"name":"isis-net"},{"definition":{"description":"source loopback interface.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"loopback"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"peers address list.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"peers"}],"permissions":{"expression":{"check":["perm","/sdn/controllers",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/controllers/{controller}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"eb447be7b8deba4c48a26dec0552342de4afd2b7ed9b023f63bf59e8a899344a","description":"SDN dns index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list sdn dns of specific type","enum":["powerdns"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/dns/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{dns}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"dns":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"50dc67b45c70a1681a0926d7329eb0d4ae996dfb9ba9c78ea09ee84a22f1b63b","description":"Create a new sdn dns object.","extra":{},"name":"create","parameters":[{"definition":{"description":"The SDN dns object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-dns-id","properties":{},"type":"string"},"name":"dns"},{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":false,"properties":{},"type":"string"},"name":"key"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"reversemaskv6"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"reversev6mask"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"ttl"},{"definition":{"description":"Plugin type.","enum":["powerdns"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":false,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["perm","/sdn/dns",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/dns"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5eabbb998398cee212dd2507f83c5e968a90e3413d0844b3f51a3a1e206e869e","description":"Delete sdn dns object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN dns object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-dns-id","properties":{},"type":"string"},"name":"dns"}],"permissions":{"expression":{"check":["perm","/sdn/dns",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f06c8afd05ffad3362aa90b64a2ab7239e95ed803211979c4579c145bffe8b3f","description":"Read sdn dns configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The SDN dns object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-dns-id","properties":{},"type":"string"},"name":"dns"}],"permissions":{"expression":{"check":["perm","/sdn/dns/{dns}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"b76b801297e8f02131d56f03a669248faefe81a603e90a6f64112dcd38c74032","description":"Update sdn dns object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The SDN dns object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-dns-id","properties":{},"type":"string"},"name":"dns"},{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"key"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"reversemaskv6"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"ttl"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["perm","/sdn/dns",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/dns/{dns}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2082f53189334ff79a0eb8a997c9e416b23b351b06e0804f95ee35b13963c6fc","description":"SDN ipams index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list sdn ipams of specific type","enum":["netbox","phpipam","pve"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/ipams/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{ipam}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"ipam":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f7bbab76fe9076cf3674d4ddd796fecd1dddc2521e708f5b995b3c623dbd0319","description":"Create a new sdn ipam object.","extra":{},"name":"create","parameters":[{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-ipam-id","properties":{},"type":"string"},"name":"ipam"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"section"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"},{"definition":{"description":"Plugin type.","enum":["netbox","phpipam","pve"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["perm","/sdn/ipams",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/ipams"},{"extra":{},"methods":[{"allow_token":true,"checksum":"02da5207be93d63cb52d2e2ffe9ddcd11d1fe46bf238811457b52efa44753926","description":"Delete sdn ipam object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-ipam-id","properties":{},"type":"string"},"name":"ipam"}],"permissions":{"expression":{"check":["perm","/sdn/ipams",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"6b0cd8f67bfc09eea4cf6d833cbf185c78ad36625225e852696671085c14793a","description":"Read sdn ipam configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-ipam-id","properties":{},"type":"string"},"name":"ipam"}],"permissions":{"expression":{"check":["perm","/sdn/ipams/{ipam}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"3199eaaa93c29c822999ea7ef1e7accf14f2bb7a43e322d7b2f8a433448d984f","description":"Update sdn ipam object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-ipam-id","properties":{},"type":"string"},"name":"ipam"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"section"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"token"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"url"}],"permissions":{"expression":{"check":["perm","/sdn/ipams",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/ipams/{ipam}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c52019e12ec302d51a715169863033bf12e24ac592bc2971022c94ad5aa1ca40","description":"List PVE IPAM Entries","extra":{},"name":"ipamindex","parameters":[{"definition":{"description":"The SDN ipam object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-ipam-id","properties":{},"type":"string"},"name":"ipam"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/sdn/ipams/{ipam}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"35789459d553372c9f1f7dfb44c53fd6a3ebb8fce0d31e0496333a82d2149240","description":"SDN vnets index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{vnet}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"86b5a2cc7a9e48b18457ff12feda3906d3ae4c5d741b26dd5901a7995eee958f","description":"Create a new sdn vnet object.","extra":{},"name":"create","parameters":[{"definition":{"description":"alias name of the vnet","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})","properties":{},"type":"string"},"name":"alias"},{"definition":{"description":"If true, sets the isolated property for all members of this VNet","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"isolate-ports"},{"definition":{"description":"vlan or vxlan id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"tag"},{"definition":{"description":"Type","enum":["vnet"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"Allow vm VLANs to pass through this vnet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"vlanaware"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"},{"definition":{"description":"zone id","enum":[],"extra":{"typetext":""},"optional":false,"properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/vnets"},{"extra":{},"methods":[{"allow_token":true,"checksum":"da877a3bc314386246845102eb0fa712a5b6bedf41a05237c17a8f7e3b132aae","description":"Delete sdn vnet object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Require 'SDN.Allocate' permission on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f5ee87298b99f638a443b6b03951db75b1d52777317d851a63e19a7f08752fb3","description":"Read sdn vnet configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"1642fc14eb2775f940104d986caa1e499536827c2e16c9331e1bdbdf63998811","description":"Update sdn vnet object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"alias name of the vnet","enum":[],"extra":{},"max_length":256,"optional":true,"pattern":"(?^i:[\\(\\)-_.\\w\\d\\s]{0,256})","properties":{},"type":"string"},"name":"alias"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"If true, sets the isolated property for all members of this VNet","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"isolate-ports"},{"definition":{"description":"vlan or vxlan id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"tag"},{"definition":{"description":"Allow vm VLANs to pass through this vnet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"vlanaware"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"},{"definition":{"description":"zone id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"zone"}],"permissions":{"description":"Require 'SDN.Allocate' permission on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/vnets/{vnet}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6c925e12bd374571292366848e1ac865fb0229b6dedb9d4cde10503893522cf6","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/sdn/vnets/{vnet}/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c0cab9f0918e5f7930cb7afa0bf62097cecca7da4c064ab71bfcfacf2eb56e6a","description":"Get vnet firewall options.","extra":{},"name":"get_options","parameters":[{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"enable":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"log_level_forward":{"description":"Log level for forwarded traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"policy_forward":{"description":"Forward policy.","enum":["ACCEPT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"95ae8196f4f9fb4e9c2e9c33bff33e25a86fa15145facb1c16d07e2a9be47b42","description":"Set Firewall options.","extra":{},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Log level for forwarded traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_forward"},{"definition":{"description":"Forward policy.","enum":["ACCEPT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_forward"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Needs SDN.Allocate permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/vnets/{vnet}/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4b504fb927d7dca8f921390236f980412256d061f0dfddb8e8355506b46818ce","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"a2a716852b677eb2cdaf25abe2858643f34901d3993587b1e2a25fe4b52f2bea","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Needs SDN.Allocate permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/vnets/{vnet}/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4d8e8fac059cbc0be99b6889ddb4c26eb6561f12f5cfc5eed863ea3dc3988732","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Needs SDN.Allocate permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"de93ee5cf59c115f0b57c1e372496467d9ff7e7ae102b79366a9f07fe12f1752","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"70c7c1adc041463df06dc3027b46c5f9c5b47fb8d18d22cdf5170a75c544b6e5","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Needs SDN.Allocate permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a423dac64ba5ecc16a6dac2b732a6bfea1020c495163272276cce2bac51baa0a","description":"Delete IP Mappings in a VNet","extra":{},"name":"ipdelete","parameters":[{"definition":{"description":"The IP address to delete","enum":[],"extra":{"typetext":""},"format":"ip","properties":{},"type":"string"},"name":"ip"},{"definition":{"description":"Unicast MAC address.","enum":[],"extra":{"format_description":"XX:XX:XX:XX:XX:XX","typetext":"","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"format":"mac-addr","optional":true,"properties":{},"type":"string"},"name":"mac"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}/{vnet}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"5a463f284f763ca8809c3a41d8862e76c8d0e4d5875c64b38265e6fe785abe17","description":"Create IP Mapping in a VNet","extra":{},"name":"ipcreate","parameters":[{"definition":{"description":"The IP address to associate with the given MAC address","enum":[],"extra":{"typetext":""},"format":"ip","properties":{},"type":"string"},"name":"ip"},{"definition":{"description":"Unicast MAC address.","enum":[],"extra":{"format_description":"XX:XX:XX:XX:XX:XX","typetext":"","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"format":"mac-addr","optional":true,"properties":{},"type":"string"},"name":"mac"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}/{vnet}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"a3611f7da20f067706c01dd97dddcaef22842c37152d79080a507aac5304ee74","description":"Update IP Mapping in a VNet","extra":{},"name":"ipupdate","parameters":[{"definition":{"description":"The IP address to associate with the given MAC address","enum":[],"extra":{"typetext":""},"format":"ip","properties":{},"type":"string"},"name":"ip"},{"definition":{"description":"Unicast MAC address.","enum":[],"extra":{"format_description":"XX:XX:XX:XX:XX:XX","typetext":"","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"format":"mac-addr","optional":true,"properties":{},"type":"string"},"name":"mac"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}/{vnet}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/vnets/{vnet}/ips"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dbc42ffbbbf8732f97a99cbce09763d0f6a8ebe6f19177715a24fe26a7100159","description":"SDN subnets index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subnet}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"ef45b8541c99ae856ecd698d8ca1e5fc068d868f77c275f469081baf681e0952","description":"Create a new sdn subnet object.","extra":{},"name":"create","parameters":[{"definition":{"description":"IP address for the DNS server","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"dhcp-dns-server"},{"definition":{"description":"A list of DHCP ranges for this subnet","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-sdn-dhcp-range","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"dhcp-range"},{"definition":{"description":"dns domain zone prefix ex: 'adm' -> .adm.mydomain.com","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"dnszoneprefix"},{"definition":{"description":"Subnet Gateway: Will be assign on vnet for layer3 zones","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"gateway"},{"definition":{"description":"enable masquerade for this subnet if pve-firewall","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"snat"},{"definition":{"description":"The SDN subnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-subnet-id","properties":{},"type":"string"},"name":"subnet"},{"definition":{"enum":["subnet"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"associated vnet","enum":[],"extra":{"typetext":""},"optional":false,"properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Require 'SDN.Allocate' permission on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/vnets/{vnet}/subnets"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7996cd14093bf8ad3a430dd245da05c37c7cbbc4a8b399233adcfece13018520","description":"Delete sdn subnet object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN subnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-subnet-id","properties":{},"type":"string"},"name":"subnet"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Require 'SDN.Allocate' permission on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"219b2a392ea717c0b31186fced0214df37a6737b9bc9b4a22f5d124e094e92cd","description":"Read sdn subnet configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"The SDN subnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-subnet-id","properties":{},"type":"string"},"name":"subnet"},{"definition":{"description":"The SDN vnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-vnet-id","properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"224cc9c3494937a9ba1fdb9f5f27b7323a01e59340392d513632ff9bcfa46779","description":"Update sdn subnet object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"IP address for the DNS server","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"dhcp-dns-server"},{"definition":{"description":"A list of DHCP ranges for this subnet","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"format":"pve-sdn-dhcp-range","properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"dhcp-range"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"dns domain zone prefix ex: 'adm' -> .adm.mydomain.com","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"dnszoneprefix"},{"definition":{"description":"Subnet Gateway: Will be assign on vnet for layer3 zones","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"gateway"},{"definition":{"description":"enable masquerade for this subnet if pve-firewall","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"snat"},{"definition":{"description":"The SDN subnet object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-subnet-id","properties":{},"type":"string"},"name":"subnet"},{"definition":{"description":"associated vnet","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"vnet"}],"permissions":{"description":"Require 'SDN.Allocate' permission on '/sdn/zones//'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/vnets/{vnet}/subnets/{subnet}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9372d8f825a3dffbbbc704fbf00fa7afd465c12454b5133bf826e1fcfb495636","description":"SDN zones index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"Only list SDN zones of specific type","enum":["evpn","faucet","qinq","simple","vlan","vxlan"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{zone}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"dhcp":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dns":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dnszone":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipam":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mtu":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"nodes":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pending":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"reversedns":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"state":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"},"zone":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"3062474e1cab1ed49b1c04a99ffa29327fdc8bff1b5849c1897838f79f17252c","description":"Create a new sdn zone object.","extra":{},"name":"create","parameters":[{"definition":{"description":"Advertise evpn subnets if you have silent hosts","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"advertise-subnets"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"bridge"},{"definition":{"description":"Disable auto mac learning.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bridge-disable-mac-learning"},{"definition":{"description":"Frr router name","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"Type of the DHCP backend for this zone","enum":["dnsmasq"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"dhcp"},{"definition":{"description":"Disable ipv4 arp && ipv6 neighbour discovery suppression","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable-arp-nd-suppression"},{"definition":{"description":"dns api server","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dns"},{"definition":{"description":"dns domain zone ex: mydomain.com","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"dnszone"},{"definition":{"description":"Faucet dataplane id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"dp-id"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"exitnodes"},{"definition":{"description":"Allow exitnodes to connect to evpn guests","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"exitnodes-local-routing"},{"definition":{"description":"Force traffic to this exitnode first.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"exitnodes-primary"},{"definition":{"description":"use a specific ipam","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ipam"},{"definition":{"description":"Anycast logical router mac address","enum":[],"extra":{"typetext":""},"format":"mac-addr","optional":true,"properties":{},"type":"string"},"name":"mac"},{"definition":{"description":"MTU","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"peers address list.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"peers"},{"definition":{"description":"reverse dns api server","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"reversedns"},{"definition":{"description":"Route-Target import","enum":[],"extra":{"typetext":""},"format":"pve-sdn-bgp-rt-list","optional":true,"properties":{},"type":"string"},"name":"rt-import"},{"definition":{"description":"Service-VLAN Tag","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"tag"},{"definition":{"description":"Plugin type.","enum":["evpn","faucet","qinq","simple","vlan","vxlan"],"extra":{},"format":"pve-configid","properties":{},"type":"string"},"name":"type"},{"definition":{"default":"802.1q","enum":["802.1q","802.1ad"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"vlan-protocol"},{"definition":{"description":"l3vni.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"vrf-vxlan"},{"definition":{"description":"Vxlan tunnel udp port (default 4789).","enum":[],"extra":{"typetext":" (1 - 65536)"},"maximum":65536,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vxlan-port"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/cluster/sdn/zones"},{"extra":{},"methods":[{"allow_token":true,"checksum":"29d4c8e5addeb52954911bda12012735580a1f65a66ea4c4280921067149579e","description":"Delete sdn zone object configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"38131dcce447712ecf268c650a95c5166219287eacc37bc414317b3c94239a9f","description":"Read sdn zone configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"Display pending config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"pending"},{"definition":{"description":"Display running config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"running"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"2e72318be5088df47e52a2c95ab9cb3de6847be6142042bfaa6b427543560ce0","description":"Update sdn zone object configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"Advertise evpn subnets if you have silent hosts","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"advertise-subnets"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"bridge"},{"definition":{"description":"Disable auto mac learning.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bridge-disable-mac-learning"},{"definition":{"description":"Frr router name","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"controller"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Type of the DHCP backend for this zone","enum":["dnsmasq"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"dhcp"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Disable ipv4 arp && ipv6 neighbour discovery suppression","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable-arp-nd-suppression"},{"definition":{"description":"dns api server","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dns"},{"definition":{"description":"dns domain zone ex: mydomain.com","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"dnszone"},{"definition":{"description":"Faucet dataplane id","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"dp-id"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"exitnodes"},{"definition":{"description":"Allow exitnodes to connect to evpn guests","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"exitnodes-local-routing"},{"definition":{"description":"Force traffic to this exitnode first.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"exitnodes-primary"},{"definition":{"description":"use a specific ipam","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ipam"},{"definition":{"description":"Anycast logical router mac address","enum":[],"extra":{"typetext":""},"format":"mac-addr","optional":true,"properties":{},"type":"string"},"name":"mac"},{"definition":{"description":"MTU","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"List of cluster node names.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"peers address list.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"peers"},{"definition":{"description":"reverse dns api server","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"reversedns"},{"definition":{"description":"Route-Target import","enum":[],"extra":{"typetext":""},"format":"pve-sdn-bgp-rt-list","optional":true,"properties":{},"type":"string"},"name":"rt-import"},{"definition":{"description":"Service-VLAN Tag","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"tag"},{"definition":{"default":"802.1q","enum":["802.1q","802.1ad"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"vlan-protocol"},{"definition":{"description":"l3vni.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"vrf-vxlan"},{"definition":{"description":"Vxlan tunnel udp port (default 4789).","enum":[],"extra":{"typetext":" (1 - 65536)"},"maximum":65536,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vxlan-port"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/cluster/sdn/zones/{zone}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5a589a6f8ca9ac2030fd4d33ef13a80e575465992929b29725526face0399cc5","description":"Get cluster status information.","extra":{},"name":"get_status","parameters":[],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"ip":{"description":"[node] IP of the resolved nodename.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"level":{"description":"[node] Proxmox VE Subscription level, indicates if eligible for enterprise support as well as access to the stable Proxmox VE Enterprise Repository.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"local":{"description":"[node] Indicates if this is the responding node.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"nodeid":{"description":"[node] ID of the node from the corosync configuration.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"nodes":{"description":"[cluster] Nodes count, including offline nodes.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"online":{"description":"[node] Indicates if the node is online or offline.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"quorate":{"description":"[cluster] Indicates if there is a majority of nodes online to make decisions","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"type":{"description":"Indicates the type, either cluster or node. The type defines the object properties e.g. quorate available for type cluster.","enum":["cluster","node"],"extra":{},"properties":{},"type":"string"},"version":{"description":"[cluster] Current version of the corosync configuration file.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d04c3b849a0aa5e5920867f414fba45c484719be08796bcbeaf8832f5833fe88","description":"List recent tasks (cluster wide).","extra":{},"name":"tasks","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"upid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/cluster/tasks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"31b002c17296ec68232ef7ac7414c584f56baeeefffa7dc7edd05d8ce5e5f183","description":"Cluster node index.","extra":{},"name":"index","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{node}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cpu":{"description":"CPU utilization.","enum":[],"extra":{"renderer":"fraction_as_percentage"},"optional":true,"properties":{},"type":"number"},"level":{"description":"Support level.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxcpu":{"description":"Number of available CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Number of available memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"mem":{"description":"Used memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"node":{"description":"The cluster node name.","enum":[],"extra":{},"format":"pve-node","properties":{},"type":"string"},"ssl_fingerprint":{"description":"The SSL fingerprint for the node certificate.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"status":{"description":"Node status.","enum":["unknown","online","offline"],"extra":{},"properties":{},"type":"string"},"uptime":{"description":"Node uptime in seconds.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes"},{"extra":{},"methods":[{"allow_token":true,"checksum":"407b3d66a300b7bc4f15ce81eadffc3e3ff161e7940cd646fc925a219be029f3","description":"Node index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"35b8e469447bd0b2011a8dfbb2d764cd4c5d26a960c23bfb523d2b8c078bbaf0","description":"Get list of appliances.","extra":{"proxyto":"node"},"name":"aplinfo","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"00f31028c241d16f472be5f801c7ca88ff829df797400ed826b4eb2177807889","description":"Download appliance templates.","extra":{"proxyto":"node"},"name":"apl_download","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage where the template will be stored","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"The template which will downloaded","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"template"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.AllocateTemplate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/aplinfo"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9fba10841493cc0c3608fd5b429677bf1e44b64bc3298479603a5da713b6c7e6","description":"Directory index for apt (Advanced Package Tool).","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/apt"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a2d6c099458fd722c750e1161be41fe0d364c22884858a3a0828f0f52cb8da10","description":"Get package changelogs.","extra":{"proxyto":"node"},"name":"changelog","parameters":[{"definition":{"description":"Package name.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Package version.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"version"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/apt/changelog"},{"extra":{},"methods":[{"allow_token":true,"checksum":"31afb6060270acc12e023a6b7f2e929996e408352872438f6456b06ca9790cd0","description":"Get APT repository information.","extra":{"proxyto":"node"},"name":"repositories","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"description":"Result from parsing the APT repository files in /etc/apt/.","enum":[],"extra":{},"properties":{"digest":{"description":"Common digest of all files.","enum":[],"extra":{},"properties":{},"type":"string"},"errors":{"description":"List of problematic repository files.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"error":{"description":"The error message","enum":[],"extra":{},"properties":{},"type":"string"},"path":{"description":"Path to the problematic file.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"files":{"description":"List of parsed repository files.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"digest":{"description":"Digest of the file as bytes.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"integer"},"properties":{},"type":"array"},"file-type":{"description":"Format of the file.","enum":["list","sources"],"extra":{},"properties":{},"type":"string"},"path":{"description":"Path to the problematic file.","enum":[],"extra":{},"properties":{},"type":"string"},"repositories":{"description":"The parsed repositories.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"Comment":{"description":"Associated comment","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"Components":{"description":"List of repository components","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"Enabled":{"description":"Whether the repository is enabled or not","enum":[],"extra":{},"properties":{},"type":"boolean"},"FileType":{"description":"Format of the defining file.","enum":["list","sources"],"extra":{},"properties":{},"type":"string"},"Options":{"description":"Additional options","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"Key":{"enum":[],"extra":{},"properties":{},"type":"string"},"Values":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"Suites":{"description":"List of package distribuitions","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"Types":{"description":"List of package types.","enum":[],"extra":{},"items":{"enum":["deb","deb-src"],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"URIs":{"description":"List of repository URIs.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"properties":{},"type":"array"},"infos":{"description":"Additional information/warnings for APT repositories.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"index":{"description":"Index of the associated repository within the file.","enum":[],"extra":{},"properties":{},"type":"string"},"kind":{"description":"Kind of the information (e.g. warning).","enum":[],"extra":{},"properties":{},"type":"string"},"message":{"description":"Information message.","enum":[],"extra":{},"properties":{},"type":"string"},"path":{"description":"Path to the associated file.","enum":[],"extra":{},"properties":{},"type":"string"},"property":{"description":"Property from which the info originates.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"standard-repos":{"description":"List of standard repositories and their configuration status","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"handle":{"description":"Handle to identify the repository.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Full name of the repository.","enum":[],"extra":{},"properties":{},"type":"string"},"status":{"description":"Indicating enabled/disabled status, if the repository is configured.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"2e6c839d6bc3336bbd44277a870b0c9286a191be1f0ab21bc059a03be572b892","description":"Change the properties of a repository. Currently only allows enabling/disabling.","extra":{"proxyto":"node"},"name":"change_repository","parameters":[{"definition":{"description":"Digest to detect modifications.","enum":[],"extra":{"typetext":""},"max_length":80,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Whether the repository should be enabled or not.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"description":"Index within the file (starting from 0).","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"index"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Path to the containing file.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"path"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"fe3a49714d62a93527594a310f2dafe8786e91acabd0932a1d50d07073dca22d","description":"Add a standard repository to the configuration","extra":{"proxyto":"node"},"name":"add_repository","parameters":[{"definition":{"description":"Digest to detect modifications.","enum":[],"extra":{"typetext":""},"max_length":80,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Handle that identifies a repository.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"handle"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/apt/repositories"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b67270ad2512c5a995135eb26fb3729c5d8711de50412275d659531302779e2a","description":"List available updates.","extra":{"proxyto":"node"},"name":"list_updates","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"09f04ca9f5dcb082fe70acb881878e191627a740681aa9102b533d1d2f8fc8af","description":"This is used to resynchronize the package index files from their sources (apt-get update).","extra":{"proxyto":"node"},"name":"update_database","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Send notification about new packages.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"notify"},{"definition":{"default":0,"description":"Only produces output suitable for logging, omitting progress indicators.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"quiet"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/apt/update"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f99cfcd0bb0ec2bf579674fc6cfd8c56025b24f68e28984c5318e468a369fa24","description":"Get package information for important Proxmox packages.","extra":{"proxyto":"node"},"name":"versions","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/apt/versions"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8323065d812e5e1377041e57ec0822474ada502b7d6d00636fe213e047e9de68","description":"Node capabilities index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/capabilities"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e27a6b54ddd6b980e5e1d7ddede6947b8cf3f81dc2cf5a3b59b263186afae2d7","description":"QEMU capabilities index.","extra":{},"name":"qemu_caps_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/capabilities/qemu"},{"extra":{},"methods":[{"allow_token":true,"checksum":"927d1325a9a50865ae950f9d9ec8be45d125376424b8b48420d3105b711ba85e","description":"List all custom and default CPU models.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Only returns custom models when the current user has Sys.Audit on /nodes.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"custom":{"description":"True if this is a custom CPU model.","enum":[],"extra":{},"properties":{},"type":"boolean"},"name":{"description":"Name of the CPU model. Identifies it for subsequent API calls. Prefixed with 'custom-' for custom models.","enum":[],"extra":{},"properties":{},"type":"string"},"vendor":{"description":"CPU vendor visible to the guest when this model is selected. Vendor of 'reported-model' in case of custom models.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/capabilities/qemu/cpu"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f73f392cef5512b8a9f7eaf223160baa4249b227ea25c40c8c0de79f730c9b85","description":"Get available QEMU/KVM machine types.","extra":{"proxyto":"node"},"name":"types","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"changes":{"description":"Notable changes of a version, currently only set for +pveX versions.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"description":"Full name of machine type and version.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The machine type.","enum":["q35","i440fx"],"extra":{},"properties":{},"type":"string"},"version":{"description":"The machine version.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/capabilities/qemu/machines"},{"extra":{},"methods":[{"allow_token":true,"checksum":"50808c982a4bc72c9bba3f95d85803db4a5a6d9897255ac750c522b0369f4f21","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph"},{"extra":{},"methods":[{"allow_token":true,"checksum":"23dca6507cde2ae0cabadf81020c2e06e2c8878c3e19c7356ba7dbc49c506a9a","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/cfg"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0a6db46755187dc915b8cc1af63033dc1d37ca5142fa6f5d6316de794dcefc35","description":"Get the Ceph configuration database.","extra":{"proxyto":"node"},"name":"db","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"can_update_at_runtime":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"level":{"enum":[],"extra":{},"properties":{},"type":"string"},"mask":{"enum":[],"extra":{},"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"section":{"enum":[],"extra":{},"properties":{},"type":"string"},"value":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/cfg/db"},{"extra":{},"methods":[{"allow_token":true,"checksum":"566ab98133cdf7bf8664225da85a43166f5b253cad7a29e5b5d58b8f36b11786","description":"Get the Ceph configuration file.","extra":{"proxyto":"node"},"name":"raw","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/ceph/cfg/raw"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dddf11f5ca592eb70a276010f716a4491a395821266e213ac9fc5ea3e36f149e","description":"Get configured values from either the config file or config DB.","extra":{"proxyto":"node"},"name":"value","parameters":[{"definition":{"description":"List of
: items.","enum":[],"extra":{"typetext":"
:[;
:]"},"pattern":"(?^:^(:?(?^i:[0-9a-z\\-_\\.]+:[0-9a-zA-Z\\-_]+))(:?[;, ](?^i:[0-9a-z\\-_\\.]+:[0-9a-zA-Z\\-_]+))*$)","properties":{},"type":"string"},"name":"config-keys"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"description":"Contains {section}->{key} children with the values","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/cfg/value"},{"extra":{},"methods":[{"allow_token":true,"checksum":"98c0d6719a80dc5b3088ba5c5793892bf04a7a07a42dfbb37861b5797b0a69f8","description":"Heuristical check if it is safe to perform an action.","extra":{"proxyto":"node"},"name":"cmd_safety","parameters":[{"definition":{"description":"Action to check","enum":["stop","destroy"],"extra":{},"properties":{},"type":"string"},"name":"action"},{"definition":{"description":"ID of the service","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service type","enum":["osd","mon","mds"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"safe":{"description":"If it is safe to run the command.","enum":[],"extra":{},"properties":{},"type":"boolean"},"status":{"description":"Status message given by Ceph.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/cmd-safety"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e0322c6f07c65f5c1619204f0c7e670156521f47e8951f35563c74787459eefd","description":"Get OSD crush map","extra":{"proxyto":"node"},"name":"crush","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/ceph/crush"},{"extra":{},"methods":[{"allow_token":true,"checksum":"26fe33f0ff9494d29cd6768124890f101bf0ce6aa94b0171689a06f41af1e95f","description":"Directory index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"data_pool":{"description":"The name of the data pool.","enum":[],"extra":{},"properties":{},"type":"string"},"metadata_pool":{"description":"The name of the metadata pool.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"The ceph filesystem name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/fs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a5b590d7b03fcb44ed813d6baec46ceeaa5bca5046b562d1a281ac2004a7c86b","description":"Create a Ceph filesystem","extra":{"proxyto":"node"},"name":"createfs","parameters":[{"definition":{"default":0,"description":"Configure the created CephFS as storage for this cluster.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add-storage"},{"definition":{"default":"cephfs","description":"The ceph filesystem name.","enum":[],"extra":{},"optional":true,"pattern":"(?^:^[^:/\\s]+$)","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":128,"description":"Number of placement groups for the backing data pool. The metadata pool will use a quarter of this.","enum":[],"extra":{"typetext":" (8 - 32768)"},"maximum":32768,"minimum":8,"optional":true,"properties":{},"type":"integer"},"name":"pg_num"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/fs/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6c2ec3e3960ce78b457e0dc6ece73e2a71c5994ce3b3b23fc63b18ac3a5e8c73","description":"Create initial ceph default configuration and setup symlinks.","extra":{"proxyto":"node"},"name":"init","parameters":[{"definition":{"description":"Declare a separate cluster network, OSDs will routeheartbeat, object replication and recovery traffic over it","enum":[],"extra":{"requires":"network","typetext":""},"format":"CIDR","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"cluster-network"},{"definition":{"default":0,"description":"Disable cephx authentication.\n\nWARNING: cephx is a security feature protecting against man-in-the-middle attacks. Only consider disabling cephx if your network is private!","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable_cephx"},{"definition":{"default":2,"description":"Minimum number of available replicas per object to allow I/O","enum":[],"extra":{"typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"min_size"},{"definition":{"description":"Use specific network for all ceph related traffic","enum":[],"extra":{"typetext":""},"format":"CIDR","max_length":128,"optional":true,"properties":{},"type":"string"},"name":"network"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":6,"description":"Placement group bits, used to specify the default number of placement groups.\n\nDepreacted. This setting was deprecated in recent Ceph versions.","enum":[],"extra":{"typetext":" (6 - 14)"},"maximum":14,"minimum":6,"optional":true,"properties":{},"type":"integer"},"name":"pg_bits"},{"definition":{"default":3,"description":"Targeted number of replicas per object","enum":[],"extra":{"typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"size"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/init"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8a31ac771c928fe9eb6235d17a52ecaf2ae45e2169ec83ac019a01378dd9c35a","description":"Read ceph log","extra":{"proxyto":"node"},"name":"log","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"572f311d8fc0eb7f66a89e38bda2cd329ee39d8ba4a8025ce6713bf3f7d6c1be","description":"MDS directory index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"addr":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"host":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"The name (ID) for the MDS","enum":[],"extra":{},"properties":{}},"rank":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"standby_replay":{"description":"If true, the standby MDS is polling the active MDS for faster recovery (hot standby).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"state":{"description":"State of the MDS","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/mds"},{"extra":{},"methods":[{"allow_token":true,"checksum":"95bfdf6b725d610975f2cb9b78b5c858072ceb2d7fa1e721df8554522b7ff936","description":"Destroy Ceph Metadata Server","extra":{"proxyto":"node"},"name":"destroymds","parameters":[{"definition":{"description":"The name (ID) of the mds","enum":[],"extra":{},"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"9c3ec6795adb762b6e5f1367b947a261fc983bf1377a29f675353f65636f8e77","description":"Create Ceph Metadata Server (MDS)","extra":{"proxyto":"node"},"name":"createmds","parameters":[{"definition":{"default":"0","description":"Determines whether a ceph-mds daemon should poll and replay the log of an active MDS. Faster switch on MDS failure, but needs more idle resources.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"hotstandby"},{"definition":{"default":"nodename","description":"The ID for the mds, when omitted the same as the nodename","enum":[],"extra":{},"max_length":200,"optional":true,"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/mds/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"66c37a28e4da09b1f5d9ed47d7aa6d37f754c5fad2f1d951d8dfd682cc4ae54a","description":"MGR directory index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"addr":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"host":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"description":"The name (ID) for the MGR","enum":[],"extra":{},"properties":{}},"state":{"description":"State of the MGR","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/mgr"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1b6eac6b4b1058f7d0564b86f899fc1c39d08317e8482afa20115de4fd4c5f3c","description":"Destroy Ceph Manager.","extra":{"proxyto":"node"},"name":"destroymgr","parameters":[{"definition":{"description":"The ID of the manager","enum":[],"extra":{},"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"9a9667c69cb29e5a499d6a2369ff4f46790bf4fd55e6b6364daaf2846d1e86f4","description":"Create Ceph Manager","extra":{"proxyto":"node"},"name":"createmgr","parameters":[{"definition":{"description":"The ID for the manager, when omitted the same as the nodename","enum":[],"extra":{},"max_length":200,"optional":true,"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/mgr/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"06bf64866d2a3b4d94987e41f6bd86edd908e439943193b47a70294b6c519ae8","description":"Get Ceph monitor list.","extra":{"proxyto":"node"},"name":"listmon","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"addr":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ceph_version":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ceph_version_short":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"direxists":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"host":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"quorum":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"rank":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"service":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"state":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/mon"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0f5ae748cffda16f98dc9978fd9e9abc28c3131e1e102f2ebe3fbf965db5b663","description":"Destroy Ceph Monitor and Manager.","extra":{"proxyto":"node"},"name":"destroymon","parameters":[{"definition":{"description":"Monitor ID","enum":[],"extra":{},"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"monid"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"da2a2ad7e4477ad2aa7b3b1f28cf3ce7e9ae03cb7c553f98f26071d6ad2c4056","description":"Create Ceph Monitor and Manager","extra":{"proxyto":"node"},"name":"createmon","parameters":[{"definition":{"description":"Overwrites autodetected monitor IP address(es). Must be in the public network(s) of Ceph.","enum":[],"extra":{"typetext":""},"format":"ip-list","optional":true,"properties":{},"type":"string"},"name":"mon-address"},{"definition":{"description":"The ID for the monitor, when omitted the same as the nodename","enum":[],"extra":{},"max_length":200,"optional":true,"pattern":"[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?","properties":{},"type":"string"},"name":"monid"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/mon/{monid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4c731af45d22963c4c9ff4d2c9e8f3eb4464b1e7e3c4b462fa0ac18c0a67ce24","description":"Get Ceph osd list/tree.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"flags":{"enum":[],"extra":{},"properties":{},"type":"string"},"root":{"description":"Tree with OSDs in the CRUSH map structure.","enum":[],"extra":{},"properties":{},"type":"object"}},"type":"object"},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"d78b83ffb41c0dc12fb4b09830b3cb6a5cc74f83857d52b4c593e6d551ac54bb","description":"Create OSD","extra":{"proxyto":"node"},"name":"createosd","parameters":[{"definition":{"description":"Set the device class of the OSD in crush.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"crush-device-class"},{"definition":{"description":"Block device name for block.db.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"db_dev"},{"definition":{"default":"bluestore_block_db_size or 10% of OSD size","description":"Size in GiB for block.db.","enum":[],"extra":{"requires":"db_dev","typetext":" (1 - N)","verbose_description":"If a block.db is requested but the size is not given, will be automatically selected by: bluestore_block_db_size from the ceph database (osd or global section) or config (osd or global section) in that order. If this is not available, it will be sized 10% of the size of the OSD device. Fails if the available size is not enough."},"minimum":1,"optional":true,"properties":{},"type":"number"},"name":"db_dev_size"},{"definition":{"description":"Block device name.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"dev"},{"definition":{"default":0,"description":"Enables encryption of the OSD.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"encrypted"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD services per physical device. Only useful for fast NVMe devices\"\n\t\t .\" to utilize their performance better.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"osds-per-device"},{"definition":{"description":"Block device name for block.wal.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"wal_dev"},{"definition":{"default":"bluestore_block_wal_size or 1% of OSD size","description":"Size in GiB for block.wal.","enum":[],"extra":{"requires":"wal_dev","typetext":" (0.5 - N)","verbose_description":"If a block.wal is requested but the size is not given, will be automatically selected by: bluestore_block_wal_size from the ceph database (osd or global section) or config (osd or global section) in that order. If this is not available, it will be sized 1% of the size of the OSD device. Fails if the available size is not enough."},"minimum":0.5,"optional":true,"properties":{},"type":"number"},"name":"wal_dev_size"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/osd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ad8e2808277aa89b9d2fe58df7fe5a889cd128fd7b21e68ac6e2fd628f18125b","description":"Destroy OSD","extra":{"proxyto":"node"},"name":"destroyosd","parameters":[{"definition":{"default":0,"description":"If set, we remove partition table entries.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"b0f0250fd1edc6d6565b0c04f6252bdec7e416f3d6f5b2209aff3559cf79b1a7","description":"OSD index.","extra":{},"name":"osdindex","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/osd/{osdid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bf7b180ff0f405fde06dc5d87505bd8ab58b5d1502106abd87441f78d23f5e26","description":"ceph osd in","extra":{"proxyto":"node"},"name":"in","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/osd/{osdid}/in"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5836bad68fa9724eac7f11cc92c5cd8dc2364d7f44ddc9a2e0e45627a167922f","description":"Get OSD volume details","extra":{"proxyto":"node"},"name":"osdvolume","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"},{"definition":{"default":"block","description":"OSD device type","enum":["block","db","wal"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"creation_time":{"description":"Creation time as reported by `lvs`.","enum":[],"extra":{},"properties":{},"type":"string"},"lv_name":{"description":"Name of the logical volume (LV).","enum":[],"extra":{},"properties":{},"type":"string"},"lv_path":{"description":"Path to the logical volume (LV).","enum":[],"extra":{},"properties":{},"type":"string"},"lv_size":{"description":"Size of the logical volume (LV).","enum":[],"extra":{},"properties":{},"type":"integer"},"lv_uuid":{"description":"UUID of the logical volume (LV).","enum":[],"extra":{},"properties":{},"type":"string"},"vg_name":{"description":"Name of the volume group (VG).","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/osd/{osdid}/lv-info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"363748f4c0625f5db816e30cd1e564a8ac21f5bc56f18f1e13b291726a256f9c","description":"Get OSD details","extra":{"proxyto":"node"},"name":"osddetails","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"devices":{"description":"Array containing data about devices","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"dev_node":{"description":"Device node","enum":[],"extra":{},"properties":{},"type":"string"},"device":{"description":"Kind of OSD device","enum":["block","db","wal"],"extra":{},"properties":{},"type":"string"},"devices":{"description":"Physical disks used","enum":[],"extra":{},"properties":{},"type":"string"},"size":{"description":"Size in bytes","enum":[],"extra":{},"properties":{},"type":"integer"},"support_discard":{"description":"Discard support of the physical device","enum":[],"extra":{},"properties":{},"type":"boolean"},"type":{"description":"Type of device. For example, hdd or ssd","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"osd":{"description":"General information about the OSD","enum":[],"extra":{},"properties":{"back_addr":{"description":"Address and port used to talk to other OSDs.","enum":[],"extra":{},"properties":{},"type":"string"},"front_addr":{"description":"Address and port used to talk to clients and monitors.","enum":[],"extra":{},"properties":{},"type":"string"},"hb_back_addr":{"description":"Heartbeat address and port for other OSDs.","enum":[],"extra":{},"properties":{},"type":"string"},"hb_front_addr":{"description":"Heartbeat address and port for clients and monitors.","enum":[],"extra":{},"properties":{},"type":"string"},"hostname":{"description":"Name of the host containing the OSD.","enum":[],"extra":{},"properties":{},"type":"string"},"id":{"description":"ID of the OSD.","enum":[],"extra":{},"properties":{},"type":"integer"},"mem_usage":{"description":"Memory usage of the OSD service.","enum":[],"extra":{},"properties":{},"type":"integer"},"osd_data":{"description":"Path to the OSD's data directory.","enum":[],"extra":{},"properties":{},"type":"string"},"osd_objectstore":{"description":"The type of object store used.","enum":[],"extra":{},"properties":{},"type":"string"},"pid":{"description":"OSD process ID.","enum":[],"extra":{},"properties":{},"type":"integer"},"version":{"description":"Ceph version of the OSD service.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/osd/{osdid}/metadata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"23d8222b59c8aab7050f8c7415d7e3d12494cab703c1ee49bb4be15f1b666800","description":"ceph osd out","extra":{"proxyto":"node"},"name":"out","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/osd/{osdid}/out"},{"extra":{},"methods":[{"allow_token":true,"checksum":"60019df48da0442ab7a3f116bc02cc627d89cc4c978434e73175e44fa0e2107b","description":"Instruct the OSD to scrub.","extra":{"proxyto":"node"},"name":"scrub","parameters":[{"definition":{"default":0,"description":"If set, instructs a deep scrub instead of a normal one.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"deep"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"OSD ID","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"osdid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/ceph/osd/{osdid}/scrub"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bfeafc5a2851d4149ce8b6da7275a7c90e2e486b0299edd8e633dd9e306a62b6","description":"List all pools and their settings (which are settable by the POST/PUT endpoints).","extra":{"proxyto":"node"},"name":"lspools","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{pool_name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"application_metadata":{"enum":[],"extra":{"title":"Associated Applications"},"optional":true,"properties":{},"type":"object"},"autoscale_status":{"enum":[],"extra":{"title":"Autoscale Status"},"optional":true,"properties":{},"type":"object"},"bytes_used":{"enum":[],"extra":{"title":"Used"},"properties":{},"type":"integer"},"crush_rule":{"enum":[],"extra":{"title":"Crush Rule"},"properties":{},"type":"integer"},"crush_rule_name":{"enum":[],"extra":{"title":"Crush Rule Name"},"properties":{},"type":"string"},"min_size":{"enum":[],"extra":{"title":"Min Size"},"properties":{},"type":"integer"},"percent_used":{"enum":[],"extra":{"title":"%-Used"},"properties":{},"type":"number"},"pg_autoscale_mode":{"enum":[],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"pg_num":{"enum":[],"extra":{"title":"PG Num"},"properties":{},"type":"integer"},"pg_num_final":{"enum":[],"extra":{"title":"Optimal PG Num"},"optional":true,"properties":{},"type":"integer"},"pg_num_min":{"enum":[],"extra":{"title":"min. PG Num"},"optional":true,"properties":{},"type":"integer"},"pool":{"enum":[],"extra":{"title":"ID"},"properties":{},"type":"integer"},"pool_name":{"enum":[],"extra":{"title":"Name"},"properties":{},"type":"string"},"size":{"enum":[],"extra":{"title":"Size"},"properties":{},"type":"integer"},"target_size":{"enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"properties":{},"type":"integer"},"target_size_ratio":{"enum":[],"extra":{"title":"PG Autoscale Target Ratio"},"optional":true,"properties":{},"type":"number"},"type":{"enum":["replicated","erasure","unknown"],"extra":{"title":"Type"},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"afce7630dadd914aea20734861d3d291db5fea4a507f0cc7fabf161e40b4073f","description":"Create Ceph pool","extra":{"proxyto":"node"},"name":"createpool","parameters":[{"definition":{"default":"0; for erasure coded pools: 1","description":"Configure VM and CT storage using the new pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storages"},{"definition":{"default":"rbd","description":"The application of the pool.","enum":["rbd","cephfs","rgw"],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"string"},"name":"application"},{"definition":{"description":"The rule to use for mapping object placement in the cluster.","enum":[],"extra":{"title":"Crush Rule Name","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"crush_rule"},{"definition":{"description":"Create an erasure coded pool for RBD with an accompaning replicated pool for metadata storage. With EC, the common ceph options 'size', 'min_size' and 'crush_rule' parameters will be applied to the metadata pool.","enum":[],"extra":{"typetext":"k= ,m= [,device-class=] [,failure-domain=] [,profile=]"},"format":{"device-class":{"description":"CRUSH device class. Will create an erasure coded pool plus a replicated pool for metadata.","format_description":"class","optional":1,"type":"string"},"failure-domain":{"default":"host","description":"CRUSH failure domain. Default is 'host'. Will create an erasure coded pool plus a replicated pool for metadata.","format_description":"domain","optional":1,"type":"string"},"k":{"description":"Number of data chunks. Will create an erasure coded pool plus a replicated pool for metadata.","minimum":2,"type":"integer"},"m":{"description":"Number of coding chunks. Will create an erasure coded pool plus a replicated pool for metadata.","minimum":1,"type":"integer"},"profile":{"description":"Override the erasure code (EC) profile to use. Will create an erasure coded pool plus a replicated pool for metadata.","format_description":"profile","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"erasure-coding"},{"definition":{"default":2,"description":"Minimum number of replicas per object","enum":[],"extra":{"title":"Min Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"min_size"},{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"title":"Name"},"pattern":"(?^:^[^:/\\s]+$)","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"warn","description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"name":"pg_autoscale_mode"},{"definition":{"default":128,"description":"Number of placement groups.","enum":[],"extra":{"title":"PG Num","typetext":" (1 - 32768)"},"maximum":32768,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"pg_num"},{"definition":{"description":"Minimal number of placement groups.","enum":[],"extra":{"title":"min. PG Num","typetext":" (-N - 32768)"},"maximum":32768,"optional":true,"properties":{},"type":"integer"},"name":"pg_num_min"},{"definition":{"default":3,"description":"Number of replicas per object","enum":[],"extra":{"title":"Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"size"},{"definition":{"description":"The estimated target size of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"pattern":"^(\\d+(\\.\\d+)?)([KMGT])?$","properties":{},"type":"string"},"name":"target_size"},{"definition":{"description":"The estimated target ratio of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Ratio","typetext":""},"optional":true,"properties":{},"type":"number"},"name":"target_size_ratio"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/pool"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8708fe36bb2d3f3abbf03cb27e6db8fd1c5baaf58225e6095a69a2ea6b3217c6","description":"Destroy pool","extra":{"proxyto":"node"},"name":"destroypool","parameters":[{"definition":{"default":0,"description":"If true, destroys pool even if in use","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":1,"description":"Remove the erasure code profile. Defaults to true, if applicable.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove_ecprofile"},{"definition":{"default":0,"description":"Remove all pveceph-managed storages configured for this pool","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove_storages"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"aa0616ec83924fa46a149a0e35dedaf66156879c4aed761d93bd66aaa00aa242","description":"Pool index.","extra":{},"name":"poolindex","parameters":[{"definition":{"description":"The name of the pool.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"4165ab074ab90f0d5e5eb8b7bcc2a0e7fce8ec275cff5623c6e243ba402f574a","description":"Change POOL settings","extra":{"proxyto":"node"},"name":"setpool","parameters":[{"definition":{"description":"The application of the pool.","enum":["rbd","cephfs","rgw"],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"string"},"name":"application"},{"definition":{"description":"The rule to use for mapping object placement in the cluster.","enum":[],"extra":{"title":"Crush Rule Name","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"crush_rule"},{"definition":{"description":"Minimum number of replicas per object","enum":[],"extra":{"title":"Min Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"min_size"},{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"title":"Name"},"pattern":"(?^:^[^:/\\s]+$)","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"name":"pg_autoscale_mode"},{"definition":{"description":"Number of placement groups.","enum":[],"extra":{"title":"PG Num","typetext":" (1 - 32768)"},"maximum":32768,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"pg_num"},{"definition":{"description":"Minimal number of placement groups.","enum":[],"extra":{"title":"min. PG Num","typetext":" (-N - 32768)"},"maximum":32768,"optional":true,"properties":{},"type":"integer"},"name":"pg_num_min"},{"definition":{"description":"Number of replicas per object","enum":[],"extra":{"title":"Size","typetext":" (1 - 7)"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"size"},{"definition":{"description":"The estimated target size of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"pattern":"^(\\d+(\\.\\d+)?)([KMGT])?$","properties":{},"type":"string"},"name":"target_size"},{"definition":{"description":"The estimated target ratio of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Ratio","typetext":""},"optional":true,"properties":{},"type":"number"},"name":"target_size_ratio"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/ceph/pool/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"08dd7d3426fe0f6a4bbedbc73726417b3386556b1ddc8aaaff5e28e6c422a25d","description":"Show the current pool status.","extra":{"proxyto":"node"},"name":"getpool","parameters":[{"definition":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"If enabled, will display additional data(eg. statistics).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verbose"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"application":{"default":"rbd","description":"The application of the pool.","enum":["rbd","cephfs","rgw"],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"string"},"application_list":{"enum":[],"extra":{"title":"Application"},"optional":true,"properties":{},"type":"array"},"autoscale_status":{"enum":[],"extra":{"title":"Autoscale Status"},"optional":true,"properties":{},"type":"object"},"crush_rule":{"description":"The rule to use for mapping object placement in the cluster.","enum":[],"extra":{"title":"Crush Rule Name"},"optional":true,"properties":{},"type":"string"},"fast_read":{"enum":[],"extra":{"title":"Fast Read"},"properties":{},"type":"boolean"},"hashpspool":{"enum":[],"extra":{"title":"hashpspool"},"properties":{},"type":"boolean"},"id":{"enum":[],"extra":{"title":"ID"},"properties":{},"type":"integer"},"min_size":{"default":2,"description":"Minimum number of replicas per object","enum":[],"extra":{"title":"Min Size"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":{"description":"The name of the pool. It must be unique.","enum":[],"extra":{"title":"Name"},"pattern":"(?^:^[^:/\\s]+$)","properties":{},"type":"string"},"nodeep-scrub":{"enum":[],"extra":{"title":"nodeep-scrub"},"properties":{},"type":"boolean"},"nodelete":{"enum":[],"extra":{"title":"nodelete"},"properties":{},"type":"boolean"},"nopgchange":{"enum":[],"extra":{"title":"nopgchange"},"properties":{},"type":"boolean"},"noscrub":{"enum":[],"extra":{"title":"noscrub"},"properties":{},"type":"boolean"},"nosizechange":{"enum":[],"extra":{"title":"nosizechange"},"properties":{},"type":"boolean"},"pg_autoscale_mode":{"default":"warn","description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"],"extra":{"title":"PG Autoscale Mode"},"optional":true,"properties":{},"type":"string"},"pg_num":{"default":128,"description":"Number of placement groups.","enum":[],"extra":{"title":"PG Num"},"maximum":32768,"minimum":1,"optional":true,"properties":{},"type":"integer"},"pg_num_min":{"description":"Minimal number of placement groups.","enum":[],"extra":{"title":"min. PG Num"},"maximum":32768,"optional":true,"properties":{},"type":"integer"},"pgp_num":{"enum":[],"extra":{"title":"PGP num"},"properties":{},"type":"integer"},"size":{"default":3,"description":"Number of replicas per object","enum":[],"extra":{"title":"Size"},"maximum":7,"minimum":1,"optional":true,"properties":{},"type":"integer"},"statistics":{"enum":[],"extra":{"title":"Statistics"},"optional":true,"properties":{},"type":"object"},"target_size":{"description":"The estimated target size of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Size"},"optional":true,"pattern":"^(\\d+(\\.\\d+)?)([KMGT])?$","properties":{},"type":"string"},"target_size_ratio":{"description":"The estimated target ratio of the pool for the PG autoscaler.","enum":[],"extra":{"title":"PG Autoscale Target Ratio"},"optional":true,"properties":{},"type":"number"},"use_gmt_hitset":{"enum":[],"extra":{"title":"use_gmt_hitset"},"properties":{},"type":"boolean"},"write_fadvise_dontneed":{"enum":[],"extra":{"title":"write_fadvise_dontneed"},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/pool/{name}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d8f63039ca364b164a8e68d30f3a03f1ebe8c071133098c0a1781588258c7c56","description":"Restart ceph services.","extra":{"proxyto":"node"},"name":"restart","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"ceph.target","description":"Ceph service name.","enum":[],"extra":{},"optional":true,"pattern":"(mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?","properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/restart"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d1d564dc8fb769d538a36abe333e96421609c5e6a7fb99fd92be6a90fedf4f44","description":"List ceph rules.","extra":{"proxyto":"node"},"name":"rules","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"name":{"description":"Name of the CRUSH rule.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/ceph/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ecb354e68cb5aeaa1e4b8b63c176ff7410fa0fed35f792c2891964ab6662d962","description":"Start ceph services.","extra":{"proxyto":"node"},"name":"start","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"ceph.target","description":"Ceph service name.","enum":[],"extra":{},"optional":true,"pattern":"(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?","properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"46eb9852d690eec67eee3282fa3db6841f26e1a7ad8a7eb34f367777223906e4","description":"Get ceph status.","extra":{"proxyto":"node"},"name":"status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/ceph/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2844e52262806ae8703017f4b336a790d3c54cd9c0ad3ae772ed9fe138def456","description":"Stop ceph services.","extra":{"proxyto":"node"},"name":"stop","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"ceph.target","description":"Ceph service name.","enum":[],"extra":{},"optional":true,"pattern":"(ceph|mon|mds|osd|mgr)(\\.[a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)?","properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/ceph/stop"},{"extra":{},"methods":[{"allow_token":true,"checksum":"407b3d66a300b7bc4f15ce81eadffc3e3ff161e7940cd646fc925a219be029f3","description":"Node index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/certificates"},{"extra":{},"methods":[{"allow_token":true,"checksum":"93b19d6ea7cca4a3a682a7c06117351418c9725fb782f6ed86050c0ac92f4bd4","description":"ACME index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/certificates/acme"},{"extra":{},"methods":[{"allow_token":true,"checksum":"79bd82498d21a1c5d90f053e1aaec400ad82efd3983c8cf0559fe0c47b5b293c","description":"Revoke existing certificate from CA.","extra":{"proxyto":"node"},"name":"revoke_certificate","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"eb094550eb00e663dca797ef8c9dc07865542e546832f3d913080f5638f81c3a","description":"Order a new certificate from ACME-compatible CA.","extra":{"proxyto":"node"},"name":"new_certificate","parameters":[{"definition":{"default":0,"description":"Overwrite existing custom certificate.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"},{"allow_token":true,"checksum":"f8eea8445722cd9588417a2079abe85620556ba298b502dd0717e3876aa1abc5","description":"Renew existing certificate from CA.","extra":{"proxyto":"node"},"name":"renew_certificate","parameters":[{"definition":{"default":0,"description":"Force renewal even if expiry is more than 30 days away.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/certificates/acme/certificate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"929493029f5253253302d24f7a1e2c0046bf726108c3d37ed8c86801ddc3384a","description":"DELETE custom certificate chain and key.","extra":{"proxyto":"node"},"name":"remove_custom_cert","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Restart pveproxy.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restart"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"604d77053bdcded86a50810bad7ad1b20c14ff8887d4068b001db73771908654","description":"Upload or update custom certificate chain and key.","extra":{"proxyto":"node"},"name":"upload_custom_cert","parameters":[{"definition":{"description":"PEM encoded certificate (chain).","enum":[],"extra":{"typetext":""},"format":"pem-certificate-chain","properties":{},"type":"string"},"name":"certificates"},{"definition":{"default":0,"description":"Overwrite existing custom or ACME certificate files.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"PEM encoded private key.","enum":[],"extra":{"typetext":""},"format":"pem-string","optional":true,"properties":{},"type":"string"},"name":"key"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Restart pveproxy.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restart"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"fingerprint":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"issuer":{"description":"Certificate issuer name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"notafter":{"description":"Certificate's notAfter timestamp (UNIX epoch).","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"notbefore":{"description":"Certificate's notBefore timestamp (UNIX epoch).","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"pem":{"description":"Certificate in PEM format","enum":[],"extra":{},"format":"pem-certificate","optional":true,"properties":{},"type":"string"},"public-key-bits":{"description":"Certificate's public key size","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"public-key-type":{"description":"Certificate's public key algorithm","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"san":{"description":"List of Certificate's SubjectAlternativeName entries.","enum":[],"extra":{"renderer":"yaml"},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"subject":{"description":"Certificate subject name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/certificates/custom"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2a9b8f5b1a046e68e76e42747bf6de9bb776652ea56f1797a0b8f6bd32e2d21b","description":"Get information about node's certificates.","extra":{"proxyto":"node"},"name":"info","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"fingerprint":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"issuer":{"description":"Certificate issuer name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"notafter":{"description":"Certificate's notAfter timestamp (UNIX epoch).","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"notbefore":{"description":"Certificate's notBefore timestamp (UNIX epoch).","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"pem":{"description":"Certificate in PEM format","enum":[],"extra":{},"format":"pem-certificate","optional":true,"properties":{},"type":"string"},"public-key-bits":{"description":"Certificate's public key size","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"public-key-type":{"description":"Certificate's public key algorithm","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"san":{"description":"List of Certificate's SubjectAlternativeName entries.","enum":[],"extra":{"renderer":"yaml"},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"subject":{"description":"Certificate subject name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/certificates/info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"794756ec24516f9b41fe455ac5e08596ea7ec3574fa768f4a288d772455c4556","description":"Get node configuration options.","extra":{"proxyto":"node"},"name":"get_config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"all","description":"Return only a specific property from the node configuration.","enum":["acme","acmedomain0","acmedomain1","acmedomain2","acmedomain3","acmedomain4","acmedomain5","ballooning-target","description","startall-onboot-delay","wakeonlan"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"property"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"acme":{"description":"Node specific ACME settings.","enum":[],"extra":{},"format":{"account":{"default":"default","description":"ACME account config file name.","format":"pve-configid","format_description":"name","optional":1,"type":"string"},"domains":{"description":"List of domains for this node's ACME certificate","format":"pve-acme-domain-list","format_description":"domain[;domain;...]","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"acmedomain[n]":{"description":"ACME domain and validation plugin","enum":[],"extra":{},"format":{"alias":{"description":"Alias for the Domain to verify ACME Challenge over DNS","format":"pve-acme-alias","format_description":"domain","optional":1,"type":"string"},"domain":{"default_key":1,"description":"domain for this node's ACME certificate","format":"pve-acme-domain","format_description":"domain","type":"string"},"plugin":{"default":"standalone","description":"The ACME plugin ID","format":"pve-configid","format_description":"name of the plugin configuration","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"ballooning-target":{"default":80,"description":"RAM usage target for ballooning (in percent of total memory)","enum":[],"extra":{},"maximum":100,"minimum":0,"optional":true,"properties":{},"type":"integer"},"description":{"description":"Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.","enum":[],"extra":{},"max_length":65536,"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":40,"optional":true,"properties":{},"type":"string"},"startall-onboot-delay":{"default":0,"description":"Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.","enum":[],"extra":{},"maximum":300,"minimum":0,"optional":true,"properties":{},"type":"integer"},"wakeonlan":{"description":"Node specific wake on LAN settings.","enum":[],"extra":{},"format":{"bind-interface":{"default":"The interface carrying the default route","description":"Bind to this interface when sending wake on LAN packet","format":"pve-iface","format_description":"bind interface","optional":1,"type":"string"},"broadcast-address":{"default":"255.255.255.255","description":"IPv4 broadcast address to use when sending wake on LAN packet","format":"ipv4","format_description":"IPv4 broadcast address","optional":1,"type":"string"},"mac":{"default_key":1,"description":"MAC address for wake on LAN","format":"mac-addr","format_description":"MAC address","type":"string"}},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"a8a8546f278f4a84463cb5cc82df0be028cdf2096e66e9143d499bdcbb0cd036","description":"Set node configuration options.","extra":{"proxyto":"node"},"name":"set_options","parameters":[{"definition":{"description":"Node specific ACME settings.","enum":[],"extra":{"typetext":"[account=] [,domains=]"},"format":{"account":{"default":"default","description":"ACME account config file name.","format":"pve-configid","format_description":"name","optional":1,"type":"string"},"domains":{"description":"List of domains for this node's ACME certificate","format":"pve-acme-domain-list","format_description":"domain[;domain;...]","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"acme"},{"definition":{"description":"ACME domain and validation plugin","enum":[],"extra":{"typetext":"[domain=] [,alias=] [,plugin=]"},"format":{"alias":{"description":"Alias for the Domain to verify ACME Challenge over DNS","format":"pve-acme-alias","format_description":"domain","optional":1,"type":"string"},"domain":{"default_key":1,"description":"domain for this node's ACME certificate","format":"pve-acme-domain","format_description":"domain","type":"string"},"plugin":{"default":"standalone","description":"The ACME plugin ID","format":"pve-configid","format_description":"name of the plugin configuration","optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"acmedomain[n]"},{"definition":{"default":80,"description":"RAM usage target for ballooning (in percent of total memory)","enum":[],"extra":{"typetext":" (0 - 100)"},"maximum":100,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"ballooning-target"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":65536,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.","enum":[],"extra":{"typetext":" (0 - 300)"},"maximum":300,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"startall-onboot-delay"},{"definition":{"description":"Node specific wake on LAN settings.","enum":[],"extra":{"typetext":"[mac=] [,bind-interface=] [,broadcast-address=]"},"format":{"bind-interface":{"default":"The interface carrying the default route","description":"Bind to this interface when sending wake on LAN packet","format":"pve-iface","format_description":"bind interface","optional":1,"type":"string"},"broadcast-address":{"default":"255.255.255.255","description":"IPv4 broadcast address to use when sending wake on LAN packet","format":"ipv4","format_description":"IPv4 broadcast address","optional":1,"type":"string"},"mac":{"default_key":1,"description":"MAC address for wake on LAN","format":"mac-addr","format_description":"MAC address","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"wakeonlan"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c852718145641f2177102cbfc0fd436f6aeef81be29c2faedeed85f289314d9f","description":"Node index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/disks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2b0b603e80bb49e4f94508459ac35fb463fc1cb96dd525ab36ee550b228e5929","description":"PVE Managed Directory storages.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"device":{"description":"The mounted device.","enum":[],"extra":{},"properties":{},"type":"string"},"options":{"description":"The mount options.","enum":[],"extra":{},"properties":{},"type":"string"},"path":{"description":"The mount path.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The filesystem type.","enum":[],"extra":{},"properties":{},"type":"string"},"unitfile":{"description":"The path of the mount unit.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"52ce612ca7baab2bdd57b06bcfceb08779ce1d2ac530d8130aff7e3c6dec9477","description":"Create a Filesystem on an unused disk. Will be mounted under '/mnt/pve/NAME'.","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"default":0,"description":"Configure storage using the directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storage"},{"definition":{"description":"The block device you want to create the filesystem on.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"device"},{"definition":{"default":"ext4","description":"The desired filesystem.","enum":["ext4","xfs"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"filesystem"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/directory"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f0fe4d0df791ab5bd40314e73c8c366417f843c3bae376bb3b8010c65009fb34","description":"Unmounts the storage and removes the mount unit.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"default":0,"description":"Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-config"},{"definition":{"default":0,"description":"Also wipe disk so it can be repurposed afterwards.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-disks"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"}],"path":"/nodes/{node}/disks/directory/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e07569915888aa6baceeffec53ed6c431ea006c760c7620558ca0980ba012061","description":"Initialize Disk with GPT","extra":{"proxyto":"node"},"name":"initgpt","parameters":[{"definition":{"description":"Block device name","enum":[],"extra":{},"pattern":"^/dev/[a-zA-Z0-9\\/]+$","properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"UUID for the GPT table","enum":[],"extra":{},"max_length":36,"optional":true,"pattern":"[a-fA-F0-9\\-]+","properties":{},"type":"string"},"name":"uuid"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/initgpt"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b19c44d4db67e33f6c20913d198f5366ed3c97ec021c2a54670041eaef285702","description":"List local disks.","extra":{"proxyto":"node"},"name":"list","parameters":[{"definition":{"default":0,"description":"Also include partitions.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"include-partitions"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Skip smart checks.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skipsmart"},{"definition":{"description":"Only list specific types of disks.","enum":["unused","journal_disks"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["or",["perm","/",["Sys.Audit"]],["perm","/nodes/{node}",["Sys.Audit"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"devpath":{"description":"The device path","enum":[],"extra":{},"properties":{},"type":"string"},"gpt":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"health":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"model":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mounted":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"osdid":{"enum":[],"extra":{},"properties":{},"type":"integer"},"osdid-list":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"integer"},"properties":{},"type":"array"},"parent":{"description":"For partitions only. The device path of the disk the partition resides on.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"size":{"enum":[],"extra":{},"properties":{},"type":"integer"},"used":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vendor":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"wwn":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/disks/list"},{"extra":{},"methods":[{"allow_token":true,"checksum":"547375dd65648a9398230df72264cdc019782638796d54756ac0b8145c21975f","description":"List LVM Volume Groups","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"children":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"children":{"description":"The underlying physical volumes","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"free":{"description":"The free bytes in the physical volume","enum":[],"extra":{},"properties":{},"type":"integer"},"leaf":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"name":{"description":"The name of the physical volume","enum":[],"extra":{},"properties":{},"type":"string"},"size":{"description":"The size of the physical volume in bytes","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"free":{"description":"The free bytes in the volume group","enum":[],"extra":{},"properties":{},"type":"integer"},"leaf":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"name":{"description":"The name of the volume group","enum":[],"extra":{},"properties":{},"type":"string"},"size":{"description":"The size of the volume group in bytes","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"leaf":{"enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"465ee8af4bac2a64832eeb82709a6ff666335ab27be88058f40175b94d5f4542","description":"Create an LVM Volume Group","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"default":0,"description":"Configure storage using the Volume Group","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storage"},{"definition":{"description":"The block device you want to create the volume group on","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"device"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/lvm"},{"extra":{},"methods":[{"allow_token":true,"checksum":"41be5d70ce8afdbc0cffdf60aba42159045297f9274a49064625dfc79884f9cb","description":"Remove an LVM Volume Group.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"default":0,"description":"Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-config"},{"definition":{"default":0,"description":"Also wipe disks so they can be repurposed afterwards.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-disks"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"}],"path":"/nodes/{node}/disks/lvm/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9d0210c30eeba102cd5491e7f961792286b4fbf7dcbaed83b1cac181115b29ee","description":"List LVM thinpools","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"lv":{"description":"The name of the thinpool.","enum":[],"extra":{},"properties":{},"type":"string"},"lv_size":{"description":"The size of the thinpool in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"metadata_size":{"description":"The size of the metadata lv in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"metadata_used":{"description":"The used bytes of the metadata lv.","enum":[],"extra":{},"properties":{},"type":"integer"},"used":{"description":"The used bytes of the thinpool.","enum":[],"extra":{},"properties":{},"type":"integer"},"vg":{"description":"The associated volume group.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"58432b26fb6a7729315b2a98c47db27b32ce10f5be1d69a6fe7132e7cf066560","description":"Create an LVM thinpool","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"default":0,"description":"Configure storage using the thinpool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storage"},{"definition":{"description":"The block device you want to create the thinpool on.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"device"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/lvmthin"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0dfc32202fa94d5574b4220343f91f097aae08e39de39e8d4153139686567f9b","description":"Remove an LVM thin pool.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"default":0,"description":"Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-config"},{"definition":{"default":0,"description":"Also wipe disks so they can be repurposed afterwards.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-disks"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"volume-group"}],"permissions":{"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"}],"path":"/nodes/{node}/disks/lvmthin/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b8be9774a5c882925ed844f0a84b0c893019315e9d99d5707940856e370cf778","description":"Get SMART Health of a disk.","extra":{"proxyto":"node"},"name":"smart","parameters":[{"definition":{"description":"Block device name","enum":[],"extra":{},"pattern":"^/dev/[a-zA-Z0-9\\/]+$","properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"If true returns only the health status","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"healthonly"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"attributes":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"array"},"health":{"enum":[],"extra":{},"properties":{},"type":"string"},"text":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/disks/smart"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5863de4fd64b709cb09f59e5ed64aa977df1243471343673fedafcc9441196d4","description":"Wipe a disk or partition.","extra":{"proxyto":"node"},"name":"wipe_disk","parameters":[{"definition":{"description":"Block device name","enum":[],"extra":{},"pattern":"^/dev/[a-zA-Z0-9\\/]+$","properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/disks/wipedisk"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d32343b2f2aa7b3ebb677e824c108e9a394940d90ed272b780889c094e876172","description":"List Zpools.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"alloc":{"description":"","enum":[],"extra":{},"properties":{},"type":"integer"},"dedup":{"description":"","enum":[],"extra":{},"properties":{},"type":"number"},"frag":{"description":"","enum":[],"extra":{},"properties":{},"type":"integer"},"free":{"description":"","enum":[],"extra":{},"properties":{},"type":"integer"},"health":{"description":"","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"","enum":[],"extra":{},"properties":{},"type":"string"},"size":{"description":"","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"9307314b98ab891eff85b9312ae22dd45789e5eec022d70ce026f3142435d1b8","description":"Create a ZFS pool.","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"default":0,"description":"Configure storage using the zpool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"add_storage"},{"definition":{"default":12,"description":"Pool sector size exponent.","enum":[],"extra":{"typetext":" (9 - 16)"},"maximum":16,"minimum":9,"optional":true,"properties":{},"type":"integer"},"name":"ashift"},{"definition":{"default":"on","description":"The compression algorithm to use.","enum":["on","off","gzip","lz4","lzjb","zle","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"compression"},{"definition":{"description":"The block devices you want to create the zpool on.","enum":[],"extra":{"typetext":""},"format":"string-list","properties":{},"type":"string"},"name":"devices"},{"definition":{"enum":[],"extra":{"typetext":"data= ,spares="},"format":{"data":{"description":"The number of data devices per redundancy group. (dRAID)","minimum":1,"type":"integer"},"spares":{"description":"Number of dRAID spares.","minimum":0,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"draid-config"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The RAID level to use.","enum":["single","mirror","raid10","raidz","raidz2","raidz3","draid","draid2","draid3"],"extra":{},"properties":{},"type":"string"},"name":"raidlevel"}],"permissions":{"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/disks/zfs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"29aa5ca8b0d31811a6ede028c5b0db8458f3816460f152e4471328fb4e1632f0","description":"Destroy a ZFS pool.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"default":0,"description":"Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-config"},{"definition":{"default":0,"description":"Also wipe disks so they can be repurposed afterwards.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"cleanup-disks"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'","expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"7557098c2bcfb870e8e6beb40292b42f3205d3ab8ac1e80b3bd1fbaf0240f93a","description":"Get details about a zpool.","extra":{"proxyto":"node"},"name":"detail","parameters":[{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"action":{"description":"Information about the recommended action to fix the state.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"children":{"description":"The pool configuration information, including the vdevs for each section (e.g. spares, cache), may be nested.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"cksum":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"msg":{"description":"An optional message about the vdev.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"The name of the vdev or section.","enum":[],"extra":{},"properties":{},"type":"string"},"read":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"state":{"description":"The state of the vdev.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"write":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"number"}},"type":"object"},"properties":{},"type":"array"},"errors":{"description":"Information about the errors on the zpool.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"The name of the zpool.","enum":[],"extra":{},"properties":{},"type":"string"},"scan":{"description":"Information about the last/current scrub.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"state":{"description":"The state of the zpool.","enum":[],"extra":{},"properties":{},"type":"string"},"status":{"description":"Information about the state of the zpool.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/disks/zfs/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a2a9840bc5b5f6fedb64fc871e0f30293e36589bef2b2cca3b75b167641bd3ad","description":"Read DNS settings.","extra":{"proxyto":"node"},"name":"dns","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"dns1":{"description":"First name server IP address.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dns2":{"description":"Second name server IP address.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dns3":{"description":"Third name server IP address.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"search":{"description":"Search domain for host-name lookup.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"aa3976a9e9313d0108087afc577aaef882c6caa542300b9aa580823664733034","description":"Write DNS settings.","extra":{"proxyto":"node"},"name":"update_dns","parameters":[{"definition":{"description":"First name server IP address.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"dns1"},{"definition":{"description":"Second name server IP address.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"dns2"},{"definition":{"description":"Third name server IP address.","enum":[],"extra":{"typetext":""},"format":"ip","optional":true,"properties":{},"type":"string"},"name":"dns3"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Search domain for host-name lookup.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"search"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/dns"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b9b5ae5cee9408c0f7067b2093039c75ae790b13b2a78ff993842ae9f2694a77","description":"Execute multiple commands in order, root only.","extra":{"proxyto":"node"},"name":"execute","parameters":[{"definition":{"description":"JSON encoded array of commands.","enum":[],"extra":{"typetext":"","verbose_description":"JSON encoded array of commands, where each command is an object with the following properties:\n args: \n\t A set of parameter names and their values.\n\n method: (GET|POST|PUT|DELETE)\n\t A method related to the API endpoint (GET, POST etc.).\n\n path: \n\t A relative path to an API endpoint on this node.\n\n"},"format":"pve-command-batch","properties":{},"type":"string"},"name":"commands"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"POST"}],"path":"/nodes/{node}/execute"},{"extra":{},"methods":[{"allow_token":true,"checksum":"23dca6507cde2ae0cabadf81020c2e06e2c8878c3e19c7356ba7dbc49c506a9a","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0bf35a80d104d2faaf32511debedeee1423c276df3c2eeba6d83b3e7ee589cd3","description":"Read firewall log","extra":{"proxyto":"node"},"name":"log","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Display log since this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"since"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"Display log until this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"until"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/firewall/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"31fe623a1f95fc844ff3c680dd4bc811894621a9591e3eb5a064132a79bb8e99","description":"Get host firewall options.","extra":{"proxyto":"node"},"name":"get_options","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"enable":{"description":"Enable host firewall rules.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"log_level_forward":{"description":"Log level for forwarded traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_level_in":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_level_out":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_nf_conntrack":{"default":0,"description":"Enable logging of conntrack information.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ndp":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"nf_conntrack_allow_invalid":{"default":0,"description":"Allow invalid packets on connection tracking.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"nf_conntrack_helpers":{"default":"","description":"Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp","enum":[],"extra":{},"format":"pve-fw-conntrack-helper","optional":true,"properties":{},"type":"string"},"nf_conntrack_max":{"default":262144,"description":"Maximum number of tracked connections.","enum":[],"extra":{},"minimum":32768,"optional":true,"properties":{},"type":"integer"},"nf_conntrack_tcp_timeout_established":{"default":432000,"description":"Conntrack established timeout.","enum":[],"extra":{},"minimum":7875,"optional":true,"properties":{},"type":"integer"},"nf_conntrack_tcp_timeout_syn_recv":{"default":60,"description":"Conntrack syn recv timeout.","enum":[],"extra":{},"maximum":60,"minimum":30,"optional":true,"properties":{},"type":"integer"},"nftables":{"default":0,"description":"Enable nftables based firewall (tech preview)","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"nosmurfs":{"description":"Enable SMURFS filter.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"protection_synflood":{"default":0,"description":"Enable synflood protection","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"protection_synflood_burst":{"default":1000,"description":"Synflood protection rate burst by ip src.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"protection_synflood_rate":{"default":200,"description":"Synflood protection rate syn/sec by ip src.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"smurf_log_level":{"description":"Log level for SMURFS filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"tcp_flags_log_level":{"description":"Log level for illegal tcp flags filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"tcpflags":{"default":0,"description":"Filter illegal combinations of TCP flags.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"a1e83a5f524250d9bbebc4c2b4cc6ac0802e73c42e3821f709fc392b938c0930","description":"Set Firewall options.","extra":{"proxyto":"node"},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Enable host firewall rules.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Log level for forwarded traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_forward"},{"definition":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_in"},{"definition":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_out"},{"definition":{"default":0,"description":"Enable logging of conntrack information.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"log_nf_conntrack"},{"definition":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ndp"},{"definition":{"default":0,"description":"Allow invalid packets on connection tracking.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nf_conntrack_allow_invalid"},{"definition":{"default":"","description":"Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp","enum":[],"extra":{"typetext":""},"format":"pve-fw-conntrack-helper","optional":true,"properties":{},"type":"string"},"name":"nf_conntrack_helpers"},{"definition":{"default":262144,"description":"Maximum number of tracked connections.","enum":[],"extra":{"typetext":" (32768 - N)"},"minimum":32768,"optional":true,"properties":{},"type":"integer"},"name":"nf_conntrack_max"},{"definition":{"default":432000,"description":"Conntrack established timeout.","enum":[],"extra":{"typetext":" (7875 - N)"},"minimum":7875,"optional":true,"properties":{},"type":"integer"},"name":"nf_conntrack_tcp_timeout_established"},{"definition":{"default":60,"description":"Conntrack syn recv timeout.","enum":[],"extra":{"typetext":" (30 - 60)"},"maximum":60,"minimum":30,"optional":true,"properties":{},"type":"integer"},"name":"nf_conntrack_tcp_timeout_syn_recv"},{"definition":{"default":0,"description":"Enable nftables based firewall (tech preview)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nftables"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Enable SMURFS filter.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nosmurfs"},{"definition":{"default":0,"description":"Enable synflood protection","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection_synflood"},{"definition":{"default":1000,"description":"Synflood protection rate burst by ip src.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"protection_synflood_burst"},{"definition":{"default":200,"description":"Synflood protection rate syn/sec by ip src.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"protection_synflood_rate"},{"definition":{"description":"Log level for SMURFS filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"smurf_log_level"},{"definition":{"description":"Log level for illegal tcp flags filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"tcp_flags_log_level"},{"definition":{"default":0,"description":"Filter illegal combinations of TCP flags.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tcpflags"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b60ddfff9873ec325386c9e661b00a7b59dc13a05b46d58a5a77ed0925c039ab","description":"List rules.","extra":{"proxyto":"node"},"name":"get_rules","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"52ed479494817bbd7348903edb0529f7d685ac0089933fad256eb2481b39031b","description":"Create new rule.","extra":{"proxyto":"node"},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9a8cd16dbdfb0ed78c0435f1e63da94e3c4fb81b5581e4ec361bbe2f9e3b8727","description":"Delete rule.","extra":{"proxyto":"node"},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"334c82a7807d96fdd30b6fc1678394170a14b3aa9668f1c3231b928df2338d78","description":"Get single rule data.","extra":{"proxyto":"node"},"name":"get_rule","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"34b4eb319950ecb2eeac91ba686ad2a44444fa1b7c330a00799252e0509bb563","description":"Modify rule data.","extra":{"proxyto":"node"},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a942affba5edd9876d3a47c7aaed97b5c3eeca8b6a2748dbb6cfd04b87ec4985","description":"Index of hardware types","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{type}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1556e034fd144677c2e86bdb15422d235a60e2b5a68ce93c6f43253902d897e5","description":"List local PCI devices.","extra":{"proxyto":"node"},"name":"pci_scan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":"05;06;0b","description":"A list of blacklisted PCI classes, which will not be returned. Following are filtered by default: Memory Controller (05), Bridge (06) and Processor (0b).","enum":[],"extra":{"typetext":""},"format":"string-list","optional":true,"properties":{},"type":"string"},"name":"pci-class-blacklist"},{"definition":{"default":1,"description":"If disabled, does only print the PCI IDs. Otherwise, additional information like vendor and device will be returned.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verbose"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Sys.Modify"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"class":{"description":"The PCI Class of the device.","enum":[],"extra":{},"properties":{},"type":"string"},"device":{"description":"The Device ID.","enum":[],"extra":{},"properties":{},"type":"string"},"device_name":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"description":"The PCI ID.","enum":[],"extra":{},"properties":{},"type":"string"},"iommugroup":{"description":"The IOMMU group in which the device is in. If no IOMMU group is detected, it is set to -1.","enum":[],"extra":{},"properties":{},"type":"integer"},"mdev":{"description":"If set, marks that the device is capable of creating mediated devices.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"subsystem_device":{"description":"The Subsystem Device ID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"subsystem_device_name":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"subsystem_vendor":{"description":"The Subsystem Vendor ID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"subsystem_vendor_name":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vendor":{"description":"The Vendor ID.","enum":[],"extra":{},"properties":{},"type":"string"},"vendor_name":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware/pci"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0380005f39419bdbf9fbd8e0605704890700d45925bdc7e09289d01a1584b88a","description":"Index of available pci methods","extra":{},"name":"pci_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{},"pattern":"(?:(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\\.[0-9a-fA-F])|([a-zA-Z][a-zA-Z0-9_-]+)","properties":{},"type":"string"},"name":"pci-id-or-mapping"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{method}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"method":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware/pci/{pci-id-or-mapping}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f3f42c8ccc4e915864049b845055cc72a2e753e5310db9fd846b53248f69ca69","description":"List mediated device types for given PCI device.","extra":{"proxyto":"node"},"name":"mdevscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The PCI ID or mapping to list the mdev types for.","enum":[],"extra":{},"pattern":"(?:(?:[0-9a-fA-F]{4}:)?[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\\.[0-9a-fA-F])|([a-zA-Z][a-zA-Z0-9_-]+)","properties":{},"type":"string"},"name":"pci-id-or-mapping"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit","Sys.Modify"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"available":{"description":"The number of still available instances of this type.","enum":[],"extra":{},"properties":{},"type":"integer"},"description":{"description":"Additional description of the type.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"A human readable name for the type.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"The name of the mdev type.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c34730e00f0d40259fe27fa8d10c86ca51d09c55d88e56c0a58a874dcf7bff9c","description":"List local USB devices.","extra":{"proxyto":"node"},"name":"usbscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"busnum":{"enum":[],"extra":{},"properties":{},"type":"integer"},"class":{"enum":[],"extra":{},"properties":{},"type":"integer"},"devnum":{"enum":[],"extra":{},"properties":{},"type":"integer"},"level":{"enum":[],"extra":{},"properties":{},"type":"integer"},"manufacturer":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"prodid":{"enum":[],"extra":{},"properties":{},"type":"string"},"product":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"speed":{"enum":[],"extra":{},"properties":{},"type":"string"},"usbpath":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vendid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/hardware/usb"},{"extra":{},"methods":[{"allow_token":true,"checksum":"245aea500b630299322623884169fd5c6b7817f39702ab7e27adcf12ffacd5d3","description":"Get the content of /etc/hosts.","extra":{"proxyto":"node"},"name":"get_etc_hosts","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"data":{"description":"The content of /etc/hosts.","enum":[],"extra":{},"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"37ce9f4f98771127e217c1cae8f1c5cee8ce3cefba81cc528f7c6ca1619d4752","description":"Write /etc/hosts.","extra":{"proxyto":"node"},"name":"write_etc_hosts","parameters":[{"definition":{"description":"The target content of /etc/hosts.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"data"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/hosts"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f19983c07943897ef9b485d0ec8107565a6488638328628e2704475ab4457b32","description":"Read Journal","extra":{"download_allowed":1,"proxyto":"node"},"name":"journal","parameters":[{"definition":{"description":"End before the given Cursor. Conflicts with 'until'","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"endcursor"},{"definition":{"description":"Limit to the last X lines. Conflicts with a range.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"lastentries"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Display all log since this UNIX epoch. Conflicts with 'startcursor'.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"since"},{"definition":{"description":"Start after the given Cursor. Conflicts with 'since'","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"startcursor"},{"definition":{"description":"Display all log until this UNIX epoch. Conflicts with 'endcursor'.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"until"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/journal"},{"extra":{},"methods":[{"allow_token":true,"checksum":"08bae417dc5c548791157b3ddc87a06d0399291ec8749449bfa51f3b9ef58d52","description":"LXC container index (per node).","extra":{"proxyto":"node"},"name":"vmlist","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Only list CTs where you have VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{vmid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cpu":{"description":"Current CPU usage.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"cpus":{"description":"Maximum usable CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"disk":{"description":"Root disk image space-usage in bytes.","enum":[],"extra":{"renderer":"bytes"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"diskread":{"description":"The amount of bytes the guest read from it's block devices since the guest was started. (Note: This info is not available for all storage types.)","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"diskwrite":{"description":"The amount of bytes the guest wrote from it's block devices since the guest was started. (Note: This info is not available for all storage types.)","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"lock":{"description":"The current config lock, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxdisk":{"description":"Root disk image size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Maximum memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxswap":{"description":"Maximum SWAP memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"mem":{"description":"Currently used memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"name":{"description":"Container name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"netin":{"description":"The amount of traffic in bytes that was sent to the guest over the network since it was started.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"netout":{"description":"The amount of traffic in bytes that was sent from the guest over the network since it was started.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"status":{"description":"LXC Container status.","enum":["stopped","running"],"extra":{},"properties":{},"type":"string"},"tags":{"description":"The current configured tags, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"template":{"default":0,"description":"Determines if the guest is a template.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"uptime":{"description":"Uptime in seconds.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"6be877a3ed9799bcc23f74f3388c65ef552ea9fc328282fd70ae02bf204bddcf","description":"Create or restore a container.","extra":{"proxyto":"node"},"name":"create_vm","parameters":[{"definition":{"default":"amd64","description":"OS architecture type.","enum":["amd64","i386","arm64","armhf","riscv32","riscv64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"default":"restore limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"default":"tty","description":"Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).","enum":["shell","console","tty"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmode"},{"definition":{"default":1,"description":"Attach a console device (/dev/console) to the container.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"console"},{"definition":{"description":"The number of cores assigned to the container. A container can use all available cores by default.","enum":[],"extra":{"typetext":" (1 - 8192)"},"maximum":8192,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"default":0,"description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.","enum":[],"extra":{"typetext":" (0 - 8192)"},"maximum":8192,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"typetext":" (0 - 500000)","verbose_description":"CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests."},"maximum":500000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"default":0,"description":"Try to be more verbose. For now this only enables debug log-level on start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"debug"},{"definition":{"description":"Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":8192,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Device to pass through to the container","enum":[],"extra":{"typetext":"[[path=]] [,deny-write=<1|0>] [,gid=] [,mode=] [,uid=]"},"format":{"deny-write":{"default":0,"description":"Deny the container to write to the device","optional":1,"type":"boolean"},"gid":{"description":"Group ID to be assigned to the device node","minimum":0,"optional":1,"type":"integer"},"mode":{"description":"Access mode to be set on the device node","format_description":"Octal access mode","optional":1,"pattern":"0[0-7]{3}","type":"string"},"path":{"default_key":1,"description":"Device to pass through to the container","format":"pve-lxc-dev-string","format_description":"Path","optional":1,"type":"string","verbose_description":"Path to the device to pass through to the container"},"uid":{"description":"User ID to be assigned to the device node","minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"dev[n]"},{"definition":{"description":"Allow containers access to advanced features.","enum":[],"extra":{"typetext":"[force_rw_sys=<1|0>] [,fuse=<1|0>] [,keyctl=<1|0>] [,mknod=<1|0>] [,mount=] [,nesting=<1|0>]"},"format":{"force_rw_sys":{"default":0,"description":"Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.","optional":1,"type":"boolean"},"fuse":{"default":0,"description":"Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.","optional":1,"type":"boolean"},"keyctl":{"default":0,"description":"For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.","optional":1,"type":"boolean"},"mknod":{"default":0,"description":"Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.","optional":1,"type":"boolean"},"mount":{"description":"Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.","format_description":"fstype;fstype;...","optional":1,"pattern":"(?^:[a-zA-Z0-9_; ]+)","type":"string"},"nesting":{"default":0,"description":"Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"features"},{"definition":{"description":"Allow to overwrite existing container.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Script that will be executed during various steps in the containers lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Set a host name for the container.","enum":[],"extra":{"typetext":""},"format":"dns-name","max_length":255,"optional":true,"properties":{},"type":"string"},"name":"hostname"},{"definition":{"description":"Ignore errors when extracting the template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ignore-unpack-errors"},{"definition":{"description":"Lock/unlock the container.","enum":["backup","create","destroyed","disk","fstrim","migrate","mounted","rollback","snapshot","snapshot-delete"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"default":512,"description":"Amount of RAM for the container in MB.","enum":[],"extra":{"typetext":" (16 - N)"},"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"memory"},{"definition":{"description":"Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[volume=] ,mp= [,acl=<1|0>] [,backup=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]"},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"backup":{"description":"Whether to include the mount point in backups.","optional":1,"type":"boolean","verbose_description":"Whether to include the mount point in backups (only used for volume mount points)."},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)","type":"string"},"mp":{"description":"Path to the mount point as seen from inside the container (must not contain symlinks).","format":"pve-lxc-mp-string","format_description":"Path","type":"string","verbose_description":"Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons."},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"mp[n]"},{"definition":{"description":"Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{"typetext":""},"format":"lxc-ip-with-ll-iface-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specifies network interfaces for the container.","enum":[],"extra":{"typetext":"name= [,bridge=] [,firewall=<1|0>] [,gw=] [,gw6=] [,hwaddr=] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=<(IPv6/CIDR|auto|dhcp|manual)>] [,link_down=<1|0>] [,mtu=] [,rate=] [,tag=] [,trunks=] [,type=]"},"format":{"bridge":{"description":"Bridge to attach the network device to.","format_description":"bridge","optional":1,"pattern":"[-_.\\w\\d]+","type":"string"},"firewall":{"description":"Controls whether this interface's firewall rules should be used.","optional":1,"type":"boolean"},"gw":{"description":"Default gateway for IPv4 traffic.","format":"ipv4","format_description":"GatewayIPv4","optional":1,"type":"string"},"gw6":{"description":"Default gateway for IPv6 traffic.","format":"ipv6","format_description":"GatewayIPv6","optional":1,"type":"string"},"hwaddr":{"description":"The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"ip":{"description":"IPv4 address in CIDR format.","format":"pve-ipv4-config","format_description":"(IPv4/CIDR|dhcp|manual)","optional":1,"type":"string"},"ip6":{"description":"IPv6 address in CIDR format.","format":"pve-ipv6-config","format_description":"(IPv6/CIDR|auto|dhcp|manual)","optional":1,"type":"string"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"mtu":{"description":"Maximum transfer unit of the interface. (lxc.network.mtu)","maximum":65535,"minimum":64,"optional":1,"type":"integer"},"name":{"description":"Name of the network device as seen from inside the container. (lxc.network.name)","format_description":"string","pattern":"[-_.\\w\\d]+","type":"string"},"rate":{"description":"Apply rate limiting to the interface","format_description":"mbps","optional":1,"type":"number"},"tag":{"description":"VLAN tag for this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN ids to pass through the interface","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:;\\d+)*)","type":"string"},"type":{"description":"Network interface type.","enum":["veth"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Specifies whether a container will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"The OS template or backup file.","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"ostemplate"},{"definition":{"description":"OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.","enum":["debian","devuan","ubuntu","centos","fedora","opensuse","archlinux","alpine","gentoo","nixos","unmanaged"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"description":"Sets root password inside container.","enum":[],"extra":{"typetext":""},"min_length":5,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Add the VM to the specified pool.","enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"default":0,"description":"Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"description":"Mark this as restore task.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restore"},{"definition":{"description":"Use volume as container root.","enum":[],"extra":{"typetext":"[volume=] [,acl=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]"},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)","type":"string"},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"rootfs"},{"definition":{"description":"Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{"typetext":""},"format":"dns-name-list","optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ssh-public-keys"},{"definition":{"default":0,"description":"Start the CT after its creation finished successfully.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"start"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"default":"local","description":"Default Storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"default":512,"description":"Amount of SWAP for the container in MB.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"swap"},{"definition":{"description":"Tags of the Container. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab","enum":[],"extra":{"typetext":""},"format":"pve-ct-timezone","optional":true,"properties":{},"type":"string"},"name":"timezone"},{"definition":{"default":2,"description":"Specify the number of tty available to the container","enum":[],"extra":{"typetext":" (0 - 6)"},"maximum":6,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"tty"},{"definition":{"description":"Assign a unique random ethernet address.","enum":[],"extra":{"requires":"restore","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"unique"},{"definition":{"default":0,"description":"Makes the container run as unprivileged user. (Should not be modified manually.)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"unprivileged"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[volume=]"},"format":{"volume":{"default_key":1,"description":"The volume that is not used currently.","format":"pve-volume-id","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permission on /vms/{vmid} or on the VM pool /pool/{pool}. For restore, it is enough if the user has 'VM.Backup' permission and the VM already exists. You also need 'Datastore.AllocateSpace' permissions on the storage.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c19475ddef11337e048bb0acd1838036c83e7f6c9e9087b79f44af4db7ddaa96","description":"Destroy the container (also delete all uses files).","extra":{"proxyto":"node"},"name":"destroy_vm","parameters":[{"definition":{"description":"If set, destroy additionally all disks with the VMID from all enabled storages which are not referenced in the config.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"destroy-unreferenced-disks"},{"definition":{"default":0,"description":"Force destroy, even if running.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Remove container from all related configurations. For example, backup jobs, replication jobs or HA. Related ACLs and Firewall entries will *always* be removed.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"purge"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"9e36c28967bab606c23a50ff07fa5524991078437cdd75bba7697aac8a894802","description":"Directory index","extra":{"proxyto":"node"},"name":"vmdiridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4bbb53382d608d5df0acb24c45061badb77671649b3feb996359f7d9b1b671ae","description":"Create a container clone/copy","extra":{"proxyto":"node"},"name":"clone_vm","parameters":[{"definition":{"default":"clone limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"description":"Description for the new CT.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Create a full copy of all disks. This is always done when you clone a normal CT. For CT templates, we try to create a linked clone by default.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"},{"definition":{"description":"Set a hostname for the new CT.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"hostname"},{"definition":{"description":"VMID for the clone.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"newid"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Add the new CT to the specified pool.","enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"Target storage for full clone.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Target node. Only allowed if the original VM is on shared storage.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions on /vms/{newid} (or on the VM pool /pool/{pool}). You also need 'Datastore.AllocateSpace' on any used storage, and 'SDN.Use' on any bridge.","expression":{"check":["and",["perm","/vms/{vmid}",["VM.Clone"]],["or",["perm","/vms/{newid}",["VM.Allocate"]],["perm","/pool/{pool}",["VM.Allocate"],"require_param","pool"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/clone"},{"extra":{},"methods":[{"allow_token":true,"checksum":"fbbeb57ca1e4e7ac589e6fa58d56d1641343bc7fc67697af0be3f26e8825ec12","description":"Get container configuration.","extra":{"proxyto":"node"},"name":"vm_config","parameters":[{"definition":{"default":0,"description":"Get current values (instead of pending values).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"current"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Fetch config values from given snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapshot"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"arch":{"default":"amd64","description":"OS architecture type.","enum":["amd64","i386","arm64","armhf","riscv32","riscv64"],"extra":{},"optional":true,"properties":{},"type":"string"},"cmode":{"default":"tty","description":"Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).","enum":["shell","console","tty"],"extra":{},"optional":true,"properties":{},"type":"string"},"console":{"default":1,"description":"Attach a console device (/dev/console) to the container.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"cores":{"description":"The number of cores assigned to the container. A container can use all available cores by default.","enum":[],"extra":{},"maximum":8192,"minimum":1,"optional":true,"properties":{},"type":"integer"},"cpulimit":{"default":0,"description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.","enum":[],"extra":{},"maximum":8192,"minimum":0,"optional":true,"properties":{},"type":"number"},"cpuunits":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"verbose_description":"CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests."},"maximum":500000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"debug":{"default":0,"description":"Try to be more verbose. For now this only enables debug log-level on start.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"description":{"description":"Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{},"max_length":8192,"optional":true,"properties":{},"type":"string"},"dev[n]":{"description":"Device to pass through to the container","enum":[],"extra":{},"format":{"deny-write":{"default":0,"description":"Deny the container to write to the device","optional":1,"type":"boolean"},"gid":{"description":"Group ID to be assigned to the device node","minimum":0,"optional":1,"type":"integer"},"mode":{"description":"Access mode to be set on the device node","format_description":"Octal access mode","optional":1,"pattern":"0[0-7]{3}","type":"string"},"path":{"default_key":1,"description":"Device to pass through to the container","format":"pve-lxc-dev-string","format_description":"Path","optional":1,"type":"string","verbose_description":"Path to the device to pass through to the container"},"uid":{"description":"User ID to be assigned to the device node","minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"digest":{"description":"SHA1 digest of configuration file. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"properties":{},"type":"string"},"features":{"description":"Allow containers access to advanced features.","enum":[],"extra":{},"format":{"force_rw_sys":{"default":0,"description":"Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.","optional":1,"type":"boolean"},"fuse":{"default":0,"description":"Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.","optional":1,"type":"boolean"},"keyctl":{"default":0,"description":"For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.","optional":1,"type":"boolean"},"mknod":{"default":0,"description":"Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.","optional":1,"type":"boolean"},"mount":{"description":"Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.","format_description":"fstype;fstype;...","optional":1,"pattern":"(?^:[a-zA-Z0-9_; ]+)","type":"string"},"nesting":{"default":0,"description":"Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"hookscript":{"description":"Script that will be executed during various steps in the containers lifetime.","enum":[],"extra":{},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"hostname":{"description":"Set a host name for the container.","enum":[],"extra":{},"format":"dns-name","max_length":255,"optional":true,"properties":{},"type":"string"},"lock":{"description":"Lock/unlock the container.","enum":["backup","create","destroyed","disk","fstrim","migrate","mounted","rollback","snapshot","snapshot-delete"],"extra":{},"optional":true,"properties":{},"type":"string"},"lxc":{"description":"Array of lxc low-level configurations ([[key1, value1], [key2, value2] ...]).","enum":[],"extra":{},"items":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"optional":true,"properties":{},"type":"array"},"memory":{"default":512,"description":"Amount of RAM for the container in MB.","enum":[],"extra":{},"minimum":16,"optional":true,"properties":{},"type":"integer"},"mp[n]":{"description":"Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"backup":{"description":"Whether to include the mount point in backups.","optional":1,"type":"boolean","verbose_description":"Whether to include the mount point in backups (only used for volume mount points)."},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)","type":"string"},"mp":{"description":"Path to the mount point as seen from inside the container (must not contain symlinks).","format":"pve-lxc-mp-string","format_description":"Path","type":"string","verbose_description":"Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons."},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"nameserver":{"description":"Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{},"format":"lxc-ip-with-ll-iface-list","optional":true,"properties":{},"type":"string"},"net[n]":{"description":"Specifies network interfaces for the container.","enum":[],"extra":{},"format":{"bridge":{"description":"Bridge to attach the network device to.","format_description":"bridge","optional":1,"pattern":"[-_.\\w\\d]+","type":"string"},"firewall":{"description":"Controls whether this interface's firewall rules should be used.","optional":1,"type":"boolean"},"gw":{"description":"Default gateway for IPv4 traffic.","format":"ipv4","format_description":"GatewayIPv4","optional":1,"type":"string"},"gw6":{"description":"Default gateway for IPv6 traffic.","format":"ipv6","format_description":"GatewayIPv6","optional":1,"type":"string"},"hwaddr":{"description":"The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"ip":{"description":"IPv4 address in CIDR format.","format":"pve-ipv4-config","format_description":"(IPv4/CIDR|dhcp|manual)","optional":1,"type":"string"},"ip6":{"description":"IPv6 address in CIDR format.","format":"pve-ipv6-config","format_description":"(IPv6/CIDR|auto|dhcp|manual)","optional":1,"type":"string"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"mtu":{"description":"Maximum transfer unit of the interface. (lxc.network.mtu)","maximum":65535,"minimum":64,"optional":1,"type":"integer"},"name":{"description":"Name of the network device as seen from inside the container. (lxc.network.name)","format_description":"string","pattern":"[-_.\\w\\d]+","type":"string"},"rate":{"description":"Apply rate limiting to the interface","format_description":"mbps","optional":1,"type":"number"},"tag":{"description":"VLAN tag for this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN ids to pass through the interface","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:;\\d+)*)","type":"string"},"type":{"description":"Network interface type.","enum":["veth"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"onboot":{"default":0,"description":"Specifies whether a container will be started during system bootup.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ostype":{"description":"OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.","enum":["debian","devuan","ubuntu","centos","fedora","opensuse","archlinux","alpine","gentoo","nixos","unmanaged"],"extra":{},"optional":true,"properties":{},"type":"string"},"protection":{"default":0,"description":"Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"rootfs":{"description":"Use volume as container root.","enum":[],"extra":{},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)","type":"string"},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"searchdomain":{"description":"Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{},"format":"dns-name-list","optional":true,"properties":{},"type":"string"},"startup":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"swap":{"default":512,"description":"Amount of SWAP for the container in MB.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"tags":{"description":"Tags of the Container. This is only meta information.","enum":[],"extra":{},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"template":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"timezone":{"description":"Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab","enum":[],"extra":{},"format":"pve-ct-timezone","optional":true,"properties":{},"type":"string"},"tty":{"default":2,"description":"Specify the number of tty available to the container","enum":[],"extra":{},"maximum":6,"minimum":0,"optional":true,"properties":{},"type":"integer"},"unprivileged":{"default":0,"description":"Makes the container run as unprivileged user. (Should not be modified manually.)","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"unused[n]":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{},"format":{"volume":{"default_key":1,"description":"The volume that is not used currently.","format":"pve-volume-id","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"9d744f7aed1a40b64cddcc2b597a93a82491bd4daa085f64ac8d4f50ae24c1b9","description":"Set container options.","extra":{"proxyto":"node"},"name":"update_vm","parameters":[{"definition":{"default":"amd64","description":"OS architecture type.","enum":["amd64","i386","arm64","armhf","riscv32","riscv64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"default":"tty","description":"Console mode. By default, the console command tries to open a connection to one of the available tty devices. By setting cmode to 'console' it tries to attach to /dev/console instead. If you set cmode to 'shell', it simply invokes a shell inside the container (no login).","enum":["shell","console","tty"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmode"},{"definition":{"default":1,"description":"Attach a console device (/dev/console) to the container.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"console"},{"definition":{"description":"The number of cores assigned to the container. A container can use all available cores by default.","enum":[],"extra":{"typetext":" (1 - 8192)"},"maximum":8192,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"default":0,"description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit.","enum":[],"extra":{"typetext":" (0 - 8192)"},"maximum":8192,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"typetext":" (0 - 500000)","verbose_description":"CPU weight for a container. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this container gets. Number is relative to the weights of all the other running guests."},"maximum":500000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"default":0,"description":"Try to be more verbose. For now this only enables debug log-level on start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"debug"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":8192,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Device to pass through to the container","enum":[],"extra":{"typetext":"[[path=]] [,deny-write=<1|0>] [,gid=] [,mode=] [,uid=]"},"format":{"deny-write":{"default":0,"description":"Deny the container to write to the device","optional":1,"type":"boolean"},"gid":{"description":"Group ID to be assigned to the device node","minimum":0,"optional":1,"type":"integer"},"mode":{"description":"Access mode to be set on the device node","format_description":"Octal access mode","optional":1,"pattern":"0[0-7]{3}","type":"string"},"path":{"default_key":1,"description":"Device to pass through to the container","format":"pve-lxc-dev-string","format_description":"Path","optional":1,"type":"string","verbose_description":"Path to the device to pass through to the container"},"uid":{"description":"User ID to be assigned to the device node","minimum":0,"optional":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"dev[n]"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Allow containers access to advanced features.","enum":[],"extra":{"typetext":"[force_rw_sys=<1|0>] [,fuse=<1|0>] [,keyctl=<1|0>] [,mknod=<1|0>] [,mount=] [,nesting=<1|0>]"},"format":{"force_rw_sys":{"default":0,"description":"Mount /sys in unprivileged containers as `rw` instead of `mixed`. This can break networking under newer (>= v245) systemd-network use.","optional":1,"type":"boolean"},"fuse":{"default":0,"description":"Allow using 'fuse' file systems in a container. Note that interactions between fuse and the freezer cgroup can potentially cause I/O deadlocks.","optional":1,"type":"boolean"},"keyctl":{"default":0,"description":"For unprivileged containers only: Allow the use of the keyctl() system call. This is required to use docker inside a container. By default unprivileged containers will see this system call as non-existent. This is mostly a workaround for systemd-networkd, as it will treat it as a fatal error when some keyctl() operations are denied by the kernel due to lacking permissions. Essentially, you can choose between running systemd-networkd or docker.","optional":1,"type":"boolean"},"mknod":{"default":0,"description":"Allow unprivileged containers to use mknod() to add certain device nodes. This requires a kernel with seccomp trap to user space support (5.3 or newer). This is experimental.","optional":1,"type":"boolean"},"mount":{"description":"Allow mounting file systems of specific types. This should be a list of file system types as used with the mount command. Note that this can have negative effects on the container's security. With access to a loop device, mounting a file can circumvent the mknod permission of the devices cgroup, mounting an NFS file system can block the host's I/O completely and prevent it from rebooting, etc.","format_description":"fstype;fstype;...","optional":1,"pattern":"(?^:[a-zA-Z0-9_; ]+)","type":"string"},"nesting":{"default":0,"description":"Allow nesting. Best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"features"},{"definition":{"description":"Script that will be executed during various steps in the containers lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Set a host name for the container.","enum":[],"extra":{"typetext":""},"format":"dns-name","max_length":255,"optional":true,"properties":{},"type":"string"},"name":"hostname"},{"definition":{"description":"Lock/unlock the container.","enum":["backup","create","destroyed","disk","fstrim","migrate","mounted","rollback","snapshot","snapshot-delete"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"default":512,"description":"Amount of RAM for the container in MB.","enum":[],"extra":{"typetext":" (16 - N)"},"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"memory"},{"definition":{"description":"Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.","enum":[],"extra":{"typetext":"[volume=] ,mp= [,acl=<1|0>] [,backup=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]"},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"backup":{"description":"Whether to include the mount point in backups.","optional":1,"type":"boolean","verbose_description":"Whether to include the mount point in backups (only used for volume mount points)."},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)","type":"string"},"mp":{"description":"Path to the mount point as seen from inside the container (must not contain symlinks).","format":"pve-lxc-mp-string","format_description":"Path","type":"string","verbose_description":"Path to the mount point as seen from inside the container.\n\nNOTE: Must not contain any symlinks for security reasons."},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"mp[n]"},{"definition":{"description":"Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{"typetext":""},"format":"lxc-ip-with-ll-iface-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specifies network interfaces for the container.","enum":[],"extra":{"typetext":"name= [,bridge=] [,firewall=<1|0>] [,gw=] [,gw6=] [,hwaddr=] [,ip=<(IPv4/CIDR|dhcp|manual)>] [,ip6=<(IPv6/CIDR|auto|dhcp|manual)>] [,link_down=<1|0>] [,mtu=] [,rate=] [,tag=] [,trunks=] [,type=]"},"format":{"bridge":{"description":"Bridge to attach the network device to.","format_description":"bridge","optional":1,"pattern":"[-_.\\w\\d]+","type":"string"},"firewall":{"description":"Controls whether this interface's firewall rules should be used.","optional":1,"type":"boolean"},"gw":{"description":"Default gateway for IPv4 traffic.","format":"ipv4","format_description":"GatewayIPv4","optional":1,"type":"string"},"gw6":{"description":"Default gateway for IPv6 traffic.","format":"ipv6","format_description":"GatewayIPv6","optional":1,"type":"string"},"hwaddr":{"description":"The interface MAC address. This is dynamically allocated by default, but you can set that statically if needed, for example to always have the same link-local IPv6 address. (lxc.network.hwaddr)","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"ip":{"description":"IPv4 address in CIDR format.","format":"pve-ipv4-config","format_description":"(IPv4/CIDR|dhcp|manual)","optional":1,"type":"string"},"ip6":{"description":"IPv6 address in CIDR format.","format":"pve-ipv6-config","format_description":"(IPv6/CIDR|auto|dhcp|manual)","optional":1,"type":"string"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"mtu":{"description":"Maximum transfer unit of the interface. (lxc.network.mtu)","maximum":65535,"minimum":64,"optional":1,"type":"integer"},"name":{"description":"Name of the network device as seen from inside the container. (lxc.network.name)","format_description":"string","pattern":"[-_.\\w\\d]+","type":"string"},"rate":{"description":"Apply rate limiting to the interface","format_description":"mbps","optional":1,"type":"number"},"tag":{"description":"VLAN tag for this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN ids to pass through the interface","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:;\\d+)*)","type":"string"},"type":{"description":"Network interface type.","enum":["veth"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Specifies whether a container will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"OS type. This is used to setup configuration inside the container, and corresponds to lxc setup scripts in /usr/share/lxc/config/.common.conf. Value 'unmanaged' can be used to skip and OS specific setup.","enum":["debian","devuan","ubuntu","centos","fedora","opensuse","archlinux","alpine","gentoo","nixos","unmanaged"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"default":0,"description":"Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"description":"Revert a pending change.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"revert"},{"definition":{"description":"Use volume as container root.","enum":[],"extra":{"typetext":"[volume=] [,acl=<1|0>] [,mountoptions=] [,quota=<1|0>] [,replicate=<1|0>] [,ro=<1|0>] [,shared=<1|0>] [,size=]"},"format":{"acl":{"description":"Explicitly enable or disable ACL support.","optional":1,"type":"boolean"},"mountoptions":{"description":"Extra mount options for rootfs/mps.","format_description":"opt[;opt...]","optional":1,"pattern":"(?^:(?^:(discard|lazytime|noatime|nodev|noexec|nosuid))(;(?^:(discard|lazytime|noatime|nodev|noexec|nosuid)))*)","type":"string"},"quota":{"description":"Enable user quotas inside the container (not supported with zfs subvolumes)","optional":1,"type":"boolean"},"replicate":{"default":1,"description":"Will include this volume to a storage replica job.","optional":1,"type":"boolean"},"ro":{"description":"Read-only mount point","optional":1,"type":"boolean"},"shared":{"default":0,"description":"Mark this non-volume mount point as available on multiple nodes (see 'nodes')","optional":1,"type":"boolean","verbose_description":"Mark this non-volume mount point as available on all nodes.\n\nWARNING: This option does not share the mount point automatically, it assumes it is shared already!"},"size":{"description":"Volume size (read only value).","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"default_key":1,"description":"Volume, device or directory to mount into the container.","format":"pve-lxc-mp-string","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"rootfs"},{"definition":{"description":"Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.","enum":[],"extra":{"typetext":""},"format":"dns-name-list","optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"default":512,"description":"Amount of SWAP for the container in MB.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"swap"},{"definition":{"description":"Tags of the Container. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Time zone to use in the container. If option isn't set, then nothing will be done. Can be set to 'host' to match the host time zone, or an arbitrary time zone option from /usr/share/zoneinfo/zone.tab","enum":[],"extra":{"typetext":""},"format":"pve-ct-timezone","optional":true,"properties":{},"type":"string"},"name":"timezone"},{"definition":{"default":2,"description":"Specify the number of tty available to the container","enum":[],"extra":{"typetext":" (0 - 6)"},"maximum":6,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"tty"},{"definition":{"default":0,"description":"Makes the container run as unprivileged user. (Should not be modified manually.)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"unprivileged"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[volume=]"},"format":{"volume":{"default_key":1,"description":"The volume that is not used currently.","format":"pve-volume-id","format_description":"volume","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"non-volume mount points in rootfs and mp[n] are restricted to root@pam","expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk","VM.Config.CPU","VM.Config.Memory","VM.Config.Network","VM.Config.Options"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1cca28754546ef80b178a942204d1b34b746054d684c6e37c44488c2d6a58e2d","description":"Check if feature for virtual machine is available.","extra":{"proxyto":"node"},"name":"vm_feature","parameters":[{"definition":{"description":"Feature to check.","enum":["snapshot","clone","copy"],"extra":{},"properties":{},"type":"string"},"name":"feature"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"hasFeature":{"enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/feature"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7ee5be237c4406d406b763db7b1c3deb794543cfa9e5376476821ff4ad174512","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0e240eee88d783388fa7fd5c605d1946866c6de040a5072e91675a7d06594943","description":"List aliases","extra":{},"name":"get_aliases","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"24f08f4001bb83fb2a6d7e9a6a5d0c3692949ea94751c543f2ce056e43beeacb","description":"Create IP or Network Alias.","extra":{},"name":"create_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/aliases"},{"extra":{},"methods":[{"allow_token":true,"checksum":"547018a4e77e1f19d15e71017e8e7e7bdb3f893052f3a61c4ac77fe1a23a7524","description":"Remove IP or Network alias.","extra":{},"name":"remove_alias","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f5bce1f868d6f087fc556f605b8dba1dadf850207fb04bbddc999079cd9486b7","description":"Read alias.","extra":{},"name":"read_alias","parameters":[{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"1e344b0d51e8e531d0d525f26ebe09c01f6c4cf270e92c36ebe11eca2779dcee","description":"Update IP or Network alias.","extra":{},"name":"update_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Rename an existing alias.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"406378d5359b09bbd6589c105f8df2f99aeef8a54b526302377c06fe5401770e","description":"List IPSets","extra":{},"name":"ipset_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"name":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f4bb41ff25f7d50144a81944017055185c7a72e313a861f8a0406de6bf34ecf2","description":"Create new IPSet","extra":{},"name":"create_ipset","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/ipset"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a40e1badd168974a686fc466a2e06598ef9762be5b279a8f1fa0eca53f7d4880","description":"Delete IPSet","extra":{},"name":"delete_ipset","parameters":[{"definition":{"description":"Delete all members of the IPSet, if there are any.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"5fc76313da1679fa4a2631d95ce58eb8b267a2dd67a0c1a8ac5a55a0ab34b13c","description":"List IPSet content","extra":{},"name":"get_ipset","parameters":[{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cidr}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"nomatch":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"a3ace74f6557fc643406d7775bd8e6eb21c0200d079174ee43ee5a0fd24506c9","description":"Add IP or Network to IPSet.","extra":{},"name":"create_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5f612a84aecce1fd03bb87a7e7c15c6786474a3e211f958a0281c55c835eeebc","description":"Remove IP or Network from IPSet.","extra":{},"name":"remove_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"cae0afef06b37e0a88847c53e617e5a4def2d669bf4da3f4d541cdf1811046a4","description":"Read IP or Network settings from IPSet.","extra":{},"name":"read_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"bb0b6ded1cf4736fae405e8af7ccf92e10623473112c4bb7a73992fdb81b4a2f","description":"Update IP or Network settings","extra":{},"name":"update_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d6b7e9154ddc56bd6b0b9af8378442e873109fc13d420483930da8dafe5fad5c","description":"Read firewall log","extra":{"proxyto":"node"},"name":"log","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Display log since this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"since"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"Display log until this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"until"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"22f206f7dd8a836164bca4599b7db3619a67e37273a95349f21e528fdf1ab8f8","description":"Get VM firewall options.","extra":{"proxyto":"node"},"name":"get_options","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"dhcp":{"default":0,"description":"Enable DHCP.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"enable":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ipfilter":{"description":"Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"log_level_in":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_level_out":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macfilter":{"default":1,"description":"Enable/disable MAC address filter.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ndp":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"policy_in":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"policy_out":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"radv":{"description":"Allow sending Router Advertisement.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"f9b4d8f7a53f2384072a66bac3473aa3052c297bc84c23a3adfdb81b594eaaac","description":"Set Firewall options.","extra":{"proxyto":"node"},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"default":0,"description":"Enable DHCP.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"dhcp"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ipfilter"},{"definition":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_in"},{"definition":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_out"},{"definition":{"default":1,"description":"Enable/disable MAC address filter.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"macfilter"},{"definition":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ndp"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_in"},{"definition":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_out"},{"definition":{"description":"Allow sending Router Advertisement.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"radv"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4d9b684dc2793a1badcd82adfe45cf304ab1efec63d4b53ff4ea0402242531d3","description":"Lists possible IPSet/Alias reference which are allowed in source/dest properties.","extra":{},"name":"refs","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list references of specified type.","enum":["alias","ipset"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"ref":{"enum":[],"extra":{},"properties":{},"type":"string"},"scope":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":["alias","ipset"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/refs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1e676eac6df97edb5a337b8ecd0aa90376496327c0712f7beec2190bec5137a1","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"8031675c54c1cfbf59734cd14ad9735f26d24b9a3960fb0a9e8420731f3d5e51","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"464d07111ad5ee01829e46153bd86a7a820949db1b9fb33ddc3144037e35f734","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f832e12c8239ec5ff27b7029d35cb91032e3059cc37e111230f82b8c74711746","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"7f95e71affdc035175864e9fdc728419b98b26887f2b75d4e04ab52c8db841e4","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"db50c406622b6a6be675d45be4eabf8616f10a670120c8bfe9daee0e3bca0365","description":"Get IP addresses of the specified container interface.","extra":{"proxyto":"node"},"name":"ip","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"hardware-address":{"description":"The MAC address of the interface","enum":[],"extra":{},"optional":false,"properties":{},"type":"string"},"hwaddr":{"description":"The MAC address of the interface","enum":[],"extra":{},"optional":false,"properties":{},"type":"string"},"inet":{"description":"The IPv4 address of the interface","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"inet6":{"description":"The IPv6 address of the interface","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ip-addresses":{"description":"The addresses of the interface","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"ip-address":{"description":"IP-Address","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ip-address-type":{"description":"IP-Family","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"prefix":{"description":"IP-Prefix","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"optional":false,"properties":{},"type":"array"},"name":{"description":"The name of the interface","enum":[],"extra":{},"optional":false,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/interfaces"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2e51013f613ed89d385f9e2be74bbdbdb760cc082b7a89d4264699ea2d8fb201","description":"Migrate the container to another node. Creates a new migration task.","extra":{"proxyto":"node"},"name":"migrate_vm","parameters":[{"definition":{"default":"migrate limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use online/live migration.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"online"},{"definition":{"description":"Use restart migration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restart"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storage-pair-list","optional":true,"properties":{},"type":"string"},"name":"target-storage"},{"definition":{"default":180,"description":"Timeout in seconds for shutdown for restart migration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5dc2e0078cc64480a11331ee212a52548608d8e15a628540354b59057841d366","description":"Move a rootfs-/mp-volume to a different storage or to a different container.","extra":{"proxyto":"node"},"name":"move_volume","parameters":[{"definition":{"default":"clone limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"default":0,"description":"Delete the original volume after successful copy. By default the original is kept as an unused volume entry.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 \" .\n\t\t \"digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target Storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Prevent changes if current configuration file of the target \" .\n\t\t \"container has a different SHA1 digest. This can be used to prevent \" .\n\t\t \"concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"target-digest"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"target-vmid"},{"definition":{"description":"The config key the volume will be moved to. Default is the source volume key.","enum":["rootfs","mp0","mp1","mp2","mp3","mp4","mp5","mp6","mp7","mp8","mp9","mp10","mp11","mp12","mp13","mp14","mp15","mp16","mp17","mp18","mp19","mp20","mp21","mp22","mp23","mp24","mp25","mp26","mp27","mp28","mp29","mp30","mp31","mp32","mp33","mp34","mp35","mp36","mp37","mp38","mp39","mp40","mp41","mp42","mp43","mp44","mp45","mp46","mp47","mp48","mp49","mp50","mp51","mp52","mp53","mp54","mp55","mp56","mp57","mp58","mp59","mp60","mp61","mp62","mp63","mp64","mp65","mp66","mp67","mp68","mp69","mp70","mp71","mp72","mp73","mp74","mp75","mp76","mp77","mp78","mp79","mp80","mp81","mp82","mp83","mp84","mp85","mp86","mp87","mp88","mp89","mp90","mp91","mp92","mp93","mp94","mp95","mp96","mp97","mp98","mp99","mp100","mp101","mp102","mp103","mp104","mp105","mp106","mp107","mp108","mp109","mp110","mp111","mp112","mp113","mp114","mp115","mp116","mp117","mp118","mp119","mp120","mp121","mp122","mp123","mp124","mp125","mp126","mp127","mp128","mp129","mp130","mp131","mp132","mp133","mp134","mp135","mp136","mp137","mp138","mp139","mp140","mp141","mp142","mp143","mp144","mp145","mp146","mp147","mp148","mp149","mp150","mp151","mp152","mp153","mp154","mp155","mp156","mp157","mp158","mp159","mp160","mp161","mp162","mp163","mp164","mp165","mp166","mp167","mp168","mp169","mp170","mp171","mp172","mp173","mp174","mp175","mp176","mp177","mp178","mp179","mp180","mp181","mp182","mp183","mp184","mp185","mp186","mp187","mp188","mp189","mp190","mp191","mp192","mp193","mp194","mp195","mp196","mp197","mp198","mp199","mp200","mp201","mp202","mp203","mp204","mp205","mp206","mp207","mp208","mp209","mp210","mp211","mp212","mp213","mp214","mp215","mp216","mp217","mp218","mp219","mp220","mp221","mp222","mp223","mp224","mp225","mp226","mp227","mp228","mp229","mp230","mp231","mp232","mp233","mp234","mp235","mp236","mp237","mp238","mp239","mp240","mp241","mp242","mp243","mp244","mp245","mp246","mp247","mp248","mp249","mp250","mp251","mp252","mp253","mp254","mp255","unused0","unused1","unused2","unused3","unused4","unused5","unused6","unused7","unused8","unused9","unused10","unused11","unused12","unused13","unused14","unused15","unused16","unused17","unused18","unused19","unused20","unused21","unused22","unused23","unused24","unused25","unused26","unused27","unused28","unused29","unused30","unused31","unused32","unused33","unused34","unused35","unused36","unused37","unused38","unused39","unused40","unused41","unused42","unused43","unused44","unused45","unused46","unused47","unused48","unused49","unused50","unused51","unused52","unused53","unused54","unused55","unused56","unused57","unused58","unused59","unused60","unused61","unused62","unused63","unused64","unused65","unused66","unused67","unused68","unused69","unused70","unused71","unused72","unused73","unused74","unused75","unused76","unused77","unused78","unused79","unused80","unused81","unused82","unused83","unused84","unused85","unused86","unused87","unused88","unused89","unused90","unused91","unused92","unused93","unused94","unused95","unused96","unused97","unused98","unused99","unused100","unused101","unused102","unused103","unused104","unused105","unused106","unused107","unused108","unused109","unused110","unused111","unused112","unused113","unused114","unused115","unused116","unused117","unused118","unused119","unused120","unused121","unused122","unused123","unused124","unused125","unused126","unused127","unused128","unused129","unused130","unused131","unused132","unused133","unused134","unused135","unused136","unused137","unused138","unused139","unused140","unused141","unused142","unused143","unused144","unused145","unused146","unused147","unused148","unused149","unused150","unused151","unused152","unused153","unused154","unused155","unused156","unused157","unused158","unused159","unused160","unused161","unused162","unused163","unused164","unused165","unused166","unused167","unused168","unused169","unused170","unused171","unused172","unused173","unused174","unused175","unused176","unused177","unused178","unused179","unused180","unused181","unused182","unused183","unused184","unused185","unused186","unused187","unused188","unused189","unused190","unused191","unused192","unused193","unused194","unused195","unused196","unused197","unused198","unused199","unused200","unused201","unused202","unused203","unused204","unused205","unused206","unused207","unused208","unused209","unused210","unused211","unused212","unused213","unused214","unused215","unused216","unused217","unused218","unused219","unused220","unused221","unused222","unused223","unused224","unused225","unused226","unused227","unused228","unused229","unused230","unused231","unused232","unused233","unused234","unused235","unused236","unused237","unused238","unused239","unused240","unused241","unused242","unused243","unused244","unused245","unused246","unused247","unused248","unused249","unused250","unused251","unused252","unused253","unused254","unused255"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"target-volume"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Volume which will be moved.","enum":["rootfs","mp0","mp1","mp2","mp3","mp4","mp5","mp6","mp7","mp8","mp9","mp10","mp11","mp12","mp13","mp14","mp15","mp16","mp17","mp18","mp19","mp20","mp21","mp22","mp23","mp24","mp25","mp26","mp27","mp28","mp29","mp30","mp31","mp32","mp33","mp34","mp35","mp36","mp37","mp38","mp39","mp40","mp41","mp42","mp43","mp44","mp45","mp46","mp47","mp48","mp49","mp50","mp51","mp52","mp53","mp54","mp55","mp56","mp57","mp58","mp59","mp60","mp61","mp62","mp63","mp64","mp65","mp66","mp67","mp68","mp69","mp70","mp71","mp72","mp73","mp74","mp75","mp76","mp77","mp78","mp79","mp80","mp81","mp82","mp83","mp84","mp85","mp86","mp87","mp88","mp89","mp90","mp91","mp92","mp93","mp94","mp95","mp96","mp97","mp98","mp99","mp100","mp101","mp102","mp103","mp104","mp105","mp106","mp107","mp108","mp109","mp110","mp111","mp112","mp113","mp114","mp115","mp116","mp117","mp118","mp119","mp120","mp121","mp122","mp123","mp124","mp125","mp126","mp127","mp128","mp129","mp130","mp131","mp132","mp133","mp134","mp135","mp136","mp137","mp138","mp139","mp140","mp141","mp142","mp143","mp144","mp145","mp146","mp147","mp148","mp149","mp150","mp151","mp152","mp153","mp154","mp155","mp156","mp157","mp158","mp159","mp160","mp161","mp162","mp163","mp164","mp165","mp166","mp167","mp168","mp169","mp170","mp171","mp172","mp173","mp174","mp175","mp176","mp177","mp178","mp179","mp180","mp181","mp182","mp183","mp184","mp185","mp186","mp187","mp188","mp189","mp190","mp191","mp192","mp193","mp194","mp195","mp196","mp197","mp198","mp199","mp200","mp201","mp202","mp203","mp204","mp205","mp206","mp207","mp208","mp209","mp210","mp211","mp212","mp213","mp214","mp215","mp216","mp217","mp218","mp219","mp220","mp221","mp222","mp223","mp224","mp225","mp226","mp227","mp228","mp229","mp230","mp231","mp232","mp233","mp234","mp235","mp236","mp237","mp238","mp239","mp240","mp241","mp242","mp243","mp244","mp245","mp246","mp247","mp248","mp249","mp250","mp251","mp252","mp253","mp254","mp255","unused0","unused1","unused2","unused3","unused4","unused5","unused6","unused7","unused8","unused9","unused10","unused11","unused12","unused13","unused14","unused15","unused16","unused17","unused18","unused19","unused20","unused21","unused22","unused23","unused24","unused25","unused26","unused27","unused28","unused29","unused30","unused31","unused32","unused33","unused34","unused35","unused36","unused37","unused38","unused39","unused40","unused41","unused42","unused43","unused44","unused45","unused46","unused47","unused48","unused49","unused50","unused51","unused52","unused53","unused54","unused55","unused56","unused57","unused58","unused59","unused60","unused61","unused62","unused63","unused64","unused65","unused66","unused67","unused68","unused69","unused70","unused71","unused72","unused73","unused74","unused75","unused76","unused77","unused78","unused79","unused80","unused81","unused82","unused83","unused84","unused85","unused86","unused87","unused88","unused89","unused90","unused91","unused92","unused93","unused94","unused95","unused96","unused97","unused98","unused99","unused100","unused101","unused102","unused103","unused104","unused105","unused106","unused107","unused108","unused109","unused110","unused111","unused112","unused113","unused114","unused115","unused116","unused117","unused118","unused119","unused120","unused121","unused122","unused123","unused124","unused125","unused126","unused127","unused128","unused129","unused130","unused131","unused132","unused133","unused134","unused135","unused136","unused137","unused138","unused139","unused140","unused141","unused142","unused143","unused144","unused145","unused146","unused147","unused148","unused149","unused150","unused151","unused152","unused153","unused154","unused155","unused156","unused157","unused158","unused159","unused160","unused161","unused162","unused163","unused164","unused165","unused166","unused167","unused168","unused169","unused170","unused171","unused172","unused173","unused174","unused175","unused176","unused177","unused178","unused179","unused180","unused181","unused182","unused183","unused184","unused185","unused186","unused187","unused188","unused189","unused190","unused191","unused192","unused193","unused194","unused195","unused196","unused197","unused198","unused199","unused200","unused201","unused202","unused203","unused204","unused205","unused206","unused207","unused208","unused209","unused210","unused211","unused212","unused213","unused214","unused215","unused216","unused217","unused218","unused219","unused220","unused221","unused222","unused223","unused224","unused225","unused226","unused227","unused228","unused229","unused230","unused231","unused232","unused233","unused234","unused235","unused236","unused237","unused238","unused239","unused240","unused241","unused242","unused243","unused244","unused245","unused246","unused247","unused248","unused249","unused250","unused251","unused252","unused253","unused254","unused255"],"extra":{},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need 'VM.Config.Disk' permissions on /vms/{vmid}, and 'Datastore.AllocateSpace' permissions on the storage. To move a volume to another container, you need the permissions on the target container as well.","expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/move_volume"},{"extra":{},"methods":[{"allow_token":true,"checksum":"cbc77f1f6c5524d9dd0aefcc53a4574533b00d1500dd5efdeda1c0681e466b66","description":"Migration tunnel endpoint - only for internal use by CT migration.","extra":{},"name":"mtunnel","parameters":[{"definition":{"description":"List of network bridges to check availability. Will be checked again for actually used bridges during migration.","enum":[],"extra":{"typetext":""},"format":"pve-bridge-id-list","optional":true,"properties":{},"type":"string"},"name":"bridges"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"List of storages to check permission and availability. Will be checked again for all actually used storages during migration.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id-list","optional":true,"properties":{},"type":"string"},"name":"storages"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permissions on '/vms/{vmid}' and Sys.Incoming on '/'. Further permission checks happen during the actual migration.","expression":{"check":["and",["perm","/vms/{vmid}",["VM.Allocate"]],["perm","/",["Sys.Incoming"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"socket":{"enum":[],"extra":{},"properties":{},"type":"string"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/mtunnel"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5074d114941c7d6bcff687122305de9ba6fe8456c7b40ccc88b503ae5f07dd59","description":"Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration.","extra":{},"name":"mtunnelwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"unix socket to forward to","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"socket"},{"definition":{"description":"ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"ticket"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need to pass a ticket valid for the selected socket. Tickets can be created via the mtunnel API call, which will check permissions accordingly.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"socket":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/mtunnelwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"eca2f9833cddd3132e0f155a1e906060d21aeb47b0a5e90c16f88d6c6bbc7c33","description":"Get container configuration, including pending changes.","extra":{"proxyto":"node"},"name":"vm_pending","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"delete":{"description":"Indicates a pending delete request if present and not 0.","enum":[],"extra":{},"maximum":2,"minimum":0,"optional":true,"properties":{},"type":"integer"},"key":{"description":"Configuration option name.","enum":[],"extra":{},"properties":{},"type":"string"},"pending":{"description":"Pending value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"value":{"description":"Current value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/pending"},{"extra":{},"methods":[{"allow_token":true,"checksum":"92d79d188f48c5ec8412882f2b26b10068c51108355bd54185019dee990cd19d","description":"Migrate the container to another cluster. Creates a new migration task. EXPERIMENTAL feature!","extra":{"proxyto":"node"},"name":"remote_migrate_vm","parameters":[{"definition":{"default":"migrate limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"bwlimit"},{"definition":{"default":0,"description":"Delete the original CT and related data after successful migration. By default the original CT is kept on the source cluster in a stopped state.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use online/live migration.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"online"},{"definition":{"description":"Use restart migration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"restart"},{"definition":{"description":"Mapping from source to target bridges. Providing only a single bridge ID maps all source bridges to that bridge. Providing the special value '1' will map each source bridge to itself.","enum":[],"extra":{"typetext":""},"format":"bridge-pair-list","properties":{},"type":"string"},"name":"target-bridge"},{"definition":{"description":"Remote target endpoint","enum":[],"extra":{"typetext":"apitoken= ,host=
[,fingerprint=] [,port=]"},"format":"proxmox-remote","properties":{},"type":"string"},"name":"target-endpoint"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storage-pair-list","optional":false,"properties":{},"type":"string"},"name":"target-storage"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"target-vmid"},{"definition":{"default":180,"description":"Timeout in seconds for shutdown for restart migration","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/remote_migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c9cbc740cc85254dd58f570dfe12a2adab7e0bfd14cae547490946e1fe519126","description":"Resize a container mount point.","extra":{"proxyto":"node"},"name":"resize_vm","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The disk you want to resize.","enum":["rootfs","mp0","mp1","mp2","mp3","mp4","mp5","mp6","mp7","mp8","mp9","mp10","mp11","mp12","mp13","mp14","mp15","mp16","mp17","mp18","mp19","mp20","mp21","mp22","mp23","mp24","mp25","mp26","mp27","mp28","mp29","mp30","mp31","mp32","mp33","mp34","mp35","mp36","mp37","mp38","mp39","mp40","mp41","mp42","mp43","mp44","mp45","mp46","mp47","mp48","mp49","mp50","mp51","mp52","mp53","mp54","mp55","mp56","mp57","mp58","mp59","mp60","mp61","mp62","mp63","mp64","mp65","mp66","mp67","mp68","mp69","mp70","mp71","mp72","mp73","mp74","mp75","mp76","mp77","mp78","mp79","mp80","mp81","mp82","mp83","mp84","mp85","mp86","mp87","mp88","mp89","mp90","mp91","mp92","mp93","mp94","mp95","mp96","mp97","mp98","mp99","mp100","mp101","mp102","mp103","mp104","mp105","mp106","mp107","mp108","mp109","mp110","mp111","mp112","mp113","mp114","mp115","mp116","mp117","mp118","mp119","mp120","mp121","mp122","mp123","mp124","mp125","mp126","mp127","mp128","mp129","mp130","mp131","mp132","mp133","mp134","mp135","mp136","mp137","mp138","mp139","mp140","mp141","mp142","mp143","mp144","mp145","mp146","mp147","mp148","mp149","mp150","mp151","mp152","mp153","mp154","mp155","mp156","mp157","mp158","mp159","mp160","mp161","mp162","mp163","mp164","mp165","mp166","mp167","mp168","mp169","mp170","mp171","mp172","mp173","mp174","mp175","mp176","mp177","mp178","mp179","mp180","mp181","mp182","mp183","mp184","mp185","mp186","mp187","mp188","mp189","mp190","mp191","mp192","mp193","mp194","mp195","mp196","mp197","mp198","mp199","mp200","mp201","mp202","mp203","mp204","mp205","mp206","mp207","mp208","mp209","mp210","mp211","mp212","mp213","mp214","mp215","mp216","mp217","mp218","mp219","mp220","mp221","mp222","mp223","mp224","mp225","mp226","mp227","mp228","mp229","mp230","mp231","mp232","mp233","mp234","mp235","mp236","mp237","mp238","mp239","mp240","mp241","mp242","mp243","mp244","mp245","mp246","mp247","mp248","mp249","mp250","mp251","mp252","mp253","mp254","mp255"],"extra":{},"properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The new size. With the '+' sign the value is added to the actual size of the volume and without it, the value is taken as an absolute one. Shrinking disk size is not supported.","enum":[],"extra":{},"pattern":"\\+?\\d+(\\.\\d+)?[KMGT]?","properties":{},"type":"string"},"name":"size"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/resize"},{"extra":{},"methods":[{"allow_token":true,"checksum":"76edba13c3870fdb403a8a46fd95c3033cf4aeecac012f3d822f9075a80aa729","description":"Read VM RRD statistics (returns PNG)","extra":{},"name":"rrd","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The list of datasources you want to display.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"ds"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/rrd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"708d135d9bf06d5aed00329691506df18a1ed11938257a15c87431dfc5b617f3","description":"Read VM RRD statistics","extra":{},"name":"rrddata","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/rrddata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2cc7acefd4e8a1d9cda78d17b71e9f5c952c548a739884a6da023cc7abf31ba4","description":"List all snapshots.","extra":{"proxyto":"node"},"name":"list","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"description":{"description":"Snapshot description.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Snapshot identifier. Value 'current' identifies the current VM.","enum":[],"extra":{},"properties":{},"type":"string"},"parent":{"description":"Parent snapshot identifier.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"snaptime":{"description":"Snapshot creation time","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"65b066ef336fa2e77e966ba74190bbf917f85c6286188204e9b813d78b916965","description":"Snapshot a container.","extra":{"proxyto":"node"},"name":"snapshot","parameters":[{"definition":{"description":"A textual description or comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/snapshot"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4eca683e9eded5aacd69fffdde27a647f386c5d8035a8a006ddf57c85f71ea94","description":"Delete a LXC snapshot.","extra":{"proxyto":"node"},"name":"delsnapshot","parameters":[{"definition":{"description":"For removal from config file, even if removing disk snapshots fails.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"832c5b9a025e005606202e4c83d793ce08937ecc33dfcd397a7fef121e0b5411","description":"","extra":{},"name":"snapshot_cmd_idx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cmd}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"65e5a768abb44d154e1140615379246ed5399a3dc43425f8e51baa6c7fbd75af","description":"Get snapshot configuration","extra":{"proxyto":"node"},"name":"get_snapshot_config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback","VM.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"281a4f10e550455fd4dd289251fc1fe0ecb359e2777227df294a67d67a5fa13b","description":"Update snapshot metadata.","extra":{"proxyto":"node"},"name":"update_snapshot_config","parameters":[{"definition":{"description":"A textual description or comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f3303e04d815dc43d11d0667bcb86834208728ef9405020f8603e0abf43fc883","description":"Rollback LXC state to specified snapshot.","extra":{"proxyto":"node"},"name":"rollback","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"default":0,"description":"Whether the container should get started after rolling back successfully","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"start"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a387cac0a81099ae0cfeba0168f3a8ecf4469ed365c0acfeac84de39ceb0ad90","description":"Returns a SPICE configuration to connect to the CT.","extra":{"proxyto":"node"},"name":"spiceproxy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).","enum":[],"extra":{"typetext":""},"format":"address","optional":true,"properties":{},"type":"string"},"name":"proxy"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"description":"Returned values can be directly passed to the 'remote-viewer' application.","enum":[],"extra":{"additionalProperties":1},"properties":{"host":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"enum":[],"extra":{},"properties":{},"type":"string"},"proxy":{"enum":[],"extra":{},"properties":{},"type":"string"},"tls-port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/spiceproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e0aec5f2ad5f243e5f05705856f0b3c74f1e863e35ceb571106f118e8b4027e3","description":"Directory index","extra":{"proxyto":"node"},"name":"vmcmdidx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"74539adae0a51cbf1e6e5754ce5cf55552ae35b0c78eda0648477ab75a550f36","description":"Get virtual machine status.","extra":{"proxyto":"node"},"name":"vm_status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"cpu":{"description":"Current CPU usage.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"cpus":{"description":"Maximum usable CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"disk":{"description":"Root disk image space-usage in bytes.","enum":[],"extra":{"renderer":"bytes"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"diskread":{"description":"The amount of bytes the guest read from it's block devices since the guest was started. (Note: This info is not available for all storage types.)","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"diskwrite":{"description":"The amount of bytes the guest wrote from it's block devices since the guest was started. (Note: This info is not available for all storage types.)","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"ha":{"description":"HA manager service status.","enum":[],"extra":{},"properties":{},"type":"object"},"lock":{"description":"The current config lock, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxdisk":{"description":"Root disk image size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Maximum memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxswap":{"description":"Maximum SWAP memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"mem":{"description":"Currently used memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"name":{"description":"Container name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"netin":{"description":"The amount of traffic in bytes that was sent to the guest over the network since it was started.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"netout":{"description":"The amount of traffic in bytes that was sent from the guest over the network since it was started.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"status":{"description":"LXC Container status.","enum":["stopped","running"],"extra":{},"properties":{},"type":"string"},"tags":{"description":"The current configured tags, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"template":{"default":0,"description":"Determines if the guest is a template.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"uptime":{"description":"Uptime in seconds.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/status/current"},{"extra":{},"methods":[{"allow_token":true,"checksum":"eba2ee91fe49acdfef5a00f589c3f8d4028b9ccaceebad3cda480818a7dc8234","description":"Reboot the container by shutting it down, and starting it again. Applies pending changes.","extra":{"proxyto":"node"},"name":"vm_reboot","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Wait maximal timeout seconds for the shutdown.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/reboot"},{"extra":{},"methods":[{"allow_token":true,"checksum":"73dcd3e2f3a70ea0d5ee48b979264e5b35f89dad81101a6e7e2fb529f4121502","description":"Resume the container.","extra":{"proxyto":"node"},"name":"vm_resume","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/resume"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1215c26a5cc93e92334e4831665c2a0bd3a37c003d8e81ee3dd292ffca4d1c30","description":"Shutdown the container. This will trigger a clean shutdown of the container, see lxc-stop(1) for details.","extra":{"proxyto":"node"},"name":"vm_shutdown","parameters":[{"definition":{"default":0,"description":"Make sure the Container stops.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"forceStop"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":60,"description":"Wait maximal timeout seconds.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/shutdown"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5c0c283d714281e0b593ed3392fd653724b50b9ede5a31f1e566121fb5919d19","description":"Start the container.","extra":{"proxyto":"node"},"name":"vm_start","parameters":[{"definition":{"default":0,"description":"If set, enables very verbose debug log-level on start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"debug"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f93fd82ece83db0f42309e14023ac63a1b4e5d301e4ab8eec9c8edaed8edc97b","description":"Stop the container. This will abruptly stop all processes running in the container.","extra":{"proxyto":"node"},"name":"vm_stop","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Try to abort active 'vzshutdown' tasks before stopping.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"overrule-shutdown"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/stop"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d8606dc5363a4702091ed917fd8a9b46f24380b6c6280a5fa213df2d6655dd57","description":"Suspend the container. This is experimental.","extra":{"proxyto":"node"},"name":"vm_suspend","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/status/suspend"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f621cca791d32aba1c7cfe0dea4167c53ffe559863efeace03ffdec6fce06339","description":"Create a Template.","extra":{"proxyto":"node"},"name":"template","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permissions on /vms/{vmid}","expression":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/template"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6e61212a198fccaf0e72dcaab2feaa049b1fc92c26133bb1e23307444f4c4faa","description":"Creates a TCP proxy connection.","extra":{},"name":"termproxy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/termproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"52b103eca96fb027f3c5fbbc84b261d13a8b5b62a276aee13f9b4da5a488217d","description":"Creates a TCP VNC proxy connections.","extra":{},"name":"vncproxy","parameters":[{"definition":{"description":"sets the height of the console in pixels.","enum":[],"extra":{"typetext":" (16 - 2160)"},"maximum":2160,"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"height"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"use websocket instead of standard VNC.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"websocket"},{"definition":{"description":"sets the width of the console in pixels.","enum":[],"extra":{"typetext":" (16 - 4096)"},"maximum":4096,"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"width"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"cert":{"enum":[],"extra":{},"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/lxc/{vmid}/vncproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6af2b0b22135014e2a279ea3e1f03813d8d5a6b7966f96298eb6bf3c5fc22916","description":"Opens a weksocket for VNC traffic.","extra":{},"name":"vncwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Port number returned by previous vncproxy call.","enum":[],"extra":{"typetext":" (5900 - 5999)"},"maximum":5999,"minimum":5900,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Ticket from previous call to vncproxy.","enum":[],"extra":{"typetext":""},"max_length":512,"properties":{},"type":"string"},"name":"vncticket"}],"permissions":{"description":"You also need to pass a valid ticket (vncticket).","expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/lxc/{vmid}/vncwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"896c5fe436ce73344ef37d78465b4785c481d5856c495b6142f3f4ba5e250983","description":"Migrate all VMs and Containers.","extra":{"proxyto":"node"},"name":"migrateall","parameters":[{"definition":{"description":"Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg. One of both must be set!","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxworkers"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Only consider Guests with these IDs.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"},{"definition":{"description":"Enable live storage migration for local disk","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"with-local-disks"}],"permissions":{"description":"The 'VM.Migrate' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/migrateall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c2c207a7e8a4df2370ac547d2a570d636677faa99ba285adbe6298dde17efefc","description":"Read tap/vm network device interface counters","extra":{"proxyto":"node"},"name":"netstat","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/netstat"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3de07e746f474e02ab38c834d3571d70c15aa5d66e4a80d73f9f67876bcd5bfc","description":"Revert network configuration changes.","extra":{"proxyto":"node"},"name":"revert_network_changes","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"36fb4f23005ef78f64e7f7590922b6681208da97c8a1603b6efb08e5192a49f1","description":"List available networks","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list specific interface types.","enum":["bridge","bond","eth","alias","vlan","OVSBridge","OVSBond","OVSPort","OVSIntPort","vnet","any_bridge","any_local_bridge"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{iface}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"active":{"description":"Set to true if the interface is active.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"address":{"description":"IP address.","enum":[],"extra":{"requires":"netmask"},"format":"ipv4","optional":true,"properties":{},"type":"string"},"address6":{"description":"IP address.","enum":[],"extra":{"requires":"netmask6"},"format":"ipv6","optional":true,"properties":{},"type":"string"},"autostart":{"description":"Automatically start interface on boot.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bond-primary":{"description":"Specify the primary interface for active-backup bond.","enum":[],"extra":{},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"bond_mode":{"description":"Bonding mode.","enum":["balance-rr","active-backup","balance-xor","broadcast","802.3ad","balance-tlb","balance-alb","balance-slb","lacp-balance-slb","lacp-balance-tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"bond_xmit_hash_policy":{"description":"Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.","enum":["layer2","layer2+3","layer3+4"],"extra":{},"optional":true,"properties":{},"type":"string"},"bridge-access":{"description":"The bridge port access VLAN.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"bridge-arp-nd-suppress":{"description":"Bridge port ARP/ND suppress flag.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bridge-learning":{"description":"Bridge port learning flag.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bridge-multicast-flood":{"description":"Bridge port multicast flood flag.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bridge-unicast-flood":{"description":"Bridge port unicast flood flag.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bridge_ports":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"bridge_vids":{"description":"Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.","enum":[],"extra":{},"format":"pve-vlan-id-or-range-list","optional":true,"properties":{},"type":"string"},"bridge_vlan_aware":{"description":"Enable bridge vlan support.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"cidr":{"description":"IPv4 CIDR.","enum":[],"extra":{},"format":"CIDRv4","optional":true,"properties":{},"type":"string"},"cidr6":{"description":"IPv6 CIDR.","enum":[],"extra":{},"format":"CIDRv6","optional":true,"properties":{},"type":"string"},"comments":{"description":"Comments","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"comments6":{"description":"Comments","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"exists":{"description":"Set to true if the interface physically exists.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"families":{"description":"The network families.","enum":[],"extra":{},"items":{"description":"A network family.","enum":["inet","inet6"],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"gateway":{"description":"Default gateway address.","enum":[],"extra":{},"format":"ipv4","optional":true,"properties":{},"type":"string"},"gateway6":{"description":"Default ipv6 gateway address.","enum":[],"extra":{},"format":"ipv6","optional":true,"properties":{},"type":"string"},"iface":{"description":"Network interface name.","enum":[],"extra":{},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"link-type":{"description":"The link type.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"method":{"description":"The network configuration method for IPv4.","enum":["loopback","dhcp","manual","static","auto"],"extra":{},"optional":true,"properties":{},"type":"string"},"method6":{"description":"The network configuration method for IPv6.","enum":["loopback","dhcp","manual","static","auto"],"extra":{},"optional":true,"properties":{},"type":"string"},"mtu":{"description":"MTU.","enum":[],"extra":{},"maximum":65520,"minimum":1280,"optional":true,"properties":{},"type":"integer"},"netmask":{"description":"Network mask.","enum":[],"extra":{"requires":"address"},"format":"ipv4mask","optional":true,"properties":{},"type":"string"},"netmask6":{"description":"Network mask.","enum":[],"extra":{"requires":"address6"},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"integer"},"options":{"description":"A list of additional interface options for IPv4.","enum":[],"extra":{},"items":{"description":"An interface property.","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"options6":{"description":"A list of additional interface options for IPv6.","enum":[],"extra":{},"items":{"description":"An interface property.","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"ovs_bonds":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"ovs_bridge":{"description":"The OVS bridge associated with a OVS port. This is required when you create an OVS port.","enum":[],"extra":{},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"ovs_options":{"description":"OVS interface options.","enum":[],"extra":{},"max_length":1024,"optional":true,"properties":{},"type":"string"},"ovs_ports":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"ovs_tag":{"description":"Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)","enum":[],"extra":{},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"priority":{"description":"The order of the interface.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"slaves":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"type":{"description":"Network interface type","enum":["bridge","bond","eth","alias","vlan","OVSBridge","OVSBond","OVSPort","OVSIntPort","vnet","unknown"],"extra":{},"properties":{},"type":"string"},"uplink-id":{"description":"The uplink ID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vlan-id":{"description":"vlan-id for a custom named vlan interface (ifupdown2 only).","enum":[],"extra":{},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"vlan-protocol":{"description":"The VLAN protocol.","enum":["802.1ad","802.1q"],"extra":{},"optional":true,"properties":{},"type":"string"},"vlan-raw-device":{"description":"Specify the raw interface for the vlan interface.","enum":[],"extra":{},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"vxlan-id":{"description":"The VXLAN ID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"vxlan-local-tunnelip":{"description":"The VXLAN local tunnel IP.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vxlan-physdev":{"description":"The physical device for the VXLAN tunnel.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vxlan-svcnodeip":{"description":"The VXLAN SVC node IP.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"0dd9cce17549bcca7d5011881351b96eac55e808f77a7b703d500ea3b0e98019","description":"Create network device configuration","extra":{"proxyto":"node"},"name":"create_network","parameters":[{"definition":{"description":"IP address.","enum":[],"extra":{"requires":"netmask","typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"address"},{"definition":{"description":"IP address.","enum":[],"extra":{"requires":"netmask6","typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"address6"},{"definition":{"description":"Automatically start interface on boot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Specify the primary interface for active-backup bond.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"bond-primary"},{"definition":{"description":"Bonding mode.","enum":["balance-rr","active-backup","balance-xor","broadcast","802.3ad","balance-tlb","balance-alb","balance-slb","lacp-balance-slb","lacp-balance-tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bond_mode"},{"definition":{"description":"Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.","enum":["layer2","layer2+3","layer3+4"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bond_xmit_hash_policy"},{"definition":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"bridge_ports"},{"definition":{"description":"Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.","enum":[],"extra":{"typetext":""},"format":"pve-vlan-id-or-range-list","optional":true,"properties":{},"type":"string"},"name":"bridge_vids"},{"definition":{"description":"Enable bridge vlan support.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bridge_vlan_aware"},{"definition":{"description":"IPv4 CIDR.","enum":[],"extra":{"typetext":""},"format":"CIDRv4","optional":true,"properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IPv6 CIDR.","enum":[],"extra":{"typetext":""},"format":"CIDRv6","optional":true,"properties":{},"type":"string"},"name":"cidr6"},{"definition":{"description":"Comments","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comments"},{"definition":{"description":"Comments","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comments6"},{"definition":{"description":"Default gateway address.","enum":[],"extra":{"typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"gateway"},{"definition":{"description":"Default ipv6 gateway address.","enum":[],"extra":{"typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"gateway6"},{"definition":{"description":"Network interface name.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"MTU.","enum":[],"extra":{"typetext":" (1280 - 65520)"},"maximum":65520,"minimum":1280,"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"Network mask.","enum":[],"extra":{"requires":"address","typetext":""},"format":"ipv4mask","optional":true,"properties":{},"type":"string"},"name":"netmask"},{"definition":{"description":"Network mask.","enum":[],"extra":{"requires":"address6","typetext":" (0 - 128)"},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"netmask6"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"ovs_bonds"},{"definition":{"description":"The OVS bridge associated with a OVS port. This is required when you create an OVS port.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"ovs_bridge"},{"definition":{"description":"OVS interface options.","enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"ovs_options"},{"definition":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"ovs_ports"},{"definition":{"description":"Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)","enum":[],"extra":{"typetext":" (1 - 4094)"},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"ovs_tag"},{"definition":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"slaves"},{"definition":{"description":"Network interface type","enum":["bridge","bond","eth","alias","vlan","OVSBridge","OVSBond","OVSPort","OVSIntPort","vnet","unknown"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"vlan-id for a custom named vlan interface (ifupdown2 only).","enum":[],"extra":{"typetext":" (1 - 4094)"},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vlan-id"},{"definition":{"description":"Specify the raw interface for the vlan interface.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"vlan-raw-device"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"5c5bb8977f0eeef180ddd9a799bd358f22ac79b3f4b58c6f1f197e7659aaabb9","description":"Reload network configuration","extra":{"proxyto":"node"},"name":"reload_network_config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/network"},{"extra":{},"methods":[{"allow_token":true,"checksum":"32c344b0dfe6220c53d77420aa2694e1bc65998071ee6a33024bccd2265550f3","description":"Delete network device configuration","extra":{"proxyto":"node"},"name":"delete_network","parameters":[{"definition":{"description":"Network interface name.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"91ab56660b1db09d5d12a3a1739ea872acc81e6d3a0f84993fa51ea56b78dea3","description":"Read network device configuration","extra":{"proxyto":"node"},"name":"network_config","parameters":[{"definition":{"description":"Network interface name.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"method":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"f3bb7ffaa0d519325b34694d2dfd0f2bf7830bf2e683af1e35faa9b1a502558b","description":"Update network device configuration","extra":{"proxyto":"node"},"name":"update_network","parameters":[{"definition":{"description":"IP address.","enum":[],"extra":{"requires":"netmask","typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"address"},{"definition":{"description":"IP address.","enum":[],"extra":{"requires":"netmask6","typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"address6"},{"definition":{"description":"Automatically start interface on boot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Specify the primary interface for active-backup bond.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"bond-primary"},{"definition":{"description":"Bonding mode.","enum":["balance-rr","active-backup","balance-xor","broadcast","802.3ad","balance-tlb","balance-alb","balance-slb","lacp-balance-slb","lacp-balance-tcp"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bond_mode"},{"definition":{"description":"Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.","enum":["layer2","layer2+3","layer3+4"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bond_xmit_hash_policy"},{"definition":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"bridge_ports"},{"definition":{"description":"Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.","enum":[],"extra":{"typetext":""},"format":"pve-vlan-id-or-range-list","optional":true,"properties":{},"type":"string"},"name":"bridge_vids"},{"definition":{"description":"Enable bridge vlan support.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"bridge_vlan_aware"},{"definition":{"description":"IPv4 CIDR.","enum":[],"extra":{"typetext":""},"format":"CIDRv4","optional":true,"properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IPv6 CIDR.","enum":[],"extra":{"typetext":""},"format":"CIDRv6","optional":true,"properties":{},"type":"string"},"name":"cidr6"},{"definition":{"description":"Comments","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comments"},{"definition":{"description":"Comments","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comments6"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Default gateway address.","enum":[],"extra":{"typetext":""},"format":"ipv4","optional":true,"properties":{},"type":"string"},"name":"gateway"},{"definition":{"description":"Default ipv6 gateway address.","enum":[],"extra":{"typetext":""},"format":"ipv6","optional":true,"properties":{},"type":"string"},"name":"gateway6"},{"definition":{"description":"Network interface name.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"MTU.","enum":[],"extra":{"typetext":" (1280 - 65520)"},"maximum":65520,"minimum":1280,"optional":true,"properties":{},"type":"integer"},"name":"mtu"},{"definition":{"description":"Network mask.","enum":[],"extra":{"requires":"address","typetext":""},"format":"ipv4mask","optional":true,"properties":{},"type":"string"},"name":"netmask"},{"definition":{"description":"Network mask.","enum":[],"extra":{"requires":"address6","typetext":" (0 - 128)"},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"netmask6"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"ovs_bonds"},{"definition":{"description":"The OVS bridge associated with a OVS port. This is required when you create an OVS port.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"ovs_bridge"},{"definition":{"description":"OVS interface options.","enum":[],"extra":{"typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"ovs_options"},{"definition":{"description":"Specify the interfaces you want to add to your bridge.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"ovs_ports"},{"definition":{"description":"Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)","enum":[],"extra":{"typetext":" (1 - 4094)"},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"ovs_tag"},{"definition":{"description":"Specify the interfaces used by the bonding device.","enum":[],"extra":{"typetext":""},"format":"pve-iface-list","optional":true,"properties":{},"type":"string"},"name":"slaves"},{"definition":{"description":"Network interface type","enum":["bridge","bond","eth","alias","vlan","OVSBridge","OVSBond","OVSPort","OVSIntPort","vnet","unknown"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"vlan-id for a custom named vlan interface (ifupdown2 only).","enum":[],"extra":{"typetext":" (1 - 4094)"},"maximum":4094,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vlan-id"},{"definition":{"description":"Specify the raw interface for the vlan interface.","enum":[],"extra":{"typetext":""},"format":"pve-iface","optional":true,"properties":{},"type":"string"},"name":"vlan-raw-device"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/network/{iface}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"636c663e1530dad9c42fcf6840143fd1ca0b18b78ff258e2653d19b25a3c9f62","description":"Virtual machine index (per node).","extra":{"proxyto":"node"},"name":"vmlist","parameters":[{"definition":{"description":"Determine the full status of active VMs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Only list VMs where you have VM.Audit permissions on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{vmid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cpu":{"description":"Current CPU usage.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"cpus":{"description":"Maximum usable CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"diskread":{"description":"The amount of bytes the guest read from it's block devices since the guest was started. (Note: This info is not available for all storage types.)","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"diskwrite":{"description":"The amount of bytes the guest wrote from it's block devices since the guest was started. (Note: This info is not available for all storage types.)","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"lock":{"description":"The current config lock, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxdisk":{"description":"Root disk size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Maximum memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"mem":{"description":"Currently used memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"name":{"description":"VM (host)name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"netin":{"description":"The amount of traffic in bytes that was sent to the guest over the network since it was started.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"netout":{"description":"The amount of traffic in bytes that was sent from the guest over the network since it was started.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"pid":{"description":"PID of the QEMU process, if the VM is running.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"qmpstatus":{"description":"VM run state from the 'query-status' QMP monitor command.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"running-machine":{"description":"The currently running machine type (if running).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"running-qemu":{"description":"The QEMU version the VM is currently using (if running).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial":{"description":"Guest has serial device configured.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"status":{"description":"QEMU process status.","enum":["stopped","running"],"extra":{},"properties":{},"type":"string"},"tags":{"description":"The current configured tags, if any","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"template":{"default":0,"description":"Determines if the guest is a template.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"uptime":{"description":"Uptime in seconds.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"ee60d640a47c6212d4e5d75288494e20a7ac94af11b96607ff508d8c7b79f00d","description":"Create or restore a virtual machine.","extra":{"proxyto":"node"},"name":"create_vm","parameters":[{"definition":{"default":1,"description":"Enable/disable ACPI.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"acpi"},{"definition":{"description":"List of host cores used to execute guest processes, for example: 0,5,8-11","enum":[],"extra":{"typetext":""},"format":"pve-cpuset","optional":true,"properties":{},"type":"string"},"name":"affinity"},{"definition":{"description":"Enable/disable communication with the QEMU Guest Agent and its properties.","enum":[],"extra":{"typetext":"[enabled=]<1|0> [,freeze-fs-on-backup=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]"},"format":{"enabled":{"default":0,"default_key":1,"description":"Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.","type":"boolean"},"freeze-fs-on-backup":{"default":1,"description":"Freeze/thaw guest filesystems on backup for consistency.","optional":1,"type":"boolean"},"fstrim_cloned_disks":{"default":0,"description":"Run fstrim after moving a disk or migrating the VM.","optional":1,"type":"boolean"},"type":{"default":"virtio","description":"Select the agent type","enum":["virtio","isa"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"agent"},{"definition":{"description":"Secure Encrypted Virtualization (SEV) features by AMD CPUs","enum":[],"extra":{"typetext":"[type=] [,allow-smt=<1|0>] [,kernel-hashes=<1|0>] [,no-debug=<1|0>] [,no-key-sharing=<1|0>]"},"format":"pve-qemu-sev-fmt","optional":true,"properties":{},"type":"string"},"name":"amd-sev"},{"definition":{"description":"Virtual processor architecture. Defaults to the host.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"description":"The backup archive. Either the file system path to a .tar or .vma file (use '-' to pipe data from stdin) or a proxmox storage backup volume identifier.","enum":[],"extra":{"typetext":""},"max_length":255,"optional":true,"properties":{},"type":"string"},"name":"archive"},{"definition":{"description":"Arbitrary arguments passed to kvm.","enum":[],"extra":{"typetext":"","verbose_description":"Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -smbios 'type=0,vendor=FOO'\n\nNOTE: this option is for experts only.\n"},"optional":true,"properties":{},"type":"string"},"name":"args"},{"definition":{"description":"Configure a audio device, useful in combination with QXL/Spice.","enum":[],"extra":{"typetext":"device= [,driver=]"},"format":{"device":{"description":"Configure an audio device.","enum":["ich9-intel-hda","intel-hda","AC97"],"type":"string"},"driver":{"default":"spice","description":"Driver backend for the audio device.","enum":["spice","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"audio0"},{"definition":{"default":0,"description":"Automatic restart after crash (currently ignored).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Amount of target RAM for the VM in MiB. Using zero disables the ballon driver.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"balloon"},{"definition":{"default":"seabios","description":"Select BIOS implementation.","enum":["seabios","ovmf"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bios"},{"definition":{"description":"Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.","enum":[],"extra":{"typetext":"[[legacy=]<[acdn]{1,4}>] [,order=]"},"format":"pve-qm-boot","optional":true,"properties":{},"type":"string"},"name":"boot"},{"definition":{"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","enum":[],"extra":{},"format":"pve-qm-bootdisk","optional":true,"pattern":"(ide|sata|scsi|virtio)\\d+","properties":{},"type":"string"},"name":"bootdisk"},{"definition":{"default":"restore limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"This is an alias for option -ide2","enum":[],"extra":{"typetext":""},"format":"pve-qm-ide","optional":true,"properties":{},"type":"string"},"name":"cdrom"},{"definition":{"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","enum":[],"extra":{"typetext":"[meta=] [,network=] [,user=] [,vendor=]"},"format":"pve-qm-cicustom","optional":true,"properties":{},"type":"string"},"name":"cicustom"},{"definition":{"description":"cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cipassword"},{"definition":{"description":"Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.","enum":["configdrive2","nocloud","opennebula"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"citype"},{"definition":{"default":1,"description":"cloud-init: do an automatic package upgrade after the first boot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ciupgrade"},{"definition":{"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ciuser"},{"definition":{"default":1,"description":"The number of cores per socket.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"description":"Emulated CPU type.","enum":[],"extra":{"typetext":"[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]"},"format":"pve-vm-cpu-conf","optional":true,"properties":{},"type":"string"},"name":"cpu"},{"definition":{"default":0,"description":"Limit of CPU usage.","enum":[],"extra":{"typetext":" (0 - 128)","verbose_description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit."},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"typetext":" (1 - 262144)","verbose_description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs."},"maximum":262144,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"description":"Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":8192,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,pre-enrolled-keys=<1|0>] [,size=]"},"format":{"efitype":{"default":"2m","description":"Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarch64 (ARM).","enum":["2m","4m"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"pre-enrolled-keys":{"default":0,"description":"Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.","optional":1,"type":"boolean"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"efidisk0"},{"definition":{"description":"Allow to overwrite existing VM.","enum":[],"extra":{"requires":"archive","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Freeze CPU at startup (use 'c' monitor command to start execution).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"freeze"},{"definition":{"description":"Script that will be executed during various steps in the vms lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Map host PCI devices into guest.","enum":[],"extra":{"typetext":"[[host=]] [,device-id=] [,legacy-igd=<1|0>] [,mapping=] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]","verbose_description":"Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"format":"pve-qm-hostpci","optional":true,"properties":{},"type":"string"},"name":"hostpci[n]"},{"definition":{"default":"network,disk,usb","description":"Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.","enum":[],"extra":{"typetext":""},"format":"pve-hotplug-features","optional":true,"properties":{},"type":"string"},"name":"hotplug"},{"definition":{"description":"Enable/disable hugepages memory.","enum":["any","2","1024"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"hugepages"},{"definition":{"description":"Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"model":{"description":"The drive's reported model name, url-encoded, up to 40 bytes long.","format":"urlencoded","format_description":"model","maxLength":120,"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"ide[n]"},{"definition":{"description":"A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"import-working-storage"},{"definition":{"description":"cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n","enum":[],"extra":{"typetext":"[gw=] [,gw6=] [,ip=] [,ip6=]"},"format":"pve-qm-ipconfig","optional":true,"properties":{},"type":"string"},"name":"ipconfig[n]"},{"definition":{"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host.","enum":[],"extra":{"typetext":"size= [,name=]"},"format":{"name":{"description":"The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.","format_description":"string","optional":1,"pattern":"[a-zA-Z0-9\\-]+","type":"string"},"size":{"description":"The size of the file in MB.","minimum":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"ivshmem"},{"definition":{"default":0,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keephugepages"},{"definition":{"description":"Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"keyboard"},{"definition":{"default":1,"description":"Enable/disable KVM hardware virtualization.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"kvm"},{"definition":{"description":"Start the VM immediately while importing or restoring in the background.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"live-restore"},{"definition":{"description":"Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"localtime"},{"definition":{"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"description":"Specify the QEMU machine.","enum":[],"extra":{"typetext":"[[type=]] [,enable-s3=<1|0>] [,enable-s4=<1|0>] [,viommu=]"},"format":{"enable-s3":{"description":"Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"enable-s4":{"description":"Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"type":{"default_key":1,"description":"Specifies the QEMU machine type.","format_description":"machine type","maxLength":40,"optional":1,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","type":"string"},"viommu":{"description":"Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).","enum":["intel","virtio"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"machine"},{"definition":{"description":"Memory properties.","enum":[],"extra":{"typetext":"[current=]"},"format":{"current":{"default":512,"default_key":1,"description":"Current amount of online RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.","minimum":16,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"memory"},{"definition":{"default":0.1,"description":"Set maximum tolerated downtime (in seconds) for migrations. Should the migration not be able to converge in the very end, because too much newly dirtied RAM needs to be transferred, the limit will be increased automatically step-by-step until migration can converge.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"migrate_downtime"},{"definition":{"default":0,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"migrate_speed"},{"definition":{"description":"Set a name for the VM. Only used on the configuration web interface.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"format":"address-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specify network devices.","enum":[],"extra":{"typetext":"[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]"},"format":{"bridge":{"description":"Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n","format":"pve-bridge-id","format_description":"bridge","optional":1,"type":"string"},"e1000":{"alias":"macaddr","keyAlias":"model"},"e1000-82540em":{"alias":"macaddr","keyAlias":"model"},"e1000-82544gc":{"alias":"macaddr","keyAlias":"model"},"e1000-82545em":{"alias":"macaddr","keyAlias":"model"},"e1000e":{"alias":"macaddr","keyAlias":"model"},"firewall":{"description":"Whether this interface should be protected by the firewall.","optional":1,"type":"boolean"},"i82551":{"alias":"macaddr","keyAlias":"model"},"i82557b":{"alias":"macaddr","keyAlias":"model"},"i82559er":{"alias":"macaddr","keyAlias":"model"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"macaddr":{"description":"MAC address. That address must be unique within your network. This is automatically generated if not specified.","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"model":{"default_key":1,"description":"Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.","enum":["e1000","e1000-82540em","e1000-82544gc","e1000-82545em","e1000e","i82551","i82557b","i82559er","ne2k_isa","ne2k_pci","pcnet","rtl8139","virtio","vmxnet3"],"type":"string"},"mtu":{"description":"Force MTU, for VirtIO only. Set to '1' to use the bridge MTU","maximum":65520,"minimum":1,"optional":1,"type":"integer"},"ne2k_isa":{"alias":"macaddr","keyAlias":"model"},"ne2k_pci":{"alias":"macaddr","keyAlias":"model"},"pcnet":{"alias":"macaddr","keyAlias":"model"},"queues":{"description":"Number of packet queues to be used on the device.","maximum":64,"minimum":0,"optional":1,"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":0,"optional":1,"type":"number"},"rtl8139":{"alias":"macaddr","keyAlias":"model"},"tag":{"description":"VLAN tag to apply to packets on this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN trunks to pass through this interface.","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"virtio":{"alias":"macaddr","keyAlias":"model"},"vmxnet3":{"alias":"macaddr","keyAlias":"model"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Enable/disable NUMA.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"numa"},{"definition":{"description":"NUMA topology.","enum":[],"extra":{"typetext":"cpus= [,hostnodes=] [,memory=] [,policy=]"},"format":{"cpus":{"description":"CPUs accessing this NUMA node.","format_description":"id[-id];...","pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"hostnodes":{"description":"Host NUMA nodes to use.","format_description":"id[-id];...","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"memory":{"description":"Amount of memory this NUMA node provides.","optional":1,"type":"number"},"policy":{"description":"NUMA allocation policy.","enum":["preferred","bind","interleave"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"numa[n]"},{"definition":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","win11","l24","l26","solaris"],"extra":{"verbose_description":"Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022/2025\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 6.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n"},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"description":"Map host parallel devices (n is 0 to 2).","enum":[],"extra":{"verbose_description":"Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"/dev/parport\\d+|/dev/usb/lp\\d+","properties":{},"type":"string"},"name":"parallel[n]"},{"definition":{"description":"Add the VM to the specified pool.","enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"default":0,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"default":1,"description":"Allow reboot. If set to '0' the VM exit on reboot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"reboot"},{"definition":{"description":"Configure a VirtIO-based Random Number Generator.","enum":[],"extra":{"typetext":"[source=] [,max_bytes=] [,period=]"},"format":"pve-qm-rng","optional":true,"properties":{},"type":"string"},"name":"rng0"},{"definition":{"description":"Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"sata[n]"},{"definition":{"description":"Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,product=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,vendor=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"product":{"description":"The drive's product name, up to 16 bytes long.","format_description":"product","optional":1,"pattern":"[A-Za-z0-9\\-_\\s]{,16}","type":"string"},"queues":{"description":"Number of queues.","minimum":2,"optional":1,"type":"integer"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"scsiblock":{"default":0,"description":"whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"vendor":{"description":"The drive's vendor name, up to 8 bytes long.","format_description":"vendor","optional":1,"pattern":"[A-Za-z0-9\\-_\\s]{,8}","type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"scsi[n]"},{"definition":{"default":"lsi","description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scsihw"},{"definition":{"description":"cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Create a serial device inside the VM (n is 0 to 3)","enum":[],"extra":{"verbose_description":"Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"(/dev/.+|socket)","properties":{},"type":"string"},"name":"serial[n]"},{"definition":{"default":1000,"description":"Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.","enum":[],"extra":{"typetext":" (0 - 50000)"},"maximum":50000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"shares"},{"definition":{"description":"Specify SMBIOS type 1 fields.","enum":[],"extra":{"typetext":"[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]"},"format":"pve-qm-smbios1","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"smbios1"},{"definition":{"default":1,"description":"The number of CPUs. Please use option -sockets instead.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"smp"},{"definition":{"default":1,"description":"The number of CPU sockets.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"sockets"},{"definition":{"description":"Configure additional enhancements for SPICE.","enum":[],"extra":{"typetext":"[foldersharing=<1|0>] [,videostreaming=]"},"format":{"foldersharing":{"default":"0","description":"Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.","optional":1,"type":"boolean"},"videostreaming":{"default":"off","description":"Enable video streaming. Uses compression for detected video streams.","enum":["off","all","filter"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"spice_enhancements"},{"definition":{"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{"typetext":""},"format":"urlencoded","optional":true,"properties":{},"type":"string"},"name":"sshkeys"},{"definition":{"default":0,"description":"Start VM after it was created successfully.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"start"},{"definition":{"default":"now","description":"Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.","enum":[],"extra":{"typetext":"(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)"},"optional":true,"pattern":"(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)","properties":{},"type":"string"},"name":"startdate"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"description":"Default storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"default":1,"description":"Enable/disable the USB tablet device.","enum":[],"extra":{"typetext":"","verbose_description":"Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)."},"optional":true,"properties":{},"type":"boolean"},"name":"tablet"},{"definition":{"description":"Tags of the VM. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable time drift fix.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tdf"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,import-from=] [,size=] [,version=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"version":{"default":"v1.2","description":"The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.","enum":["v1.2","v2.0"],"optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"tpmstate0"},{"definition":{"description":"Assign a unique random ethernet address.","enum":[],"extra":{"requires":"archive","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"unique"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[file=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id","format_description":"volume","type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).","enum":[],"extra":{"typetext":"[[host=]] [,mapping=] [,usb3=<1|0>]"},"format":{"host":{"default_key":1,"description":"The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadecimal numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n\nEither this or the 'mapping' key must be set.\n","format_description":"HOSTUSBDEVICE|spice","optional":1,"pattern":"(?^:(?:(?:(?^:(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})))|(?:(?^:(\\d+)\\-(\\d+(\\.\\d+)*)))|[Ss][Pp][Ii][Cc][Ee]))","type":"string"},"mapping":{"description":"The ID of a cluster wide mapping. Either this or the default-key 'host' must be set.","format":"pve-configid","format_description":"mapping-id","optional":1,"type":"string"},"usb3":{"default":0,"description":"Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"usb[n]"},{"definition":{"default":0,"description":"Number of hotplugged vcpus.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vcpus"},{"definition":{"description":"Configure the VGA hardware.","enum":[],"extra":{"typetext":"[[type=]] [,clipboard=] [,memory=]","verbose_description":"Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal."},"format":{"clipboard":{"description":"Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Migration with VNC clipboard is not yet supported!","enum":["vnc"],"optional":1,"type":"string"},"memory":{"description":"Sets the VGA memory (in MiB). Has no effect with serial display.","maximum":512,"minimum":4,"optional":1,"type":"integer"},"type":{"default":"std","default_key":1,"description":"Select the VGA type. Using type 'cirrus' is not recommended.","enum":["cirrus","qxl","qxl2","qxl3","qxl4","none","serial0","serial1","serial2","serial3","std","virtio","virtio-gl","vmware"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"vga"},{"definition":{"description":"Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"virtio[n]"},{"definition":{"description":"Configuration for sharing a directory between host and guest using Virtio-fs.","enum":[],"extra":{"typetext":"[dirid=] [,cache=] [,direct-io=<1|0>] [,expose-acl=<1|0>] [,expose-xattr=<1|0>]"},"format":{"cache":{"default":"auto","description":"The caching policy the file system should use (auto, always, metadata, never).","enum":["auto","always","metadata","never"],"optional":1,"type":"string"},"direct-io":{"default":0,"description":"Honor the O_DIRECT flag passed down by guest applications.","optional":1,"type":"boolean"},"dirid":{"default_key":1,"description":"Mapping identifier of the directory mapping to be shared with the guest. Also used as a mount tag inside the VM.","format":"pve-configid","format_description":"mapping-id","type":"string"},"expose-acl":{"default":0,"description":"Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.","optional":1,"type":"boolean"},"expose-xattr":{"default":0,"description":"Enable support for extended attributes for this mount.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"virtiofs[n]"},{"definition":{"default":"1 (autogenerated)","description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","enum":[],"extra":{"format_description":"UUID","verbose_description":"The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file."},"optional":true,"pattern":"(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])","properties":{},"type":"string"},"name":"vmgenid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Default storage for VM state volumes/files.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"vmstatestorage"},{"definition":{"description":"Create a virtual hardware watchdog device.","enum":[],"extra":{"typetext":"[[model=]] [,action=]","verbose_description":"Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)"},"format":"pve-qm-watchdog","optional":true,"properties":{},"type":"string"},"name":"watchdog"}],"permissions":{"description":"You need 'VM.Allocate' permissions on /vms/{vmid} or on the VM pool /pool/{pool}. For restore (option 'archive'), it is enough if the user has 'VM.Backup' permission and the VM already exists. If you create disks you need 'Datastore.AllocateSpace' on any used storage.If you use a bridge/vlan, you need 'SDN.Use' on any used bridge/vlan.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0253c629732d317131f9345a056f4d9af4c6fea99c38d29385854345b0db182b","description":"Destroy the VM and all used/owned volumes. Removes any VM specific permissions and firewall rules","extra":{"proxyto":"node"},"name":"destroy_vm","parameters":[{"definition":{"default":0,"description":"If set, destroy additionally all disks not referenced in the config but with a matching VMID from all enabled storages.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"destroy-unreferenced-disks"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Remove VMID from configurations, like backup & replication jobs and HA.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"purge"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"9e36c28967bab606c23a50ff07fa5524991078437cdd75bba7697aac8a894802","description":"Directory index","extra":{"proxyto":"node"},"name":"vmdiridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"123fba96dc634dbf1c98a76b02abda83611fd4d1163d8da2f37506d731a3990d","description":"QEMU Guest Agent command index.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"description":"Returns the list of QEMU Guest Agent commands","enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"a34fce41251801f19513a1e043e2f7e812152a0f0b87511286cf7d15ba5859ce","description":"Execute QEMU Guest Agent commands.","extra":{"proxyto":"node"},"name":"agent","parameters":[{"definition":{"description":"The QGA command.","enum":["fsfreeze-freeze","fsfreeze-status","fsfreeze-thaw","fstrim","get-fsinfo","get-host-name","get-memory-block-info","get-memory-blocks","get-osinfo","get-time","get-timezone","get-users","get-vcpus","info","network-get-interfaces","ping","shutdown","suspend-disk","suspend-hybrid","suspend-ram"],"extra":{},"properties":{},"type":"string"},"name":"command"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bc8dd110385ba748aa587181a1768221c5e6f869d1eacdbe6fd8161a8d19f22a","description":"Executes the given command in the vm via the guest-agent and returns an object with the pid.","extra":{"proxyto":"node"},"name":"exec","parameters":[{"definition":{"description":"The command as a list of program + arguments.","enum":[],"extra":{"typetext":""},"items":{"description":"A single part of the program + arguments.","enum":[],"extra":{},"format":"string","properties":{}},"properties":{},"type":"array"},"name":"command"},{"definition":{"description":"Data to pass as 'input-data' to the guest. Usually treated as STDIN to 'command'.","enum":[],"extra":{"typetext":""},"max_length":65536,"optional":true,"properties":{},"type":"string"},"name":"input-data"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"pid":{"description":"The PID of the process started by the guest-agent.","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/exec"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6a7ee1eefcc5c00bbbcd35466833460d2c751f9c313fbc93cef1b0bb003d257b","description":"Gets the status of the given pid started by the guest-agent","extra":{"proxyto":"node"},"name":"exec-status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The PID to query","enum":[],"extra":{"typetext":""},"properties":{},"type":"integer"},"name":"pid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"err-data":{"description":"stderr of the process","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"err-truncated":{"description":"true if stderr was not fully captured","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"exitcode":{"description":"process exit code if it was normally terminated.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"exited":{"description":"Tells if the given command has exited yet.","enum":[],"extra":{},"properties":{},"type":"boolean"},"out-data":{"description":"stdout of the process","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"out-truncated":{"description":"true if stdout was not fully captured","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"signal":{"description":"signal number or exception code if the process was abnormally terminated.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/exec-status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c51527c21ff3614e4a1a057d347b1cbbdda6b2ea93c1744cc0459586b91a143a","description":"Reads the given file via guest agent. Is limited to 16777216 bytes.","extra":{"proxyto":"node"},"name":"file-read","parameters":[{"definition":{"description":"The path to the file","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"file"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a `content` property.","enum":[],"extra":{},"properties":{"content":{"description":"The content of the file, maximum 16777216","enum":[],"extra":{},"properties":{},"type":"string"},"truncated":{"description":"If set to 1, the output is truncated and not complete","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/file-read"},{"extra":{},"methods":[{"allow_token":true,"checksum":"787948f70abf97a1c897cc6099ebccbcabcd6327097439d862bc7cc19884293f","description":"Writes the given file via guest agent.","extra":{"proxyto":"node"},"name":"file-write","parameters":[{"definition":{"description":"The content to write into the file.","enum":[],"extra":{"typetext":""},"max_length":61440,"properties":{},"type":"string"},"name":"content"},{"definition":{"default":1,"description":"If set, the content will be encoded as base64 (required by QEMU).Otherwise the content needs to be encoded beforehand - defaults to true.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"encode"},{"definition":{"description":"The path to the file.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"file"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/file-write"},{"extra":{},"methods":[{"allow_token":true,"checksum":"07e9b7bf19543ec523fc2f7555ddf6dfa2b7d5d86677fed84de7d9c0771f4668","description":"Execute fsfreeze-freeze.","extra":{"proxyto":"node"},"name":"fsfreeze-freeze","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f64f330e59b81228abf48cd6f4830194ebba00a6f70e124b16ee63dbf8e7fe9e","description":"Execute fsfreeze-status.","extra":{"proxyto":"node"},"name":"fsfreeze-status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"293617a00e4eef18fceffebd38e4262c031f097a2d1b7b4d850e844ead5ce134","description":"Execute fsfreeze-thaw.","extra":{"proxyto":"node"},"name":"fsfreeze-thaw","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw"},{"extra":{},"methods":[{"allow_token":true,"checksum":"eeeae960f84c6af2bb494e8d483d7e8f7ea2a360dee8fdfcfd35060bebdf8b34","description":"Execute fstrim.","extra":{"proxyto":"node"},"name":"fstrim","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/fstrim"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9224209cd5b7bd5c023542603461e8d215a2ec5fe5725b94a40cbe7d0b7908f8","description":"Execute get-fsinfo.","extra":{"proxyto":"node"},"name":"get-fsinfo","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-fsinfo"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9cf4b6fc3212b396c58d6a512c432cccb2ea717ff2fcbc90d605a1297424bdc6","description":"Execute get-host-name.","extra":{"proxyto":"node"},"name":"get-host-name","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-host-name"},{"extra":{},"methods":[{"allow_token":true,"checksum":"158dd8fc432a96832a911df134ade2cd529edf621ab2aefe88cb64187b4f91bb","description":"Execute get-memory-block-info.","extra":{"proxyto":"node"},"name":"get-memory-block-info","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e28c4e7551b0ea74802bcdfbd6510a98487aa617c9968974ee6ce719ba61f22b","description":"Execute get-memory-blocks.","extra":{"proxyto":"node"},"name":"get-memory-blocks","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7446c414575aae4c9243aaadb5578134b14b38122810e827324ef429c1fbfba9","description":"Execute get-osinfo.","extra":{"proxyto":"node"},"name":"get-osinfo","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-osinfo"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3879b872b117327e90bb78e894517a4b68e58a4816adbf3bdd673d7dec72a599","description":"Execute get-time.","extra":{"proxyto":"node"},"name":"get-time","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-time"},{"extra":{},"methods":[{"allow_token":true,"checksum":"32d97a69447f2fd009b2a4012869cf4e16afb2f8a6006a7a7b3917b37942acd1","description":"Execute get-timezone.","extra":{"proxyto":"node"},"name":"get-timezone","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-timezone"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ff161720295d61537c82ed690c54cfc912bb3c17e1769fc04e5b686c320db52f","description":"Execute get-users.","extra":{"proxyto":"node"},"name":"get-users","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-users"},{"extra":{},"methods":[{"allow_token":true,"checksum":"10bd4248a21459773c0e73d0155de01cc015cc6a9d2ba190fbf6493dc3127e5d","description":"Execute get-vcpus.","extra":{"proxyto":"node"},"name":"get-vcpus","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/get-vcpus"},{"extra":{},"methods":[{"allow_token":true,"checksum":"70191e74c99a3efad5e88ead947ad8b543992a3271177f4bc7451037b4b20c90","description":"Execute info.","extra":{"proxyto":"node"},"name":"info","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/info"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8dc633c349dff59ce47b216de66ccefbd8684a22b2961c4816a44ecf4f3ffe93","description":"Execute network-get-interfaces.","extra":{"proxyto":"node"},"name":"network-get-interfaces","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces"},{"extra":{},"methods":[{"allow_token":true,"checksum":"907759754adc76d6da6f11332ac330ec1c1a456d00ae871a0e316c4ba4c8361e","description":"Execute ping.","extra":{"proxyto":"node"},"name":"ping","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/ping"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7bacdeabd84dabf4482a817651abd478c850eeb6a794475dbf072a1a3b29e87c","description":"Sets the password for the given user to the given password","extra":{"proxyto":"node"},"name":"set-user-password","parameters":[{"definition":{"default":0,"description":"set to 1 if the password has already been passed through crypt()","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"crypted"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The new password.","enum":[],"extra":{"typetext":""},"max_length":1024,"min_length":5,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"The user to set the password for.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"username"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/set-user-password"},{"extra":{},"methods":[{"allow_token":true,"checksum":"fe0338c16d67e6a7b937b819060f9979a6d90ad8aaa046fe45bbc277da148be4","description":"Execute shutdown.","extra":{"proxyto":"node"},"name":"shutdown","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/shutdown"},{"extra":{},"methods":[{"allow_token":true,"checksum":"972107d11db5913da62ed6598e8a565b8f3bd3e8a513457a6879dff0d6791484","description":"Execute suspend-disk.","extra":{"proxyto":"node"},"name":"suspend-disk","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/suspend-disk"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e1a3ef06b27eb037f58801e954f450836f13cfe7a516ee3df7b21bb895e07456","description":"Execute suspend-hybrid.","extra":{"proxyto":"node"},"name":"suspend-hybrid","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid"},{"extra":{},"methods":[{"allow_token":true,"checksum":"21f78a62fa2c134dba3618f4b5ba2697f1ee69d28da568e7dcb7b5a7f1395c7f","description":"Execute suspend-ram.","extra":{"proxyto":"node"},"name":"suspend-ram","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"description":"Returns an object with a single `result` property.","enum":[],"extra":{},"properties":{},"type":"object"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/agent/suspend-ram"},{"extra":{},"methods":[{"allow_token":true,"checksum":"10b4a9fb335a196b339d68a3084b9541edb26fa4f1e13b6a12d9f2e0306e0ffd","description":"Create a copy of virtual machine/template.","extra":{"proxyto":"node"},"name":"clone_vm","parameters":[{"definition":{"default":"clone limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"Description for the new VM.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Target format for file storage. Only valid for full clone.","enum":["raw","qcow2","vmdk"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"Create a full copy of all disks. This is always done when you clone a normal VM. For VM templates, we try to create a linked clone by default.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"full"},{"definition":{"description":"Set a name for the new VM.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"VMID for the clone.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"newid"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Add the new VM to the specified pool.","enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"Target storage for full clone.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Target node. Only allowed if the original VM is on shared storage.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Clone' permissions on /vms/{vmid}, and 'VM.Allocate' permissions on /vms/{newid} (or on the VM pool /pool/{pool}). You also need 'Datastore.AllocateSpace' on any used storage and 'SDN.Use' on any used bridge/vnet","expression":{"check":["and",["perm","/vms/{vmid}",["VM.Clone"]],["or",["perm","/vms/{newid}",["VM.Allocate"]],["perm","/pool/{pool}",["VM.Allocate"],"require_param","pool"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/clone"},{"extra":{},"methods":[{"allow_token":true,"checksum":"536f115222144300cae0a79ff9232f285dc046f51fa00c6c287753e4b66e6381","description":"Get the cloudinit configuration with both current and pending values.","extra":{"proxyto":"node"},"name":"cloudinit_pending","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"delete":{"description":"Indicates a pending delete request if present and not 0. ","enum":[],"extra":{},"maximum":1,"minimum":0,"optional":true,"properties":{},"type":"integer"},"key":{"description":"Configuration option name.","enum":[],"extra":{},"properties":{},"type":"string"},"pending":{"description":"The new pending value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"value":{"description":"Value as it was used to generate the current cloudinit image.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"cd8eb44b3b45afbd5e723e5e6e6717db900b9ecb3bc4f8749547f0819b37d962","description":"Regenerate and change cloudinit config drive.","extra":{"proxyto":"node"},"name":"cloudinit_update","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Cloudinit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/cloudinit"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5e03b909a48d15544b7f9793fe2aaca3498b6ef2d0ea53660fa2870cb934972c","description":"Get automatically generated cloudinit config.","extra":{"proxyto":"node"},"name":"cloudinit_generated_config_dump","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Config type.","enum":["user","network","meta"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/cloudinit/dump"},{"extra":{},"methods":[{"allow_token":true,"checksum":"cd4885a39a873fa1a1bb38a034f351989d0e0da35da04692e17be693e250ea0d","description":"Get the virtual machine configuration with pending configuration changes applied. Set the 'current' parameter to get the current configuration instead.","extra":{"proxyto":"node"},"name":"vm_config","parameters":[{"definition":{"default":0,"description":"Get current values (instead of pending values).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"current"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Fetch config values from given snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapshot"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"description":"The VM configuration.","enum":[],"extra":{},"properties":{"acpi":{"default":1,"description":"Enable/disable ACPI.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"affinity":{"description":"List of host cores used to execute guest processes, for example: 0,5,8-11","enum":[],"extra":{},"format":"pve-cpuset","optional":true,"properties":{},"type":"string"},"agent":{"description":"Enable/disable communication with the QEMU Guest Agent and its properties.","enum":[],"extra":{},"format":{"enabled":{"default":0,"default_key":1,"description":"Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.","type":"boolean"},"freeze-fs-on-backup":{"default":1,"description":"Freeze/thaw guest filesystems on backup for consistency.","optional":1,"type":"boolean"},"fstrim_cloned_disks":{"default":0,"description":"Run fstrim after moving a disk or migrating the VM.","optional":1,"type":"boolean"},"type":{"default":"virtio","description":"Select the agent type","enum":["virtio","isa"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"amd-sev":{"description":"Secure Encrypted Virtualization (SEV) features by AMD CPUs","enum":[],"extra":{},"format":"pve-qemu-sev-fmt","optional":true,"properties":{},"type":"string"},"arch":{"description":"Virtual processor architecture. Defaults to the host.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"args":{"description":"Arbitrary arguments passed to kvm.","enum":[],"extra":{"verbose_description":"Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -smbios 'type=0,vendor=FOO'\n\nNOTE: this option is for experts only.\n"},"optional":true,"properties":{},"type":"string"},"audio0":{"description":"Configure a audio device, useful in combination with QXL/Spice.","enum":[],"extra":{},"format":{"device":{"description":"Configure an audio device.","enum":["ich9-intel-hda","intel-hda","AC97"],"type":"string"},"driver":{"default":"spice","description":"Driver backend for the audio device.","enum":["spice","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"autostart":{"default":0,"description":"Automatic restart after crash (currently ignored).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"balloon":{"description":"Amount of target RAM for the VM in MiB. Using zero disables the ballon driver.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"bios":{"default":"seabios","description":"Select BIOS implementation.","enum":["seabios","ovmf"],"extra":{},"optional":true,"properties":{},"type":"string"},"boot":{"description":"Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.","enum":[],"extra":{},"format":"pve-qm-boot","optional":true,"properties":{},"type":"string"},"bootdisk":{"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","enum":[],"extra":{},"format":"pve-qm-bootdisk","optional":true,"pattern":"(ide|sata|scsi|virtio)\\d+","properties":{},"type":"string"},"cdrom":{"description":"This is an alias for option -ide2","enum":[],"extra":{"typetext":""},"format":"pve-qm-ide","optional":true,"properties":{},"type":"string"},"cicustom":{"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","enum":[],"extra":{},"format":"pve-qm-cicustom","optional":true,"properties":{},"type":"string"},"cipassword":{"description":"cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"citype":{"description":"Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.","enum":["configdrive2","nocloud","opennebula"],"extra":{},"optional":true,"properties":{},"type":"string"},"ciupgrade":{"default":1,"description":"cloud-init: do an automatic package upgrade after the first boot.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ciuser":{"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"cores":{"default":1,"description":"The number of cores per socket.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"cpu":{"description":"Emulated CPU type.","enum":[],"extra":{},"format":"pve-vm-cpu-conf","optional":true,"properties":{},"type":"string"},"cpulimit":{"default":0,"description":"Limit of CPU usage.","enum":[],"extra":{"verbose_description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit."},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"number"},"cpuunits":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"verbose_description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs."},"maximum":262144,"minimum":1,"optional":true,"properties":{},"type":"integer"},"description":{"description":"Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{},"max_length":8192,"optional":true,"properties":{},"type":"string"},"digest":{"description":"SHA1 digest of configuration file. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"properties":{},"type":"string"},"efidisk0":{"description":"Configure a disk for storing EFI vars.","enum":[],"extra":{},"format":{"efitype":{"default":"2m","description":"Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarch64 (ARM).","enum":["2m","4m"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"pre-enrolled-keys":{"default":0,"description":"Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.","optional":1,"type":"boolean"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"freeze":{"description":"Freeze CPU at startup (use 'c' monitor command to start execution).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"hookscript":{"description":"Script that will be executed during various steps in the vms lifetime.","enum":[],"extra":{},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"hostpci[n]":{"description":"Map host PCI devices into guest.","enum":[],"extra":{"verbose_description":"Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"format":"pve-qm-hostpci","optional":true,"properties":{},"type":"string"},"hotplug":{"default":"network,disk,usb","description":"Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.","enum":[],"extra":{},"format":"pve-hotplug-features","optional":true,"properties":{},"type":"string"},"hugepages":{"description":"Enable/disable hugepages memory.","enum":["any","2","1024"],"extra":{},"optional":true,"properties":{},"type":"string"},"ide[n]":{"description":"Use volume as IDE hard disk or CD-ROM (n is 0 to 3).","enum":[],"extra":{},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"model":{"description":"The drive's reported model name, url-encoded, up to 40 bytes long.","format":"urlencoded","format_description":"model","maxLength":120,"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"ipconfig[n]":{"description":"cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n","enum":[],"extra":{},"format":"pve-qm-ipconfig","optional":true,"properties":{},"type":"string"},"ivshmem":{"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host.","enum":[],"extra":{},"format":{"name":{"description":"The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.","format_description":"string","optional":1,"pattern":"[a-zA-Z0-9\\-]+","type":"string"},"size":{"description":"The size of the file in MB.","minimum":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"keephugepages":{"default":0,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"keyboard":{"description":"Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"kvm":{"default":1,"description":"Enable/disable KVM hardware virtualization.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"localtime":{"description":"Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"lock":{"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"],"extra":{},"optional":true,"properties":{},"type":"string"},"machine":{"description":"Specify the QEMU machine.","enum":[],"extra":{},"format":{"enable-s3":{"description":"Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"enable-s4":{"description":"Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"type":{"default_key":1,"description":"Specifies the QEMU machine type.","format_description":"machine type","maxLength":40,"optional":1,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","type":"string"},"viommu":{"description":"Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).","enum":["intel","virtio"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"memory":{"description":"Memory properties.","enum":[],"extra":{},"format":{"current":{"default":512,"default_key":1,"description":"Current amount of online RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.","minimum":16,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"migrate_downtime":{"default":0.1,"description":"Set maximum tolerated downtime (in seconds) for migrations. Should the migration not be able to converge in the very end, because too much newly dirtied RAM needs to be transferred, the limit will be increased automatically step-by-step until migration can converge.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"number"},"migrate_speed":{"default":0,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":{"description":"Set a name for the VM. Only used on the configuration web interface.","enum":[],"extra":{},"format":"dns-name","optional":true,"properties":{},"type":"string"},"nameserver":{"description":"cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{},"format":"address-list","optional":true,"properties":{},"type":"string"},"net[n]":{"description":"Specify network devices.","enum":[],"extra":{},"format":{"bridge":{"description":"Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n","format":"pve-bridge-id","format_description":"bridge","optional":1,"type":"string"},"e1000":{"alias":"macaddr","keyAlias":"model"},"e1000-82540em":{"alias":"macaddr","keyAlias":"model"},"e1000-82544gc":{"alias":"macaddr","keyAlias":"model"},"e1000-82545em":{"alias":"macaddr","keyAlias":"model"},"e1000e":{"alias":"macaddr","keyAlias":"model"},"firewall":{"description":"Whether this interface should be protected by the firewall.","optional":1,"type":"boolean"},"i82551":{"alias":"macaddr","keyAlias":"model"},"i82557b":{"alias":"macaddr","keyAlias":"model"},"i82559er":{"alias":"macaddr","keyAlias":"model"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"macaddr":{"description":"MAC address. That address must be unique within your network. This is automatically generated if not specified.","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"model":{"default_key":1,"description":"Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.","enum":["e1000","e1000-82540em","e1000-82544gc","e1000-82545em","e1000e","i82551","i82557b","i82559er","ne2k_isa","ne2k_pci","pcnet","rtl8139","virtio","vmxnet3"],"type":"string"},"mtu":{"description":"Force MTU, for VirtIO only. Set to '1' to use the bridge MTU","maximum":65520,"minimum":1,"optional":1,"type":"integer"},"ne2k_isa":{"alias":"macaddr","keyAlias":"model"},"ne2k_pci":{"alias":"macaddr","keyAlias":"model"},"pcnet":{"alias":"macaddr","keyAlias":"model"},"queues":{"description":"Number of packet queues to be used on the device.","maximum":64,"minimum":0,"optional":1,"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":0,"optional":1,"type":"number"},"rtl8139":{"alias":"macaddr","keyAlias":"model"},"tag":{"description":"VLAN tag to apply to packets on this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN trunks to pass through this interface.","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"virtio":{"alias":"macaddr","keyAlias":"model"},"vmxnet3":{"alias":"macaddr","keyAlias":"model"}},"optional":true,"properties":{},"type":"string"},"numa":{"default":0,"description":"Enable/disable NUMA.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"numa[n]":{"description":"NUMA topology.","enum":[],"extra":{},"format":{"cpus":{"description":"CPUs accessing this NUMA node.","format_description":"id[-id];...","pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"hostnodes":{"description":"Host NUMA nodes to use.","format_description":"id[-id];...","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"memory":{"description":"Amount of memory this NUMA node provides.","optional":1,"type":"number"},"policy":{"description":"NUMA allocation policy.","enum":["preferred","bind","interleave"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"onboot":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ostype":{"description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","win11","l24","l26","solaris"],"extra":{"verbose_description":"Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022/2025\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 6.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n"},"optional":true,"properties":{},"type":"string"},"parallel[n]":{"description":"Map host parallel devices (n is 0 to 2).","enum":[],"extra":{"verbose_description":"Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"/dev/parport\\d+|/dev/usb/lp\\d+","properties":{},"type":"string"},"protection":{"default":0,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"reboot":{"default":1,"description":"Allow reboot. If set to '0' the VM exit on reboot.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"rng0":{"description":"Configure a VirtIO-based Random Number Generator.","enum":[],"extra":{},"format":"pve-qm-rng","optional":true,"properties":{},"type":"string"},"sata[n]":{"description":"Use volume as SATA hard disk or CD-ROM (n is 0 to 5).","enum":[],"extra":{},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"scsi[n]":{"description":"Use volume as SCSI hard disk or CD-ROM (n is 0 to 30).","enum":[],"extra":{},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"product":{"description":"The drive's product name, up to 16 bytes long.","format_description":"product","optional":1,"pattern":"[A-Za-z0-9\\-_\\s]{,16}","type":"string"},"queues":{"description":"Number of queues.","minimum":2,"optional":1,"type":"integer"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"scsiblock":{"default":0,"description":"whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"vendor":{"description":"The drive's vendor name, up to 8 bytes long.","format_description":"vendor","optional":1,"pattern":"[A-Za-z0-9\\-_\\s]{,8}","type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"scsihw":{"default":"lsi","description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"extra":{},"optional":true,"properties":{},"type":"string"},"searchdomain":{"description":"cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial[n]":{"description":"Create a serial device inside the VM (n is 0 to 3)","enum":[],"extra":{"verbose_description":"Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"(/dev/.+|socket)","properties":{},"type":"string"},"shares":{"default":1000,"description":"Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.","enum":[],"extra":{},"maximum":50000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"smbios1":{"description":"Specify SMBIOS type 1 fields.","enum":[],"extra":{},"format":"pve-qm-smbios1","max_length":512,"optional":true,"properties":{},"type":"string"},"smp":{"default":1,"description":"The number of CPUs. Please use option -sockets instead.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"sockets":{"default":1,"description":"The number of CPU sockets.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"spice_enhancements":{"description":"Configure additional enhancements for SPICE.","enum":[],"extra":{},"format":{"foldersharing":{"default":"0","description":"Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.","optional":1,"type":"boolean"},"videostreaming":{"default":"off","description":"Enable video streaming. Uses compression for detected video streams.","enum":["off","all","filter"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"sshkeys":{"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{},"format":"urlencoded","optional":true,"properties":{},"type":"string"},"startdate":{"default":"now","description":"Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.","enum":[],"extra":{"typetext":"(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)"},"optional":true,"pattern":"(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)","properties":{},"type":"string"},"startup":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"tablet":{"default":1,"description":"Enable/disable the USB tablet device.","enum":[],"extra":{"verbose_description":"Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)."},"optional":true,"properties":{},"type":"boolean"},"tags":{"description":"Tags of the VM. This is only meta information.","enum":[],"extra":{},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"tdf":{"default":0,"description":"Enable/disable time drift fix.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"template":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"tpmstate0":{"description":"Configure a Disk for storing TPM state. The format is fixed to 'raw'.","enum":[],"extra":{},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"version":{"default":"v1.2","description":"The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.","enum":["v1.2","v2.0"],"optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"unused[n]":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id","format_description":"volume","type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"usb[n]":{"description":"Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).","enum":[],"extra":{},"format":{"host":{"default_key":1,"description":"The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadecimal numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n\nEither this or the 'mapping' key must be set.\n","format_description":"HOSTUSBDEVICE|spice","optional":1,"pattern":"(?^:(?:(?:(?^:(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})))|(?:(?^:(\\d+)\\-(\\d+(\\.\\d+)*)))|[Ss][Pp][Ii][Cc][Ee]))","type":"string"},"mapping":{"description":"The ID of a cluster wide mapping. Either this or the default-key 'host' must be set.","format":"pve-configid","format_description":"mapping-id","optional":1,"type":"string"},"usb3":{"default":0,"description":"Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"vcpus":{"default":0,"description":"Number of hotplugged vcpus.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"vga":{"description":"Configure the VGA hardware.","enum":[],"extra":{"verbose_description":"Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal."},"format":{"clipboard":{"description":"Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Migration with VNC clipboard is not yet supported!","enum":["vnc"],"optional":1,"type":"string"},"memory":{"description":"Sets the VGA memory (in MiB). Has no effect with serial display.","maximum":512,"minimum":4,"optional":1,"type":"integer"},"type":{"default":"std","default_key":1,"description":"Select the VGA type. Using type 'cirrus' is not recommended.","enum":["cirrus","qxl","qxl2","qxl3","qxl4","none","serial0","serial1","serial2","serial3","std","virtio","virtio-gl","vmware"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"virtio[n]":{"description":"Use volume as VIRTIO hard disk (n is 0 to 15).","enum":[],"extra":{},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"virtiofs[n]":{"description":"Configuration for sharing a directory between host and guest using Virtio-fs.","enum":[],"extra":{},"format":{"cache":{"default":"auto","description":"The caching policy the file system should use (auto, always, metadata, never).","enum":["auto","always","metadata","never"],"optional":1,"type":"string"},"direct-io":{"default":0,"description":"Honor the O_DIRECT flag passed down by guest applications.","optional":1,"type":"boolean"},"dirid":{"default_key":1,"description":"Mapping identifier of the directory mapping to be shared with the guest. Also used as a mount tag inside the VM.","format":"pve-configid","format_description":"mapping-id","type":"string"},"expose-acl":{"default":0,"description":"Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.","optional":1,"type":"boolean"},"expose-xattr":{"default":0,"description":"Enable support for extended attributes for this mount.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"vmgenid":{"default":"1 (autogenerated)","description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","enum":[],"extra":{"format_description":"UUID","verbose_description":"The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file."},"optional":true,"pattern":"(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])","properties":{},"type":"string"},"vmstatestorage":{"description":"Default storage for VM state volumes/files.","enum":[],"extra":{"format_description":"storage ID"},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"watchdog":{"description":"Create a virtual hardware watchdog device.","enum":[],"extra":{"verbose_description":"Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)"},"format":"pve-qm-watchdog","optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"0ff4bb795dc88dd6a073dd9d9cce5d30a5384487a009830ff3306a427377229c","description":"Set virtual machine options (asynchronous API).","extra":{"proxyto":"node"},"name":"update_vm_async","parameters":[{"definition":{"default":1,"description":"Enable/disable ACPI.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"acpi"},{"definition":{"description":"List of host cores used to execute guest processes, for example: 0,5,8-11","enum":[],"extra":{"typetext":""},"format":"pve-cpuset","optional":true,"properties":{},"type":"string"},"name":"affinity"},{"definition":{"description":"Enable/disable communication with the QEMU Guest Agent and its properties.","enum":[],"extra":{"typetext":"[enabled=]<1|0> [,freeze-fs-on-backup=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]"},"format":{"enabled":{"default":0,"default_key":1,"description":"Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.","type":"boolean"},"freeze-fs-on-backup":{"default":1,"description":"Freeze/thaw guest filesystems on backup for consistency.","optional":1,"type":"boolean"},"fstrim_cloned_disks":{"default":0,"description":"Run fstrim after moving a disk or migrating the VM.","optional":1,"type":"boolean"},"type":{"default":"virtio","description":"Select the agent type","enum":["virtio","isa"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"agent"},{"definition":{"description":"Secure Encrypted Virtualization (SEV) features by AMD CPUs","enum":[],"extra":{"typetext":"[type=] [,allow-smt=<1|0>] [,kernel-hashes=<1|0>] [,no-debug=<1|0>] [,no-key-sharing=<1|0>]"},"format":"pve-qemu-sev-fmt","optional":true,"properties":{},"type":"string"},"name":"amd-sev"},{"definition":{"description":"Virtual processor architecture. Defaults to the host.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"description":"Arbitrary arguments passed to kvm.","enum":[],"extra":{"typetext":"","verbose_description":"Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -smbios 'type=0,vendor=FOO'\n\nNOTE: this option is for experts only.\n"},"optional":true,"properties":{},"type":"string"},"name":"args"},{"definition":{"description":"Configure a audio device, useful in combination with QXL/Spice.","enum":[],"extra":{"typetext":"device= [,driver=]"},"format":{"device":{"description":"Configure an audio device.","enum":["ich9-intel-hda","intel-hda","AC97"],"type":"string"},"driver":{"default":"spice","description":"Driver backend for the audio device.","enum":["spice","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"audio0"},{"definition":{"default":0,"description":"Automatic restart after crash (currently ignored).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Time to wait for the task to finish. We return 'null' if the task finish within that time.","enum":[],"extra":{"typetext":" (1 - 30)"},"maximum":30,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"background_delay"},{"definition":{"description":"Amount of target RAM for the VM in MiB. Using zero disables the ballon driver.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"balloon"},{"definition":{"default":"seabios","description":"Select BIOS implementation.","enum":["seabios","ovmf"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bios"},{"definition":{"description":"Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.","enum":[],"extra":{"typetext":"[[legacy=]<[acdn]{1,4}>] [,order=]"},"format":"pve-qm-boot","optional":true,"properties":{},"type":"string"},"name":"boot"},{"definition":{"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","enum":[],"extra":{},"format":"pve-qm-bootdisk","optional":true,"pattern":"(ide|sata|scsi|virtio)\\d+","properties":{},"type":"string"},"name":"bootdisk"},{"definition":{"description":"This is an alias for option -ide2","enum":[],"extra":{"typetext":""},"format":"pve-qm-ide","optional":true,"properties":{},"type":"string"},"name":"cdrom"},{"definition":{"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","enum":[],"extra":{"typetext":"[meta=] [,network=] [,user=] [,vendor=]"},"format":"pve-qm-cicustom","optional":true,"properties":{},"type":"string"},"name":"cicustom"},{"definition":{"description":"cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cipassword"},{"definition":{"description":"Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.","enum":["configdrive2","nocloud","opennebula"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"citype"},{"definition":{"default":1,"description":"cloud-init: do an automatic package upgrade after the first boot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ciupgrade"},{"definition":{"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ciuser"},{"definition":{"default":1,"description":"The number of cores per socket.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"description":"Emulated CPU type.","enum":[],"extra":{"typetext":"[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]"},"format":"pve-vm-cpu-conf","optional":true,"properties":{},"type":"string"},"name":"cpu"},{"definition":{"default":0,"description":"Limit of CPU usage.","enum":[],"extra":{"typetext":" (0 - 128)","verbose_description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit."},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"typetext":" (1 - 262144)","verbose_description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs."},"maximum":262144,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":8192,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,pre-enrolled-keys=<1|0>] [,size=]"},"format":{"efitype":{"default":"2m","description":"Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarch64 (ARM).","enum":["2m","4m"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"pre-enrolled-keys":{"default":0,"description":"Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.","optional":1,"type":"boolean"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"efidisk0"},{"definition":{"description":"Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.","enum":[],"extra":{"requires":"delete","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Freeze CPU at startup (use 'c' monitor command to start execution).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"freeze"},{"definition":{"description":"Script that will be executed during various steps in the vms lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Map host PCI devices into guest.","enum":[],"extra":{"typetext":"[[host=]] [,device-id=] [,legacy-igd=<1|0>] [,mapping=] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]","verbose_description":"Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"format":"pve-qm-hostpci","optional":true,"properties":{},"type":"string"},"name":"hostpci[n]"},{"definition":{"default":"network,disk,usb","description":"Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.","enum":[],"extra":{"typetext":""},"format":"pve-hotplug-features","optional":true,"properties":{},"type":"string"},"name":"hotplug"},{"definition":{"description":"Enable/disable hugepages memory.","enum":["any","2","1024"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"hugepages"},{"definition":{"description":"Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"model":{"description":"The drive's reported model name, url-encoded, up to 40 bytes long.","format":"urlencoded","format_description":"model","maxLength":120,"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"ide[n]"},{"definition":{"description":"A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"import-working-storage"},{"definition":{"description":"cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n","enum":[],"extra":{"typetext":"[gw=] [,gw6=] [,ip=] [,ip6=]"},"format":"pve-qm-ipconfig","optional":true,"properties":{},"type":"string"},"name":"ipconfig[n]"},{"definition":{"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host.","enum":[],"extra":{"typetext":"size= [,name=]"},"format":{"name":{"description":"The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.","format_description":"string","optional":1,"pattern":"[a-zA-Z0-9\\-]+","type":"string"},"size":{"description":"The size of the file in MB.","minimum":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"ivshmem"},{"definition":{"default":0,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keephugepages"},{"definition":{"description":"Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"keyboard"},{"definition":{"default":1,"description":"Enable/disable KVM hardware virtualization.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"kvm"},{"definition":{"description":"Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"localtime"},{"definition":{"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"description":"Specify the QEMU machine.","enum":[],"extra":{"typetext":"[[type=]] [,enable-s3=<1|0>] [,enable-s4=<1|0>] [,viommu=]"},"format":{"enable-s3":{"description":"Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"enable-s4":{"description":"Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"type":{"default_key":1,"description":"Specifies the QEMU machine type.","format_description":"machine type","maxLength":40,"optional":1,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","type":"string"},"viommu":{"description":"Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).","enum":["intel","virtio"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"machine"},{"definition":{"description":"Memory properties.","enum":[],"extra":{"typetext":"[current=]"},"format":{"current":{"default":512,"default_key":1,"description":"Current amount of online RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.","minimum":16,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"memory"},{"definition":{"default":0.1,"description":"Set maximum tolerated downtime (in seconds) for migrations. Should the migration not be able to converge in the very end, because too much newly dirtied RAM needs to be transferred, the limit will be increased automatically step-by-step until migration can converge.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"migrate_downtime"},{"definition":{"default":0,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"migrate_speed"},{"definition":{"description":"Set a name for the VM. Only used on the configuration web interface.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"format":"address-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specify network devices.","enum":[],"extra":{"typetext":"[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]"},"format":{"bridge":{"description":"Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n","format":"pve-bridge-id","format_description":"bridge","optional":1,"type":"string"},"e1000":{"alias":"macaddr","keyAlias":"model"},"e1000-82540em":{"alias":"macaddr","keyAlias":"model"},"e1000-82544gc":{"alias":"macaddr","keyAlias":"model"},"e1000-82545em":{"alias":"macaddr","keyAlias":"model"},"e1000e":{"alias":"macaddr","keyAlias":"model"},"firewall":{"description":"Whether this interface should be protected by the firewall.","optional":1,"type":"boolean"},"i82551":{"alias":"macaddr","keyAlias":"model"},"i82557b":{"alias":"macaddr","keyAlias":"model"},"i82559er":{"alias":"macaddr","keyAlias":"model"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"macaddr":{"description":"MAC address. That address must be unique within your network. This is automatically generated if not specified.","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"model":{"default_key":1,"description":"Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.","enum":["e1000","e1000-82540em","e1000-82544gc","e1000-82545em","e1000e","i82551","i82557b","i82559er","ne2k_isa","ne2k_pci","pcnet","rtl8139","virtio","vmxnet3"],"type":"string"},"mtu":{"description":"Force MTU, for VirtIO only. Set to '1' to use the bridge MTU","maximum":65520,"minimum":1,"optional":1,"type":"integer"},"ne2k_isa":{"alias":"macaddr","keyAlias":"model"},"ne2k_pci":{"alias":"macaddr","keyAlias":"model"},"pcnet":{"alias":"macaddr","keyAlias":"model"},"queues":{"description":"Number of packet queues to be used on the device.","maximum":64,"minimum":0,"optional":1,"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":0,"optional":1,"type":"number"},"rtl8139":{"alias":"macaddr","keyAlias":"model"},"tag":{"description":"VLAN tag to apply to packets on this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN trunks to pass through this interface.","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"virtio":{"alias":"macaddr","keyAlias":"model"},"vmxnet3":{"alias":"macaddr","keyAlias":"model"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Enable/disable NUMA.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"numa"},{"definition":{"description":"NUMA topology.","enum":[],"extra":{"typetext":"cpus= [,hostnodes=] [,memory=] [,policy=]"},"format":{"cpus":{"description":"CPUs accessing this NUMA node.","format_description":"id[-id];...","pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"hostnodes":{"description":"Host NUMA nodes to use.","format_description":"id[-id];...","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"memory":{"description":"Amount of memory this NUMA node provides.","optional":1,"type":"number"},"policy":{"description":"NUMA allocation policy.","enum":["preferred","bind","interleave"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"numa[n]"},{"definition":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","win11","l24","l26","solaris"],"extra":{"verbose_description":"Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022/2025\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 6.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n"},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"description":"Map host parallel devices (n is 0 to 2).","enum":[],"extra":{"verbose_description":"Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"/dev/parport\\d+|/dev/usb/lp\\d+","properties":{},"type":"string"},"name":"parallel[n]"},{"definition":{"default":0,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"default":1,"description":"Allow reboot. If set to '0' the VM exit on reboot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"reboot"},{"definition":{"description":"Revert a pending change.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"revert"},{"definition":{"description":"Configure a VirtIO-based Random Number Generator.","enum":[],"extra":{"typetext":"[source=] [,max_bytes=] [,period=]"},"format":"pve-qm-rng","optional":true,"properties":{},"type":"string"},"name":"rng0"},{"definition":{"description":"Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"sata[n]"},{"definition":{"description":"Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,product=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,vendor=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"product":{"description":"The drive's product name, up to 16 bytes long.","format_description":"product","optional":1,"pattern":"[A-Za-z0-9\\-_\\s]{,16}","type":"string"},"queues":{"description":"Number of queues.","minimum":2,"optional":1,"type":"integer"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"scsiblock":{"default":0,"description":"whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"vendor":{"description":"The drive's vendor name, up to 8 bytes long.","format_description":"vendor","optional":1,"pattern":"[A-Za-z0-9\\-_\\s]{,8}","type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"scsi[n]"},{"definition":{"default":"lsi","description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scsihw"},{"definition":{"description":"cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Create a serial device inside the VM (n is 0 to 3)","enum":[],"extra":{"verbose_description":"Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"(/dev/.+|socket)","properties":{},"type":"string"},"name":"serial[n]"},{"definition":{"default":1000,"description":"Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.","enum":[],"extra":{"typetext":" (0 - 50000)"},"maximum":50000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"shares"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Specify SMBIOS type 1 fields.","enum":[],"extra":{"typetext":"[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]"},"format":"pve-qm-smbios1","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"smbios1"},{"definition":{"default":1,"description":"The number of CPUs. Please use option -sockets instead.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"smp"},{"definition":{"default":1,"description":"The number of CPU sockets.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"sockets"},{"definition":{"description":"Configure additional enhancements for SPICE.","enum":[],"extra":{"typetext":"[foldersharing=<1|0>] [,videostreaming=]"},"format":{"foldersharing":{"default":"0","description":"Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.","optional":1,"type":"boolean"},"videostreaming":{"default":"off","description":"Enable video streaming. Uses compression for detected video streams.","enum":["off","all","filter"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"spice_enhancements"},{"definition":{"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{"typetext":""},"format":"urlencoded","optional":true,"properties":{},"type":"string"},"name":"sshkeys"},{"definition":{"default":"now","description":"Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.","enum":[],"extra":{"typetext":"(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)"},"optional":true,"pattern":"(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)","properties":{},"type":"string"},"name":"startdate"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"default":1,"description":"Enable/disable the USB tablet device.","enum":[],"extra":{"typetext":"","verbose_description":"Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)."},"optional":true,"properties":{},"type":"boolean"},"name":"tablet"},{"definition":{"description":"Tags of the VM. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable time drift fix.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tdf"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,import-from=] [,size=] [,version=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"version":{"default":"v1.2","description":"The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.","enum":["v1.2","v2.0"],"optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"tpmstate0"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[file=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id","format_description":"volume","type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).","enum":[],"extra":{"typetext":"[[host=]] [,mapping=] [,usb3=<1|0>]"},"format":{"host":{"default_key":1,"description":"The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadecimal numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n\nEither this or the 'mapping' key must be set.\n","format_description":"HOSTUSBDEVICE|spice","optional":1,"pattern":"(?^:(?:(?:(?^:(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})))|(?:(?^:(\\d+)\\-(\\d+(\\.\\d+)*)))|[Ss][Pp][Ii][Cc][Ee]))","type":"string"},"mapping":{"description":"The ID of a cluster wide mapping. Either this or the default-key 'host' must be set.","format":"pve-configid","format_description":"mapping-id","optional":1,"type":"string"},"usb3":{"default":0,"description":"Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"usb[n]"},{"definition":{"default":0,"description":"Number of hotplugged vcpus.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vcpus"},{"definition":{"description":"Configure the VGA hardware.","enum":[],"extra":{"typetext":"[[type=]] [,clipboard=] [,memory=]","verbose_description":"Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal."},"format":{"clipboard":{"description":"Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Migration with VNC clipboard is not yet supported!","enum":["vnc"],"optional":1,"type":"string"},"memory":{"description":"Sets the VGA memory (in MiB). Has no effect with serial display.","maximum":512,"minimum":4,"optional":1,"type":"integer"},"type":{"default":"std","default_key":1,"description":"Select the VGA type. Using type 'cirrus' is not recommended.","enum":["cirrus","qxl","qxl2","qxl3","qxl4","none","serial0","serial1","serial2","serial3","std","virtio","virtio-gl","vmware"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"vga"},{"definition":{"description":"Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"virtio[n]"},{"definition":{"description":"Configuration for sharing a directory between host and guest using Virtio-fs.","enum":[],"extra":{"typetext":"[dirid=] [,cache=] [,direct-io=<1|0>] [,expose-acl=<1|0>] [,expose-xattr=<1|0>]"},"format":{"cache":{"default":"auto","description":"The caching policy the file system should use (auto, always, metadata, never).","enum":["auto","always","metadata","never"],"optional":1,"type":"string"},"direct-io":{"default":0,"description":"Honor the O_DIRECT flag passed down by guest applications.","optional":1,"type":"boolean"},"dirid":{"default_key":1,"description":"Mapping identifier of the directory mapping to be shared with the guest. Also used as a mount tag inside the VM.","format":"pve-configid","format_description":"mapping-id","type":"string"},"expose-acl":{"default":0,"description":"Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.","optional":1,"type":"boolean"},"expose-xattr":{"default":0,"description":"Enable support for extended attributes for this mount.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"virtiofs[n]"},{"definition":{"default":"1 (autogenerated)","description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","enum":[],"extra":{"format_description":"UUID","verbose_description":"The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file."},"optional":true,"pattern":"(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])","properties":{},"type":"string"},"name":"vmgenid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Default storage for VM state volumes/files.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"vmstatestorage"},{"definition":{"description":"Create a virtual hardware watchdog device.","enum":[],"extra":{"typetext":"[[model=]] [,action=]","verbose_description":"Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)"},"format":"pve-qm-watchdog","optional":true,"properties":{},"type":"string"},"name":"watchdog"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk","VM.Config.CDROM","VM.Config.CPU","VM.Config.Memory","VM.Config.Network","VM.Config.HWType","VM.Config.Options","VM.Config.Cloudinit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"verb":"POST"},{"allow_token":true,"checksum":"ed9ed69ee0b437a8754b78d30ad4fafd217b769651f91f9407b4e2caaff3fd7d","description":"Set virtual machine options (synchronous API) - You should consider using the POST method instead for any actions involving hotplug or storage allocation.","extra":{"proxyto":"node"},"name":"update_vm","parameters":[{"definition":{"default":1,"description":"Enable/disable ACPI.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"acpi"},{"definition":{"description":"List of host cores used to execute guest processes, for example: 0,5,8-11","enum":[],"extra":{"typetext":""},"format":"pve-cpuset","optional":true,"properties":{},"type":"string"},"name":"affinity"},{"definition":{"description":"Enable/disable communication with the QEMU Guest Agent and its properties.","enum":[],"extra":{"typetext":"[enabled=]<1|0> [,freeze-fs-on-backup=<1|0>] [,fstrim_cloned_disks=<1|0>] [,type=]"},"format":{"enabled":{"default":0,"default_key":1,"description":"Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.","type":"boolean"},"freeze-fs-on-backup":{"default":1,"description":"Freeze/thaw guest filesystems on backup for consistency.","optional":1,"type":"boolean"},"fstrim_cloned_disks":{"default":0,"description":"Run fstrim after moving a disk or migrating the VM.","optional":1,"type":"boolean"},"type":{"default":"virtio","description":"Select the agent type","enum":["virtio","isa"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"agent"},{"definition":{"description":"Secure Encrypted Virtualization (SEV) features by AMD CPUs","enum":[],"extra":{"typetext":"[type=] [,allow-smt=<1|0>] [,kernel-hashes=<1|0>] [,no-debug=<1|0>] [,no-key-sharing=<1|0>]"},"format":"pve-qemu-sev-fmt","optional":true,"properties":{},"type":"string"},"name":"amd-sev"},{"definition":{"description":"Virtual processor architecture. Defaults to the host.","enum":["x86_64","aarch64"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"arch"},{"definition":{"description":"Arbitrary arguments passed to kvm.","enum":[],"extra":{"typetext":"","verbose_description":"Arbitrary arguments passed to kvm, for example:\n\nargs: -no-reboot -smbios 'type=0,vendor=FOO'\n\nNOTE: this option is for experts only.\n"},"optional":true,"properties":{},"type":"string"},"name":"args"},{"definition":{"description":"Configure a audio device, useful in combination with QXL/Spice.","enum":[],"extra":{"typetext":"device= [,driver=]"},"format":{"device":{"description":"Configure an audio device.","enum":["ich9-intel-hda","intel-hda","AC97"],"type":"string"},"driver":{"default":"spice","description":"Driver backend for the audio device.","enum":["spice","none"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"audio0"},{"definition":{"default":0,"description":"Automatic restart after crash (currently ignored).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"autostart"},{"definition":{"description":"Amount of target RAM for the VM in MiB. Using zero disables the ballon driver.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"balloon"},{"definition":{"default":"seabios","description":"Select BIOS implementation.","enum":["seabios","ovmf"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"bios"},{"definition":{"description":"Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.","enum":[],"extra":{"typetext":"[[legacy=]<[acdn]{1,4}>] [,order=]"},"format":"pve-qm-boot","optional":true,"properties":{},"type":"string"},"name":"boot"},{"definition":{"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","enum":[],"extra":{},"format":"pve-qm-bootdisk","optional":true,"pattern":"(ide|sata|scsi|virtio)\\d+","properties":{},"type":"string"},"name":"bootdisk"},{"definition":{"description":"This is an alias for option -ide2","enum":[],"extra":{"typetext":""},"format":"pve-qm-ide","optional":true,"properties":{},"type":"string"},"name":"cdrom"},{"definition":{"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","enum":[],"extra":{"typetext":"[meta=] [,network=] [,user=] [,vendor=]"},"format":"pve-qm-cicustom","optional":true,"properties":{},"type":"string"},"name":"cicustom"},{"definition":{"description":"cloud-init: Password to assign the user. Using this is generally not recommended. Use ssh keys instead. Also note that older cloud-init versions do not support hashed passwords.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cipassword"},{"definition":{"description":"Specifies the cloud-init configuration format. The default depends on the configured operating system type (`ostype`. We use the `nocloud` format for Linux, and `configdrive2` for windows.","enum":["configdrive2","nocloud","opennebula"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"citype"},{"definition":{"default":1,"description":"cloud-init: do an automatic package upgrade after the first boot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ciupgrade"},{"definition":{"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"ciuser"},{"definition":{"default":1,"description":"The number of cores per socket.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cores"},{"definition":{"description":"Emulated CPU type.","enum":[],"extra":{"typetext":"[[cputype=]] [,flags=<+FLAG[;-FLAG...]>] [,hidden=<1|0>] [,hv-vendor-id=] [,phys-bits=<8-64|host>] [,reported-model=]"},"format":"pve-vm-cpu-conf","optional":true,"properties":{},"type":"string"},"name":"cpu"},{"definition":{"default":0,"description":"Limit of CPU usage.","enum":[],"extra":{"typetext":" (0 - 128)","verbose_description":"Limit of CPU usage.\n\nNOTE: If the computer has 2 CPUs, it has total of '2' CPU time. Value '0' indicates no CPU limit."},"maximum":128,"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"cpulimit"},{"definition":{"default":"cgroup v1: 1024, cgroup v2: 100","description":"CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.","enum":[],"extra":{"typetext":" (1 - 262144)","verbose_description":"CPU weight for a VM. Argument is used in the kernel fair scheduler. The larger the number is, the more CPU time this VM gets. Number is relative to weights of all the other running VMs."},"maximum":262144,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"cpuunits"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.","enum":[],"extra":{"typetext":""},"max_length":8192,"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Configure a disk for storing EFI vars. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and that the default EFI vars are copied to the volume instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,efitype=<2m|4m>] [,format=] [,import-from=] [,pre-enrolled-keys=<1|0>] [,size=]"},"format":{"efitype":{"default":"2m","description":"Size and type of the OVMF EFI vars. '4m' is newer and recommended, and required for Secure Boot. For backwards compatibility, '2m' is used if not otherwise specified. Ignored for VMs with arch=aarch64 (ARM).","enum":["2m","4m"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"pre-enrolled-keys":{"default":0,"description":"Use am EFI vars template with distribution-specific and Microsoft Standard keys enrolled, if used with 'efitype=4m'. Note that this will enable Secure Boot by default, though it can still be turned off from within the VM.","optional":1,"type":"boolean"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"efidisk0"},{"definition":{"description":"Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.","enum":[],"extra":{"requires":"delete","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"Freeze CPU at startup (use 'c' monitor command to start execution).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"freeze"},{"definition":{"description":"Script that will be executed during various steps in the vms lifetime.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"hookscript"},{"definition":{"description":"Map host PCI devices into guest.","enum":[],"extra":{"typetext":"[[host=]] [,device-id=] [,legacy-igd=<1|0>] [,mapping=] [,mdev=] [,pcie=<1|0>] [,rombar=<1|0>] [,romfile=] [,sub-device-id=] [,sub-vendor-id=] [,vendor-id=] [,x-vga=<1|0>]","verbose_description":"Map host PCI devices into guest.\n\nNOTE: This option allows direct access to host hardware. So it is no longer\npossible to migrate such machines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"format":"pve-qm-hostpci","optional":true,"properties":{},"type":"string"},"name":"hostpci[n]"},{"definition":{"default":"network,disk,usb","description":"Selectively enable hotplug features. This is a comma separated list of hotplug features: 'network', 'disk', 'cpu', 'memory', 'usb' and 'cloudinit'. Use '0' to disable hotplug completely. Using '1' as value is an alias for the default `network,disk,usb`. USB hotplugging is possible for guests with machine version >= 7.1 and ostype l26 or windows > 7.","enum":[],"extra":{"typetext":""},"format":"pve-hotplug-features","optional":true,"properties":{},"type":"string"},"name":"hotplug"},{"definition":{"description":"Enable/disable hugepages memory.","enum":["any","2","1024"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"hugepages"},{"definition":{"description":"Use volume as IDE hard disk or CD-ROM (n is 0 to 3). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,model=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"model":{"description":"The drive's reported model name, url-encoded, up to 40 bytes long.","format":"urlencoded","format_description":"model","maxLength":120,"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"ide[n]"},{"definition":{"description":"cloud-init: Specify IP addresses and gateways for the corresponding interface.\n\nIP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.\n\nThe special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit\ngateway should be provided.\nFor IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires\ncloud-init 19.4 or newer.\n\nIf cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using\ndhcp on IPv4.\n","enum":[],"extra":{"typetext":"[gw=] [,gw6=] [,ip=] [,ip6=]"},"format":"pve-qm-ipconfig","optional":true,"properties":{},"type":"string"},"name":"ipconfig[n]"},{"definition":{"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host.","enum":[],"extra":{"typetext":"size= [,name=]"},"format":{"name":{"description":"The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.","format_description":"string","optional":1,"pattern":"[a-zA-Z0-9\\-]+","type":"string"},"size":{"description":"The size of the file in MB.","minimum":1,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"ivshmem"},{"definition":{"default":0,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keephugepages"},{"definition":{"description":"Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS.","enum":["de","de-ch","da","en-gb","en-us","es","fi","fr","fr-be","fr-ca","fr-ch","hu","is","it","ja","lt","mk","nl","no","pl","pt","pt-br","sv","sl","tr"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"keyboard"},{"definition":{"default":1,"description":"Enable/disable KVM hardware virtualization.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"kvm"},{"definition":{"description":"Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"localtime"},{"definition":{"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"lock"},{"definition":{"description":"Specify the QEMU machine.","enum":[],"extra":{"typetext":"[[type=]] [,enable-s3=<1|0>] [,enable-s4=<1|0>] [,viommu=]"},"format":{"enable-s3":{"description":"Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"enable-s4":{"description":"Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"type":{"default_key":1,"description":"Specifies the QEMU machine type.","format_description":"machine type","maxLength":40,"optional":1,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","type":"string"},"viommu":{"description":"Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).","enum":["intel","virtio"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"machine"},{"definition":{"description":"Memory properties.","enum":[],"extra":{"typetext":"[current=]"},"format":{"current":{"default":512,"default_key":1,"description":"Current amount of online RAM for the VM in MiB. This is the maximum available memory when you use the balloon device.","minimum":16,"type":"integer"}},"optional":true,"properties":{},"type":"string"},"name":"memory"},{"definition":{"default":0.1,"description":"Set maximum tolerated downtime (in seconds) for migrations. Should the migration not be able to converge in the very end, because too much newly dirtied RAM needs to be transferred, the limit will be increased automatically step-by-step until migration can converge.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"number"},"name":"migrate_downtime"},{"definition":{"default":0,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"migrate_speed"},{"definition":{"description":"Set a name for the VM. Only used on the configuration web interface.","enum":[],"extra":{"typetext":""},"format":"dns-name","optional":true,"properties":{},"type":"string"},"name":"name"},{"definition":{"description":"cloud-init: Sets DNS server IP address for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"format":"address-list","optional":true,"properties":{},"type":"string"},"name":"nameserver"},{"definition":{"description":"Specify network devices.","enum":[],"extra":{"typetext":"[model=] [,bridge=] [,firewall=<1|0>] [,link_down=<1|0>] [,macaddr=] [,mtu=] [,queues=] [,rate=] [,tag=] [,trunks=] [,=]"},"format":{"bridge":{"description":"Bridge to attach the network device to. The Proxmox VE standard bridge\nis called 'vmbr0'.\n\nIf you do not specify a bridge, we create a kvm user (NATed) network\ndevice, which provides DHCP and DNS services. The following addresses\nare used:\n\n 10.0.2.2 Gateway\n 10.0.2.3 DNS Server\n 10.0.2.4 SMB Server\n\nThe DHCP server assign addresses to the guest starting from 10.0.2.15.\n","format":"pve-bridge-id","format_description":"bridge","optional":1,"type":"string"},"e1000":{"alias":"macaddr","keyAlias":"model"},"e1000-82540em":{"alias":"macaddr","keyAlias":"model"},"e1000-82544gc":{"alias":"macaddr","keyAlias":"model"},"e1000-82545em":{"alias":"macaddr","keyAlias":"model"},"e1000e":{"alias":"macaddr","keyAlias":"model"},"firewall":{"description":"Whether this interface should be protected by the firewall.","optional":1,"type":"boolean"},"i82551":{"alias":"macaddr","keyAlias":"model"},"i82557b":{"alias":"macaddr","keyAlias":"model"},"i82559er":{"alias":"macaddr","keyAlias":"model"},"link_down":{"description":"Whether this interface should be disconnected (like pulling the plug).","optional":1,"type":"boolean"},"macaddr":{"description":"MAC address. That address must be unique within your network. This is automatically generated if not specified.","format":"mac-addr","format_description":"XX:XX:XX:XX:XX:XX","optional":1,"type":"string","verbose_description":"A common MAC address with the I/G (Individual/Group) bit not set."},"model":{"default_key":1,"description":"Network Card Model. The 'virtio' model provides the best performance with very low CPU overhead. If your guest does not support this driver, it is usually best to use 'e1000'.","enum":["e1000","e1000-82540em","e1000-82544gc","e1000-82545em","e1000e","i82551","i82557b","i82559er","ne2k_isa","ne2k_pci","pcnet","rtl8139","virtio","vmxnet3"],"type":"string"},"mtu":{"description":"Force MTU, for VirtIO only. Set to '1' to use the bridge MTU","maximum":65520,"minimum":1,"optional":1,"type":"integer"},"ne2k_isa":{"alias":"macaddr","keyAlias":"model"},"ne2k_pci":{"alias":"macaddr","keyAlias":"model"},"pcnet":{"alias":"macaddr","keyAlias":"model"},"queues":{"description":"Number of packet queues to be used on the device.","maximum":64,"minimum":0,"optional":1,"type":"integer"},"rate":{"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":0,"optional":1,"type":"number"},"rtl8139":{"alias":"macaddr","keyAlias":"model"},"tag":{"description":"VLAN tag to apply to packets on this interface.","maximum":4094,"minimum":1,"optional":1,"type":"integer"},"trunks":{"description":"VLAN trunks to pass through this interface.","format_description":"vlanid[;vlanid...]","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"virtio":{"alias":"macaddr","keyAlias":"model"},"vmxnet3":{"alias":"macaddr","keyAlias":"model"}},"optional":true,"properties":{},"type":"string"},"name":"net[n]"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Enable/disable NUMA.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"numa"},{"definition":{"description":"NUMA topology.","enum":[],"extra":{"typetext":"cpus= [,hostnodes=] [,memory=] [,policy=]"},"format":{"cpus":{"description":"CPUs accessing this NUMA node.","format_description":"id[-id];...","pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"hostnodes":{"description":"Host NUMA nodes to use.","format_description":"id[-id];...","optional":1,"pattern":"(?^:\\d+(?:-\\d+)?(?:;\\d+(?:-\\d+)?)*)","type":"string"},"memory":{"description":"Amount of memory this NUMA node provides.","optional":1,"type":"number"},"policy":{"description":"NUMA allocation policy.","enum":["preferred","bind","interleave"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"numa[n]"},{"definition":{"default":0,"description":"Specifies whether a VM will be started during system bootup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"onboot"},{"definition":{"description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","win11","l24","l26","solaris"],"extra":{"verbose_description":"Specify guest operating system. This is used to enable special\noptimization/features for specific operating systems:\n\n[horizontal]\nother;; unspecified OS\nwxp;; Microsoft Windows XP\nw2k;; Microsoft Windows 2000\nw2k3;; Microsoft Windows 2003\nw2k8;; Microsoft Windows 2008\nwvista;; Microsoft Windows Vista\nwin7;; Microsoft Windows 7\nwin8;; Microsoft Windows 8/2012/2012r2\nwin10;; Microsoft Windows 10/2016/2019\nwin11;; Microsoft Windows 11/2022/2025\nl24;; Linux 2.4 Kernel\nl26;; Linux 2.6 - 6.X Kernel\nsolaris;; Solaris/OpenSolaris/OpenIndiania kernel\n"},"optional":true,"properties":{},"type":"string"},"name":"ostype"},{"definition":{"description":"Map host parallel devices (n is 0 to 2).","enum":[],"extra":{"verbose_description":"Map host parallel devices (n is 0 to 2).\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"/dev/parport\\d+|/dev/usb/lp\\d+","properties":{},"type":"string"},"name":"parallel[n]"},{"definition":{"default":0,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protection"},{"definition":{"default":1,"description":"Allow reboot. If set to '0' the VM exit on reboot.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"reboot"},{"definition":{"description":"Revert a pending change.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"revert"},{"definition":{"description":"Configure a VirtIO-based Random Number Generator.","enum":[],"extra":{"typetext":"[source=] [,max_bytes=] [,period=]"},"format":"pve-qm-rng","optional":true,"properties":{},"type":"string"},"name":"rng0"},{"definition":{"description":"Use volume as SATA hard disk or CD-ROM (n is 0 to 5). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"sata[n]"},{"definition":{"description":"Use volume as SCSI hard disk or CD-ROM (n is 0 to 30). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,product=] [,queues=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,scsiblock=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,ssd=<1|0>] [,trans=] [,vendor=] [,werror=] [,wwn=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"product":{"description":"The drive's product name, up to 16 bytes long.","format_description":"product","optional":1,"pattern":"[A-Za-z0-9\\-_\\s]{,16}","type":"string"},"queues":{"description":"Number of queues.","minimum":2,"optional":1,"type":"integer"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"scsiblock":{"default":0,"description":"whether to use scsi-block for full passthrough of host block device\n\nWARNING: can lead to I/O errors in combination with low memory or high memory fragmentation on host","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"ssd":{"description":"Whether to expose this drive as an SSD, rather than a rotational hard disk.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"vendor":{"description":"The drive's vendor name, up to 8 bytes long.","format_description":"vendor","optional":1,"pattern":"[A-Za-z0-9\\-_\\s]{,8}","type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"},"wwn":{"description":"The drive's worldwide name, encoded as 16 bytes hex string, prefixed by '0x'.","format_description":"wwn","optional":1,"pattern":"(?^:^(0x)[0-9a-fA-F]{16})","type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"scsi[n]"},{"definition":{"default":"lsi","description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"scsihw"},{"definition":{"description":"cloud-init: Sets DNS search domains for a container. Create will automatically use the setting from the host if neither searchdomain nor nameserver are set.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"searchdomain"},{"definition":{"description":"Create a serial device inside the VM (n is 0 to 3)","enum":[],"extra":{"verbose_description":"Create a serial device inside the VM (n is 0 to 3), and pass through a\nhost serial device (i.e. /dev/ttyS0), or create a unix socket on the\nhost side (use 'qm terminal' to open a terminal connection).\n\nNOTE: If you pass through a host serial device, it is no longer possible to migrate such machines -\nuse with special care.\n\nCAUTION: Experimental! User reported problems with this option.\n"},"optional":true,"pattern":"(/dev/.+|socket)","properties":{},"type":"string"},"name":"serial[n]"},{"definition":{"default":1000,"description":"Amount of memory shares for auto-ballooning. The larger the number is, the more memory this VM gets. Number is relative to weights of all other running VMs. Using zero disables auto-ballooning. Auto-ballooning is done by pvestatd.","enum":[],"extra":{"typetext":" (0 - 50000)"},"maximum":50000,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"shares"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Specify SMBIOS type 1 fields.","enum":[],"extra":{"typetext":"[base64=<1|0>] [,family=] [,manufacturer=] [,product=] [,serial=] [,sku=] [,uuid=] [,version=]"},"format":"pve-qm-smbios1","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"smbios1"},{"definition":{"default":1,"description":"The number of CPUs. Please use option -sockets instead.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"smp"},{"definition":{"default":1,"description":"The number of CPU sockets.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"sockets"},{"definition":{"description":"Configure additional enhancements for SPICE.","enum":[],"extra":{"typetext":"[foldersharing=<1|0>] [,videostreaming=]"},"format":{"foldersharing":{"default":"0","description":"Enable folder sharing via SPICE. Needs Spice-WebDAV daemon installed in the VM.","optional":1,"type":"boolean"},"videostreaming":{"default":"off","description":"Enable video streaming. Uses compression for detected video streams.","enum":["off","all","filter"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"spice_enhancements"},{"definition":{"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","enum":[],"extra":{"typetext":""},"format":"urlencoded","optional":true,"properties":{},"type":"string"},"name":"sshkeys"},{"definition":{"default":"now","description":"Set the initial date of the real time clock. Valid format for date are:'now' or '2006-06-17T16:01:21' or '2006-06-17'.","enum":[],"extra":{"typetext":"(now | YYYY-MM-DD | YYYY-MM-DDTHH:MM:SS)"},"optional":true,"pattern":"(now|\\d{4}-\\d{1,2}-\\d{1,2}(T\\d{1,2}:\\d{1,2}:\\d{1,2})?)","properties":{},"type":"string"},"name":"startdate"},{"definition":{"description":"Startup and shutdown behavior. Order is a non-negative number defining the general startup order. Shutdown in done with reverse ordering. Additionally you can set the 'up' or 'down' delay in seconds, which specifies a delay to wait before the next VM is started or stopped.","enum":[],"extra":{"typetext":"[[order=]\\d+] [,up=\\d+] [,down=\\d+] "},"format":"pve-startup-order","optional":true,"properties":{},"type":"string"},"name":"startup"},{"definition":{"default":1,"description":"Enable/disable the USB tablet device.","enum":[],"extra":{"typetext":"","verbose_description":"Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. Else the mouse runs out of sync with normal VNC clients. If you're running lots of console-only guests on one host, you may consider disabling this to save some context switches. This is turned off by default if you use spice (`qm set --vga qxl`)."},"optional":true,"properties":{},"type":"boolean"},"name":"tablet"},{"definition":{"description":"Tags of the VM. This is only meta information.","enum":[],"extra":{"typetext":""},"format":"pve-tag-list","optional":true,"properties":{},"type":"string"},"name":"tags"},{"definition":{"default":0,"description":"Enable/disable time drift fix.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tdf"},{"definition":{"default":0,"description":"Enable/disable Template.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"template"},{"definition":{"description":"Configure a Disk for storing TPM state. The format is fixed to 'raw'. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Note that SIZE_IN_GiB is ignored here and 4 MiB will be used instead. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,import-from=] [,size=] [,version=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"version":{"default":"v1.2","description":"The TPM interface version. v2.0 is newer and should be preferred. Note that this cannot be changed later on.","enum":["v1.2","v2.0"],"optional":1,"type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"tpmstate0"},{"definition":{"description":"Reference to unused volumes. This is used internally, and should not be modified manually.","enum":[],"extra":{"typetext":"[file=]"},"format":{"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id","format_description":"volume","type":"string"},"volume":{"alias":"file"}},"optional":true,"properties":{},"type":"string"},"name":"unused[n]"},{"definition":{"description":"Configure an USB device (n is 0 to 4, for machine version >= 7.1 and ostype l26 or windows > 7, n can be up to 14).","enum":[],"extra":{"typetext":"[[host=]] [,mapping=] [,usb3=<1|0>]"},"format":{"host":{"default_key":1,"description":"The Host USB device or port or the value 'spice'. HOSTUSBDEVICE syntax is:\n\n 'bus-port(.port)*' (decimal numbers) or\n 'vendor_id:product_id' (hexadecimal numbers) or\n 'spice'\n\nYou can use the 'lsusb -t' command to list existing usb devices.\n\nNOTE: This option allows direct access to host hardware. So it is no longer possible to migrate such\nmachines - use with special care.\n\nThe value 'spice' can be used to add a usb redirection devices for spice.\n\nEither this or the 'mapping' key must be set.\n","format_description":"HOSTUSBDEVICE|spice","optional":1,"pattern":"(?^:(?:(?:(?^:(0x)?([0-9A-Fa-f]{4}):(0x)?([0-9A-Fa-f]{4})))|(?:(?^:(\\d+)\\-(\\d+(\\.\\d+)*)))|[Ss][Pp][Ii][Cc][Ee]))","type":"string"},"mapping":{"description":"The ID of a cluster wide mapping. Either this or the default-key 'host' must be set.","format":"pve-configid","format_description":"mapping-id","optional":1,"type":"string"},"usb3":{"default":0,"description":"Specifies whether if given host option is a USB3 device or port. For modern guests (machine version >= 7.1 and ostype l26 and windows > 7), this flag is irrelevant (all devices are plugged into a xhci controller).","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"usb[n]"},{"definition":{"default":0,"description":"Number of hotplugged vcpus.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"vcpus"},{"definition":{"description":"Configure the VGA hardware.","enum":[],"extra":{"typetext":"[[type=]] [,clipboard=] [,memory=]","verbose_description":"Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is 'std' for all OS types besides some Windows versions (XP and older) which use 'cirrus'. The 'qxl' option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays them self.\nYou can also run without any graphic card, using a serial device as terminal."},"format":{"clipboard":{"description":"Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Migration with VNC clipboard is not yet supported!","enum":["vnc"],"optional":1,"type":"string"},"memory":{"description":"Sets the VGA memory (in MiB). Has no effect with serial display.","maximum":512,"minimum":4,"optional":1,"type":"integer"},"type":{"default":"std","default_key":1,"description":"Select the VGA type. Using type 'cirrus' is not recommended.","enum":["cirrus","qxl","qxl2","qxl3","qxl4","none","serial0","serial1","serial2","serial3","std","virtio","virtio-gl","vmware"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"vga"},{"definition":{"description":"Use volume as VIRTIO hard disk (n is 0 to 15). Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. Use STORAGE_ID:0 and the 'import-from' parameter to import from an existing volume.","enum":[],"extra":{"typetext":"[file=] [,aio=] [,backup=<1|0>] [,bps=] [,bps_max_length=] [,bps_rd=] [,bps_rd_max_length=] [,bps_wr=] [,bps_wr_max_length=] [,cache=] [,cyls=] [,detect_zeroes=<1|0>] [,discard=] [,format=] [,heads=] [,import-from=] [,iops=] [,iops_max=] [,iops_max_length=] [,iops_rd=] [,iops_rd_max=] [,iops_rd_max_length=] [,iops_wr=] [,iops_wr_max=] [,iops_wr_max_length=] [,iothread=<1|0>] [,mbps=] [,mbps_max=] [,mbps_rd=] [,mbps_rd_max=] [,mbps_wr=] [,mbps_wr_max=] [,media=] [,replicate=<1|0>] [,rerror=] [,ro=<1|0>] [,secs=] [,serial=] [,shared=<1|0>] [,size=] [,snapshot=<1|0>] [,trans=] [,werror=]"},"format":{"aio":{"description":"AIO type to use.","enum":["native","threads","io_uring"],"optional":1,"type":"string"},"backup":{"description":"Whether the drive should be included when making backups.","optional":1,"type":"boolean"},"bps":{"description":"Maximum r/w speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_rd":{"description":"Maximum read speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_rd_length":{"alias":"bps_rd_max_length"},"bps_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"bps_wr":{"description":"Maximum write speed in bytes per second.","format_description":"bps","optional":1,"type":"integer"},"bps_wr_length":{"alias":"bps_wr_max_length"},"bps_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"cache":{"description":"The drive's cache mode","enum":["none","writethrough","writeback","unsafe","directsync"],"optional":1,"type":"string"},"cyls":{"description":"Force the drive's physical geometry to have a specific cylinder count.","optional":1,"type":"integer"},"detect_zeroes":{"description":"Controls whether to detect and try to optimize writes of zeroes.","optional":1,"type":"boolean"},"discard":{"description":"Controls whether to pass discard/trim requests to the underlying storage.","enum":["ignore","on"],"optional":1,"type":"string"},"file":{"default_key":1,"description":"The drive's backing volume.","format":"pve-volume-id-or-qm-path","format_description":"volume","type":"string"},"format":{"description":"The drive's backing file's data format.","enum":["raw","qcow","qed","qcow2","vmdk","cloop"],"optional":1,"type":"string"},"heads":{"description":"Force the drive's physical geometry to have a specific head count.","optional":1,"type":"integer"},"import-from":{"description":"Create a new disk, importing from this source (volume ID or absolute path). When an absolute path is specified, it's up to you to ensure that the source is not actively used by another process during the import!","format":"pve-volume-id-or-absolute-path","format_description":"source volume","optional":1,"type":"string"},"iops":{"description":"Maximum r/w I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max":{"description":"Maximum unthrottled r/w I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_max_length":{"description":"Maximum length of I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_rd":{"description":"Maximum read I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_length":{"alias":"iops_rd_max_length"},"iops_rd_max":{"description":"Maximum unthrottled read I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_rd_max_length":{"description":"Maximum length of read I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iops_wr":{"description":"Maximum write I/O in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_length":{"alias":"iops_wr_max_length"},"iops_wr_max":{"description":"Maximum unthrottled write I/O pool in operations per second.","format_description":"iops","optional":1,"type":"integer"},"iops_wr_max_length":{"description":"Maximum length of write I/O bursts in seconds.","format_description":"seconds","minimum":1,"optional":1,"type":"integer"},"iothread":{"description":"Whether to use iothreads for this drive","optional":1,"type":"boolean"},"mbps":{"description":"Maximum r/w speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_max":{"description":"Maximum unthrottled r/w pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd":{"description":"Maximum read speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_rd_max":{"description":"Maximum unthrottled read pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr":{"description":"Maximum write speed in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"mbps_wr_max":{"description":"Maximum unthrottled write pool in megabytes per second.","format_description":"mbps","optional":1,"type":"number"},"media":{"default":"disk","description":"The drive's media type.","enum":["cdrom","disk"],"optional":1,"type":"string"},"replicate":{"default":1,"description":"Whether the drive should considered for replication jobs.","optional":1,"type":"boolean"},"rerror":{"description":"Read error action.","enum":["ignore","report","stop"],"optional":1,"type":"string"},"ro":{"description":"Whether the drive is read-only.","optional":1,"type":"boolean"},"secs":{"description":"Force the drive's physical geometry to have a specific sector count.","optional":1,"type":"integer"},"serial":{"description":"The drive's reported serial number, url-encoded, up to 20 bytes long.","format":"urlencoded","format_description":"serial","maxLength":60,"optional":1,"type":"string"},"shared":{"default":0,"description":"Mark this locally-managed volume as available on all nodes","optional":1,"type":"boolean","verbose_description":"Mark this locally-managed volume as available on all nodes.\n\nWARNING: This option does not share the volume automatically, it assumes it is shared already!"},"size":{"description":"Disk size. This is purely informational and has no effect.","format":"disk-size","format_description":"DiskSize","optional":1,"type":"string"},"snapshot":{"description":"Controls qemu's snapshot mode feature. If activated, changes made to the disk are temporary and will be discarded when the VM is shutdown.","optional":1,"type":"boolean"},"trans":{"description":"Force disk geometry bios translation mode.","enum":["none","lba","auto"],"optional":1,"type":"string"},"volume":{"alias":"file"},"werror":{"description":"Write error action.","enum":["enospc","ignore","report","stop"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"virtio[n]"},{"definition":{"description":"Configuration for sharing a directory between host and guest using Virtio-fs.","enum":[],"extra":{"typetext":"[dirid=] [,cache=] [,direct-io=<1|0>] [,expose-acl=<1|0>] [,expose-xattr=<1|0>]"},"format":{"cache":{"default":"auto","description":"The caching policy the file system should use (auto, always, metadata, never).","enum":["auto","always","metadata","never"],"optional":1,"type":"string"},"direct-io":{"default":0,"description":"Honor the O_DIRECT flag passed down by guest applications.","optional":1,"type":"boolean"},"dirid":{"default_key":1,"description":"Mapping identifier of the directory mapping to be shared with the guest. Also used as a mount tag inside the VM.","format":"pve-configid","format_description":"mapping-id","type":"string"},"expose-acl":{"default":0,"description":"Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.","optional":1,"type":"boolean"},"expose-xattr":{"default":0,"description":"Enable support for extended attributes for this mount.","optional":1,"type":"boolean"}},"optional":true,"properties":{},"type":"string"},"name":"virtiofs[n]"},{"definition":{"default":"1 (autogenerated)","description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","enum":[],"extra":{"format_description":"UUID","verbose_description":"The VM generation ID (vmgenid) device exposes a 128-bit integer value identifier to the guest OS. This allows to notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template). The guest operating system notices the change, and is then able to react as appropriate by marking its copies of distributed databases as dirty, re-initializing its random number generator, etc.\nNote that auto-creation only works when done through API/CLI create or update methods, but not when manually editing the config file."},"optional":true,"pattern":"(?:[a-fA-F0-9]{8}(?:-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}|[01])","properties":{},"type":"string"},"name":"vmgenid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Default storage for VM state volumes/files.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"vmstatestorage"},{"definition":{"description":"Create a virtual hardware watchdog device.","enum":[],"extra":{"typetext":"[[model=]] [,action=]","verbose_description":"Create a virtual hardware watchdog device. Once enabled (by a guest action), the watchdog must be periodically polled by an agent inside the guest or else the watchdog will reset the guest (or execute the respective action specified)"},"format":"pve-qm-watchdog","optional":true,"properties":{},"type":"string"},"name":"watchdog"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk","VM.Config.CDROM","VM.Config.CPU","VM.Config.Memory","VM.Config.Network","VM.Config.HWType","VM.Config.Options","VM.Config.Cloudinit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e46fb90f7815c5a4b54ba120dc3731ab19995905d1555869d89156ed48776592","description":"Check if feature for virtual machine is available.","extra":{"proxyto":"node"},"name":"vm_feature","parameters":[{"definition":{"description":"Feature to check.","enum":["snapshot","clone","copy"],"extra":{},"properties":{},"type":"string"},"name":"feature"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"optional":true,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"hasFeature":{"enum":[],"extra":{},"properties":{},"type":"boolean"},"nodes":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/feature"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7ee5be237c4406d406b763db7b1c3deb794543cfa9e5376476821ff4ad174512","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/firewall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0e240eee88d783388fa7fd5c605d1946866c6de040a5072e91675a7d06594943","description":"List aliases","extra":{},"name":"get_aliases","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"24f08f4001bb83fb2a6d7e9a6a5d0c3692949ea94751c543f2ce056e43beeacb","description":"Create IP or Network Alias.","extra":{},"name":"create_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/aliases"},{"extra":{},"methods":[{"allow_token":true,"checksum":"547018a4e77e1f19d15e71017e8e7e7bdb3f893052f3a61c4ac77fe1a23a7524","description":"Remove IP or Network alias.","extra":{},"name":"remove_alias","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f5bce1f868d6f087fc556f605b8dba1dadf850207fb04bbddc999079cd9486b7","description":"Read alias.","extra":{},"name":"read_alias","parameters":[{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"1e344b0d51e8e531d0d525f26ebe09c01f6c4cf270e92c36ebe11eca2779dcee","description":"Update IP or Network alias.","extra":{},"name":"update_alias","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDR","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Alias name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Rename an existing alias.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"406378d5359b09bbd6589c105f8df2f99aeef8a54b526302377c06fe5401770e","description":"List IPSets","extra":{},"name":"ipset_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"name":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"f4bb41ff25f7d50144a81944017055185c7a72e313a861f8a0406de6bf34ecf2","description":"Create new IPSet","extra":{},"name":"create_ipset","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.","enum":[],"extra":{},"max_length":64,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"rename"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/ipset"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a40e1badd168974a686fc466a2e06598ef9762be5b279a8f1fa0eca53f7d4880","description":"Delete IPSet","extra":{},"name":"delete_ipset","parameters":[{"definition":{"description":"Delete all members of the IPSet, if there are any.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"5fc76313da1679fa4a2631d95ce58eb8b267a2dd67a0c1a8ac5a55a0ab34b13c","description":"List IPSet content","extra":{},"name":"get_ipset","parameters":[{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cidr}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"cidr":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"digest":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{},"max_length":64,"optional":false,"properties":{},"type":"string"},"nomatch":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"a3ace74f6557fc643406d7775bd8e6eb21c0200d079174ee43ee5a0fd24506c9","description":"Add IP or Network to IPSet.","extra":{},"name":"create_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5f612a84aecce1fd03bb87a7e7c15c6786474a3e211f958a0281c55c835eeebc","description":"Remove IP or Network from IPSet.","extra":{},"name":"remove_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"cae0afef06b37e0a88847c53e617e5a4def2d669bf4da3f4d541cdf1811046a4","description":"Read IP or Network settings from IPSet.","extra":{},"name":"read_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"bb0b6ded1cf4736fae405e8af7ccf92e10623473112c4bb7a73992fdb81b4a2f","description":"Update IP or Network settings","extra":{},"name":"update_ip","parameters":[{"definition":{"description":"Network/IP specification in CIDR format.","enum":[],"extra":{"typetext":""},"format":"IPorCIDRorAlias","properties":{},"type":"string"},"name":"cidr"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"IP set name.","enum":[],"extra":{},"max_length":64,"min_length":2,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"name"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nomatch"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d6b7e9154ddc56bd6b0b9af8378442e873109fc13d420483930da8dafe5fad5c","description":"Read firewall log","extra":{"proxyto":"node"},"name":"log","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Display log since this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"since"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"Display log until this UNIX epoch.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"until"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"22f206f7dd8a836164bca4599b7db3619a67e37273a95349f21e528fdf1ab8f8","description":"Get VM firewall options.","extra":{"proxyto":"node"},"name":"get_options","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"dhcp":{"default":0,"description":"Enable DHCP.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"enable":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ipfilter":{"description":"Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"log_level_in":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"log_level_out":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macfilter":{"default":1,"description":"Enable/disable MAC address filter.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"ndp":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"policy_in":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"policy_out":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"radv":{"description":"Allow sending Router Advertisement.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"f9b4d8f7a53f2384072a66bac3473aa3052c297bc84c23a3adfdb81b594eaaac","description":"Set Firewall options.","extra":{"proxyto":"node"},"name":"set_options","parameters":[{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"default":0,"description":"Enable DHCP.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"dhcp"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"default":0,"description":"Enable/disable firewall rules.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enable"},{"definition":{"description":"Enable default IP filters. This is equivalent to adding an empty ipfilter-net ipset for every interface. Such ipsets implicitly contain sane default restrictions such as restricting IPv6 link local addresses to the one derived from the interface's MAC address. For containers the configured IP addresses will be implicitly added.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ipfilter"},{"definition":{"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_in"},{"definition":{"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log_level_out"},{"definition":{"default":1,"description":"Enable/disable MAC address filter.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"macfilter"},{"definition":{"default":0,"description":"Enable NDP (Neighbor Discovery Protocol).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"ndp"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_in"},{"definition":{"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"policy_out"},{"definition":{"description":"Allow sending Router Advertisement.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"radv"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/options"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4d9b684dc2793a1badcd82adfe45cf304ab1efec63d4b53ff4ea0402242531d3","description":"Lists possible IPSet/Alias reference which are allowed in source/dest properties.","extra":{},"name":"refs","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list references of specified type.","enum":["alias","ipset"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"name":{"enum":[],"extra":{},"properties":{},"type":"string"},"ref":{"enum":[],"extra":{},"properties":{},"type":"string"},"scope":{"enum":[],"extra":{},"properties":{},"type":"string"},"type":{"enum":["alias","ipset"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/refs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1e676eac6df97edb5a337b8ecd0aa90376496327c0712f7beec2190bec5137a1","description":"List rules.","extra":{"proxyto":null},"name":"get_rules","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{pos}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"8031675c54c1cfbf59734cd14ad9735f26d24b9a3960fb0a9e8420731f3d5e51","description":"Create new rule.","extra":{"proxyto":null},"name":"create_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":false,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":false,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/rules"},{"extra":{},"methods":[{"allow_token":true,"checksum":"464d07111ad5ee01829e46153bd86a7a820949db1b9fb33ddc3144037e35f734","description":"Delete rule.","extra":{"proxyto":null},"name":"delete_rule","parameters":[{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"f832e12c8239ec5ff27b7029d35cb91032e3059cc37e111230f82b8c74711746","description":"Get single rule data.","extra":{"proxyto":null},"name":"get_rule","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"action":{"enum":[],"extra":{},"properties":{},"type":"string"},"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dest":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"dport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"enable":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"icmp-type":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"iface":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"ipversion":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"log":{"description":"Log level for firewall rule","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"macro":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"pos":{"enum":[],"extra":{},"properties":{},"type":"integer"},"proto":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"source":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sport":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"7f95e71affdc035175864e9fdc728419b98b26887f2b75d4e04ab52c8db841e4","description":"Modify rule data.","extra":{"proxyto":null},"name":"update_rule","parameters":[{"definition":{"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.","enum":[],"extra":{},"max_length":20,"min_length":2,"optional":true,"pattern":"[A-Za-z][A-Za-z0-9\\-\\_]+","properties":{},"type":"string"},"name":"action"},{"definition":{"description":"Descriptive comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Restrict packet destination address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"dest"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Restrict TCP/UDP destination port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-dport-spec","optional":true,"properties":{},"type":"string"},"name":"dport"},{"definition":{"description":"Flag to enable/disable a rule.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"enable"},{"definition":{"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-icmp-type-spec","optional":true,"properties":{},"type":"string"},"name":"icmp-type"},{"definition":{"description":"Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.","enum":[],"extra":{"typetext":""},"format":"pve-iface","max_length":20,"min_length":2,"optional":true,"properties":{},"type":"string"},"name":"iface"},{"definition":{"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"log"},{"definition":{"description":"Use predefined standard macro.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"macro"},{"definition":{"description":"Move rule to new position . Other arguments are ignored.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"moveto"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Update rule at position .","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"pos"},{"definition":{"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","enum":[],"extra":{"typetext":""},"format":"pve-fw-protocol-spec","optional":true,"properties":{},"type":"string"},"name":"proto"},{"definition":{"description":"Restrict packet source address. This can refer to a single IP address, an IP set ('+ipsetname') or an IP alias definition. You can also specify an address range like '20.34.101.207-201.3.9.99', or a list of IP addresses and networks (entries are separated by comma). Please do not mix IPv4 and IPv6 addresses inside such lists.","enum":[],"extra":{"typetext":""},"format":"pve-fw-addr-spec","max_length":512,"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"description":"Restrict TCP/UDP source port. You can use service names or simple numbers (0-65535), as defined in '/etc/services'. Port ranges can be specified with '\\d+:\\d+', for example '80:85', and you can use comma separated list to match several ports or ranges.","enum":[],"extra":{"typetext":""},"format":"pve-fw-sport-spec","optional":true,"properties":{},"type":"string"},"name":"sport"},{"definition":{"description":"Rule type.","enum":["in","out","forward","group"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7a5d9ad0607e41db5658797f952522d604352483572b2ed161e60f2dbab54195","description":"Get preconditions for migration.","extra":{"proxyto":"node"},"name":"migrate_vm_precondition","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"allowed_nodes":{"description":"List of nodes allowed for migration.","enum":[],"extra":{},"items":{"description":"An allowed node","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"local_disks":{"description":"List local disks including CD-Rom, unused and not referenced disks","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"cdrom":{"description":"True if the disk is a cdrom.","enum":[],"extra":{},"properties":{},"type":"boolean"},"is_unused":{"description":"True if the disk is unused.","enum":[],"extra":{},"properties":{},"type":"boolean"},"size":{"description":"The size of the disk in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"volid":{"description":"The volid of the disk.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"local_resources":{"description":"List local resources (e.g. pci, usb) that block migration.","enum":[],"extra":{},"items":{"description":"A local resource","enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"mapped-resource-info":{"description":"Object of mapped resources with additional information such if they're live migratable.","enum":[],"extra":{},"properties":{},"type":"object"},"mapped-resources":{"description":"List of mapped resources e.g. pci, usb. Deprecated, use 'mapped-resource-info' instead.","enum":[],"extra":{},"items":{"description":"A mapped resource","enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"not_allowed_nodes":{"description":"List of not allowed nodes with additional information.","enum":[],"extra":{},"optional":true,"properties":{"unavailable_storages":{"description":"A list of not available storages.","enum":[],"extra":{},"items":{"description":"A storage","enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"running":{"description":"Determines if the VM is running.","enum":[],"extra":{},"properties":{},"type":"boolean"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"c9328031e7c0d5c5ec49987bdcbbce4ca6accaa9df93356140b22e7d7e8b1d43","description":"Migrate virtual machine. Creates a new migration task.","extra":{"proxyto":"node"},"name":"migrate_vm","parameters":[{"definition":{"default":"migrate limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"description":"Allow to migrate VMs which use local devices. Only root may use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"CIDR of the (sub) network that is used for migration.","enum":[],"extra":{"typetext":""},"format":"CIDR","optional":true,"properties":{},"type":"string"},"name":"migration_network"},{"definition":{"description":"Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.","enum":["secure","insecure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"migration_type"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use online/live migration if VM is running. Ignored if VM is stopped.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"online"},{"definition":{"description":"Target node.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storage-pair-list","optional":true,"properties":{},"type":"string"},"name":"targetstorage"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Enable live storage migration for local disk","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"with-local-disks"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2aa7e55cc3132025304448da934831275303456b74961514f2d3b4041b067bb6","description":"Execute QEMU monitor commands.","extra":{"proxyto":"node"},"name":"monitor","parameters":[{"definition":{"description":"The monitor command.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"command"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"Sys.Modify is required for (sub)commands which are not read-only ('info *' and 'help')","expression":{"check":["perm","/vms/{vmid}",["VM.Monitor"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/monitor"},{"extra":{},"methods":[{"allow_token":true,"checksum":"192b2ef07a128fa86b69604030f7054b890f32479717c1c781e4530c4cff6e50","description":"Move volume to different storage or to a different VM.","extra":{"proxyto":"node"},"name":"move_vm_disk","parameters":[{"definition":{"default":"move limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"default":0,"description":"Delete the original disk after successful copy. By default the original disk is kept as unused disk.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has different SHA1\"\n\t\t .\" digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The disk you want to move.","enum":["ide0","ide1","ide2","ide3","scsi0","scsi1","scsi2","scsi3","scsi4","scsi5","scsi6","scsi7","scsi8","scsi9","scsi10","scsi11","scsi12","scsi13","scsi14","scsi15","scsi16","scsi17","scsi18","scsi19","scsi20","scsi21","scsi22","scsi23","scsi24","scsi25","scsi26","scsi27","scsi28","scsi29","scsi30","virtio0","virtio1","virtio2","virtio3","virtio4","virtio5","virtio6","virtio7","virtio8","virtio9","virtio10","virtio11","virtio12","virtio13","virtio14","virtio15","sata0","sata1","sata2","sata3","sata4","sata5","efidisk0","tpmstate0","unused0","unused1","unused2","unused3","unused4","unused5","unused6","unused7","unused8","unused9","unused10","unused11","unused12","unused13","unused14","unused15","unused16","unused17","unused18","unused19","unused20","unused21","unused22","unused23","unused24","unused25","unused26","unused27","unused28","unused29","unused30","unused31","unused32","unused33","unused34","unused35","unused36","unused37","unused38","unused39","unused40","unused41","unused42","unused43","unused44","unused45","unused46","unused47","unused48","unused49","unused50","unused51","unused52","unused53","unused54","unused55","unused56","unused57","unused58","unused59","unused60","unused61","unused62","unused63","unused64","unused65","unused66","unused67","unused68","unused69","unused70","unused71","unused72","unused73","unused74","unused75","unused76","unused77","unused78","unused79","unused80","unused81","unused82","unused83","unused84","unused85","unused86","unused87","unused88","unused89","unused90","unused91","unused92","unused93","unused94","unused95","unused96","unused97","unused98","unused99","unused100","unused101","unused102","unused103","unused104","unused105","unused106","unused107","unused108","unused109","unused110","unused111","unused112","unused113","unused114","unused115","unused116","unused117","unused118","unused119","unused120","unused121","unused122","unused123","unused124","unused125","unused126","unused127","unused128","unused129","unused130","unused131","unused132","unused133","unused134","unused135","unused136","unused137","unused138","unused139","unused140","unused141","unused142","unused143","unused144","unused145","unused146","unused147","unused148","unused149","unused150","unused151","unused152","unused153","unused154","unused155","unused156","unused157","unused158","unused159","unused160","unused161","unused162","unused163","unused164","unused165","unused166","unused167","unused168","unused169","unused170","unused171","unused172","unused173","unused174","unused175","unused176","unused177","unused178","unused179","unused180","unused181","unused182","unused183","unused184","unused185","unused186","unused187","unused188","unused189","unused190","unused191","unused192","unused193","unused194","unused195","unused196","unused197","unused198","unused199","unused200","unused201","unused202","unused203","unused204","unused205","unused206","unused207","unused208","unused209","unused210","unused211","unused212","unused213","unused214","unused215","unused216","unused217","unused218","unused219","unused220","unused221","unused222","unused223","unused224","unused225","unused226","unused227","unused228","unused229","unused230","unused231","unused232","unused233","unused234","unused235","unused236","unused237","unused238","unused239","unused240","unused241","unused242","unused243","unused244","unused245","unused246","unused247","unused248","unused249","unused250","unused251","unused252","unused253","unused254","unused255"],"extra":{},"properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"Target Format.","enum":["raw","qcow2","vmdk"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Target storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Prevent changes if the current config file of the target VM has a\"\n\t\t .\" different SHA1 digest. This can be used to detect concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"target-digest"},{"definition":{"description":"The config key the disk will be moved to on the target VM (for example, ide0 or scsi1). Default is the source disk key.","enum":["ide0","ide1","ide2","ide3","scsi0","scsi1","scsi2","scsi3","scsi4","scsi5","scsi6","scsi7","scsi8","scsi9","scsi10","scsi11","scsi12","scsi13","scsi14","scsi15","scsi16","scsi17","scsi18","scsi19","scsi20","scsi21","scsi22","scsi23","scsi24","scsi25","scsi26","scsi27","scsi28","scsi29","scsi30","virtio0","virtio1","virtio2","virtio3","virtio4","virtio5","virtio6","virtio7","virtio8","virtio9","virtio10","virtio11","virtio12","virtio13","virtio14","virtio15","sata0","sata1","sata2","sata3","sata4","sata5","efidisk0","tpmstate0","unused0","unused1","unused2","unused3","unused4","unused5","unused6","unused7","unused8","unused9","unused10","unused11","unused12","unused13","unused14","unused15","unused16","unused17","unused18","unused19","unused20","unused21","unused22","unused23","unused24","unused25","unused26","unused27","unused28","unused29","unused30","unused31","unused32","unused33","unused34","unused35","unused36","unused37","unused38","unused39","unused40","unused41","unused42","unused43","unused44","unused45","unused46","unused47","unused48","unused49","unused50","unused51","unused52","unused53","unused54","unused55","unused56","unused57","unused58","unused59","unused60","unused61","unused62","unused63","unused64","unused65","unused66","unused67","unused68","unused69","unused70","unused71","unused72","unused73","unused74","unused75","unused76","unused77","unused78","unused79","unused80","unused81","unused82","unused83","unused84","unused85","unused86","unused87","unused88","unused89","unused90","unused91","unused92","unused93","unused94","unused95","unused96","unused97","unused98","unused99","unused100","unused101","unused102","unused103","unused104","unused105","unused106","unused107","unused108","unused109","unused110","unused111","unused112","unused113","unused114","unused115","unused116","unused117","unused118","unused119","unused120","unused121","unused122","unused123","unused124","unused125","unused126","unused127","unused128","unused129","unused130","unused131","unused132","unused133","unused134","unused135","unused136","unused137","unused138","unused139","unused140","unused141","unused142","unused143","unused144","unused145","unused146","unused147","unused148","unused149","unused150","unused151","unused152","unused153","unused154","unused155","unused156","unused157","unused158","unused159","unused160","unused161","unused162","unused163","unused164","unused165","unused166","unused167","unused168","unused169","unused170","unused171","unused172","unused173","unused174","unused175","unused176","unused177","unused178","unused179","unused180","unused181","unused182","unused183","unused184","unused185","unused186","unused187","unused188","unused189","unused190","unused191","unused192","unused193","unused194","unused195","unused196","unused197","unused198","unused199","unused200","unused201","unused202","unused203","unused204","unused205","unused206","unused207","unused208","unused209","unused210","unused211","unused212","unused213","unused214","unused215","unused216","unused217","unused218","unused219","unused220","unused221","unused222","unused223","unused224","unused225","unused226","unused227","unused228","unused229","unused230","unused231","unused232","unused233","unused234","unused235","unused236","unused237","unused238","unused239","unused240","unused241","unused242","unused243","unused244","unused245","unused246","unused247","unused248","unused249","unused250","unused251","unused252","unused253","unused254","unused255"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"target-disk"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"target-vmid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Config.Disk' permissions on /vms/{vmid}, and 'Datastore.AllocateSpace' permissions on the storage. To move a disk to another VM, you need the permissions on the target VM as well.","expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/move_disk"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1b0766e6b516ab7ddfdd5bfa201c2fbf4cb5e80b1e4da9003a00142d8b12360e","description":"Migration tunnel endpoint - only for internal use by VM migration.","extra":{},"name":"mtunnel","parameters":[{"definition":{"description":"List of network bridges to check availability. Will be checked again for actually used bridges during migration.","enum":[],"extra":{"typetext":""},"format":"pve-bridge-id-list","optional":true,"properties":{},"type":"string"},"name":"bridges"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"List of storages to check permission and availability. Will be checked again for all actually used storages during migration.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id-list","optional":true,"properties":{},"type":"string"},"name":"storages"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permissions on '/vms/{vmid}' and Sys.Incoming on '/'. Further permission checks happen during the actual migration.","expression":{"check":["and",["perm","/vms/{vmid}",["VM.Allocate"]],["perm","/",["Sys.Incoming"]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"socket":{"enum":[],"extra":{},"properties":{},"type":"string"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/mtunnel"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5074d114941c7d6bcff687122305de9ba6fe8456c7b40ccc88b503ae5f07dd59","description":"Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration.","extra":{},"name":"mtunnelwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"unix socket to forward to","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"socket"},{"definition":{"description":"ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"ticket"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need to pass a ticket valid for the selected socket. Tickets can be created via the mtunnel API call, which will check permissions accordingly.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"socket":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/mtunnelwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b1d298cc9afb32d9b551dfc75531f6345ae64b9d7c9a89216a6ed693aaaff195","description":"Get the virtual machine configuration with both current and pending values.","extra":{"proxyto":"node"},"name":"vm_pending","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"delete":{"description":"Indicates a pending delete request if present and not 0. The value 2 indicates a force-delete request.","enum":[],"extra":{},"maximum":2,"minimum":0,"optional":true,"properties":{},"type":"integer"},"key":{"description":"Configuration option name.","enum":[],"extra":{},"properties":{},"type":"string"},"pending":{"description":"Pending value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"value":{"description":"Current value.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/pending"},{"extra":{},"methods":[{"allow_token":true,"checksum":"07c2414abc8f0d7497305e98b12b9bcef5f5e7acd6686d51a772ff505244f535","description":"Migrate virtual machine to a remote cluster. Creates a new migration task. EXPERIMENTAL feature!","extra":{"proxyto":"node"},"name":"remote_migrate_vm","parameters":[{"definition":{"default":"migrate limit from datacenter or storage config","description":"Override I/O bandwidth limit (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"default":0,"description":"Delete the original VM and related data after successful migration. By default the original VM is kept on the source cluster in a stopped state.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use online/live migration if VM is running. Ignored if VM is stopped.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"online"},{"definition":{"description":"Mapping from source to target bridges. Providing only a single bridge ID maps all source bridges to that bridge. Providing the special value '1' will map each source bridge to itself.","enum":[],"extra":{"typetext":""},"format":"bridge-pair-list","properties":{},"type":"string"},"name":"target-bridge"},{"definition":{"description":"Remote target endpoint","enum":[],"extra":{"typetext":"apitoken= ,host=
[,fingerprint=] [,port=]"},"format":"proxmox-remote","properties":{},"type":"string"},"name":"target-endpoint"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storage-pair-list","optional":false,"properties":{},"type":"string"},"name":"target-storage"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"target-vmid"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/remote_migrate"},{"extra":{},"methods":[{"allow_token":true,"checksum":"58d4860cf474784e8fbde34c0b8b950396e45b8d06b66833f07d75010d8b2f4a","description":"Extend volume size.","extra":{"proxyto":"node"},"name":"resize_vm","parameters":[{"definition":{"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":40,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"The disk you want to resize.","enum":["ide0","ide1","ide2","ide3","scsi0","scsi1","scsi2","scsi3","scsi4","scsi5","scsi6","scsi7","scsi8","scsi9","scsi10","scsi11","scsi12","scsi13","scsi14","scsi15","scsi16","scsi17","scsi18","scsi19","scsi20","scsi21","scsi22","scsi23","scsi24","scsi25","scsi26","scsi27","scsi28","scsi29","scsi30","virtio0","virtio1","virtio2","virtio3","virtio4","virtio5","virtio6","virtio7","virtio8","virtio9","virtio10","virtio11","virtio12","virtio13","virtio14","virtio15","sata0","sata1","sata2","sata3","sata4","sata5","efidisk0","tpmstate0"],"extra":{},"properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The new size. With the `+` sign the value is added to the actual size of the volume and without it, the value is taken as an absolute one. Shrinking disk size is not supported.","enum":[],"extra":{},"pattern":"\\+?\\d+(\\.\\d+)?[KMGT]?","properties":{},"type":"string"},"name":"size"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/resize"},{"extra":{},"methods":[{"allow_token":true,"checksum":"76edba13c3870fdb403a8a46fd95c3033cf4aeecac012f3d822f9075a80aa729","description":"Read VM RRD statistics (returns PNG)","extra":{},"name":"rrd","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The list of datasources you want to display.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"ds"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/rrd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"708d135d9bf06d5aed00329691506df18a1ed11938257a15c87431dfc5b617f3","description":"Read VM RRD statistics","extra":{},"name":"rrddata","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/rrddata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b2f2f0cc7b858cbfe4870f1600fa6c7629a3f649f6bd9bd8a612d5d66e3e4424","description":"Send key event to virtual machine.","extra":{"proxyto":"node"},"name":"vm_sendkey","parameters":[{"definition":{"description":"The key (qemu monitor encoding).","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"key"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/sendkey"},{"extra":{},"methods":[{"allow_token":true,"checksum":"516df1fbcace02aca60a45bb75bb3ddcf9496f29f0d72107b79b93c5c4cfbd7e","description":"List all snapshots.","extra":{"proxyto":"node"},"name":"snapshot_list","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"description":{"description":"Snapshot description.","enum":[],"extra":{},"properties":{},"type":"string"},"name":{"description":"Snapshot identifier. Value 'current' identifies the current VM.","enum":[],"extra":{},"properties":{},"type":"string"},"parent":{"description":"Parent snapshot identifier.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"snaptime":{"description":"Snapshot creation time","enum":[],"extra":{"renderer":"timestamp"},"optional":true,"properties":{},"type":"integer"},"vmstate":{"description":"Snapshot includes RAM.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"1b31c240c6005572df666a4955380aeea50707ff3f3d84736d7d500d82d1a847","description":"Snapshot a VM.","extra":{"proxyto":"node"},"name":"snapshot","parameters":[{"definition":{"description":"A textual description or comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Save the vmstate","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"vmstate"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/snapshot"},{"extra":{},"methods":[{"allow_token":true,"checksum":"af2c83c0a994a51bc20120133f51f0e154e3b81bf203e73b5e3952f094470d67","description":"Delete a VM snapshot.","extra":{"proxyto":"node"},"name":"delsnapshot","parameters":[{"definition":{"description":"For removal from config file, even if removing disk snapshots fails.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"832c5b9a025e005606202e4c83d793ce08937ecc33dfcd397a7fef121e0b5411","description":"","extra":{},"name":"snapshot_cmd_idx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{cmd}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"65e5a768abb44d154e1140615379246ed5399a3dc43425f8e51baa6c7fbd75af","description":"Get snapshot configuration","extra":{"proxyto":"node"},"name":"get_snapshot_config","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback","VM.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"281a4f10e550455fd4dd289251fc1fe0ecb359e2777227df294a67d67a5fa13b","description":"Update snapshot metadata.","extra":{"proxyto":"node"},"name":"update_snapshot_config","parameters":[{"definition":{"description":"A textual description or comment.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"description"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c343ddb104f76a6e634b68829860eb0867ffb5ab1905319105d06052fb1da4c5","description":"Rollback VM state to specified snapshot.","extra":{"proxyto":"node"},"name":"rollback","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The name of the snapshot.","enum":[],"extra":{"typetext":""},"format":"pve-configid","max_length":40,"properties":{},"type":"string"},"name":"snapname"},{"definition":{"default":0,"description":"Whether the VM should get started after rolling back successfully. (Note: VMs will be automatically started if the snapshot includes RAM.)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"start"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback"],"any",1]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback"},{"extra":{},"methods":[{"allow_token":true,"checksum":"287de2ffbbffecf702677d7ec661948a707a380fa535c8871a4fe97b0512c131","description":"Returns a SPICE configuration to connect to the VM.","extra":{"proxyto":"node"},"name":"spiceproxy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).","enum":[],"extra":{"typetext":""},"format":"address","optional":true,"properties":{},"type":"string"},"name":"proxy"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"description":"Returned values can be directly passed to the 'remote-viewer' application.","enum":[],"extra":{"additionalProperties":1},"properties":{"host":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"enum":[],"extra":{},"properties":{},"type":"string"},"proxy":{"enum":[],"extra":{},"properties":{},"type":"string"},"tls-port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/spiceproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e0aec5f2ad5f243e5f05705856f0b3c74f1e863e35ceb571106f118e8b4027e3","description":"Directory index","extra":{"proxyto":"node"},"name":"vmcmdidx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"df6212e121275a0cf5a8a95d62db1131ffb420477d2768864b39fb4fe2e85c0e","description":"Get virtual machine status.","extra":{"proxyto":"node"},"name":"vm_status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"agent":{"description":"QEMU Guest Agent is enabled in config.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"clipboard":{"description":"Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added.","enum":["vnc"],"extra":{},"optional":true,"properties":{},"type":"string"},"cpu":{"description":"Current CPU usage.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"cpus":{"description":"Maximum usable CPUs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"number"},"diskread":{"description":"The amount of bytes the guest read from it's block devices since the guest was started. (Note: This info is not available for all storage types.)","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"diskwrite":{"description":"The amount of bytes the guest wrote from it's block devices since the guest was started. (Note: This info is not available for all storage types.)","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"ha":{"description":"HA manager service status.","enum":[],"extra":{},"properties":{},"type":"object"},"lock":{"description":"The current config lock, if any.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"maxdisk":{"description":"Root disk size in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"maxmem":{"description":"Maximum memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"mem":{"description":"Currently used memory in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"name":{"description":"VM (host)name.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"netin":{"description":"The amount of traffic in bytes that was sent to the guest over the network since it was started.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"netout":{"description":"The amount of traffic in bytes that was sent from the guest over the network since it was started.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"pid":{"description":"PID of the QEMU process, if the VM is running.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"qmpstatus":{"description":"VM run state from the 'query-status' QMP monitor command.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"running-machine":{"description":"The currently running machine type (if running).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"running-qemu":{"description":"The QEMU version the VM is currently using (if running).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serial":{"description":"Guest has serial device configured.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"spice":{"description":"QEMU VGA configuration supports spice.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"status":{"description":"QEMU process status.","enum":["stopped","running"],"extra":{},"properties":{},"type":"string"},"tags":{"description":"The current configured tags, if any","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"template":{"default":0,"description":"Determines if the guest is a template.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"uptime":{"description":"Uptime in seconds.","enum":[],"extra":{"renderer":"duration"},"optional":true,"properties":{},"type":"integer"},"vmid":{"description":"The (unique) ID of the VM.","enum":[],"extra":{},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/status/current"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6810bf03658282f27a25f6c7c0f1a3f13b04d943fbf948b7f786335ce6be363d","description":"Reboot the VM by shutting it down, and starting it again. Applies pending changes.","extra":{"proxyto":"node"},"name":"vm_reboot","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Wait maximal timeout seconds for the shutdown.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/reboot"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2edc46a4f88a3321618629b71a2672f7045bdf7cb3e854025b33dfc3a75d561c","description":"Reset virtual machine.","extra":{"proxyto":"node"},"name":"vm_reset","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/reset"},{"extra":{},"methods":[{"allow_token":true,"checksum":"caa58b1d1a2bf8eb0e5cf1e0b63c83966d59a011469f65748e04d233c519dc1e","description":"Resume virtual machine.","extra":{"proxyto":"node"},"name":"vm_resume","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nocheck"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/resume"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e8a90c03243834c470a30bbf05af277d953cd43a8ae2299957ed3a355f4815f7","description":"Shutdown virtual machine. This is similar to pressing the power button on a physical machine. This will send an ACPI event for the guest OS, which should then proceed to a clean shutdown.","extra":{"proxyto":"node"},"name":"vm_shutdown","parameters":[{"definition":{"default":0,"description":"Make sure the VM stops.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"forceStop"},{"definition":{"default":0,"description":"Do not deactivate storage volumes.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keepActive"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Wait maximal timeout seconds.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/shutdown"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4e322476816446d800762dea6f282cf2ba54928c30d981743ba48f401a84cc58","description":"Start virtual machine.","extra":{"proxyto":"node"},"name":"vm_start","parameters":[{"definition":{"description":"Override QEMU's -cpu argument with the given string.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"force-cpu"},{"definition":{"description":"Specify the QEMU machine.","enum":[],"extra":{"typetext":"[[type=]] [,enable-s3=<1|0>] [,enable-s4=<1|0>] [,viommu=]"},"format":{"enable-s3":{"description":"Enables S3 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"enable-s4":{"description":"Enables S4 power state. Defaults to false beginning with machine types 9.2+pve1, true before.","optional":1,"type":"boolean"},"type":{"default_key":1,"description":"Specifies the QEMU machine type.","format_description":"machine type","maxLength":40,"optional":1,"pattern":"(pc|pc(-i440fx)?-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|q35|pc-q35-\\d+(\\.\\d+)+(\\+pve\\d+)?(\\.pxe)?|virt(?:-\\d+(\\.\\d+)+)?(\\+pve\\d+)?)","type":"string"},"viommu":{"description":"Enable and set guest vIOMMU variant (Intel vIOMMU needs q35 to be set as machine type).","enum":["intel","virtio"],"optional":1,"type":"string"}},"optional":true,"properties":{},"type":"string"},"name":"machine"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"migratedfrom"},{"definition":{"description":"CIDR of the (sub) network that is used for migration.","enum":[],"extra":{"typetext":""},"format":"CIDR","optional":true,"properties":{},"type":"string"},"name":"migration_network"},{"definition":{"description":"Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance.","enum":["secure","insecure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"migration_type"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Some command save/restore state from this location.","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"stateuri"},{"definition":{"description":"Mapping from source to target storages. Providing only a single storage ID maps all source storages to that storage. Providing the special value '1' will map each source storage to itself.","enum":[],"extra":{"typetext":""},"format":"storage-pair-list","optional":true,"properties":{},"type":"string"},"name":"targetstorage"},{"definition":{"default":"max(30, vm memory in GiB)","description":"Wait maximal timeout seconds.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7ba56cd2614e573423e6f4004d858593872c0d9a7f06f78ce94c91ea02bcefc0","description":"Stop virtual machine. The qemu process will exit immediately. This is akin to pulling the power plug of a running computer and may damage the VM data.","extra":{"proxyto":"node"},"name":"vm_stop","parameters":[{"definition":{"default":0,"description":"Do not deactivate storage volumes.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"keepActive"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"migratedfrom"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Try to abort active 'qmshutdown' tasks before stopping.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"overrule-shutdown"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"Wait maximal timeout seconds.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/stop"},{"extra":{},"methods":[{"allow_token":true,"checksum":"bfca4805bf3684736d2e2606c6653af753b62cbcafc6b400b9f040af71eb592b","description":"Suspend virtual machine.","extra":{"proxyto":"node"},"name":"vm_suspend","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Ignore locks - only root is allowed to use this option.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skiplock"},{"definition":{"description":"The storage for the VM state","enum":[],"extra":{"format_description":"storage ID","requires":"todisk","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"statestorage"},{"definition":{"default":0,"description":"If set, suspends the VM to disk. Will be resumed on next VM start.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"todisk"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.PowerMgmt' on /vms/{vmid}, and if you have set 'todisk', you need also 'VM.Config.Disk' on /vms/{vmid} and 'Datastore.AllocateSpace' on the storage for the vmstate.","expression":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/status/suspend"},{"extra":{},"methods":[{"allow_token":true,"checksum":"97358aa1702b91208eda4752b983ba9081f332b95e37c94abd786162d0a40b6d","description":"Create a Template.","extra":{"proxyto":"node"},"name":"template","parameters":[{"definition":{"description":"If you want to convert only 1 disk to base image.","enum":["ide0","ide1","ide2","ide3","scsi0","scsi1","scsi2","scsi3","scsi4","scsi5","scsi6","scsi7","scsi8","scsi9","scsi10","scsi11","scsi12","scsi13","scsi14","scsi15","scsi16","scsi17","scsi18","scsi19","scsi20","scsi21","scsi22","scsi23","scsi24","scsi25","scsi26","scsi27","scsi28","scsi29","scsi30","virtio0","virtio1","virtio2","virtio3","virtio4","virtio5","virtio6","virtio7","virtio8","virtio9","virtio10","virtio11","virtio12","virtio13","virtio14","virtio15","sata0","sata1","sata2","sata3","sata4","sata5","efidisk0","tpmstate0"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"disk"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need 'VM.Allocate' permissions on /vms/{vmid}","expression":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"extra":{}},"protected":true,"returns":{"description":"the task ID.","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/template"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b80c14bb6855e37771805d1bc11b32e18b58bfd2f8ebcbf3498db55f90b15922","description":"Creates a TCP proxy connections.","extra":{},"name":"termproxy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"opens a serial terminal (defaults to display)","enum":["serial0","serial1","serial2","serial3"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"serial"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/termproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f5e5cd97555e5c8643c717a0afbc20f319f7988fec9bcee73fbb0bb4db80adce","description":"Unlink/delete disk images.","extra":{"proxyto":"node"},"name":"unlink","parameters":[{"definition":{"description":"Force physical removal. Without this, we simple remove the disk from the config file and create an additional configuration entry called 'unused[n]', which contains the volume ID. Unlink of unused[n] always cause physical removal.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"A list of disk IDs you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"idlist"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/qemu/{vmid}/unlink"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b7fb97485697171765ae5d968cb3fa606f396f9e34aa2d43b1a586b336f6afeb","description":"Creates a TCP VNC proxy connections.","extra":{},"name":"vncproxy","parameters":[{"definition":{"default":0,"description":"Generates a random password to be used as ticket instead of the API ticket.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"generate-password"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Prepare for websocket upgrade (only required when using serial terminal, otherwise upgrade is always possible).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"websocket"}],"permissions":{"expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"cert":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"description":"Returned if requested with 'generate-password' param. Consists of printable ASCII characters ('!' .. '~').","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/qemu/{vmid}/vncproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6af2b0b22135014e2a279ea3e1f03813d8d5a6b7966f96298eb6bf3c5fc22916","description":"Opens a weksocket for VNC traffic.","extra":{},"name":"vncwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Port number returned by previous vncproxy call.","enum":[],"extra":{"typetext":" (5900 - 5999)"},"maximum":5999,"minimum":5900,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The (unique) ID of the VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"},{"definition":{"description":"Ticket from previous call to vncproxy.","enum":[],"extra":{"typetext":""},"max_length":512,"properties":{},"type":"string"},"name":"vncticket"}],"permissions":{"description":"You also need to pass a valid ticket (vncticket).","expression":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/qemu/{vmid}/vncwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"538f04b05067fbe6554d199b705e5299ce19bca0fdf31783b3407037f79ccbfb","description":"Query metadata of an URL: file size, file name and mime type.","extra":{"proxyto":"node"},"name":"query_url_metadata","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The URL to query the metadata from.","enum":[],"extra":{},"pattern":"https?://.*","properties":{},"type":"string"},"name":"url"},{"definition":{"default":1,"description":"If false, no SSL/TLS certificates will be verified.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify-certificates"}],"permissions":{"expression":{"check":["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/nodes/{node}",["Sys.AccessNetwork"]]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"mimetype":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"size":{"enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/query-url-metadata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"744f7304013b6bfb4e58d7da6cc6ae8a97c3a1795b3dd6b02cc2becdaf44733d","description":"List status of all replication jobs on this node.","extra":{"proxyto":"node"},"name":"status","parameters":[{"definition":{"description":"Only list replication jobs for this guest.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"guest"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires the VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{id}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/replication"},{"extra":{},"methods":[{"allow_token":true,"checksum":"201ac105a0b4f70bec7ac00e32a949db054741cbd2465d2f625462367edce6f7","description":"Directory index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/replication/{id}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6ffc6cc2602df84fe4f8eb72ae99567ce4f7fb02dec2ca8db396ff090772cd58","description":"Read replication job log.","extra":{"proxyto":"node"},"name":"read_job_log","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"}],"permissions":{"description":"Requires the VM.Audit permission on /vms/, or 'Sys.Audit' on '/nodes/'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/replication/{id}/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"77e6d9fc5931226e0ebc15d1967865306c48edb8c36e7ab4acd3c992bc22e6ef","description":"Schedule replication job to start as soon as possible.","extra":{"proxyto":"node"},"name":"schedule_now","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/replication/{id}/schedule_now"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4be58d6638ffb32fbaa33db58fac6d3964014ed3286339e84f35ca0cb6d006e1","description":"Get replication job status.","extra":{"proxyto":"node"},"name":"job_status","parameters":[{"definition":{"description":"Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.","enum":[],"extra":{},"format":"pve-replication-job-id","pattern":"[1-9][0-9]{2,8}-\\d{1,9}","properties":{},"type":"string"},"name":"id"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Requires the VM.Audit permission on /vms/.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/replication/{id}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0e37ddadedaa3a4ce296c24b888b12f7012e4e23b1732222e40075a4f8a9ed1f","description":"Gather various systems information about a node","extra":{"proxyto":"node"},"name":"report","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/report"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d974667aed5e89c095ef17a66fb4537d6dda82a55fa1ec5f1c05cba57f78464c","description":"Read node RRD statistics (returns PNG)","extra":{},"name":"rrd","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The list of datasources you want to display.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"ds"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/rrd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"766180222a6d70a2fd631255767fa56f8cd6a67cebf4530b038018cccd49487f","description":"Read node RRD statistics","extra":{},"name":"rrddata","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/rrddata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7cca8a7c1631d17653d463ea99f96401217997b7a680967bfc57a06b99302ff1","description":"Index of available scan methods","extra":{},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{method}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"method":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2ec831a4ad191d89200069d552cc1eedbbe77316334360b9e98672a3d4cf3a94","description":"Scan remote CIFS server.","extra":{"proxyto":"node"},"name":"cifsscan","parameters":[{"definition":{"description":"SMB domain (Workgroup).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"User password.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"The server address (name or IP).","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","properties":{},"type":"string"},"name":"server"},{"definition":{"description":"User name.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"description":{"description":"Descriptive text from server.","enum":[],"extra":{},"properties":{},"type":"string"},"share":{"description":"The cifs share name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/cifs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"75c1967f47ee50cfdaf4558a4fa699bbdc9317e2fe69fd3ddccd30a2707dfe2d","description":"Scan remote GlusterFS server.","extra":{"proxyto":"node"},"name":"glusterfsscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The server address (name or IP).","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","properties":{},"type":"string"},"name":"server"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"volname":{"description":"The volume name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/glusterfs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f0b69d1299f3a287b51f9e20eddd3a6c423da92c62c5263da3308104c8f9e3d8","description":"Scan remote iSCSI server.","extra":{"proxyto":"node"},"name":"iscsiscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The iSCSI portal (IP or DNS name with optional port).","enum":[],"extra":{"typetext":""},"format":"pve-storage-portal-dns","properties":{},"type":"string"},"name":"portal"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"portal":{"description":"The iSCSI portal name.","enum":[],"extra":{},"properties":{},"type":"string"},"target":{"description":"The iSCSI target name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/iscsi"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ee58724ae9c2fbdaf09f891f8286f1c4a97862a33274213f55b64ef257c82810","description":"List local LVM volume groups.","extra":{"proxyto":"node"},"name":"lvmscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"vg":{"description":"The LVM logical volume group name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/lvm"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b85f98a17a9f58549d6a53aafbaf22bfdf0e5d1665f87e90bb69fd57fad754e8","description":"List local LVM Thin Pools.","extra":{"proxyto":"node"},"name":"lvmthinscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{},"max_length":100,"pattern":"[a-zA-Z0-9\\.\\+\\_][a-zA-Z0-9\\.\\+\\_\\-]+","properties":{},"type":"string"},"name":"vg"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"lv":{"description":"The LVM Thin Pool name (LVM logical volume).","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/lvmthin"},{"extra":{},"methods":[{"allow_token":true,"checksum":"d9ddde30d7f532fbc6f06fbe726c2833705e8d4807f2c6cd617ee8fdae18d97d","description":"Scan remote NFS server.","extra":{"proxyto":"node"},"name":"nfsscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The server address (name or IP).","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","properties":{},"type":"string"},"name":"server"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"options":{"description":"NFS export options.","enum":[],"extra":{},"properties":{},"type":"string"},"path":{"description":"The exported path.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/nfs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3ce919d002c3d125b6b1ad3b5fd0cb889318319ec14cee96f7282ff12db0bda8","description":"Scan remote Proxmox Backup Server.","extra":{"proxyto":"node"},"name":"pbsscan","parameters":[{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"User password or API token secret.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"password"},{"definition":{"default":8007,"description":"Optional port.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"The server address (name or IP).","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","properties":{},"type":"string"},"name":"server"},{"definition":{"description":"User-name or API token-ID.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"username"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"comment":{"description":"Comment from server.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"store":{"description":"The datastore name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/pbs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5742df84db0fb3e83b8a85993cee8d4667b1a311b08d135a1b751e04afd1caeb","description":"Scan zfs pool list on local node.","extra":{"proxyto":"node"},"name":"zfsscan","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"pool":{"description":"ZFS pool name.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/scan/zfs"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ff83507bdfaa5cb101794ba2e4c40051a63c313286ecc2e102ae09a550357898","description":"SDN index.","extra":{},"name":"sdnindex","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn"},{"extra":{},"methods":[{"allow_token":true,"checksum":"12403a45a714d49c82c079929ecd505c3b507a59dc93a9d8179f4b90a7ce7318","description":"Get status for all zones.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"description":"Only list entries where you have 'SDN.Audit'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{zone}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"status":{"description":"Status of zone","enum":["available","pending","error"],"extra":{},"properties":{},"type":"string"},"zone":{"description":"The SDN zone object identifier.","enum":[],"extra":{},"format":"pve-sdn-zone-id","properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/zones"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8a85cf269cae44e965f4987f67477d55f9c0dbd96ca0ce98eeacd89f9c89084e","description":"","extra":{},"name":"diridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Audit"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/zones/{zone}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"37027697e4ca9f13e96aaeed743d261261396e7f4689693272393d7d7c53e2ac","description":"List zone content.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The SDN zone object identifier.","enum":[],"extra":{"typetext":""},"format":"pve-sdn-zone-id","properties":{},"type":"string"},"name":"zone"}],"permissions":{"expression":{"check":["perm","/sdn/zones/{zone}",["SDN.Audit"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{vnet}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"status":{"description":"Status.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"statusmsg":{"description":"Status details","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vnet":{"description":"Vnet identifier.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/sdn/zones/{zone}/content"},{"extra":{},"methods":[{"allow_token":true,"checksum":"28dfc7ff0d1244e9784ad47960d10b8e5aba10d904ddab0fc817befa32f29b9a","description":"Service list.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{service}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/services"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6f84ec756ee728f7f4edef6c7bf549b613c4bd317cc57b63c0f70ab219dd314e","description":"Directory index","extra":{},"name":"srvcmdidx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","postfix","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/services/{service}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"c30eefe484f450f83ed4ab0eb9aa41fe5e4f1367b3332727b6da4dbe83bd43e0","description":"Reload service. Falls back to restart if service cannot be reloaded.","extra":{"proxyto":"node"},"name":"service_reload","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","postfix","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/services/{service}/reload"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1e658a77fb8d9cb4e603eebe1d318070b18df345eed31f24d3b146750c06ea6c","description":"Hard restart service. Use reload if you want to reduce interruptions.","extra":{"proxyto":"node"},"name":"service_restart","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","postfix","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/services/{service}/restart"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f03a14a7d7ddd10b28a73302d808652b26c74999d33365e69359255c538caaee","description":"Start service.","extra":{"proxyto":"node"},"name":"service_start","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","postfix","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/services/{service}/start"},{"extra":{},"methods":[{"allow_token":true,"checksum":"93adca1b678fcbdba8bd843e650534d9ba0cd5e4a2ff2ea165c52f454771ed77","description":"Read service properties","extra":{"proxyto":"node"},"name":"service_state","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","postfix","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/services/{service}/state"},{"extra":{},"methods":[{"allow_token":true,"checksum":"65d1bc2e276eaea3d9c9b76a2a243c4a255d7f1eaa782aeb4ebb8d46a8bffdd0","description":"Stop service.","extra":{"proxyto":"node"},"name":"service_stop","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":["chrony","corosync","cron","ksmtuned","postfix","pve-cluster","pve-firewall","pve-ha-crm","pve-ha-lrm","pvedaemon","pvefw-logger","pveproxy","pvescheduler","pvestatd","spiceproxy","sshd","syslog","systemd-journald","systemd-timesyncd"],"extra":{},"properties":{},"type":"string"},"name":"service"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/services/{service}/stop"},{"extra":{},"methods":[{"allow_token":true,"checksum":"739ad701777de346a42cd667488d43ff41ef70b0970136821edb6e154575ba71","description":"Creates a SPICE shell.","extra":{"proxyto":"node"},"name":"spiceshell","parameters":[{"definition":{"default":"login","description":"Run specific command or default to login (requires 'root@pam')","enum":["ceph_install","upgrade","login"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmd"},{"definition":{"default":"","description":"Add parameters to a command. Encoded as null terminated strings.","enum":[],"extra":{"requires":"cmd","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cmd-opts"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs 'spiceproxy', so it is up to the client to choose one. By default, we return the node where the VM is currently running. As reasonable setting is to use same node you use to connect to the API (This is window.location.hostname for the JS GUI).","enum":[],"extra":{"typetext":""},"format":"address","optional":true,"properties":{},"type":"string"},"name":"proxy"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"description":"Returned values can be directly passed to the 'remote-viewer' application.","enum":[],"extra":{"additionalProperties":1},"properties":{"host":{"enum":[],"extra":{},"properties":{},"type":"string"},"password":{"enum":[],"extra":{},"properties":{},"type":"string"},"proxy":{"enum":[],"extra":{},"properties":{},"type":"string"},"tls-port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/spiceshell"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ec80ea1c2fbaa0128ad1277e098081db8e1ed6887318cb24f7fe962dd1dc4bd6","description":"Start all VMs and containers located on this node (by default only those with onboot=1).","extra":{"proxyto":"node"},"name":"startall","parameters":[{"definition":{"default":"off","description":"Issue start command even if virtual guest have 'onboot' not set or set to off.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only consider guests from this comma separated list of VMIDs.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"}],"permissions":{"description":"The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/startall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"dd462de2ef27d17e9065b8459293f8ef348fbba356006168b1d5d9f877a74521","description":"Read node status","extra":{"proxyto":"node"},"name":"status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":1},"properties":{"boot-info":{"description":"Meta-information about the boot mode.","enum":[],"extra":{},"properties":{"mode":{"description":"Through which firmware the system got booted.","enum":["efi","legacy-bios"],"extra":{},"properties":{},"type":"string"},"secureboot":{"description":"System is booted in secure mode, only applicable for the \"efi\" mode.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"}},"type":"object"},"cpu":{"description":"The current cpu usage.","enum":[],"extra":{},"properties":{},"type":"number"},"cpuinfo":{"enum":[],"extra":{},"properties":{"cores":{"description":"The number of physical cores of the CPU.","enum":[],"extra":{},"properties":{},"type":"integer"},"cpus":{"description":"The number of logical threads of the CPU.","enum":[],"extra":{},"properties":{},"type":"integer"},"model":{"description":"The CPU model","enum":[],"extra":{},"properties":{},"type":"string"},"sockets":{"description":"The number of logical threads of the CPU.","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"current-kernel":{"description":"Meta-information about the currently booted kernel of this node.","enum":[],"extra":{},"properties":{"machine":{"description":"Hardware (architecture) type","enum":[],"extra":{},"properties":{},"type":"string"},"release":{"description":"OS kernel release (e.g., \"6.8.0\")","enum":[],"extra":{},"properties":{},"type":"string"},"sysname":{"description":"OS kernel name (e.g., \"Linux\")","enum":[],"extra":{},"properties":{},"type":"string"},"version":{"description":"OS kernel version with build info","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"loadavg":{"description":"An array of load avg for 1, 5 and 15 minutes respectively.","enum":[],"extra":{},"items":{"description":"The value of the load.","enum":[],"extra":{},"properties":{},"type":"string"},"properties":{},"type":"array"},"memory":{"enum":[],"extra":{},"properties":{"free":{"description":"The free memory in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"total":{"description":"The total memory in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"used":{"description":"The used memory in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"},"pveversion":{"description":"The PVE version string.","enum":[],"extra":{},"properties":{},"type":"string"},"rootfs":{"enum":[],"extra":{},"properties":{"avail":{"description":"The available bytes in the root filesystem.","enum":[],"extra":{},"properties":{},"type":"integer"},"free":{"description":"The free bytes on the root filesystem.","enum":[],"extra":{},"properties":{},"type":"integer"},"total":{"description":"The total size of the root filesystem in bytes.","enum":[],"extra":{},"properties":{},"type":"integer"},"used":{"description":"The used bytes in the root filesystem.","enum":[],"extra":{},"properties":{},"type":"integer"}},"type":"object"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"f11d86bf5eb63c8f7c9cd23dd0579477ea908eb3b936d39f4f8c5a20bfd0bef7","description":"Reboot or shutdown a node.","extra":{"proxyto":"node"},"name":"node_cmd","parameters":[{"definition":{"description":"Specify the command.","enum":["reboot","shutdown"],"extra":{},"properties":{},"type":"string"},"name":"command"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"}],"path":"/nodes/{node}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f0bf330d9be14654c45843287074e32b7a4bac98bc5c440d3be95d31b993ac47","description":"Stop all VMs and Containers.","extra":{"proxyto":"node"},"name":"stopall","parameters":[{"definition":{"default":1,"description":"Force a hard-stop after the timeout.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force-stop"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":180,"description":"Timeout for each guest shutdown task. Depending on `force-stop`, the shutdown gets then simply aborted or a hard-stop is forced.","enum":[],"extra":{"typetext":" (0 - 7200)"},"maximum":7200,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"timeout"},{"definition":{"description":"Only consider Guests with these IDs.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"}],"permissions":{"description":"The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/stopall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"658baed770457636aec97aae39d2d15301aceb8898bc1cea445fe7ce18fc3537","description":"Get status for all datastores.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"Only list stores which support this content type.","enum":[],"extra":{"typetext":""},"format":"pve-storage-content-list","optional":true,"properties":{},"type":"string"},"name":"content"},{"definition":{"default":0,"description":"Only list stores which are enabled (not disabled in config).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"enabled"},{"definition":{"default":0,"description":"Include information about formats","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"format"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list status for specified storage","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"If target is different to 'node', we only lists shared storages which content is accessible on this 'node' and the specified 'target' node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target"}],"permissions":{"description":"Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{storage}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"active":{"description":"Set when storage is accessible.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"avail":{"description":"Available storage space in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"content":{"description":"Allowed storage content types.","enum":[],"extra":{},"format":"pve-storage-content-list","properties":{},"type":"string"},"enabled":{"description":"Set when storage is enabled (not disabled).","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"shared":{"description":"Shared flag from storage configuration.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"storage":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID"},"format":"pve-storage-id","properties":{},"type":"string"},"total":{"description":"Total storage space in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"type":{"description":"Storage type.","enum":[],"extra":{},"properties":{},"type":"string"},"used":{"description":"Used storage space in bytes.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"used_fraction":{"description":"Used fraction (used/total).","enum":[],"extra":{"renderer":"fraction_as_percentage"},"optional":true,"properties":{},"type":"number"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage"},{"extra":{},"methods":[{"allow_token":true,"checksum":"0f34572e237a199ec9df2c4b490f1be7b4803af30d4ca82611bada9412d062b9","description":"","extra":{},"name":"diridx","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{subdir}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"subdir":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"09b70ee4a4d5380916f33e4ce2d9d44f1a031a516eced603ac4da2280b553c99","description":"List storage content.","extra":{"proxyto":"node"},"name":"index","parameters":[{"definition":{"description":"Only list content of this type.","enum":[],"extra":{"typetext":""},"format":"pve-storage-content","optional":true,"properties":{},"type":"string"},"name":"content"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Only list images for this VM","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"links":[{"href":"{volid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"ctime":{"description":"Creation time (seconds since the UNIX Epoch).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"encrypted":{"description":"If whole backup is encrypted, value is the fingerprint or '1' if encrypted. Only useful for the Proxmox Backup Server storage type.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"format":{"description":"Format identifier ('raw', 'qcow2', 'subvol', 'iso', 'tgz' ...)","enum":[],"extra":{},"properties":{},"type":"string"},"notes":{"description":"Optional notes. If they contain multiple lines, only the first one is returned here.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"parent":{"description":"Volume identifier of parent (for linked cloned).","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"protected":{"description":"Protection status. Currently only supported for backups.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"size":{"description":"Volume size in bytes.","enum":[],"extra":{"renderer":"bytes"},"properties":{},"type":"integer"},"used":{"description":"Used space. Please note that most storage plugins do not report anything useful here.","enum":[],"extra":{"renderer":"bytes"},"optional":true,"properties":{},"type":"integer"},"verification":{"description":"Last backup verification result, only useful for PBS storages.","enum":[],"extra":{},"optional":true,"properties":{"state":{"description":"Last backup verification state.","enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"description":"Last backup verification UPID.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"vmid":{"description":"Associated Owner VMID.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"volid":{"description":"Volume identifier.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"96cbd6fc8a176b7a0d5aadee14f55b99b6474880ee40613149589daff21cc06a","description":"Allocate disk images.","extra":{"proxyto":"node"},"name":"create","parameters":[{"definition":{"description":"The name of the file to create.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"filename"},{"definition":{"description":"Format of the image.","enum":["raw","qcow2","subvol","vmdk"],"extra":{"requires":"size"},"optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Size in kilobyte (1024 bytes). Optional suffixes 'M' (megabyte, 1024K) and 'G' (gigabyte, 1024M)","enum":[],"extra":{},"pattern":"\\d+[MG]?","properties":{},"type":"string"},"name":"size"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Specify owner VM","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.AllocateSpace"]]},"extra":{}},"protected":true,"returns":{"description":"Volume identifier","enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/storage/{storage}/content"},{"extra":{},"methods":[{"allow_token":true,"checksum":"00189b956be91b24e3a41a3ea431f9e1ced9caf6170502ae77c1b796a58f9e57","description":"Delete volume","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"description":"Time to wait for the task to finish. We return 'null' if the task finish within that time.","enum":[],"extra":{"typetext":" (1 - 30)"},"maximum":30,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"delay"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need 'Datastore.Allocate' privilege on the storage (or 'Datastore.AllocateSpace' for backup volumes if you have VM.Backup privilege on the VM).","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"3baa865a5c097996d513818c079aac6d6c03cf45638cd8f3c6ee701afd7878ab","description":"Get volume attributes","extra":{"proxyto":"node"},"name":"info","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"format":{"description":"Format identifier ('raw', 'qcow2', 'subvol', 'iso', 'tgz' ...)","enum":[],"extra":{},"properties":{},"type":"string"},"notes":{"description":"Optional notes.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"path":{"description":"The Path","enum":[],"extra":{},"properties":{},"type":"string"},"protected":{"description":"Protection status. Currently only supported for backups.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"size":{"description":"Volume size in bytes.","enum":[],"extra":{"renderer":"bytes"},"properties":{},"type":"integer"},"used":{"description":"Used space. Please note that most storage plugins do not report anything useful here.","enum":[],"extra":{"renderer":"bytes"},"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"d3edd035cd3bedade91a18abce3de0cd8c13011e4a281f7a271fd98ad9858be0","description":"Copy a volume. This is experimental code - do not use.","extra":{"proxyto":"node"},"name":"copy","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Target volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"Target node. Default is local node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"target_node"},{"definition":{"description":"Source volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"},{"allow_token":true,"checksum":"dad56b6a2a822d2722f0399472681acc089bfedac37418abf6787fa31e6370cf","description":"Update volume attributes","extra":{"proxyto":"node"},"name":"updateattributes","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The new notes.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"notes"},{"definition":{"description":"Protection status. Currently only supported for backups.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protected"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/storage/{storage}/content/{volume}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"6b19c2c6757f47b20079d7dc70256c7e35b4dee7beb51cbea37a2335b838720e","description":"Download templates, ISO images, OVAs and VM images by using an URL.","extra":{"proxyto":"node"},"name":"download_url","parameters":[{"definition":{"description":"The expected checksum of the file.","enum":[],"extra":{"requires":"checksum-algorithm","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"checksum"},{"definition":{"description":"The algorithm to calculate the checksum of the file.","enum":["md5","sha1","sha224","sha256","sha384","sha512"],"extra":{"requires":"checksum"},"optional":true,"properties":{},"type":"string"},"name":"checksum-algorithm"},{"definition":{"description":"Decompress the downloaded file using the specified compression algorithm.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"compression"},{"definition":{"description":"Content type.","enum":["iso","vztmpl","import"],"extra":{},"format":"pve-storage-content","properties":{},"type":"string"},"name":"content"},{"definition":{"description":"The name of the file to create. Caution: This will be normalized!","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"filename"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"The URL to download the file from.","enum":[],"extra":{},"pattern":"https?://.*","properties":{},"type":"string"},"name":"url"},{"definition":{"default":1,"description":"If false, no SSL/TLS certificates will be verified.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"verify-certificates"}],"permissions":{"description":"Requires allocation access on the storage and as this allows one to probe the (local!) host network indirectly it also requires one of Sys.Modify on / (for backwards compatibility) or the newer Sys.AccessNetwork privilege on the node.","expression":{"check":["and",["perm","/storage/{storage}",["Datastore.AllocateTemplate"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/nodes/{node}",["Sys.AccessNetwork"]]]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/storage/{storage}/download-url"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f17dd8ea50a61163da50ea44dd5bb18e74f3cfe5c6d3b87eacea93f2669730a3","description":"Extract a file or directory (as zip archive) from a PBS backup.","extra":{"download_allowed":1,"proxyto":"node"},"name":"download","parameters":[{"definition":{"description":"base64-path to the directory or file to download.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"filepath"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"default":0,"description":"Download dirs as 'tar.zst' instead of 'zip'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tar"},{"definition":{"description":"Backup volume ID or name. Currently only PBS snapshots are supported.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"any"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/file-restore/download"},{"extra":{},"methods":[{"allow_token":true,"checksum":"1f5d9f6eb8537d97c9debc4d0d83740d147c362674619cc48f0d2fa21a60ff5a","description":"List files and directories for single file restore under the given path.","extra":{"proxyto":"node"},"name":"list","parameters":[{"definition":{"description":"base64-path to the directory or file being listed, or \"/\".","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"filepath"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Backup volume ID or name. Currently only PBS snapshots are supported.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"filepath":{"description":"base64 path of the current entry","enum":[],"extra":{},"properties":{},"type":"string"},"leaf":{"description":"If this entry is a leaf in the directory graph.","enum":[],"extra":{},"properties":{},"type":"boolean"},"mtime":{"description":"Entry last-modified time (unix timestamp).","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"size":{"description":"Entry file size.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"text":{"description":"Entry display text.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"Entry type.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/file-restore/list"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7955a18eaf60f9c62ee87e38b5b2a0c438bbc8af4cd9b077138d411caa6623a7","description":"Get the base parameters for creating a guest which imports data from a foreign importable guest, like an ESXi VM","extra":{"proxyto":"node"},"name":"get_import_metadata","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Volume identifier for the guest archive/entry.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"You need read access for the volume.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"description":"Information about how to import a guest.","enum":[],"extra":{"additionalProperties":0},"properties":{"create-args":{"description":"Parameters which can be used in a call to create a VM or container.","enum":[],"extra":{"additionalProperties":1},"properties":{},"type":"object"},"disks":{"description":"Recognised disk volumes as `$bus$id` => `$storeid:$path` map.","enum":[],"extra":{"additionalProperties":1},"optional":true,"properties":{},"type":"object"},"net":{"description":"Recognised network interfaces as `net$id` => { ...params } object.","enum":[],"extra":{"additionalProperties":1},"optional":true,"properties":{},"type":"object"},"source":{"description":"The type of the import-source of this guest volume.","enum":["esxi"],"extra":{},"properties":{},"type":"string"},"type":{"description":"The type of guest this is going to produce.","enum":["vm"],"extra":{},"properties":{},"type":"string"},"warnings":{"description":"List of known issues that can affect the import of a guest. Note that lack of warning does not imply that there cannot be any problems.","enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"key":{"description":"Related subject (config) key of warning.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"description":"What this warning is about.","enum":["cdrom-image-ignored","efi-state-lost","guest-is-running","nvme-unsupported","ova-needs-extracting","ovmf-with-lsi-unsupported","serial-port-socket-only"],"extra":{},"properties":{},"type":"string"},"value":{"description":"Related subject (config) value of warning.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"optional":true,"properties":{},"type":"array"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/import-metadata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"9820bccd0c8e4fa6d9e76952af7601b655780063585e6f5ab98152fc5f6a6090","description":"Prune backups. Only those using the standard naming scheme are considered.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Either 'qemu' or 'lxc'. Only consider backups for guests of this type.","enum":["qemu","lxc"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"Only prune backups for this VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"You need the 'Datastore.Allocate' privilege on the storage (or if a VM ID is specified, 'Datastore.AllocateSpace' and 'VM.Backup' for the VM).","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"DELETE"},{"allow_token":true,"checksum":"dc997ca715271d56e6b13c8bf092a59c488beea7395d33101289f62d0044ad0f","description":"Get prune information for backups. NOTE: this is only a preview and might not be what a subsequent prune call does if backups are removed/added in the meantime.","extra":{"proxyto":"node"},"name":"dryrun","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Either 'qemu' or 'lxc'. Only consider backups for guests of this type.","enum":["qemu","lxc"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"Only consider backups for this guest.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"ctime":{"description":"Creation time of the backup (seconds since the UNIX epoch).","enum":[],"extra":{},"properties":{},"type":"integer"},"mark":{"description":"Whether the backup would be kept or removed. Backups that are protected or don't use the standard naming scheme are not removed.","enum":["keep","remove","protected","renamed"],"extra":{},"properties":{},"type":"string"},"type":{"description":"One of 'qemu', 'lxc', 'openvz' or 'unknown'.","enum":[],"extra":{},"properties":{},"type":"string"},"vmid":{"description":"The VM the backup belongs to.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"volid":{"description":"Backup volume ID.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/prunebackups"},{"extra":{},"methods":[{"allow_token":true,"checksum":"ef810ce3bbce11f3f3cdcc6607ae9cf7dc62b1b39282e05b40167d2acfff93de","description":"Read storage RRD statistics (returns PNG).","extra":{"proxyto":"node"},"name":"rrd","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The list of datasources you want to display.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","properties":{},"type":"string"},"name":"ds"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"filename":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/rrd"},{"extra":{},"methods":[{"allow_token":true,"checksum":"7ea36673b7e9e620442b49b8b240fefdebd96b87315ed46cbe29cb6d3d943180","description":"Read storage RRD statistics.","extra":{"proxyto":"node"},"name":"rrddata","parameters":[{"definition":{"description":"The RRD consolidation function","enum":["AVERAGE","MAX"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cf"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"],"extra":{},"properties":{},"type":"string"},"name":"timeframe"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/rrddata"},{"extra":{},"methods":[{"allow_token":true,"checksum":"2f8079eef2b090c7078390e3dc69805cca6f6765ec1db4a6d77d60e6bfda29f0","description":"Read storage status.","extra":{"proxyto":"node"},"name":"read_status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/storage/{storage}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"3b7941d7a0a66338f7e143b5bfcd44890820f378aa6c4b1064b3c1f8affc1b62","description":"Upload templates, ISO images, OVAs and VM images.","extra":{},"name":"upload","parameters":[{"definition":{"description":"The expected checksum of the file.","enum":[],"extra":{"requires":"checksum-algorithm","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"checksum"},{"definition":{"description":"The algorithm to calculate the checksum of the file.","enum":["md5","sha1","sha224","sha256","sha384","sha512"],"extra":{"requires":"checksum"},"optional":true,"properties":{},"type":"string"},"name":"checksum-algorithm"},{"definition":{"description":"Content type.","enum":["iso","vztmpl","import"],"extra":{},"format":"pve-storage-content","properties":{},"type":"string"},"name":"content"},{"definition":{"description":"The name of the file to create. Caution: This will be normalized!","enum":[],"extra":{"typetext":""},"max_length":255,"properties":{},"type":"string"},"name":"filename"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"The source file name. This parameter is usually set by the REST handler. You can only overwrite it when connecting to the trusted port on localhost.","enum":[],"extra":{},"optional":true,"pattern":"/var/tmp/pveupload-[0-9a-f]+","properties":{},"type":"string"},"name":"tmpfilename"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.AllocateTemplate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/storage/{storage}/upload"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f69a09923a7e070b2be36d4ccb06e891f14a3518902eee5f7f7c27f6c58e46e7","description":"Delete subscription key of this node.","extra":{"proxyto":"node"},"name":"delete","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"4e8dea82ae94ae036d6411f557d2895ac4a0e56b9760df6d8bac0b42d8bd109d","description":"Read subscription info.","extra":{"proxyto":"node"},"name":"get","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"checktime":{"description":"Timestamp of the last check done.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"key":{"description":"The subscription key, if set and permitted to access.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"level":{"description":"A short code for the subscription level.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"message":{"description":"A more human readable status message.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"nextduedate":{"description":"Next due date of the set subscription.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"productname":{"description":"Human readable productname of the set subscription.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"regdate":{"description":"Register date of the set subscription.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"serverid":{"description":"The server ID, if permitted to access.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"signature":{"description":"Signature for offline keys","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"sockets":{"description":"The number of sockets for this host.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"status":{"description":"The current subscription status.","enum":["new","notfound","active","invalid","expired","suspended"],"extra":{},"properties":{},"type":"string"},"url":{"description":"URL to the web shop.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"fd4ac8b650dd7e96bdb5021c8454a3b09b574435f893a76329e3fad2900aa892","description":"Update subscription info.","extra":{"proxyto":"node"},"name":"update","parameters":[{"definition":{"default":0,"description":"Always connect to server, even if local cache is still valid.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"force"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"36ff0176410661df4a71dff72988369e92078b7b833c101aa43f014a614dc695","description":"Set subscription key.","extra":{"proxyto":"node"},"name":"set","parameters":[{"definition":{"description":"Proxmox VE subscription key","enum":[],"extra":{},"max_length":32,"pattern":"\\s*pve([1248])([cbsp])-[0-9a-f]{10}\\s*","properties":{},"type":"string"},"name":"key"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/subscription"},{"extra":{},"methods":[{"allow_token":true,"checksum":"587e035e3d3dbd7fd5303a82fb97d0601d15082b6461818d913c0ee3361f0d3f","description":"Suspend all VMs.","extra":{"proxyto":"node"},"name":"suspendall","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only consider Guests with these IDs.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"}],"permissions":{"description":"The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter. Additionally, you need 'VM.Config.Disk' on the '/vms/{vmid}' path and 'Datastore.AllocateSpace' for the configured state-storage(s)","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/suspendall"},{"extra":{},"methods":[{"allow_token":true,"checksum":"627733cfb797f5cb56b37117c3cd10de855d36183e4e87b8e57c0207e6238edd","description":"Read system log","extra":{"proxyto":"node"},"name":"syslog","parameters":[{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Service ID","enum":[],"extra":{"typetext":""},"max_length":128,"optional":true,"properties":{},"type":"string"},"name":"service"},{"definition":{"description":"Display all log since this date-time string.","enum":[],"extra":{},"optional":true,"pattern":"^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$","properties":{},"type":"string"},"name":"since"},{"definition":{"enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"Display all log until this date-time string.","enum":[],"extra":{},"optional":true,"pattern":"^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$","properties":{},"type":"string"},"name":"until"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/syslog"},{"extra":{},"methods":[{"allow_token":true,"checksum":"cd12dd65de0ad938bc722d13a6b37ae0d9adca2b2d298f5f384871e58655af5e","description":"Read task list for one node (finished tasks).","extra":{"proxyto":"node"},"name":"node_tasks","parameters":[{"definition":{"default":0,"description":"Only list tasks with a status of ERROR.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"errors"},{"definition":{"default":50,"description":"Only list this amount of tasks.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Only list tasks since this UNIX epoch.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"since"},{"definition":{"default":"archive","description":"List archived, active or all tasks.","enum":["archive","active","all"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"source"},{"definition":{"default":0,"description":"List tasks beginning from this offset.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"List of Task States that should be returned.","enum":[],"extra":{"typetext":""},"format":"pve-task-status-type-list","optional":true,"properties":{},"type":"string"},"name":"statusfilter"},{"definition":{"description":"Only list tasks of this type (e.g., vzstart, vzdump).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"typefilter"},{"definition":{"description":"Only list tasks until this UNIX epoch.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"until"},{"definition":{"description":"Only list tasks from this user.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"userfilter"},{"definition":{"description":"Only list tasks for this VM.","enum":[],"extra":{"typetext":" (100 - 999999999)"},"format":"pve-vmid","maximum":999999999,"minimum":100,"optional":true,"properties":{},"type":"integer"},"name":"vmid"}],"permissions":{"description":"List task associated with the current user, or all task the user has 'Sys.Audit' permissions on /nodes/ (the the task runs on).","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{upid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"endtime":{"enum":[],"extra":{"title":"Endtime"},"optional":true,"properties":{},"type":"integer"},"id":{"enum":[],"extra":{"title":"ID"},"properties":{},"type":"string"},"node":{"enum":[],"extra":{"title":"Node"},"properties":{},"type":"string"},"pid":{"enum":[],"extra":{"title":"PID"},"properties":{},"type":"integer"},"pstart":{"enum":[],"extra":{},"properties":{},"type":"integer"},"starttime":{"enum":[],"extra":{"title":"Starttime"},"properties":{},"type":"integer"},"status":{"enum":[],"extra":{"title":"Status"},"optional":true,"properties":{},"type":"string"},"type":{"enum":[],"extra":{"title":"Type"},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{"title":"UPID"},"properties":{},"type":"string"},"user":{"enum":[],"extra":{"title":"User"},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/tasks"},{"extra":{},"methods":[{"allow_token":true,"checksum":"8858ff934ad9888088c08685fc89c7640b161692fc40eb48b890b6349353f5e3","description":"Stop a task.","extra":{"proxyto":"node"},"name":"stop_task","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"upid"}],"permissions":{"description":"The user needs 'Sys.Modify' permissions on '/nodes/' if they aren't the owner of the task.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"88930b3a0d6654f9ead4d8adc76725935668dd88774af0a950aa627485d41dbf","description":"","extra":{},"name":"upid_index","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"upid"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{name}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/tasks/{upid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"20aef70abac87a557ea7d91eb54f5b63471d6a5b9b54a0af34ec36edc8931346","description":"Read task log.","extra":{"download_allowed":1,"proxyto":"node"},"name":"read_task_log","parameters":[{"definition":{"description":"Whether the tasklog file should be downloaded. This parameter can't be used in conjunction with other parameters","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"download"},{"definition":{"default":50,"description":"The amount of lines to read from the tasklog.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"limit"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"default":0,"description":"Start at this line when reading the tasklog","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"start"},{"definition":{"description":"The task's unique ID.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"upid"}],"permissions":{"description":"The user needs 'Sys.Audit' permissions on '/nodes/' if they aren't the owner of the task.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{"n":{"description":"Line number","enum":[],"extra":{},"properties":{},"type":"integer"},"t":{"description":"Line text","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"}],"path":"/nodes/{node}/tasks/{upid}/log"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e5dfb923817d11920e1fbf8b6b850f93409ba0826a5758d8960edf9c3f2c3901","description":"Read task status.","extra":{"proxyto":"node"},"name":"read_task_status","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The task's unique ID.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"upid"}],"permissions":{"description":"The user needs 'Sys.Audit' permissions on '/nodes/' if they are not the owner of the task.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"exitstatus":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"node":{"enum":[],"extra":{},"properties":{},"type":"string"},"pid":{"enum":[],"extra":{},"properties":{},"type":"integer"},"pstart":{"enum":[],"extra":{},"properties":{},"type":"integer"},"starttime":{"enum":[],"extra":{},"properties":{},"type":"integer"},"status":{"enum":["running","stopped"],"extra":{},"properties":{},"type":"string"},"type":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/tasks/{upid}/status"},{"extra":{},"methods":[{"allow_token":true,"checksum":"4119f0ba5d16067adc7894478eb6fcb25e1b4a337eaf42c399d99545cbadff9f","description":"Creates a VNC Shell proxy.","extra":{},"name":"termproxy","parameters":[{"definition":{"default":"login","description":"Run specific command or default to login (requires 'root@pam')","enum":["ceph_install","upgrade","login"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmd"},{"definition":{"default":"","description":"Add parameters to a command. Encoded as null terminated strings.","enum":[],"extra":{"requires":"cmd","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cmd-opts"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/termproxy"},{"extra":{},"methods":[{"allow_token":true,"checksum":"15558dd947c7c5db6fd939f2882db13ec7cc1f3ed3889a21151f2ece44c27e19","description":"Read server time and time zone settings.","extra":{"proxyto":"node"},"name":"time","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"localtime":{"description":"Seconds since 1970-01-01 00:00:00 (local time)","enum":[],"extra":{"renderer":"timestamp_gmt"},"minimum":1297163644,"properties":{},"type":"integer"},"time":{"description":"Seconds since 1970-01-01 00:00:00 UTC.","enum":[],"extra":{"renderer":"timestamp"},"minimum":1297163644,"properties":{},"type":"integer"},"timezone":{"description":"Time zone","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"6e0e6c4e973322e4ff4de02a8f54fc9a9a9de171237797934f9056943f940639","description":"Set time zone.","extra":{"proxyto":"node"},"name":"set_timezone","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names.","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"timezone"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/nodes/{node}/time"},{"extra":{},"methods":[{"allow_token":true,"checksum":"a2f20ffba970376ccb2903020b544f6ac94e79d7aaba8ea5df4a4cf3a2cfd266","description":"API version details","extra":{"proxyto":"node"},"name":"version","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"release":{"description":"The current installed Proxmox VE Release","enum":[],"extra":{},"properties":{},"type":"string"},"repoid":{"description":"The short git commit hash ID from which this version was build","enum":[],"extra":{},"properties":{},"type":"string"},"version":{"description":"The current installed pve-manager package version","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/version"},{"extra":{},"methods":[{"allow_token":true,"checksum":"fb19c1ead825100445dc4eb131724fa9d29db3d2bf44517f5ec57057a50191e3","description":"Creates a VNC Shell proxy.","extra":{},"name":"vncshell","parameters":[{"definition":{"default":"login","description":"Run specific command or default to login (requires 'root@pam')","enum":["ceph_install","upgrade","login"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"cmd"},{"definition":{"default":"","description":"Add parameters to a command. Encoded as null terminated strings.","enum":[],"extra":{"requires":"cmd","typetext":""},"optional":true,"properties":{},"type":"string"},"name":"cmd-opts"},{"definition":{"description":"sets the height of the console in pixels.","enum":[],"extra":{"typetext":" (16 - 2160)"},"maximum":2160,"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"height"},{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"use websocket instead of standard vnc.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"websocket"},{"definition":{"description":"sets the width of the console in pixels.","enum":[],"extra":{"typetext":" (16 - 4096)"},"maximum":4096,"minimum":16,"optional":true,"properties":{},"type":"integer"},"name":"width"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"cert":{"enum":[],"extra":{},"properties":{},"type":"string"},"port":{"enum":[],"extra":{},"properties":{},"type":"integer"},"ticket":{"enum":[],"extra":{},"properties":{},"type":"string"},"upid":{"enum":[],"extra":{},"properties":{},"type":"string"},"user":{"enum":[],"extra":{},"properties":{},"type":"string"}}},"verb":"POST"}],"path":"/nodes/{node}/vncshell"},{"extra":{},"methods":[{"allow_token":true,"checksum":"e70e4f63d5ad10b5060d68e3aa8edf4af5bd1254910eb770cdd6a5393dc73970","description":"Opens a websocket for VNC traffic.","extra":{},"name":"vncwebsocket","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Port number returned by previous vncproxy call.","enum":[],"extra":{"typetext":" (5900 - 5999)"},"maximum":5999,"minimum":5900,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"Ticket from previous call to vncproxy.","enum":[],"extra":{"typetext":""},"max_length":512,"properties":{},"type":"string"},"name":"vncticket"}],"permissions":{"description":"You also need to pass a valid ticket (vncticket).","expression":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"port":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/vncwebsocket"},{"extra":{},"methods":[{"allow_token":true,"checksum":"5b30df49bdd4e7cfc69b603cec4f3d27a1ddb8a932a253ac99d05ae50ad4dba0","description":"Create backup.","extra":{"proxyto":"node"},"name":"vzdump","parameters":[{"definition":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"all"},{"definition":{"default":0,"description":"Limit I/O bandwidth (in KiB/s).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"bwlimit"},{"definition":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"compress"},{"definition":{"description":"Store resulting files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"dumpdir"},{"definition":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"exclude"},{"definition":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{"typetext":""},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"name":"exclude-path"},{"definition":{"description":"Options for backup fleecing (VM only).","enum":[],"extra":{"typetext":"[[enabled=]<1|0>] [,storage=]"},"format":"backup-fleecing","optional":true,"properties":{},"type":"string"},"name":"fleecing"},{"definition":{"default":7,"description":"Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.","enum":[],"extra":{"typetext":" (0 - 8)"},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"ionice"},{"definition":{"description":"The ID of the backup job. If set, the 'backup-job' metadata field of the backup notification will be set to this value. Only root@pam can set this parameter.","enum":[],"extra":{},"max_length":50,"optional":true,"pattern":"\\S+","properties":{},"type":"string"},"name":"job-id"},{"definition":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"lockwait"},{"definition":{"default":"always","description":"Deprecated: use notification targets/matchers instead. Specify when to send a notification mail","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mailnotification"},{"definition":{"description":"Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{"typetext":""},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"name":"mailto"},{"definition":{"description":"Deprecated: use 'prune-backups' instead. Maximal number of backup files per guest system.","enum":[],"extra":{"typetext":" (1 - N)"},"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"maxfiles"},{"definition":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"mode"},{"definition":{"description":"Only run if executed on this node.","enum":[],"extra":{"typetext":""},"format":"pve-node","optional":true,"properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.","enum":[],"extra":{"requires":"storage","typetext":""},"max_length":1024,"optional":true,"properties":{},"type":"string"},"name":"notes-template"},{"definition":{"default":"auto","description":"Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.","enum":["auto","legacy-sendmail","notification-system"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"notification-mode"},{"definition":{"default":"always","description":"Deprecated: Do not use","enum":["always","failure","never"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"notification-policy"},{"definition":{"description":"Deprecated: Do not use","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"notification-target"},{"definition":{"description":"PBS mode used to detect file changes and switch encoding format for container backups.","enum":["legacy","data","metadata"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"pbs-change-detection-mode"},{"definition":{"description":"Other performance-related settings.","enum":[],"extra":{"typetext":"[max-workers=] [,pbs-entries-max=]"},"format":"backup-performance","optional":true,"properties":{},"type":"string"},"name":"performance"},{"definition":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"pigz"},{"definition":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"If true, mark backup(s) as protected.","enum":[],"extra":{"requires":"storage","typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"protected"},{"definition":{"default":"keep-all=1","description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"default":0,"description":"Be quiet.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"quiet"},{"definition":{"default":1,"description":"Prune older backups according to 'prune-backups'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"remove"},{"definition":{"description":"Use specified hook script.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"script"},{"definition":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stdexcludes"},{"definition":{"description":"Write tar to stdout, not to a file.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stdout"},{"definition":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"stop"},{"definition":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"stopwait"},{"definition":{"description":"Store resulting file to this storage.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Store temporary files to specified directory.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"tmpdir"},{"definition":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vmid"},{"definition":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"integer"},"name":"zstd"}],"permissions":{"description":"The user needs 'VM.Backup' permissions on any VM, and 'Datastore.AllocateSpace' on the backup storage (and fleecing storage when fleecing is used). The 'tmpdir', 'dumpdir', 'script' and 'job-id' parameters are restricted to the 'root@pam' user. The 'maxfiles' and 'prune-backups' settings require 'Datastore.Allocate' on the backup storage. The 'bwlimit', 'performance' and 'ionice' parameters require 'Sys.Modify' on '/'.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/vzdump"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b79c168fc7bac7b98a6023f822dc8d7218c506a80657b6ad22caf180e4a0f2f0","description":"Get the currently configured vzdump defaults.","extra":{"proxyto":"node"},"name":"defaults","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"name":"storage"}],"permissions":{"description":"The user needs 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions for the specified storage (or default storage if none specified). Some properties are only returned when the user has 'Sys.Audit' permissions for the node.","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"all":{"default":0,"description":"Backup all known guest systems on this host.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"bwlimit":{"default":0,"description":"Limit I/O bandwidth (in KiB/s).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"compress":{"default":"0","description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"extra":{},"optional":true,"properties":{},"type":"string"},"dumpdir":{"description":"Store resulting files to specified directory.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"exclude":{"description":"Exclude specified guest systems (assumes --all)","enum":[],"extra":{},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"exclude-path":{"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.","enum":[],"extra":{},"items":{"enum":[],"extra":{},"properties":{},"type":"string"},"optional":true,"properties":{},"type":"array"},"fleecing":{"description":"Options for backup fleecing (VM only).","enum":[],"extra":{},"format":"backup-fleecing","optional":true,"properties":{},"type":"string"},"ionice":{"default":7,"description":"Set IO priority when using the BFQ scheduler. For snapshot and suspend mode backups of VMs, this only affects the compressor. A value of 8 means the idle priority is used, otherwise the best-effort priority is used with the specified value.","enum":[],"extra":{},"maximum":8,"minimum":0,"optional":true,"properties":{},"type":"integer"},"lockwait":{"default":180,"description":"Maximal time to wait for the global lock (minutes).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"mailnotification":{"default":"always","description":"Deprecated: use notification targets/matchers instead. Specify when to send a notification mail","enum":["always","failure"],"extra":{},"optional":true,"properties":{},"type":"string"},"mailto":{"description":"Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.","enum":[],"extra":{},"format":"email-or-username-list","optional":true,"properties":{},"type":"string"},"maxfiles":{"description":"Deprecated: use 'prune-backups' instead. Maximal number of backup files per guest system.","enum":[],"extra":{},"minimum":1,"optional":true,"properties":{},"type":"integer"},"mode":{"default":"snapshot","description":"Backup mode.","enum":["snapshot","suspend","stop"],"extra":{},"optional":true,"properties":{},"type":"string"},"node":{"description":"Only run if executed on this node.","enum":[],"extra":{},"format":"pve-node","optional":true,"properties":{},"type":"string"},"notes-template":{"description":"Template string for generating notes for the backup(s). It can contain variables which will be replaced by their values. Currently supported are {{cluster}}, {{guestname}}, {{node}}, and {{vmid}}, but more might be added in the future. Needs to be a single line, newline and backslash need to be escaped as '\\n' and '\\\\' respectively.","enum":[],"extra":{"requires":"storage"},"max_length":1024,"optional":true,"properties":{},"type":"string"},"notification-mode":{"default":"auto","description":"Determine which notification system to use. If set to 'legacy-sendmail', vzdump will consider the mailto/mailnotification parameters and send emails to the specified address(es) via the 'sendmail' command. If set to 'notification-system', a notification will be sent via PVE's notification system, and the mailto and mailnotification will be ignored. If set to 'auto' (default setting), an email will be sent if mailto is set, and the notification system will be used if not.","enum":["auto","legacy-sendmail","notification-system"],"extra":{},"optional":true,"properties":{},"type":"string"},"notification-policy":{"default":"always","description":"Deprecated: Do not use","enum":["always","failure","never"],"extra":{},"optional":true,"properties":{},"type":"string"},"notification-target":{"description":"Deprecated: Do not use","enum":[],"extra":{},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"pbs-change-detection-mode":{"description":"PBS mode used to detect file changes and switch encoding format for container backups.","enum":["legacy","data","metadata"],"extra":{},"optional":true,"properties":{},"type":"string"},"performance":{"description":"Other performance-related settings.","enum":[],"extra":{},"format":"backup-performance","optional":true,"properties":{},"type":"string"},"pigz":{"default":0,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"},"pool":{"description":"Backup all known guest systems included in the specified pool.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"protected":{"description":"If true, mark backup(s) as protected.","enum":[],"extra":{"requires":"storage"},"optional":true,"properties":{},"type":"boolean"},"prune-backups":{"default":"keep-all=1","description":"Use these retention options instead of those from the storage configuration.","enum":[],"extra":{},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"quiet":{"default":0,"description":"Be quiet.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"remove":{"default":1,"description":"Prune older backups according to 'prune-backups'.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"script":{"description":"Use specified hook script.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"stdexcludes":{"default":1,"description":"Exclude temporary files and logs.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"stop":{"default":0,"description":"Stop running backup jobs on this host.","enum":[],"extra":{},"optional":true,"properties":{},"type":"boolean"},"stopwait":{"default":10,"description":"Maximal time to wait until a guest system is stopped (minutes).","enum":[],"extra":{},"minimum":0,"optional":true,"properties":{},"type":"integer"},"storage":{"description":"Store resulting file to this storage.","enum":[],"extra":{"format_description":"storage ID"},"format":"pve-storage-id","optional":true,"properties":{},"type":"string"},"tmpdir":{"description":"Store temporary files to specified directory.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"vmid":{"description":"The ID of the guest system you want to backup.","enum":[],"extra":{},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"zstd":{"default":1,"description":"Zstd threads. N=0 uses half of the available cores, if N is set to a value bigger than 0, N is used as thread count.","enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"verb":"GET"}],"path":"/nodes/{node}/vzdump/defaults"},{"extra":{},"methods":[{"allow_token":true,"checksum":"46b5389418506fa5f7d2d85017d6a32be6b0374dbb76191ec24067f39e16e8d9","description":"Extract configuration from vzdump backup archive.","extra":{"proxyto":"node"},"name":"extractconfig","parameters":[{"definition":{"description":"The cluster node name.","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"},{"definition":{"description":"Volume identifier","enum":[],"extra":{"typetext":""},"properties":{},"type":"string"},"name":"volume"}],"permissions":{"description":"The user needs 'VM.Backup' permissions on the backed up guest ID, and 'Datastore.AllocateSpace' on the backup storage.","expression":{},"extra":{},"user":"all"},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"string"},"verb":"GET"}],"path":"/nodes/{node}/vzdump/extractconfig"},{"extra":{},"methods":[{"allow_token":true,"checksum":"08ea4b11d331163e4a96a0c898ba2d8587d9560fda14d97304383f4248499e0e","description":"Try to wake a node via 'wake on LAN' network packet.","extra":{},"name":"wakeonlan","parameters":[{"definition":{"description":"target node for wake on LAN packet","enum":[],"extra":{"typetext":""},"format":"pve-node","properties":{},"type":"string"},"name":"node"}],"permissions":{"expression":{"check":["perm","/nodes/{node}",["Sys.PowerMgmt"]]},"extra":{}},"protected":true,"returns":{"description":"MAC address used to assemble the WoL magic packet.","enum":[],"extra":{},"format":"mac-addr","properties":{},"type":"string"},"verb":"POST"}],"path":"/nodes/{node}/wakeonlan"},{"extra":{},"methods":[{"allow_token":true,"checksum":"f4566d45dc0a2a49009509edfd1756bd72eabd7f60446d1184660ea5bc43c1f7","description":"Delete pool.","extra":{},"name":"delete_pool","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"}],"permissions":{"description":"You can only delete empty pools (no members).","expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"33205b793af733e2b704df3fd61c56dee43038332e936764e59c0f5fb185823a","description":"List pools or get pool configuration.","extra":{},"name":"index","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","optional":true,"properties":{},"type":"string"},"name":"poolid"},{"definition":{"enum":["qemu","lxc","storage"],"extra":{"requires":"poolid"},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"List all pools where you have Pool.Audit permissions on /pool/, or the pool specific with {poolid}","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{poolid}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"members":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"node":{"enum":[],"extra":{},"properties":{},"type":"string"},"storage":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":["qemu","lxc","openvz","storage"],"extra":{},"properties":{},"type":"string"},"vmid":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"optional":true,"properties":{},"type":"array"},"poolid":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"a2cb3cd45802791e51049833b8254ee8828f1f7e701c0fad2bf797ed4c4ed346","description":"Create new pool.","extra":{},"name":"create_pool","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"}],"permissions":{"expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"POST"},{"allow_token":true,"checksum":"c211aff3cf1cda7aa8ffb37e56d69ef36e3cc19bda75c341fd6b6d9fd565ae5c","description":"Update pool.","extra":{},"name":"update_pool","parameters":[{"definition":{"default":0,"description":"Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"allow-move"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":0,"description":"Remove the passed VMIDs and/or storage IDs instead of adding them.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"},{"definition":{"description":"List of storage IDs to add or remove from this pool.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id-list","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"List of guest VMIDs to add or remove from this pool.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"}],"permissions":{"description":"You also need the right to modify permissions on any object you add/delete.","expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/pools"},{"extra":{},"methods":[{"allow_token":true,"checksum":"b7038e5f294f100d28cfdc7123623f8b4d5f7c2151133c6b9708146818711cd0","description":"Delete pool (deprecated, no support for nested pools, use 'DELETE /pools/?poolid={poolid}').","extra":{},"name":"delete_pool_deprecated","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"}],"permissions":{"description":"You can only delete empty pools (no members).","expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"961b5c048f0d5f962830bb4c34b9f06b519c08ea28f8f115d23bd8e5c497ffdc","description":"Get pool configuration (deprecated, no support for nested pools, use 'GET /pools/?poolid={poolid}').","extra":{},"name":"read_pool","parameters":[{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"},{"definition":{"enum":["qemu","lxc","storage"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"expression":{"check":["perm","/pool/{poolid}",["Pool.Audit"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{"additionalProperties":0},"properties":{"comment":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"members":{"enum":[],"extra":{},"items":{"enum":[],"extra":{"additionalProperties":1},"properties":{"id":{"enum":[],"extra":{},"properties":{},"type":"string"},"node":{"enum":[],"extra":{},"properties":{},"type":"string"},"storage":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"string"},"type":{"enum":["qemu","lxc","openvz","storage"],"extra":{},"properties":{},"type":"string"},"vmid":{"enum":[],"extra":{},"optional":true,"properties":{},"type":"integer"}},"type":"object"},"properties":{},"type":"array"}},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"adf5ed4e8c004cb01739cd4841194fc9f1f84bd0a1dfde041a0618373ea1cb31","description":"Update pool data (deprecated, no support for nested pools - use 'PUT /pools/?poolid={poolid}' instead).","extra":{},"name":"update_pool_deprecated","parameters":[{"definition":{"default":0,"description":"Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"allow-move"},{"definition":{"enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comment"},{"definition":{"default":0,"description":"Remove the passed VMIDs and/or storage IDs instead of adding them.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"delete"},{"definition":{"enum":[],"extra":{"typetext":""},"format":"pve-poolid","properties":{},"type":"string"},"name":"poolid"},{"definition":{"description":"List of storage IDs to add or remove from this pool.","enum":[],"extra":{"typetext":""},"format":"pve-storage-id-list","optional":true,"properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"List of guest VMIDs to add or remove from this pool.","enum":[],"extra":{"typetext":""},"format":"pve-vmid-list","optional":true,"properties":{},"type":"string"},"name":"vms"}],"permissions":{"description":"You also need the right to modify permissions on any object you add/delete.","expression":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"PUT"}],"path":"/pools/{poolid}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"76106a4576ad3fad1d601091a1a529780fe3a6c331c0dad10ddf19ea698c7872","description":"Storage index.","extra":{},"name":"index","parameters":[{"definition":{"description":"Only list storage of specific type","enum":["btrfs","cephfs","cifs","dir","esxi","glusterfs","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"type"}],"permissions":{"description":"Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'","expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{"links":[{"href":"{storage}","rel":"child"}]},"items":{"enum":[],"extra":{},"properties":{"storage":{"enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"properties":{},"type":"array"},"verb":"GET"},{"allow_token":true,"checksum":"1fbd824c3f35667d3e65aa1ea4bd89a4595439e9876b71726cfa92117433a5c2","description":"Create a new storage.","extra":{},"name":"create","parameters":[{"definition":{"description":"Authsupported.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"authsupported"},{"definition":{"description":"Base volume. This volume is automatically activated.","enum":[],"extra":{"typetext":""},"format":"pve-volume-id","optional":true,"properties":{},"type":"string"},"name":"base"},{"definition":{"description":"block size","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"blocksize"},{"definition":{"description":"Set I/O bandwidth limit for various operations (in KiB/s).","enum":[],"extra":{"typetext":"[clone=] [,default=] [,migration=] [,move=] [,restore=]"},"format":{"clone":{"description":"bandwidth limit in KiB/s for cloning disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"default":{"description":"default bandwidth limit in KiB/s","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"migration":{"description":"bandwidth limit in KiB/s for migrating guests (including moving local disks)","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"move":{"description":"bandwidth limit in KiB/s for moving disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"restore":{"description":"bandwidth limit in KiB/s for restoring guests from backups","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"}},"optional":true,"properties":{},"type":"string"},"name":"bwlimit"},{"definition":{"description":"host group for comstar views","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comstar_hg"},{"definition":{"description":"target group for comstar views","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comstar_tg"},{"definition":{"description":"Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n","enum":[],"extra":{"typetext":""},"format":"pve-storage-content-list","optional":true,"properties":{},"type":"string"},"name":"content"},{"definition":{"description":"Overrides for default content type directories.","enum":[],"extra":{"typetext":""},"format":"pve-dir-override-list","optional":true,"properties":{},"type":"string"},"name":"content-dirs"},{"definition":{"default":"yes","description":"Create the base directory if it doesn't exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"create-base-path"},{"definition":{"default":"yes","description":"Populate the directory with the default structure.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"create-subdirs"},{"definition":{"description":"Data Pool (for erasure coding only)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"data-pool"},{"definition":{"description":"Proxmox Backup Server datastore name.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"datastore"},{"definition":{"description":"Flag to disable the storage.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"CIFS domain.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"Encryption key. Use 'autogen' to generate one automatically without passphrase.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"encryption-key"},{"definition":{"description":"NFS export path.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"export"},{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"Default image format.","enum":["raw","qcow2","subvol","vmdk"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"The Ceph filesystem name.","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"fs-name"},{"definition":{"description":"Mount CephFS through FUSE.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"fuse"},{"definition":{"default":"no","description":"Assume the given path is an externally managed mountpoint and consider the storage offline if it is not mounted. Using a boolean (yes/no) value serves as a shortcut to using the target path in this field.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"is_mountpoint"},{"definition":{"description":"iscsi provider","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"iscsiprovider"},{"definition":{"description":"Client keyring contents (for external clusters).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"keyring"},{"definition":{"default":0,"description":"Always access rbd through krbd kernel module.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"krbd"},{"definition":{"description":"target portal group for Linux LIO targets","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lio_tpg"},{"definition":{"description":"Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"master-pubkey"},{"definition":{"default":"Unlimited for users with Datastore.Allocate privilege, 5 for other users","description":"Maximal number of protected backups per guest. Use '-1' for unlimited.","enum":[],"extra":{"typetext":" (-1 - N)"},"minimum":-1,"optional":true,"properties":{},"type":"integer"},"name":"max-protected-backups"},{"definition":{"description":"Deprecated: use 'prune-backups' instead. Maximal number of backup files per VM. Use '0' for unlimited.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"maxfiles"},{"definition":{"default":"yes","description":"Create the directory if it doesn't exist and populate it with default sub-dirs. NOTE: Deprecated, use the 'create-base-path' and 'create-subdirs' options instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"mkdir"},{"definition":{"description":"IP addresses of monitors (for external clusters).","enum":[],"extra":{"typetext":""},"format":"pve-storage-portal-dns-list","optional":true,"properties":{},"type":"string"},"name":"monhost"},{"definition":{"description":"mount point","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"mountpoint"},{"definition":{"description":"Namespace.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"namespace"},{"definition":{"default":0,"description":"Set the NOCOW flag on files. Disables data checksumming and causes data errors to be unrecoverable from while allowing direct I/O. Only use this if data does not need to be any more safe than on a single ext4 formatted disk with no underlying raid system.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nocow"},{"definition":{"description":"List of nodes for which the storage configuration applies.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"disable write caching on the target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nowritecache"},{"definition":{"description":"NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')","enum":[],"extra":{"typetext":""},"format":"pve-storage-options","optional":true,"properties":{},"type":"string"},"name":"options"},{"definition":{"description":"Password for accessing the share/datastore.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"File system path.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"path"},{"definition":{"description":"Pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"Use this port to connect to the storage instead of the default one (for example, with PBS or ESXi). For NFS and CIFS, use the 'options' option to configure the port via the mount options.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"description":"iSCSI portal (IP or DNS name with optional port).","enum":[],"extra":{"typetext":""},"format":"pve-storage-portal-dns","optional":true,"properties":{},"type":"string"},"name":"portal"},{"definition":{"default":"metadata","description":"Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off.","enum":["off","metadata","falloc","full"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"preallocation"},{"definition":{"description":"The retention options with shorter intervals are processed first with --keep-last being the very first one. Each option covers a specific period of time. We say that backups within this period are covered by this option. The next option does not take care of already covered backups and only considers older backups.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"description":"Zero-out data when removing LVs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"saferemove"},{"definition":{"description":"Wipe throughput (cstream -t parameter value).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"saferemove_throughput"},{"definition":{"description":"Server IP or DNS name.","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","optional":true,"properties":{},"type":"string"},"name":"server"},{"definition":{"description":"Backup volfile server IP or DNS name.","enum":[],"extra":{"requires":"server","typetext":""},"format":"pve-storage-server","optional":true,"properties":{},"type":"string"},"name":"server2"},{"definition":{"description":"CIFS share.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"share"},{"definition":{"description":"Indicate that this is a single storage with the same contents on all nodes (or all listed in the 'nodes' option). It will not make the contents of a local storage automatically accessible to other nodes, it just marks an already shared storage as such!","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"shared"},{"definition":{"default":"false","description":"Disable TLS certificate verification, only enable on fully trusted networks!","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skip-cert-verification"},{"definition":{"default":"default","description":"SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server.","enum":["default","2.0","2.1","3","3.0","3.11"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"smbversion"},{"definition":{"description":"use sparse volumes","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"sparse"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Subdir to mount.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"subdir"},{"definition":{"description":"Only use logical volumes tagged with 'pve-vm-ID'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tagged_only"},{"definition":{"description":"iSCSI target.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"target"},{"definition":{"description":"LVM thin pool LV name.","enum":[],"extra":{"typetext":""},"format":"pve-storage-vgname","optional":true,"properties":{},"type":"string"},"name":"thinpool"},{"definition":{"description":"Gluster transport: tcp or rdma","enum":["tcp","rdma","unix"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"transport"},{"definition":{"description":"Storage type.","enum":["btrfs","cephfs","cifs","dir","esxi","glusterfs","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"properties":{},"type":"string"},"name":"type"},{"definition":{"description":"RBD Id.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username"},{"definition":{"description":"Volume group name.","enum":[],"extra":{"typetext":""},"format":"pve-storage-vgname","optional":true,"properties":{},"type":"string"},"name":"vgname"},{"definition":{"description":"Glusterfs Volume.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"volume"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"config":{"description":"Partial, possible server generated, configuration properties.","enum":[],"extra":{"additionalProperties":1},"optional":true,"properties":{"encryption-key":{"description":"The, possible auto-generated, encryption-key.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"storage":{"description":"The ID of the created storage.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The type of the created storage.","enum":["btrfs","cephfs","cifs","dir","esxi","glusterfs","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"POST"}],"path":"/storage"},{"extra":{},"methods":[{"allow_token":true,"checksum":"37429346228be0afd5c6d7e7489e2958f25d9fdf19dee4f3c724b44696c84565","description":"Delete storage configuration.","extra":{},"name":"delete","parameters":[{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{},"type":"null"},"verb":"DELETE"},{"allow_token":true,"checksum":"19316a49fd07ddbf0d58da4bf761b3bad2f3e4a5b88f990919a04589241ca0b1","description":"Read storage configuration.","extra":{},"name":"read","parameters":[{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"}],"permissions":{"expression":{"check":["perm","/storage/{storage}",["Datastore.Allocate"]]},"extra":{}},"protected":false,"returns":{"enum":[],"extra":{},"properties":{},"type":"object"},"verb":"GET"},{"allow_token":true,"checksum":"05ba30356b49b25654f302f8fa5557bb60bafad565d8d9cf48da3bb61cce331b","description":"Update storage configuration.","extra":{},"name":"update","parameters":[{"definition":{"description":"block size","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"blocksize"},{"definition":{"description":"Set I/O bandwidth limit for various operations (in KiB/s).","enum":[],"extra":{"typetext":"[clone=] [,default=] [,migration=] [,move=] [,restore=]"},"format":{"clone":{"description":"bandwidth limit in KiB/s for cloning disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"default":{"description":"default bandwidth limit in KiB/s","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"migration":{"description":"bandwidth limit in KiB/s for migrating guests (including moving local disks)","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"move":{"description":"bandwidth limit in KiB/s for moving disks","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"},"restore":{"description":"bandwidth limit in KiB/s for restoring guests from backups","format_description":"LIMIT","minimum":"0","optional":1,"type":"number"}},"optional":true,"properties":{},"type":"string"},"name":"bwlimit"},{"definition":{"description":"host group for comstar views","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comstar_hg"},{"definition":{"description":"target group for comstar views","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"comstar_tg"},{"definition":{"description":"Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\n","enum":[],"extra":{"typetext":""},"format":"pve-storage-content-list","optional":true,"properties":{},"type":"string"},"name":"content"},{"definition":{"description":"Overrides for default content type directories.","enum":[],"extra":{"typetext":""},"format":"pve-dir-override-list","optional":true,"properties":{},"type":"string"},"name":"content-dirs"},{"definition":{"default":"yes","description":"Create the base directory if it doesn't exist.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"create-base-path"},{"definition":{"default":"yes","description":"Populate the directory with the default structure.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"create-subdirs"},{"definition":{"description":"Data Pool (for erasure coding only)","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"data-pool"},{"definition":{"description":"A list of settings you want to delete.","enum":[],"extra":{"typetext":""},"format":"pve-configid-list","max_length":4096,"optional":true,"properties":{},"type":"string"},"name":"delete"},{"definition":{"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.","enum":[],"extra":{"typetext":""},"max_length":64,"optional":true,"properties":{},"type":"string"},"name":"digest"},{"definition":{"description":"Flag to disable the storage.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"disable"},{"definition":{"description":"CIFS domain.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"domain"},{"definition":{"description":"Encryption key. Use 'autogen' to generate one automatically without passphrase.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"encryption-key"},{"definition":{"description":"Certificate SHA 256 fingerprint.","enum":[],"extra":{},"optional":true,"pattern":"([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}","properties":{},"type":"string"},"name":"fingerprint"},{"definition":{"description":"Default image format.","enum":["raw","qcow2","subvol","vmdk"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"format"},{"definition":{"description":"The Ceph filesystem name.","enum":[],"extra":{"typetext":""},"format":"pve-configid","optional":true,"properties":{},"type":"string"},"name":"fs-name"},{"definition":{"description":"Mount CephFS through FUSE.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"fuse"},{"definition":{"default":"no","description":"Assume the given path is an externally managed mountpoint and consider the storage offline if it is not mounted. Using a boolean (yes/no) value serves as a shortcut to using the target path in this field.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"is_mountpoint"},{"definition":{"description":"Client keyring contents (for external clusters).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"keyring"},{"definition":{"default":0,"description":"Always access rbd through krbd kernel module.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"krbd"},{"definition":{"description":"target portal group for Linux LIO targets","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"lio_tpg"},{"definition":{"description":"Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"master-pubkey"},{"definition":{"default":"Unlimited for users with Datastore.Allocate privilege, 5 for other users","description":"Maximal number of protected backups per guest. Use '-1' for unlimited.","enum":[],"extra":{"typetext":" (-1 - N)"},"minimum":-1,"optional":true,"properties":{},"type":"integer"},"name":"max-protected-backups"},{"definition":{"description":"Deprecated: use 'prune-backups' instead. Maximal number of backup files per VM. Use '0' for unlimited.","enum":[],"extra":{"typetext":" (0 - N)"},"minimum":0,"optional":true,"properties":{},"type":"integer"},"name":"maxfiles"},{"definition":{"default":"yes","description":"Create the directory if it doesn't exist and populate it with default sub-dirs. NOTE: Deprecated, use the 'create-base-path' and 'create-subdirs' options instead.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"mkdir"},{"definition":{"description":"IP addresses of monitors (for external clusters).","enum":[],"extra":{"typetext":""},"format":"pve-storage-portal-dns-list","optional":true,"properties":{},"type":"string"},"name":"monhost"},{"definition":{"description":"mount point","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"mountpoint"},{"definition":{"description":"Namespace.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"namespace"},{"definition":{"default":0,"description":"Set the NOCOW flag on files. Disables data checksumming and causes data errors to be unrecoverable from while allowing direct I/O. Only use this if data does not need to be any more safe than on a single ext4 formatted disk with no underlying raid system.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nocow"},{"definition":{"description":"List of nodes for which the storage configuration applies.","enum":[],"extra":{"typetext":""},"format":"pve-node-list","optional":true,"properties":{},"type":"string"},"name":"nodes"},{"definition":{"description":"disable write caching on the target","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"nowritecache"},{"definition":{"description":"NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')","enum":[],"extra":{"typetext":""},"format":"pve-storage-options","optional":true,"properties":{},"type":"string"},"name":"options"},{"definition":{"description":"Password for accessing the share/datastore.","enum":[],"extra":{"typetext":""},"max_length":256,"optional":true,"properties":{},"type":"string"},"name":"password"},{"definition":{"description":"Pool.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"pool"},{"definition":{"description":"Use this port to connect to the storage instead of the default one (for example, with PBS or ESXi). For NFS and CIFS, use the 'options' option to configure the port via the mount options.","enum":[],"extra":{"typetext":" (1 - 65535)"},"maximum":65535,"minimum":1,"optional":true,"properties":{},"type":"integer"},"name":"port"},{"definition":{"default":"metadata","description":"Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off.","enum":["off","metadata","falloc","full"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"preallocation"},{"definition":{"description":"The retention options with shorter intervals are processed first with --keep-last being the very first one. Each option covers a specific period of time. We say that backups within this period are covered by this option. The next option does not take care of already covered backups and only considers older backups.","enum":[],"extra":{"typetext":"[keep-all=<1|0>] [,keep-daily=] [,keep-hourly=] [,keep-last=] [,keep-monthly=] [,keep-weekly=] [,keep-yearly=]"},"format":"prune-backups","optional":true,"properties":{},"type":"string"},"name":"prune-backups"},{"definition":{"description":"Zero-out data when removing LVs.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"saferemove"},{"definition":{"description":"Wipe throughput (cstream -t parameter value).","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"saferemove_throughput"},{"definition":{"description":"Server IP or DNS name.","enum":[],"extra":{"typetext":""},"format":"pve-storage-server","optional":true,"properties":{},"type":"string"},"name":"server"},{"definition":{"description":"Backup volfile server IP or DNS name.","enum":[],"extra":{"requires":"server","typetext":""},"format":"pve-storage-server","optional":true,"properties":{},"type":"string"},"name":"server2"},{"definition":{"description":"Indicate that this is a single storage with the same contents on all nodes (or all listed in the 'nodes' option). It will not make the contents of a local storage automatically accessible to other nodes, it just marks an already shared storage as such!","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"shared"},{"definition":{"default":"false","description":"Disable TLS certificate verification, only enable on fully trusted networks!","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"skip-cert-verification"},{"definition":{"default":"default","description":"SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server.","enum":["default","2.0","2.1","3","3.0","3.11"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"smbversion"},{"definition":{"description":"use sparse volumes","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"sparse"},{"definition":{"description":"The storage identifier.","enum":[],"extra":{"format_description":"storage ID","typetext":""},"format":"pve-storage-id","properties":{},"type":"string"},"name":"storage"},{"definition":{"description":"Subdir to mount.","enum":[],"extra":{"typetext":""},"format":"pve-storage-path","optional":true,"properties":{},"type":"string"},"name":"subdir"},{"definition":{"description":"Only use logical volumes tagged with 'pve-vm-ID'.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"boolean"},"name":"tagged_only"},{"definition":{"description":"Gluster transport: tcp or rdma","enum":["tcp","rdma","unix"],"extra":{},"optional":true,"properties":{},"type":"string"},"name":"transport"},{"definition":{"description":"RBD Id.","enum":[],"extra":{"typetext":""},"optional":true,"properties":{},"type":"string"},"name":"username"}],"permissions":{"expression":{"check":["perm","/storage",["Datastore.Allocate"]]},"extra":{}},"protected":true,"returns":{"enum":[],"extra":{},"properties":{"config":{"description":"Partial, possible server generated, configuration properties.","enum":[],"extra":{"additionalProperties":1},"optional":true,"properties":{"encryption-key":{"description":"The, possible auto-generated, encryption-key.","enum":[],"extra":{},"optional":true,"properties":{},"type":"string"}},"type":"object"},"storage":{"description":"The ID of the created storage.","enum":[],"extra":{},"properties":{},"type":"string"},"type":{"description":"The type of the created storage.","enum":["btrfs","cephfs","cifs","dir","esxi","glusterfs","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"PUT"}],"path":"/storage/{storage}"},{"extra":{},"methods":[{"allow_token":true,"checksum":"45540f92dcd5801a88dc510d274bd94436e995188f217cf527e705b6b92320f8","description":"API version details, including some parts of the global datacenter config.","extra":{},"name":"version","parameters":[],"permissions":{"expression":{},"extra":{},"user":"all"},"protected":false,"returns":{"enum":[],"extra":{},"properties":{"console":{"description":"The default console viewer to use.","enum":["applet","vv","html5","xtermjs"],"extra":{},"optional":true,"properties":{},"type":"string"},"release":{"description":"The current Proxmox VE point release in `x.y` format.","enum":[],"extra":{},"properties":{},"type":"string"},"repoid":{"description":"The short git revision from which this version was build.","enum":[],"extra":{},"pattern":"[0-9a-fA-F]{8,64}","properties":{},"type":"string"},"version":{"description":"The full pve-manager package version of this node.","enum":[],"extra":{},"properties":{},"type":"string"}},"type":"object"},"verb":"GET"}],"path":"/version"}],"raw_sha256":"bbe03a42c55b3f9ae77a5b5216c1a8554f4fffd0f4b266848f4af26be295946e","retrieved_at":"2026-07-15T10:49:34.692186Z","source_version":"8.4.5"} \ No newline at end of file diff --git a/contracts/vsphere/7.0.0/manifest.json b/contracts/vsphere/7.0.0/manifest.json new file mode 100644 index 0000000..c418b25 --- /dev/null +++ b/contracts/vsphere/7.0.0/manifest.json @@ -0,0 +1,167 @@ +{ + "product": "vmware-api-simulator", + "plane": "vsphere-rest", + "major": 6, + "series": "vSphere 7.0", + "version": "7.0.0", + "kind": "stub-openapi-matrix", + "notes": "Stub contract derived from app/vsphere/rest/coverage.py + PATH_FLOOR. Not a Broadcom OpenAPI dump; used for catalog browse and hot-swap gating.", + "method_count": 31, + "methods": [ + { + "verb": "DELETE", + "path": "/api/session", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/rest/com/vmware/cis/session", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/appliance/system/version", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/session", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/cluster", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/datacenter", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/datastore", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/datastore/{datastore}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/folder", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/host", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/host/{host}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/network", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/resource-pool", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/identity", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/appliance/system/version", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/com/vmware/cis/session", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/cluster", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/datacenter", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/datastore", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/host", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/network", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/vm", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/vm/{vm}", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/session", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/power", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/rest/com/vmware/cis/session", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/rest/vcenter/vm/{vm}/power", + "status": "implemented" + } + ] +} diff --git a/contracts/vsphere/7.0.3/manifest.json b/contracts/vsphere/7.0.3/manifest.json new file mode 100644 index 0000000..e6e1517 --- /dev/null +++ b/contracts/vsphere/7.0.3/manifest.json @@ -0,0 +1,397 @@ +{ + "product": "vmware-api-simulator", + "plane": "vsphere-rest", + "major": 7, + "series": "vSphere 7.0 U3", + "version": "7.0.3", + "kind": "stub-openapi-matrix", + "notes": "Stub contract derived from app/vsphere/rest/coverage.py + PATH_FLOOR. Not a Broadcom OpenAPI dump; used for catalog browse and hot-swap gating.", + "method_count": 77, + "methods": [ + { + "verb": "DELETE", + "path": "/api/cis/tagging/category/{category_id}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/cis/tagging/tag/{tag_id}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/session", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/cluster/{cluster}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/datacenter/{datacenter}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/folder/{folder}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/resource-pool/{resource_pool}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/snapshots/{snapshot}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/rest/com/vmware/cis/session", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/appliance/system/version", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tagging/category", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tagging/category/{category_id}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tagging/tag", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tagging/tag/{tag_id}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tasks", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tasks/{task}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/session", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/cluster", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/datacenter", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/datastore", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/datastore/{datastore}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/datastore/{datastore}/files", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/folder", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/folder/{folder}/children", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/host", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/host/{host}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/network", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/resource-pool", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/identity", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/networking", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/power", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/boot", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/cpu", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/disk", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/ethernet", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/memory", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/snapshots", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/tools", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/appliance/system/version", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/com/vmware/cis/session", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/cluster", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/datacenter", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/datastore", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/host", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/network", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/vm", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/vm/{vm}", + "status": "implemented" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/cpu", + "status": "implemented" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/memory", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/cis/tagging/category", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/cis/tagging/tag", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/cis/tagging/tag-association", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/session", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/cluster", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/datacenter", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/datastore/{datastore}/files", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/folder", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/folder/{folder}", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/host/{host}/maintenance", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/resource-pool", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/clone", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/power", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/disk", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/ethernet", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/power", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/relocate", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/snapshots", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/snapshots/{snapshot}", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/tools", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/rest/com/vmware/cis/session", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/rest/vcenter/vm/{vm}/power", + "status": "implemented" + } + ] +} diff --git a/contracts/vsphere/8.0.0/manifest.json b/contracts/vsphere/8.0.0/manifest.json new file mode 100644 index 0000000..b9a1720 --- /dev/null +++ b/contracts/vsphere/8.0.0/manifest.json @@ -0,0 +1,527 @@ +{ + "product": "vmware-api-simulator", + "plane": "vsphere-rest", + "major": 8, + "series": "vSphere 8.0", + "version": "8.0.0", + "kind": "stub-openapi-matrix", + "notes": "Stub contract derived from app/vsphere/rest/coverage.py + PATH_FLOOR. Not a Broadcom OpenAPI dump; used for catalog browse and hot-swap gating.", + "method_count": 103, + "methods": [ + { + "verb": "DELETE", + "path": "/api/cis/tagging/category/{category_id}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/cis/tagging/tag/{tag_id}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/session", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/authorization/permissions/{permission_id}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/cluster/{cluster}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/datacenter/{datacenter}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/folder/{folder}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/resource-pool/{resource_pool}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/snapshots/{snapshot}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/rest/com/vmware/cis/session", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/appliance/health/system", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/appliance/networking", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/appliance/system/version", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/appliance/timesync", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tagging/category", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tagging/category/{category_id}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tagging/tag", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tagging/tag/{tag_id}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tasks", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tasks/{task}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/content/library", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/content/library/item", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/session", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/authentication/component", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/service", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/activity-history", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/authorization/permissions", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/authorization/roles", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/cluster", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/datacenter", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/datastore", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/datastore/{datastore}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/datastore/{datastore}/files", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/folder", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/folder/{folder}/children", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/host", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/host/{host}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/host/{host}/networking", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/host/{host}/storage/storage-device", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/identity/providers", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/network", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/network/dvs", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/privilege", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/resource-pool", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/storage/policies", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/storage/policies/{policy}/vm", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/identity", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/networking", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/power", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/boot", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/cpu", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/disk", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/ethernet", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/memory", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/snapshots", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/tools", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/appliance/system/version", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/com/vmware/cis/session", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/cluster", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/datacenter", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/datastore", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/host", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/network", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/vm", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/vm/{vm}", + "status": "implemented" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/cpu", + "status": "implemented" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/memory", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/cis/tagging/category", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/cis/tagging/tag", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/cis/tagging/tag-association", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/content/library/item", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/content/local-library", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/session", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/authorization/permissions", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/cluster", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/datacenter", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/datastore/{datastore}/files", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/folder", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/folder/{folder}", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/host/{host}/maintenance", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/network/dvpg", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/network/dvs", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/ovf/library-item/{item_id}", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/resource-pool", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/clone", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/console/tickets", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/customization", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/power", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/disk", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/ethernet", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/power", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/relocate", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/snapshots", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/snapshots/{snapshot}", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/tools", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/rest/com/vmware/cis/session", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/rest/vcenter/vm/{vm}/power", + "status": "implemented" + } + ] +} diff --git a/contracts/vsphere/8.0.2/manifest.json b/contracts/vsphere/8.0.2/manifest.json new file mode 100644 index 0000000..2ca5d3c --- /dev/null +++ b/contracts/vsphere/8.0.2/manifest.json @@ -0,0 +1,5397 @@ +{ + "product": "vmware-api-simulator", + "plane": "vsphere-rest", + "major": 9, + "series": "vSphere 8.0 U2", + "version": "8.0.2", + "kind": "stub-openapi-matrix", + "notes": "Stub contract derived from app/vsphere/rest/coverage.py + PATH_FLOOR. Not a Broadcom OpenAPI dump; used for catalog browse and hot-swap gating.", + "method_count": 1077, + "methods": [ + { + "verb": "DELETE", + "path": "/api/appliance/local-accounts", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/appliance/networking/proxy", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/appliance/recovery/backup/schedules", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/appliance/support-bundle", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/appliance/tls/manual-parameters/services/{service}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/appliance/update/staged", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/cis/tagging/category/{category_id}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/cis/tagging/tag/{tag_id}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/content/library/{library_id}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/library/{library_id}/item/{item_id}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/library/{library_id}/item/{item_id}/download-session/{download_session_id}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/library/{library_id}/item/{item_id}/update-session/{update_session_id}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/library/{library_id}/item/{item_id}/updatesession/file", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/library/{library_id}/subscriptions/{subscription_id}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/library/{library_id}/usages/{usage_id}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/local-library/{library_id}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/subscribed-library/{library_id}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/content/trusted-certificates", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/configuration/drafts/{draft}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/add-on", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/add-on", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/components/{component}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/hardware-support", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/removed-components", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/components/{component}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/hardware-support", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/removed-components", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/software/solutions", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/clusters/{cluster}/vms/solutions", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/depots/{depot}/offline", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/depots/{depot}/online", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/depots/{depot}/umds", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/add-on", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/components/{component}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/removed-components", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/hosts/{host}/software/solutions", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/add-on", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/add-on", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/components/{component}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/hardware-support", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/removed-components", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/components/{component}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/hardware-support", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/esx/settings/repository/software/drafts/{draft}/removed-components", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/session", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/authorization/permissions/{permission_id}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/authorization/roles/{role}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/authorization/vt-containers/mappings", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/certificate-management/vcenter/trusted-root-chains/{chain}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/cluster/{cluster}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/compute/policies/{policy}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/consumption-domains/zones/{zone}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/content/registries/harbor", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/content/registries/harbor/projects/{project}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/crypto-manager/kms/providers/{provider}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/datacenter/{datacenter}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/folder/{folder}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/guest/customization-specs", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/host/{host}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/identity/providers/{provider}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/lcm/discovery/associated-products", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/infrastructure-policies", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/networks/{network}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisor-services", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisor-services/cluster-supervisor-services", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisor-services/versions/{version}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisors", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/container-image-registries", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/providers/{provider}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/management-services", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/metrics/remote-endpoints", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/networks/{network}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/supervisor-services", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/zones/{zone}/bindings", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespace-management/virtual-machine-classes", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespaces/{namespace}/access", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespaces/{namespace}/instances", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespaces/{namespace}/instances/zones", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/namespaces/{namespace}/management-services/access-grants", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/phm/hardware-support-managers", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/resource-pool/{resource_pool}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/attestation/services/{service}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/kms/services/{service}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/os/esx/base-images", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/tpm2/ca-certificates", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/tpm2/endorsement-keys", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/consumer-principals", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/attestation/services-applied-config", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/attestation/services/{service}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/kms/services-applied-config", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/kms/services/{service}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/services-applied-config", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm-template/library-items/{item_id}/check-outs/{vm}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm-template/library-items/{item_id}/versions/{version}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/data-sets", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/data-sets/entries", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/nvme/{adapter}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/sata/{adapter}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/scsi/{adapter}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/cdrom/{cdrom}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/disk/{disk}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/ethernet/{nic}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/floppy/{floppy}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/parallel/{port}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/hardware/serial/{port}", + "status": "stub" + }, + { + "verb": "DELETE", + "path": "/api/vcenter/vm/{vm}/snapshots/{snapshot}", + "status": "implemented" + }, + { + "verb": "DELETE", + "path": "/rest/com/vmware/cis/session", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/appliance/access/consolecli", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/access/dcui", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/access/shell", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/access/ssh", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/cores", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health-check-settings", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/applmgmt", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/database", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/databasestorage", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/load", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/mem", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/softwarepackages", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/storage", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/swap", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/health/system", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/appliance/infraprofile/configs", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/local-accounts", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/local-accounts/policy", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/logging/forwarding", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/logging/liagent/log-collection", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/monitoring", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/dns/domains", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/dns/hostname", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/dns/servers", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/firewall/inbound", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/interfaces", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/interfaces/{interface}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/interfaces/{interface}/ipv4", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/interfaces/{interface}/ipv6", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/no-proxy", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/networking/proxy", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/ntp", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/recovery", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/recovery/backup/job", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/recovery/backup/job/details", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/recovery/backup/parts", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/recovery/backup/schedules", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/recovery/reconciliation/job", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/recovery/restore/job", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/services", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/services/{service}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/shutdown", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/support-bundle", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/support-bundle/components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/system/crypto-hash", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/system/crypto-hash/options", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/system/security/global-fips", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/system/storage", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/system/time", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/system/time/timezone", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/system/uptime", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/system/version", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/appliance/timesync", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/appliance/tls/manual-parameters/global", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/tls/manual-parameters/services", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/tls/manual-parameters/services/{service}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/tls/profiles", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/tls/profiles/{profile}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/tls/profiles/{profile}/global", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/update", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/update/pending", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/update/policy", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/appliance/update/staged", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/cis/tagging/category", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tagging/category/{category_id}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tagging/tag", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tagging/tag/{tag_id}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tasks", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/cis/tasks/{task}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/content/configuration", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/content/library/item", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/changes", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/download-session", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/download-session/{download_session_id}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/downloadsession/file", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/file", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/storage", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/update-session", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/update-session/{update_session_id}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/item/{item_id}/updatesession/file", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/subscriptions", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/subscriptions/{subscription_id}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/usages", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/library/{library_id}/usages/{usage_id}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/local-library", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/local-library/{library_id}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/security-policies", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/subscribed-library", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/subscribed-library/{library_id}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/trusted-certificates", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/content/type", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/hcl/compatibility-data", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/hcl/hosts/{host}/compatibility-releases", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/hcl/hosts/{host}/compatibility-report", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/hcl/reports", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/hosts/{host}/software", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/hosts/{host}/software/installed-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration/audit-records", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration/drafts", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration/drafts/{draft}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration/reports/last-apply-result", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration/reports/last-compliance-result", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration/reports/last-precheck-result", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration/reports/recent-tasks", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/configuration/schema", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/depot-overrides", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/enablement/configuration", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/enablement/configuration/transition", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/enablement/software", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/installed-images", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/policies/{policy}/apply", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/policies/{policy}/apply/effective", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/add-on", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/display-name", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/selection-criteria", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software/add-on", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software/base-image", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software/components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software/components/{component}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software/effective-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software/hardware-support", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software/removed-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software/solutions", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/base-image", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/commits", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/compliance", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/components/{component}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/display-name", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/add-on", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/display-name", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/selection-criteria", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/add-on", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/base-image", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/components/{component}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/effective-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/hardware-support", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/removed-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/base-image", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/components/{component}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/effective-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/hardware-support", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/removed-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/effective-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/hardware-support", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/recommendations", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/removed-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/apply-impact", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/hardware-compatibility", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/hardware-compatibility/details", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/last-apply-result", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/last-check-result", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/software-spec-metadata", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/software/solutions", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/vms/lifecycle-hooks", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/clusters/{cluster}/vms/solutions", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/defaults/clusters/{cluster}/policies/{policy}/apply", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/defaults/clusters/{cluster}/policies/{policy}/apply/effective", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/defaults/hosts/{host}/policies/{policy}/apply", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/defaults/hosts/{host}/policies/{policy}/apply/effective", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depot-content/add-ons", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depot-content/add-ons/versions", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depot-content/base-images", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depot-content/base-images/versions", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depot-content/components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depot-content/components/{component}/versions", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depots/{depot}/offline", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depots/{depot}/offline/content", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depots/{depot}/online", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depots/{depot}/online/content", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depots/{depot}/sync-schedule", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depots/{depot}/umds", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/depots/{depot}/umds/content", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hardware-support/managers", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hardware-support/managers/packages", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hardware-support/managers/packages/versions", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/depot-overrides", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/enablement/software", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/policies/{policy}/apply", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/policies/{policy}/apply/effective", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/add-on", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/base-image", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/commits", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/compliance", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/components/{component}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/display-name", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/add-on", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/base-image", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/components/{component}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/effective-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/removed-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/effective-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/recommendations", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/removed-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/reports/apply-impact", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/reports/last-apply-result", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/reports/last-check-result", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/software-spec-metadata", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/hosts/{host}/software/solutions", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/inventory/reports/summary/clusters", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/inventory/reports/summary/hosts", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/inventory/reports/transition-summary/clusters", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/inventory/reports/transition-summary/hosts", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/alternative-images/effective-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/add-on", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/add-on", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/base-image", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/components/{component}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/display-name", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/effective-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/hardware-support", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/removed-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/selection-criteria", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/base-image", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/components/{component}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/display-name", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/effective-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/hardware-support", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/drafts/{draft}/removed-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/esx/settings/repository/software/effective-components", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/session", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/authentication/component", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/authentication/component/{component}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/authentication/package", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/authentication/service", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/authentication/service/{service}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/authentication/service/{service}/operation", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/cli/command", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/cli/namespace", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/component", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/component/{component}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/enumeration", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/package", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/resource", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/resource/model", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/service", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/service/{service}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/service/{service}/operation", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/metamodel/structure", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/privilege/component", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/privilege/component/{component}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/privilege/package", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/privilege/service", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/privilege/service/{service}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vapi/metadata/privilege/service/{service}/operation", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/activity-history", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/authorization/permissions", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/authorization/permissions/{permission_id}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/authorization/privilege-checks/latest", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/authorization/roles", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/authorization/roles/{role}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/authorization/vt-containers/mappings", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/capacity/usage", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/certificate-management/vcenter/signing-certificate", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/certificate-management/vcenter/tls", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/certificate-management/vcenter/trusted-root-chains", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/certificate-management/vcenter/trusted-root-chains/{chain}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/cluster", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/cluster/{cluster}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/cluster/{cluster}/evc-mode", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/compute/policies", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/compute/policies/{policy}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/compute/policies/{policy}/capabilities", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/compute/policies/{policy}/tag-usage", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/consumption-domains/zone-associations/cluster", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/consumption-domains/zones", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/consumption-domains/zones/{zone}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/consumption-domains/zones/{zone}/capacity/summary", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/consumption-domains/zones/{zone}/cluster/{cluster}/associations", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/content/registries/harbor", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/content/registries/harbor/projects", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/content/registries/harbor/projects/{project}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/content/registries/health", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/crypto-manager/hosts/{host}/kms/providers", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/crypto-manager/hosts/{host}/kms/providers/{provider}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/crypto-manager/kms/providers", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/crypto-manager/kms/providers/{provider}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/crypto/fips/modules", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/datacenter", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/datacenter/{datacenter}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/datastore", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/datastore/{datastore}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/datastore/{datastore}/default-policy", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/datastore/{datastore}/files", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment/import-history", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment/install", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment/install/initial-config/remote-psc/thumbprint", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment/migrate", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment/question", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment/size", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment/size/status", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/deployment/upgrade", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/environment-browser/config-option-descriptors", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/environment-browser/config-options", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/environment-browser/config-targets", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/folder", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/folder/{folder}/children", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/foundation-load-balancers", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/foundation-load-balancers/nodes", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/foundation-load-balancers/nodes/{node}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/guest/customization-specs", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/host", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/host/{host}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/host/{host}/crypto/fips/modules", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/host/{host}/entropy/external-pool", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/host/{host}/hardware/direct-path-devices", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/host/{host}/networking", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/host/{host}/storage/storage-device", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/identity/broker/tenants/admin-client", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/identity/broker/tenants/operator-client", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/identity/providers", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/identity/providers/{provider}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/inventory/datastore", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/inventory/network", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/deployment/migration-upgrade", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/deployment/migration-upgrade/planned-downtime", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/deployment/migration-upgrade/status", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/deployment/repository", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/depot/{depot}/services", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/discovery/associated-products", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/discovery/product-catalog", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/reports", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/lcm/update/pending", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/cluster-available-versions", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/cluster-compatibility", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/cluster-size-info", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/clusters", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/clusters/{cluster}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/clusters/{cluster}/topology", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/distributed-switch-compatibility", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/edge-cluster-compatibility", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/hosts-config", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/infrastructure-policies", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/lifecycle/content/libraries", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/lifecycle/content/libraries/{library_id}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/load-balancers", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/namespace-resource-options", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks/{network}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/distributed-switches", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/edges", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/projects", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/projects/{project}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/projects/{project}/vpc-connectivity-profiles", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/projects/{project}/vpcs", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/projects/{project}/vpcs/{vpc}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/nsx-tier0-gateway", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/software/clusters", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/software/clusters/{cluster}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/software/supervisors/{supervisor}/prechecks", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/software/supervisors/{supervisor}/upgrades", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/software/supervisors/{supervisor}/versions", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/software/supervisors/{supervisor}/versions/{version}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/software/supervisors/{supervisor}/versions/{version}/control-plane/sizes", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/stats/time-series", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisor-services", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisor-services/cluster-supervisor-services", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisor-services/versions", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisor-services/versions/{version}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/capabilities", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/certificates", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/certificates/key-sizes", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/conditions", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/container-image-registries", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/control-plane/networks/{network}/settings", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/control-plane/settings", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/control-plane/storage/policies", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/crypto/fips/modules", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/domains", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/domains/{domain}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/providers", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/providers/{provider}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/logs/agent-configuration", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/management-services", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/metrics/remote-endpoints", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/networks", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/networks/{network}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/networks/{network}/edges", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/recovery/backup/archives", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/storage/cloud-native/resource-checks", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/summary", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/supervisor-service-settings", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/supervisor-services", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/supervisor-services/signatures", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/topology", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/vsphere-pod-settings", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/images/{image}/settings", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/kube-api-server-settings", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/networks/{network}/settings", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/storage/cloud-native/file-volumes", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/storage/policies", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/zones/{zone}/bindings", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespace-management/virtual-machine-classes", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespaces/{namespace}/access", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespaces/{namespace}/instances", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespaces/{namespace}/management-services/access-grants", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespaces/{namespace}/mobility/virtualmachines/imports", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespaces/{namespace}/namespace-self-service", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespaces/{namespace}/namespace-templates", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespaces/{namespace}/networks/{network}/nsx/subnets", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/namespaces/{namespace}/user/instances", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/network", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/network/dvs", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/network/{network}/projects", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/network/{network}/projects/{project}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/network/{network}/projects/{project}/vpcs", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/network/{network}/projects/{project}/vpcs/{vpc}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/network/{network}/projects/{project}/vpcs/{vpc}/subnets", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/network/{network}/projects/{project}/vpcs/{vpc}/subnets/{subnet}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/ovf/export-flag", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/ovf/import-flag", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/phm/about", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/phm/hardware-support-managers", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/phm/hardware-support-managers/managed-hosts", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/phm/hardware-support-managers/resource-bundle", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/privilege", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/resource-pool", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/resource-pool/{resource_pool}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/services/{service}/service", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/storage/policies", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/storage/policies/{policy}/compliance", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/storage/policies/{policy}/compliance/vm", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/storage/policies/{policy}/vm", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/system-config/deployment-type", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/system-config/psc-registration", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/tagging/associations", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/tagging/categories", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/tagging/tags", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/topology/nodes", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/topology/nodes/{node}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/topology/replication-status", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/attestation/services/{service}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/hosts/{host}/hardware/tpm", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/hosts/{host}/hardware/tpm/endorsement-keys", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/hosts/{host}/hardware/tpm/event-log", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/kms/services/{service}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/principal", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/os/esx/base-images", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/service-status", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/tpm2/ca-certificates", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/tpm2/endorsement-keys", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/tpm2/settings", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/consumer-principals", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/client-certificate", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/client-certificate/csr", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/current-peer-certificates", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/trusted-peer-certificates", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/service-status", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-hosts/attestation", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-hosts/kms", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/attestation/services-applied-config", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/attestation/services/{service}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/kms/services-applied-config", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/kms/services/{service}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/services-applied-config", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/utilization/connections", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/utilization/proxies", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vcha/cluster/{cluster}/deployment-type", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vcha/cluster/{cluster}/mode", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vcha/operations", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm-template/library-items/{item_id}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm-template/library-items/{item_id}/check-outs", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm-template/library-items/{item_id}/check-outs/{vm}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm-template/library-items/{item_id}/versions", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm-template/library-items/{item_id}/versions/{version}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/compute/policies", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/data-sets", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/data-sets/entries", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/evc-mode", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/customization", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/customization-live", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/identity", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/local-filesystem", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/networking", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/networking/interfaces", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/networking/routes", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/operations", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/guest/power", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/nvme", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/nvme/{adapter}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/sata", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/sata/{adapter}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/scsi", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/scsi/{adapter}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/boot", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/boot/device", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/cdrom", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/cdrom/{cdrom}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/cpu", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/disk", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/disk/{disk}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/ethernet", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/ethernet/{nic}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/floppy", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/floppy/{floppy}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/memory", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/parallel", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/parallel/{port}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/serial", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/hardware/serial/{port}", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/library-item", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/power", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/snapshots", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/storage/policy", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/storage/policy/{policy}/compliance", + "status": "stub" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/tools", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/api/vcenter/vm/{vm}/tools/installer", + "status": "stub" + }, + { + "verb": "GET", + "path": "/rest/appliance/system/version", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/com/vmware/cis/session", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/cluster", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/datacenter", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/datastore", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/host", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/network", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/vm", + "status": "implemented" + }, + { + "verb": "GET", + "path": "/rest/vcenter/vm/{vm}", + "status": "implemented" + }, + { + "verb": "PATCH", + "path": "/api/appliance/health-check-settings", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/appliance/local-accounts", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/appliance/networking", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/appliance/recovery/backup/schedules", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/cis/tagging/category/{category_id}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/cis/tagging/tag/{tag_id}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/content/configuration", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/content/library/{library_id}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/content/library/{library_id}/item/{item_id}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/content/library/{library_id}/item/{item_id}/update-session/{update_session_id}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/content/library/{library_id}/subscriptions/{subscription_id}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/content/local-library/{library_id}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/content/subscribed-library/{library_id}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/components/{component}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/components/{component}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/hardware-compatibility/pci-device-overrides/vcg-entries", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/hardware-compatibility/storage-device-overrides/compliance-status", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/hardware-compatibility/storage-device-overrides/vcg-entries", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/clusters/{cluster}/software/solutions", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/depots/{depot}/online", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/depots/{depot}/umds", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/components/{component}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/repository/software", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/components/{component}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/esx/settings/repository/software/drafts/{draft}/components/{component}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/authorization/permissions/{permission_id}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/authorization/roles/{role}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/compute/policies/{policy}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/crypto-manager/kms/providers/{provider}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/deployment/size", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/identity/providers/{provider}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/lcm/discovery/associated-products", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/clusters/{cluster}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/load-balancers", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/networks/{network}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisor-services", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisor-services/versions", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/certificates", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/certificates/key-sizes", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/container-image-registries", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/control-plane/networks/{network}/settings", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/control-plane/settings", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/control-plane/storage/policies", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/providers/{provider}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/management-services", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/metrics/remote-endpoints", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/networks/{network}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/networks/{network}/edges", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/supervisor-service-settings", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/vsphere-pod-settings", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/images/{image}/settings", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/kube-api-server-settings", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/networks/{network}/settings", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/storage/cloud-native/file-volumes", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/workloads/storage/policies", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/zones/{zone}/bindings", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespace-management/virtual-machine-classes", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespaces/{namespace}/instances", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespaces/{namespace}/management-services/access-grants", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/namespaces/{namespace}/namespace-templates", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/phm/hardware-support-managers/managed-hosts", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/phm/hardware-support-managers/resource-bundle", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/resource-pool/{resource_pool}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/services/{service}/service", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/tagging/associations", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/tpm2/settings", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/client-certificate", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/trusted-peer-certificates", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/attestation/services-applied-config", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/kms/services-applied-config", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/services-applied-config", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/data-sets", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/scsi/{adapter}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/boot", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/cdrom/{cdrom}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/cpu", + "status": "implemented" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/disk/{disk}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/ethernet/{nic}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/floppy/{floppy}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/memory", + "status": "implemented" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/parallel/{port}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/hardware/serial/{port}", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/storage/policy", + "status": "stub" + }, + { + "verb": "PATCH", + "path": "/api/vcenter/vm/{vm}/tools", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/infraprofile/configs", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/local-accounts", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/logging/forwarding", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/networking", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/networking/dns/domains", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/networking/dns/hostname", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/networking/dns/servers", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/networking/proxy", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/ntp", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/recovery/backup", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/recovery/backup/job", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/recovery/backup/schedules", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/recovery/backup/system-name", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/recovery/backup/system-name/archive", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/recovery/reconciliation/job", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/recovery/restore", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/recovery/restore/job", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/services", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/shutdown", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/support-bundle", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/system/storage", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/update", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/appliance/update/pending", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/cis/tagging/category", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/cis/tagging/tag", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/cis/tagging/tag-association", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/cis/tasks", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/item", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}/item", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}/item/{item_id}/download-session", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}/item/{item_id}/downloadsession/file", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}/item/{item_id}/update-session", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}/item/{item_id}/updatesession/file", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}/subscribed-item", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}/subscriptions", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/library/{library_id}/usages", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/local-library", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/content/local-library/{library_id}", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/subscribed-library", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/subscribed-library/{library_id}", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/content/trusted-certificates", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/hcl/compatibility-data", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/hcl/hosts/{host}/compatibility-report", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/configuration", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/configuration/drafts", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/configuration/drafts/{draft}", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/depot-overrides", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/enablement/configuration/transition", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/enablement/software", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/installed-images", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/software", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/software/alternative-images/software", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/software/recommendations", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/software/reports/hardware-compatibility", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/vms/lifecycle-hooks", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/vms/solutions", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/clusters/{cluster}/vms/transition", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/depots", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/depots/{depot}/offline", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/depots/{depot}/online", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/hosts/{host}/configuration", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/hosts/{host}/depot-overrides", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/hosts/{host}/enablement/software", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/hosts/{host}/software", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/hosts/{host}/software/drafts", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/hosts/{host}/software/recommendations", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/inventory", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/repository/software", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/repository/software/drafts", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/session", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vapi/metadata/cli/command", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vapi/metadata/cli/namespace/{namespace}", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/authentication/token", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/authorization/permissions", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/authorization/privilege-checks", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/authorization/roles", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/authorization/vt-containers/mappings", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/certificate-management/vcenter/signing-certificate", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/certificate-management/vcenter/tls", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/certificate-management/vcenter/tls-csr", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/certificate-management/vcenter/trusted-root-chains", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/certificate-management/vcenter/vmca-root", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/cluster", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/cluster/{cluster}/evc-mode", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/compute/policies", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/confidential-computing/sgx/hosts", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/consumption-domains/zone-associations/association-changes", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/consumption-domains/zones", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/consumption-domains/zones/{zone}/capacity/summary", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/consumption-domains/zones/{zone}/cluster/{cluster}/associations", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/content/registries/harbor", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/content/registries/harbor/projects", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/crypto-manager/kms/providers", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/datacenter", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/datastore/{datastore}/files", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/import-history", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/install", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/install/psc/replicated", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/install/psc/standalone", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/install/remote-psc", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/migrate", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/migrate/active-directory", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/question", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/deployment/upgrade", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/evc-modes", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/folder", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/folder/{folder}", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/foundation-load-balancers", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/foundation-load-balancers/nodes", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/guest/customization-specs", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/host", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/host/{host}/entropy/external-pool", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/host/{host}/hardware/direct-path-devices", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/host/{host}/maintenance", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/identity/providers", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/iso/image", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/lcm/deployment/migration-upgrade", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/lcm/discovery/associated-products", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/lcm/discovery/interop-report", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/lcm/update/precheck-report", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/clusters", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/infrastructure-policies", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/lifecycle/content/libraries", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/networks", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/distributed-switches/compatibility", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/edges/compatibility", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/projects/{project}/compatibility", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/projects/{project}/vpcconnectivityprofiles/compatibility", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/networks/{network}/nsx/projects/{project}/vpcs/{vpc}/compatibility", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/software/clusters", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/software/supervisors/{supervisor}/prechecks", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/software/supervisors/{supervisor}/upgrades/jobs", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/software/supervisors/{supervisor}/versions", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/storage/profiles", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisor-services", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisor-services/cluster-supervisor-services", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisor-services/versions", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/certificates/signing-requests", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/container-image-registries", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/control-plane/passwords", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/providers", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/management-services", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/metrics/remote-endpoints", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/networks", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/networks/{network}/edges", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/recovery/backup/jobs", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/recovery/restore/jobs", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/storage/cloud-native/resource-checks", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/supervisor-services", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/support-bundles", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/zones/{zone}/bindings", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/support-bundle", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/virtual-machine-classes", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespace-management/zones/{zone}/cluster-compatibilities", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespaces/{namespace}/access", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespaces/{namespace}/instances", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespaces/{namespace}/management-services/access-grants", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespaces/{namespace}/mobility/virtualmachines/imports", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespaces/{namespace}/namespace-self-service", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/namespaces/{namespace}/namespace-templates", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/network/dvpg", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/network/dvs", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/ovf/library-item", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/ovf/library-item/{item_id}", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/ovfs", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/phm/hardware-support-managers", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/registered-tokens", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/resource-pool", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/services/{service}/service", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/storage/policies", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/system", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/system-config/psc-registration", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/attestation/services", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/hosts/{host}/hardware/tpm/endorsement-keys", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/kms/services", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/os/esx/base-images", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/tpm2/ca-certificates", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/attestation/tpm2/endorsement-keys", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/consumer-principals", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/client-certificate", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/client-certificate/csr", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-hosts/attestation", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-hosts/kms", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/attestation/services", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/attestation/services-applied-config", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/kms/services", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/trusted-infrastructure/trusted-clusters/kms/services-applied-config", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vcha/cluster", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vcha/cluster/{cluster}/active", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vcha/cluster/{cluster}/passive", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vcha/cluster/{cluster}/witness", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm-template/library-items", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm-template/library-items/{item_id}/check-outs", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm-template/library-items/{item_id}/versions", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/clone", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/console/tickets", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/data-sets", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/customization", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/customization-live", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/environment", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/filesystem/directories", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/filesystem/files", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/filesystem/transfers", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/power", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/guest/processes", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/nvme", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/sata", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/adapter/scsi", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/cdrom", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/disk", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/ethernet", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/floppy", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/parallel", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/hardware/serial", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/power", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/relocate", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/snapshots", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/snapshots/{snapshot}", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/storage/policy/{policy}/compliance", + "status": "stub" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/tools", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/api/vcenter/vm/{vm}/tools/installer", + "status": "stub" + }, + { + "verb": "POST", + "path": "/rest/com/vmware/cis/session", + "status": "implemented" + }, + { + "verb": "POST", + "path": "/rest/vcenter/vm/{vm}/power", + "status": "implemented" + }, + { + "verb": "PUT", + "path": "/api/appliance/access/consolecli", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/access/dcui", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/access/shell", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/access/ssh", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/local-accounts", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/local-accounts/policy", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/logging/forwarding", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/logging/liagent/log-collection", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/networking/dns/domains/{domain}", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/networking/dns/hostname", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/networking/dns/servers", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/networking/firewall/inbound", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/networking/interfaces/{interface}/ipv4", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/networking/interfaces/{interface}/ipv6", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/networking/no-proxy", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/networking/proxy", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/ntp", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/system/security/global-fips", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/system/time/timezone", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/timesync", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/tls/manual-parameters/global", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/tls/manual-parameters/services/{service}", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/tls/profiles/{profile}/global", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/appliance/update/policy", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/enablement/software", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/policies/{policy}/apply", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/display-name", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/add-on", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/display-name", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/selection-criteria", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/add-on", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/components/{component}", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/hardware-support", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/alternative-images/software/removed-components", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/base-image", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/components/{component}", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/hardware-support", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/drafts/{draft}/software/removed-components", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/software/solutions", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/clusters/{cluster}/vms/solutions", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/defaults/clusters/{cluster}/policies/{policy}/apply", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/defaults/hosts/{host}/policies/{policy}/apply", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/depots/{depot}/sync-schedule", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/depots/{depot}/umds", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/hosts/{host}/enablement/software", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/hosts/{host}/policies/{policy}/apply", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/display-name", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/add-on", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/base-image", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/components/{component}", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/hosts/{host}/software/drafts/{draft}/software/removed-components", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/hosts/{host}/software/solutions", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/add-on", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/add-on", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/components/{component}", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/display-name", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/hardware-support", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/removed-components", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/alternative-images/selection-criteria", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/base-image", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/components/{component}", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/display-name", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/hardware-support", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/esx/settings/repository/software/drafts/{draft}/removed-components", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/certificate-management/vcenter/signing-certificate", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/certificate-management/vcenter/tls", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/cluster/{cluster}/evc-mode", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/guest/customization-specs", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/lcm/deployment/migration-upgrade", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/lcm/deployment/repository", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/lcm/depot/{depot}/services", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/lcm/interop/interop-bundle", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/clusters/{cluster}", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/infrastructure-policies", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/lifecycle/content/libraries/{library_id}", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/load-balancers", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/networks/{network}", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/supervisor-services/cluster-supervisor-services", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/identity/providers/{provider}", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/logs/agent-configuration", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/metrics/remote-endpoints", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/supervisor-services", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespace-management/supervisors/{supervisor}/zones/{zone}/bindings", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespaces/{namespace}/access", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/namespaces/{namespace}/instances", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/phm/hardware-support-managers", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/system-config/deployment-type", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/trusted-infrastructure/trust-authority-clusters/kms/providers/{provider}/credential", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/vcha/cluster/{cluster}/mode", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/vm/{vm}/data-sets/entries", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/vm/{vm}/evc-mode", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/vm/{vm}/guest/customization", + "status": "stub" + }, + { + "verb": "PUT", + "path": "/api/vcenter/vm/{vm}/hardware/boot/device", + "status": "stub" + } + ] +} diff --git a/contracts/vsphere/README.md b/contracts/vsphere/README.md new file mode 100644 index 0000000..bd9d1cd --- /dev/null +++ b/contracts/vsphere/README.md @@ -0,0 +1,9 @@ +**Language / Язык:** [English](README.md) | [Русский](README.ru.md) + +# vSphere stub contracts + +Versioned JSON matrices generated from `app/vsphere/contracts/matrix.py`. +Hot-swap (`POST /ui/api/contract/apply?major=N`) switches the active **catalog** +major for Web UI / evidence only; runtime still serves the full registered +surface (no HTTP 501 from version floor). Regenerate with +`make vsphere-bundles`. diff --git a/contracts/vsphere/README.ru.md b/contracts/vsphere/README.ru.md new file mode 100644 index 0000000..aa48145 --- /dev/null +++ b/contracts/vsphere/README.ru.md @@ -0,0 +1,9 @@ +**Language / Язык:** [English](README.md) | [Русский](README.ru.md) + +# vSphere stub-контракты + +Версионированные JSON-матрицы, сгенерированные из `app/vsphere/contracts/matrix.py`. +Hot-swap (`POST /ui/api/contract/apply?major=N`) переключает активный **catalog** +major только для Web UI / evidence; runtime по-прежнему обслуживает полную +зарегистрированную поверхность (без HTTP 501 из-за version floor). +Перегенерация: `make vsphere-bundles`. diff --git a/contracts/vsphere/broadcom-9.1-operations-index.txt b/contracts/vsphere/broadcom-9.1-operations-index.txt new file mode 100644 index 0000000..f4666b8 --- /dev/null +++ b/contracts/vsphere/broadcom-9.1-operations-index.txt @@ -0,0 +1,3783 @@ +vSphere Automation API Operations Index | vSphere Automation API + +# vSphere Automation API Operations Index + +9.1(Latest) 9.0 8.0.3 v8.0U2 v8.0U1 v8.0.0 v7.0U3 v7.0U2 v6.5 - v7.0U2 + +vSphere Automation API Operations Index + +All available vSphere Automation API Operations + +Appliance + +Appliance Access Consolecli + +GET Appliance Access Consolecli get + +PUT Appliance Access Consolecli set + +Appliance Access Dcui + +GET Appliance Access Dcui get + +PUT Appliance Access Dcui set + +Appliance Access Shell + +GET Appliance Access Shell get + +PUT Appliance Access Shell set + +Appliance Access Ssh + +GET Appliance Access Ssh get + +PUT Appliance Access Ssh set + +Appliance Cores + +GET Appliance Cores list + +Appliance Health + +GET Appliance Health messages + +Appliance Health Applmgmt + +GET Appliance Health Applmgmt get + +Appliance Health Check Settings + +GET Appliance HealthCheckSettings get + +PATCH Appliance HealthCheckSettings update + +Appliance Health Database + +GET Appliance Health Database get + +Appliance Health Databasestorage + +GET Appliance Health Databasestorage get + +Appliance Health Load + +GET Appliance Health Load get + +Appliance Health Mem + +GET Appliance Health Mem get + +Appliance Health Softwarepackages + +GET Appliance Health Softwarepackages get + +Appliance Health Storage + +GET Appliance Health Storage get + +Appliance Health Swap + +GET Appliance Health Swap get + +Appliance Health System + +GET Appliance Health System lastcheck + +GET Appliance Health System get + +Appliance Local Accounts + +GET Appliance LocalAccounts get + +PUT Appliance LocalAccounts set + +DELETE Appliance LocalAccounts delete + +PATCH Appliance LocalAccounts update + +GET Appliance LocalAccounts list + +POST Appliance LocalAccounts create + +Appliance Local Accounts Policy + +GET Appliance LocalAccounts Policy get + +PUT Appliance LocalAccounts Policy set + +Appliance Logging Forwarding + +POST Appliance Logging Forwarding test + +GET Appliance Logging Forwarding get + +PUT Appliance Logging Forwarding set + +Appliance Logging Liagent Log Collection + +GET Appliance Logging Liagent LogCollection get + +PUT Appliance Logging Liagent LogCollection set + +Appliance Monitoring + +GET Appliance Monitoring query + +GET Appliance Monitoring list + +GET Appliance Monitoring get + +Appliance Networking + +GET Appliance Networking get + +PATCH Appliance Networking update + +POST Appliance Networking reset + +POST Appliance Networking change$Task + +Appliance Networking Dns Domains + +GET Appliance Networking Dns Domains list + +PUT Appliance Networking Dns Domains set + +POST Appliance Networking Dns Domains add + +Appliance Networking Dns Hostname + +POST Appliance Networking Dns Hostname test + +GET Appliance Networking Dns Hostname get + +PUT Appliance Networking Dns Hostname set + +Appliance Networking Dns Servers + +POST Appliance Networking Dns Servers test + +GET Appliance Networking Dns Servers get + +PUT Appliance Networking Dns Servers set + +POST Appliance Networking Dns Servers add + +Appliance Networking Firewall Inbound + +GET Appliance Networking Firewall Inbound get + +PUT Appliance Networking Firewall Inbound set + +Appliance Networking Interfaces + +GET Appliance Networking Interfaces list + +GET Appliance Networking Interfaces get + +Appliance Networking Interfaces Ipv4 + +GET Appliance Networking Interfaces Ipv4 get + +PUT Appliance Networking Interfaces Ipv4 set + +Appliance Networking Interfaces Ipv6 + +GET Appliance Networking Interfaces Ipv6 get + +PUT Appliance Networking Interfaces Ipv6 set + +Appliance Networking No Proxy + +GET Appliance Networking NoProxy get + +PUT Appliance Networking NoProxy set + +Appliance Networking Proxy + +POST Appliance Networking Proxy test + +GET Appliance Networking Proxy get + +PUT Appliance Networking Proxy set + +DELETE Appliance Networking Proxy delete + +GET Appliance Networking Proxy list + +Appliance Ntp + +POST Appliance Ntp test + +GET Appliance Ntp get + +PUT Appliance Ntp set + +Appliance Recovery + +GET Appliance Recovery get + +Appliance Services + +POST Appliance Services start + +POST Appliance Services stop + +POST Appliance Services restart + +GET Appliance Services get + +GET Appliance Services list + +Appliance Shutdown + +POST Appliance Shutdown cancel + +POST Appliance Shutdown poweroff + +POST Appliance Shutdown reboot + +GET Appliance Shutdown get + +Appliance Support Bundle + +GET Appliance SupportBundle list + +DELETE Appliance SupportBundle delete + +POST Appliance SupportBundle create$Task + +Appliance Support Bundle Components + +GET Appliance SupportBundle Components get + +Appliance System Crypto Hash + +GET Appliance System CryptoHash get + +Appliance System Crypto Hash Options + +GET Appliance System CryptoHash Options list + +Appliance System Security Global Fips + +GET Appliance System Security GlobalFips get + +PUT Appliance System Security GlobalFips update + +Appliance System Storage + +GET Appliance System Storage list + +POST Appliance System Storage resize + +POST Appliance System Storage resizeEx + +Appliance System Time + +GET Appliance System Time get + +Appliance System Time Timezone + +GET Appliance System Time Timezone get + +PUT Appliance System Time Timezone set + +Appliance System Uptime + +GET Appliance System Uptime get + +Appliance System Version + +GET Appliance System Version get + +Appliance Timesync + +GET Appliance Timesync get + +PUT Appliance Timesync set + +Appliance Tls Manual Parameters Global + +GET Appliance Tls ManualParameters Global get + +PUT Appliance Tls ManualParameters Global set$Task + +Appliance Tls Manual Parameters Services + +GET Appliance Tls ManualParameters Services list + +GET Appliance Tls ManualParameters Services get + +PUT Appliance Tls ManualParameters Services set$Task + +DELETE Appliance Tls ManualParameters Services delete$Task + +Appliance Tls Profiles + +GET Appliance Tls Profiles get + +GET Appliance Tls Profiles list + +Appliance Tls Profiles Global + +GET Appliance Tls Profiles Global get + +PUT Appliance Tls Profiles Global set$Task + +Appliance Update + +GET Appliance Update get + +POST Appliance Update cancel + +Appliance Update Pending + +GET Appliance Update Pending list + +GET Appliance Update Pending get + +GET Appliance Update Pending listUpgradeableComponents + +POST Appliance Update Pending precheck + +POST Appliance Update Pending stage + +POST Appliance Update Pending validate + +POST Appliance Update Pending install + +POST Appliance Update Pending stageAndInstall + +POST Appliance Update Pending rollback + +Appliance Update Policy + +GET Appliance Update Policy get + +PUT Appliance Update Policy set + +Appliance Update Staged + +GET Appliance Update Staged get + +DELETE Appliance Update Staged delete + +Appliance Infraprofile + +Appliance Infraprofile Configs + +GET Appliance Infraprofile Configs list + +POST Appliance Infraprofile Configs export + +POST Appliance Infraprofile Configs validate$Task + +POST Appliance Infraprofile Configs importProfile$Task + +Appliance Recovery + +Appliance Recovery Backup + +POST Appliance Recovery Backup validate + +Appliance Recovery Backup Job + +POST Appliance Recovery Backup Job cancel + +GET Appliance Recovery Backup Job list + +POST Appliance Recovery Backup Job create + +GET Appliance Recovery Backup Job get + +Appliance Recovery Backup Job Details + +GET Appliance Recovery Backup Job Details list + +Appliance Recovery Backup Parts + +GET Appliance Recovery Backup Parts list + +GET Appliance Recovery Backup Parts get + +Appliance Recovery Backup Schedules + +GET Appliance Recovery Backup Schedules list + +POST Appliance Recovery Backup Schedules create + +POST Appliance Recovery Backup Schedules run + +GET Appliance Recovery Backup Schedules get + +DELETE Appliance Recovery Backup Schedules delete + +PATCH Appliance Recovery Backup Schedules update + +Appliance Recovery Backup System Name + +POST Appliance Recovery Backup SystemName list + +Appliance Recovery Backup System Name Archive + +POST Appliance Recovery Backup SystemName Archive get + +POST Appliance Recovery Backup SystemName Archive list + +Appliance Recovery Reconciliation Job + +GET Appliance Recovery Reconciliation Job get + +POST Appliance Recovery Reconciliation Job create + +Appliance Recovery Restore + +POST Appliance Recovery Restore validate + +Appliance Recovery Restore Job + +POST Appliance Recovery Restore Job cancel + +GET Appliance Recovery Restore Job get + +POST Appliance Recovery Restore Job create + +Cis + +Cis Session + +GET Cis Session get + +POST Cis Session create + +DELETE Cis Session delete + +Cis Tasks + +GET Cis Tasks get + +POST Cis Tasks list + +POST Cis Tasks cancel + +Cis Tagging + +Cis Tagging Category + +GET Cis Tagging Category list + +POST Cis Tagging Category create + +GET Cis Tagging Category get + +DELETE Cis Tagging Category delete + +PATCH Cis Tagging Category update + +POST Cis Tagging Category listUsedCategories + +POST Cis Tagging Category addToUsedBy + +POST Cis Tagging Category removeFromUsedBy + +POST Cis Tagging Category revokePropagatingPermissions + +Cis Tagging Tag + +GET Cis Tagging Tag list + +POST Cis Tagging Tag create + +GET Cis Tagging Tag get + +DELETE Cis Tagging Tag delete + +PATCH Cis Tagging Tag update + +POST Cis Tagging Tag listUsedTags + +POST Cis Tagging Tag listTagsForCategory + +POST Cis Tagging Tag addToUsedBy + +POST Cis Tagging Tag removeFromUsedBy + +POST Cis Tagging Tag revokePropagatingPermissions + +Cis Tagging Tag Association + +POST Cis Tagging TagAssociation attach + +POST Cis Tagging TagAssociation attachMultipleTagsToObject + +POST Cis Tagging TagAssociation attachTagToMultipleObjects + +POST Cis Tagging TagAssociation detach + +POST Cis Tagging TagAssociation detachMultipleTagsFromObject + +POST Cis Tagging TagAssociation detachTagFromMultipleObjects + +POST Cis Tagging TagAssociation listAttachedObjects + +POST Cis Tagging TagAssociation listAttachedObjectsOnTags + +POST Cis Tagging TagAssociation listAttachedTags + +POST Cis Tagging TagAssociation listAttachedTagsOnObjects + +POST Cis Tagging TagAssociation listAttachableTags + +Content + +Content Configuration + +GET Content Configuration get + +PATCH Content Configuration update + +Content Library + +GET Content Library get + +DELETE Content Library delete + +PATCH Content Library update + +GET Content Library list + +POST Content Library find + +POST Content Library migrate + +POST Content Library convert + +POST Content Library enterMaintenance + +POST Content Library exitMaintenance + +POST Content Library forceDelete + +Content Library Item + +POST Content Library Item copy + +POST Content Library Item create + +GET Content Library Item get + +DELETE Content Library Item delete + +PATCH Content Library Item update + +GET Content Library Item list + +POST Content Library Item find + +POST Content Library Item publish + +Content Library Item Changes + +GET Content Library Item Changes list + +GET Content Library Item Changes get + +Content Library Item Download Session + +GET Content Library Item DownloadSession list + +POST Content Library Item DownloadSession create + +GET Content Library Item DownloadSession get + +DELETE Content Library Item DownloadSession delete + +POST Content Library Item DownloadSession keepAlive + +POST Content Library Item DownloadSession cancel + +POST Content Library Item DownloadSession fail + +Content Library Item Downloadsession File + +GET Content Library Item Downloadsession File list + +POST Content Library Item Downloadsession File prepare + +GET Content Library Item Downloadsession File get + +Content Library Item File + +GET Content Library Item File get + +GET Content Library Item File list + +Content Library Item Storage + +GET Content Library Item Storage get + +GET Content Library Item Storage list + +Content Library Item Update Session + +GET Content Library Item UpdateSession list + +POST Content Library Item UpdateSession create + +GET Content Library Item UpdateSession get + +DELETE Content Library Item UpdateSession delete + +PATCH Content Library Item UpdateSession update + +POST Content Library Item UpdateSession complete + +POST Content Library Item UpdateSession keepAlive + +POST Content Library Item UpdateSession cancel + +POST Content Library Item UpdateSession fail + +Content Library Item Updatesession File + +POST Content Library Item Updatesession File validate + +GET Content Library Item Updatesession File list + +POST Content Library Item Updatesession File add + +GET Content Library Item Updatesession File get + +DELETE Content Library Item Updatesession File remove + +Content Library Subscribed Item + +POST Content Library SubscribedItem evict + +POST Content Library SubscribedItem sync + +Content Library Subscriptions + +GET Content Library Subscriptions list + +POST Content Library Subscriptions create + +GET Content Library Subscriptions get + +DELETE Content Library Subscriptions delete + +PATCH Content Library Subscriptions update + +Content Library Usages + +GET Content Library Usages list + +POST Content Library Usages add + +GET Content Library Usages get + +DELETE Content Library Usages remove + +Content Local Library + +GET Content LocalLibrary list + +POST Content LocalLibrary create + +GET Content LocalLibrary get + +DELETE Content LocalLibrary delete + +PATCH Content LocalLibrary update + +POST Content LocalLibrary forceDelete + +POST Content LocalLibrary publish + +Content Security Policies + +GET Content SecurityPolicies list + +Content Subscribed Library + +GET Content SubscribedLibrary list + +POST Content SubscribedLibrary create + +GET Content SubscribedLibrary get + +DELETE Content SubscribedLibrary delete + +PATCH Content SubscribedLibrary update + +POST Content SubscribedLibrary forceDelete + +POST Content SubscribedLibrary evict + +POST Content SubscribedLibrary sync + +POST Content SubscribedLibrary probe + +Content Trusted Certificates + +GET Content TrustedCertificates list + +POST Content TrustedCertificates create + +GET Content TrustedCertificates get + +DELETE Content TrustedCertificates delete + +Content Type + +GET Content Type list + +Esx Hcl + +Esx Hcl Compatibility Data + +GET Esx Hcl CompatibilityData get + +POST Esx Hcl CompatibilityData update$Task + +Esx Hcl Hosts Compatibility Releases + +GET Esx Hcl Hosts CompatibilityReleases list + +Esx Hcl Hosts Compatibility Report + +GET Esx Hcl Hosts CompatibilityReport get + +POST Esx Hcl Hosts CompatibilityReport create$Task + +Esx Hcl Reports + +GET Esx Hcl Reports get + +Esx Hosts + +Esx Hosts Software + +GET Esx Hosts Software get + +Esx Hosts Software Installed Components + +GET Esx Hosts Software InstalledComponents list + +Esx Settings + +Esx Settings Clusters Configuration + +GET Esx Settings Clusters Configuration get + +POST Esx Settings Clusters Configuration exportConfig + +POST Esx Settings Clusters Configuration apply$Task + +POST Esx Settings Clusters Configuration checkCompliance$Task + +POST Esx Settings Clusters Configuration validate$Task + +POST Esx Settings Clusters Configuration precheck$Task + +POST Esx Settings Clusters Configuration importConfig$Task + +Esx Settings Clusters Configuration Audit Records + +GET Esx Settings Clusters Configuration AuditRecords list + +Esx Settings Clusters Configuration Drafts + +GET Esx Settings Clusters Configuration Drafts list + +POST Esx Settings Clusters Configuration Drafts create + +GET Esx Settings Clusters Configuration Drafts getSchema + +GET Esx Settings Clusters Configuration Drafts get + +DELETE Esx Settings Clusters Configuration Drafts delete + +POST Esx Settings Clusters Configuration Drafts exportConfig + +POST Esx Settings Clusters Configuration Drafts update + +GET Esx Settings Clusters Configuration Drafts showChanges + +POST Esx Settings Clusters Configuration Drafts apply + +POST Esx Settings Clusters Configuration Drafts importFromHost$Task + +POST Esx Settings Clusters Configuration Drafts checkCompliance$Task + +POST Esx Settings Clusters Configuration Drafts precheck$Task + +POST Esx Settings Clusters Configuration Drafts importConfig$Task + +POST Esx Settings Clusters Configuration Drafts getAvailableValues$Task + +Esx Settings Clusters Configuration Reports Last Apply Result + +GET Esx Settings Clusters Configuration Reports LastApplyResult get + +Esx Settings Clusters Configuration Reports Last Compliance Result + +GET Esx Settings Clusters Configuration Reports LastComplianceResult get + +Esx Settings Clusters Configuration Reports Last Precheck Result + +GET Esx Settings Clusters Configuration Reports LastPrecheckResult get + +Esx Settings Clusters Configuration Reports Recent Tasks + +GET Esx Settings Clusters Configuration Reports RecentTasks get + +Esx Settings Clusters Configuration Schema + +GET Esx Settings Clusters Configuration Schema get + +Esx Settings Clusters Depot Overrides + +GET Esx Settings Clusters DepotOverrides get + +POST Esx Settings Clusters DepotOverrides add + +POST Esx Settings Clusters DepotOverrides remove + +Esx Settings Clusters Enablement Configuration + +GET Esx Settings Clusters Enablement Configuration get + +Esx Settings Clusters Enablement Configuration Transition + +GET Esx Settings Clusters Enablement Configuration Transition get + +POST Esx Settings Clusters Enablement Configuration Transition cancel + +POST Esx Settings Clusters Enablement Configuration Transition importFromFile + +POST Esx Settings Clusters Enablement Configuration Transition exportConfig + +POST Esx Settings Clusters Enablement Configuration Transition exportSchema + +POST Esx Settings Clusters Enablement Configuration Transition checkEligibility$Task + +POST Esx Settings Clusters Enablement Configuration Transition importFromHost$Task + +POST Esx Settings Clusters Enablement Configuration Transition validateConfig$Task + +POST Esx Settings Clusters Enablement Configuration Transition precheck$Task + +POST Esx Settings Clusters Enablement Configuration Transition enable$Task + +Esx Settings Clusters Enablement Software + +GET Esx Settings Clusters Enablement Software get + +POST Esx Settings Clusters Enablement Software check$Task + +PUT Esx Settings Clusters Enablement Software enable$Task + +Esx Settings Clusters Installed Images + +GET Esx Settings Clusters InstalledImages get + +POST Esx Settings Clusters InstalledImages extract$Task + +Esx Settings Clusters Policies Apply + +GET Esx Settings Clusters Policies Apply get + +PUT Esx Settings Clusters Policies Apply set + +Esx Settings Clusters Policies Apply Effective + +GET Esx Settings Clusters Policies Apply Effective get + +Esx Settings Clusters Software + +GET Esx Settings Clusters Software get + +GET Esx Settings Clusters Software getDefaultImage + +POST Esx Settings Clusters Software export + +GET Esx Settings Clusters Software getDisplayName + +POST Esx Settings Clusters Software scan$Task + +POST Esx Settings Clusters Software stage$Task + +POST Esx Settings Clusters Software apply$Task + +POST Esx Settings Clusters Software check$Task + +Esx Settings Clusters Software Add On + +GET Esx Settings Clusters Software AddOn get + +Esx Settings Clusters Software Alternative Images + +GET Esx Settings Clusters Software AlternativeImages get + +GET Esx Settings Clusters Software AlternativeImages list + +Esx Settings Clusters Software Alternative Images Display Name + +GET Esx Settings Clusters Software AlternativeImages DisplayName get + +Esx Settings Clusters Software Alternative Images Selection Criteria + +GET Esx Settings Clusters Software AlternativeImages SelectionCriteria get + +Esx Settings Clusters Software Alternative Images Software + +POST Esx Settings Clusters Software AlternativeImages Software export + +Esx Settings Clusters Software Alternative Images Software Add On + +GET Esx Settings Clusters Software AlternativeImages Software AddOn get + +Esx Settings Clusters Software Alternative Images Software Base Image + +GET Esx Settings Clusters Software AlternativeImages Software BaseImage get + +Esx Settings Clusters Software Alternative Images Software Components + +GET Esx Settings Clusters Software AlternativeImages Software Components get + +GET Esx Settings Clusters Software AlternativeImages Software Components list + +Esx Settings Clusters Software Alternative Images Software Effective Components + +GET Esx Settings Clusters Software AlternativeImages Software EffectiveComponents list + +GET Esx Settings Clusters Software AlternativeImages Software EffectiveComponents listWithRemovedComponents + +Esx Settings Clusters Software Alternative Images Software Hardware Support + +GET Esx Settings Clusters Software AlternativeImages Software HardwareSupport get + +Esx Settings Clusters Software Alternative Images Software Removed Components + +GET Esx Settings Clusters Software AlternativeImages Software RemovedComponents get + +GET Esx Settings Clusters Software AlternativeImages Software RemovedComponents list + +Esx Settings Clusters Software Alternative Images Software Solutions + +GET Esx Settings Clusters Software AlternativeImages Software Solutions get + +GET Esx Settings Clusters Software AlternativeImages Software Solutions list + +Esx Settings Clusters Software Base Image + +GET Esx Settings Clusters Software BaseImage get + +Esx Settings Clusters Software Commits + +GET Esx Settings Clusters Software Commits get + +Esx Settings Clusters Software Compliance + +GET Esx Settings Clusters Software Compliance get + +Esx Settings Clusters Software Components + +GET Esx Settings Clusters Software Components get + +GET Esx Settings Clusters Software Components list + +Esx Settings Clusters Software Drafts + +GET Esx Settings Clusters Software Drafts list + +POST Esx Settings Clusters Software Drafts create + +GET Esx Settings Clusters Software Drafts get + +DELETE Esx Settings Clusters Software Drafts delete + +POST Esx Settings Clusters Software Drafts importSoftwareSpec + +POST Esx Settings Clusters Software Drafts commit$Task + +POST Esx Settings Clusters Software Drafts validate$Task + +POST Esx Settings Clusters Software Drafts scan$Task + +Esx Settings Clusters Software Drafts Display Name + +GET Esx Settings Clusters Software Drafts DisplayName get + +PUT Esx Settings Clusters Software Drafts DisplayName set + +Esx Settings Clusters Software Drafts Software Add On + +GET Esx Settings Clusters Software Drafts Software AddOn get + +PUT Esx Settings Clusters Software Drafts Software AddOn set + +DELETE Esx Settings Clusters Software Drafts Software AddOn delete + +Esx Settings Clusters Software Drafts Software Alternative Images + +GET Esx Settings Clusters Software Drafts Software AlternativeImages list + +POST Esx Settings Clusters Software Drafts Software AlternativeImages create + +GET Esx Settings Clusters Software Drafts Software AlternativeImages get + +DELETE Esx Settings Clusters Software Drafts Software AlternativeImages delete + +Esx Settings Clusters Software Drafts Software Alternative Images Display Name + +GET Esx Settings Clusters Software Drafts Software AlternativeImages DisplayName get + +PUT Esx Settings Clusters Software Drafts Software AlternativeImages DisplayName set + +Esx Settings Clusters Software Drafts Software Alternative Images Selection Criteria + +GET Esx Settings Clusters Software Drafts Software AlternativeImages SelectionCriteria get + +PUT Esx Settings Clusters Software Drafts Software AlternativeImages SelectionCriteria set + +Esx Settings Clusters Software Drafts Software Alternative Images Software Add On + +GET Esx Settings Clusters Software Drafts Software AlternativeImages Software AddOn get + +PUT Esx Settings Clusters Software Drafts Software AlternativeImages Software AddOn set + +DELETE Esx Settings Clusters Software Drafts Software AlternativeImages Software AddOn delete + +Esx Settings Clusters Software Drafts Software Alternative Images Software Base Image + +GET Esx Settings Clusters Software Drafts Software AlternativeImages Software BaseImage get + +Esx Settings Clusters Software Drafts Software Alternative Images Software Components + +GET Esx Settings Clusters Software Drafts Software AlternativeImages Software Components get + +PUT Esx Settings Clusters Software Drafts Software AlternativeImages Software Components set + +DELETE Esx Settings Clusters Software Drafts Software AlternativeImages Software Components delete + +GET Esx Settings Clusters Software Drafts Software AlternativeImages Software Components list + +PATCH Esx Settings Clusters Software Drafts Software AlternativeImages Software Components update + +Esx Settings Clusters Software Drafts Software Alternative Images Software Effective Components + +GET Esx Settings Clusters Software Drafts Software AlternativeImages Software EffectiveComponents list + +GET Esx Settings Clusters Software Drafts Software AlternativeImages Software EffectiveComponents listWithRemovedComponents + +Esx Settings Clusters Software Drafts Software Alternative Images Software Hardware Support + +GET Esx Settings Clusters Software Drafts Software AlternativeImages Software HardwareSupport get + +PUT Esx Settings Clusters Software Drafts Software AlternativeImages Software HardwareSupport set + +DELETE Esx Settings Clusters Software Drafts Software AlternativeImages Software HardwareSupport delete + +Esx Settings Clusters Software Drafts Software Alternative Images Software Removed Components + +GET Esx Settings Clusters Software Drafts Software AlternativeImages Software RemovedComponents get + +PUT Esx Settings Clusters Software Drafts Software AlternativeImages Software RemovedComponents set + +DELETE Esx Settings Clusters Software Drafts Software AlternativeImages Software RemovedComponents delete + +GET Esx Settings Clusters Software Drafts Software AlternativeImages Software RemovedComponents list + +Esx Settings Clusters Software Drafts Software Base Image + +GET Esx Settings Clusters Software Drafts Software BaseImage get + +PUT Esx Settings Clusters Software Drafts Software BaseImage set + +Esx Settings Clusters Software Drafts Software Components + +GET Esx Settings Clusters Software Drafts Software Components get + +PUT Esx Settings Clusters Software Drafts Software Components set + +DELETE Esx Settings Clusters Software Drafts Software Components delete + +GET Esx Settings Clusters Software Drafts Software Components list + +PATCH Esx Settings Clusters Software Drafts Software Components update + +Esx Settings Clusters Software Drafts Software Effective Components + +GET Esx Settings Clusters Software Drafts Software EffectiveComponents list + +GET Esx Settings Clusters Software Drafts Software EffectiveComponents listWithRemovedComponents + +Esx Settings Clusters Software Drafts Software Hardware Support + +GET Esx Settings Clusters Software Drafts Software HardwareSupport get + +PUT Esx Settings Clusters Software Drafts Software HardwareSupport set + +DELETE Esx Settings Clusters Software Drafts Software HardwareSupport delete + +Esx Settings Clusters Software Drafts Software Removed Components + +GET Esx Settings Clusters Software Drafts Software RemovedComponents get + +PUT Esx Settings Clusters Software Drafts Software RemovedComponents set + +DELETE Esx Settings Clusters Software Drafts Software RemovedComponents delete + +GET Esx Settings Clusters Software Drafts Software RemovedComponents list + +Esx Settings Clusters Software Effective Components + +GET Esx Settings Clusters Software EffectiveComponents list + +GET Esx Settings Clusters Software EffectiveComponents listWithRemovedComponents + +Esx Settings Clusters Software Hardware Support + +GET Esx Settings Clusters Software HardwareSupport get + +Esx Settings Clusters Software Recommendations + +GET Esx Settings Clusters Software Recommendations get + +POST Esx Settings Clusters Software Recommendations generate$Task + +Esx Settings Clusters Software Removed Components + +GET Esx Settings Clusters Software RemovedComponents get + +GET Esx Settings Clusters Software RemovedComponents list + +Esx Settings Clusters Software Reports Apply Impact + +GET Esx Settings Clusters Software Reports ApplyImpact get + +Esx Settings Clusters Software Reports Hardware Compatibility + +GET Esx Settings Clusters Software Reports HardwareCompatibility get + +POST Esx Settings Clusters Software Reports HardwareCompatibility check$Task + +Esx Settings Clusters Software Reports Hardware Compatibility Details + +GET Esx Settings Clusters Software Reports HardwareCompatibility Details get + +Esx Settings Clusters Software Reports Hardware Compatibility Pci Device Overrides Vcg Entries + +PATCH Esx Settings Clusters Software Reports HardwareCompatibility PciDeviceOverrides VcgEntries update$Task + +Esx Settings Clusters Software Reports Hardware Compatibility Storage Device Overrides Compliance Status + +PATCH Esx Settings Clusters Software Reports HardwareCompatibility StorageDeviceOverrides ComplianceStatus update$Task + +Esx Settings Clusters Software Reports Hardware Compatibility Storage Device Overrides Vcg Entries + +PATCH Esx Settings Clusters Software Reports HardwareCompatibility StorageDeviceOverrides VcgEntries update$Task + +Esx Settings Clusters Software Reports Last Apply Result + +GET Esx Settings Clusters Software Reports LastApplyResult get + +Esx Settings Clusters Software Reports Last Check Result + +GET Esx Settings Clusters Software Reports LastCheckResult get + +Esx Settings Clusters Software Software Spec Metadata + +GET Esx Settings Clusters Software SoftwareSpecMetadata get + +Esx Settings Clusters Software Solutions + +GET Esx Settings Clusters Software Solutions get + +GET Esx Settings Clusters Software Solutions list + +PUT Esx Settings Clusters Software Solutions set$Task + +DELETE Esx Settings Clusters Software Solutions delete$Task + +PATCH Esx Settings Clusters Software Solutions update$Task + +Esx Settings Clusters Vms Lifecycle Hooks + +POST Esx Settings Clusters Vms LifecycleHooks markAsProcessed + +GET Esx Settings Clusters Vms LifecycleHooks list + +POST Esx Settings Clusters Vms LifecycleHooks processDynamicUpdate + +Esx Settings Clusters Vms Solutions + +GET Esx Settings Clusters Vms Solutions get + +GET Esx Settings Clusters Vms Solutions list + +PUT Esx Settings Clusters Vms Solutions set$Task + +DELETE Esx Settings Clusters Vms Solutions delete$Task + +POST Esx Settings Clusters Vms Solutions apply$Task + +POST Esx Settings Clusters Vms Solutions checkCompliance$Task + +Esx Settings Clusters Vms Transition + +POST Esx Settings Clusters Vms Transition enable$Task + +POST Esx Settings Clusters Vms Transition multiSourceEnable$Task + +POST Esx Settings Clusters Vms Transition transition$Task + +Esx Settings Defaults Clusters Policies Apply + +GET Esx Settings Defaults Clusters Policies Apply get + +PUT Esx Settings Defaults Clusters Policies Apply set + +Esx Settings Defaults Clusters Policies Apply Effective + +GET Esx Settings Defaults Clusters Policies Apply Effective get + +Esx Settings Defaults Hosts Policies Apply + +GET Esx Settings Defaults Hosts Policies Apply get + +PUT Esx Settings Defaults Hosts Policies Apply set + +Esx Settings Defaults Hosts Policies Apply Effective + +GET Esx Settings Defaults Hosts Policies Apply Effective get + +Esx Settings Depot Content Add Ons + +GET Esx Settings DepotContent AddOns list + +Esx Settings Depot Content Add Ons Versions + +GET Esx Settings DepotContent AddOns Versions get + +Esx Settings Depot Content Base Images + +GET Esx Settings DepotContent BaseImages list + +Esx Settings Depot Content Base Images Versions + +GET Esx Settings DepotContent BaseImages Versions get + +Esx Settings Depot Content Components + +GET Esx Settings DepotContent Components list + +Esx Settings Depot Content Components Versions + +GET Esx Settings DepotContent Components Versions get + +Esx Settings Depots + +POST Esx Settings Depots sync$Task + +Esx Settings Depots Offline + +GET Esx Settings Depots Offline get + +DELETE Esx Settings Depots Offline delete + +GET Esx Settings Depots Offline list + +POST Esx Settings Depots Offline create$Task + +DELETE Esx Settings Depots Offline delete$Task + +POST Esx Settings Depots Offline createFromHost$Task + +Esx Settings Depots Offline Content + +GET Esx Settings Depots Offline Content get + +Esx Settings Depots Online + +GET Esx Settings Depots Online list + +POST Esx Settings Depots Online create + +GET Esx Settings Depots Online get + +DELETE Esx Settings Depots Online delete + +PATCH Esx Settings Depots Online update + +DELETE Esx Settings Depots Online delete$Task + +POST Esx Settings Depots Online flush$Task + +Esx Settings Depots Online Content + +GET Esx Settings Depots Online Content get + +Esx Settings Depots Sync Schedule + +GET Esx Settings Depots SyncSchedule get + +PUT Esx Settings Depots SyncSchedule set + +Esx Settings Depots Umds + +GET Esx Settings Depots Umds get + +PUT Esx Settings Depots Umds set + +DELETE Esx Settings Depots Umds delete + +PATCH Esx Settings Depots Umds update + +DELETE Esx Settings Depots Umds delete$Task + +Esx Settings Depots Umds Content + +GET Esx Settings Depots Umds Content get + +Esx Settings Hardware Support Managers + +GET Esx Settings HardwareSupport Managers list + +Esx Settings Hardware Support Managers Packages + +GET Esx Settings HardwareSupport Managers Packages list + +Esx Settings Hardware Support Managers Packages Versions + +GET Esx Settings HardwareSupport Managers Packages Versions get + +Esx Settings Hosts Configuration + +POST Esx Settings Hosts Configuration extract + +Esx Settings Hosts Depot Overrides + +GET Esx Settings Hosts DepotOverrides get + +POST Esx Settings Hosts DepotOverrides add + +POST Esx Settings Hosts DepotOverrides remove + +Esx Settings Hosts Enablement Software + +GET Esx Settings Hosts Enablement Software get + +POST Esx Settings Hosts Enablement Software check$Task + +PUT Esx Settings Hosts Enablement Software enable$Task + +Esx Settings Hosts Policies Apply + +GET Esx Settings Hosts Policies Apply get + +PUT Esx Settings Hosts Policies Apply set + +Esx Settings Hosts Policies Apply Effective + +GET Esx Settings Hosts Policies Apply Effective get + +Esx Settings Hosts Software + +GET Esx Settings Hosts Software get + +POST Esx Settings Hosts Software export + +GET Esx Settings Hosts Software getDisplayName + +POST Esx Settings Hosts Software scan$Task + +POST Esx Settings Hosts Software stage$Task + +POST Esx Settings Hosts Software apply$Task + +POST Esx Settings Hosts Software check$Task + +Esx Settings Hosts Software Add On + +GET Esx Settings Hosts Software AddOn get + +Esx Settings Hosts Software Base Image + +GET Esx Settings Hosts Software BaseImage get + +Esx Settings Hosts Software Commits + +GET Esx Settings Hosts Software Commits get + +Esx Settings Hosts Software Compliance + +GET Esx Settings Hosts Software Compliance get + +Esx Settings Hosts Software Components + +GET Esx Settings Hosts Software Components get + +GET Esx Settings Hosts Software Components list + +Esx Settings Hosts Software Drafts + +GET Esx Settings Hosts Software Drafts list + +POST Esx Settings Hosts Software Drafts create + +GET Esx Settings Hosts Software Drafts get + +DELETE Esx Settings Hosts Software Drafts delete + +POST Esx Settings Hosts Software Drafts importSoftwareSpec + +POST Esx Settings Hosts Software Drafts commit$Task + +POST Esx Settings Hosts Software Drafts validate$Task + +POST Esx Settings Hosts Software Drafts scan$Task + +Esx Settings Hosts Software Drafts Display Name + +GET Esx Settings Hosts Software Drafts DisplayName get + +PUT Esx Settings Hosts Software Drafts DisplayName set + +Esx Settings Hosts Software Drafts Software Add On + +GET Esx Settings Hosts Software Drafts Software AddOn get + +PUT Esx Settings Hosts Software Drafts Software AddOn set + +DELETE Esx Settings Hosts Software Drafts Software AddOn delete + +Esx Settings Hosts Software Drafts Software Base Image + +GET Esx Settings Hosts Software Drafts Software BaseImage get + +PUT Esx Settings Hosts Software Drafts Software BaseImage set + +Esx Settings Hosts Software Drafts Software Components + +GET Esx Settings Hosts Software Drafts Software Components get + +PUT Esx Settings Hosts Software Drafts Software Components set + +DELETE Esx Settings Hosts Software Drafts Software Components delete + +GET Esx Settings Hosts Software Drafts Software Components list + +PATCH Esx Settings Hosts Software Drafts Software Components update + +Esx Settings Hosts Software Drafts Software Effective Components + +GET Esx Settings Hosts Software Drafts Software EffectiveComponents list + +GET Esx Settings Hosts Software Drafts Software EffectiveComponents listWithRemovedComponents + +Esx Settings Hosts Software Drafts Software Removed Components + +GET Esx Settings Hosts Software Drafts Software RemovedComponents get + +PUT Esx Settings Hosts Software Drafts Software RemovedComponents set + +DELETE Esx Settings Hosts Software Drafts Software RemovedComponents delete + +GET Esx Settings Hosts Software Drafts Software RemovedComponents list + +Esx Settings Hosts Software Effective Components + +GET Esx Settings Hosts Software EffectiveComponents list + +GET Esx Settings Hosts Software EffectiveComponents listWithRemovedComponents + +Esx Settings Hosts Software Recommendations + +GET Esx Settings Hosts Software Recommendations get + +POST Esx Settings Hosts Software Recommendations generate$Task + +Esx Settings Hosts Software Removed Components + +GET Esx Settings Hosts Software RemovedComponents get + +GET Esx Settings Hosts Software RemovedComponents list + +Esx Settings Hosts Software Reports Apply Impact + +GET Esx Settings Hosts Software Reports ApplyImpact get + +Esx Settings Hosts Software Reports Last Apply Result + +GET Esx Settings Hosts Software Reports LastApplyResult get + +Esx Settings Hosts Software Reports Last Check Result + +GET Esx Settings Hosts Software Reports LastCheckResult get + +Esx Settings Hosts Software Software Spec Metadata + +GET Esx Settings Hosts Software SoftwareSpecMetadata get + +Esx Settings Hosts Software Solutions + +GET Esx Settings Hosts Software Solutions get + +GET Esx Settings Hosts Software Solutions list + +PUT Esx Settings Hosts Software Solutions set$Task + +DELETE Esx Settings Hosts Software Solutions delete$Task + +Esx Settings Inventory + +POST Esx Settings Inventory apply$Task + +POST Esx Settings Inventory assignEntities$Task + +POST Esx Settings Inventory check$Task + +POST Esx Settings Inventory extractInstalledImage$Task + +POST Esx Settings Inventory scan$Task + +POST Esx Settings Inventory stage$Task + +POST Esx Settings Inventory transition$Task + +POST Esx Settings Inventory updateVumCapability$Task + +Esx Settings Inventory Reports Summary Clusters + +GET Esx Settings Inventory Reports Summary Clusters get + +Esx Settings Inventory Reports Summary Hosts + +GET Esx Settings Inventory Reports Summary Hosts get + +Esx Settings Inventory Reports Transition Summary Clusters + +GET Esx Settings Inventory Reports TransitionSummary Clusters get + +Esx Settings Inventory Reports Transition Summary Hosts + +GET Esx Settings Inventory Reports TransitionSummary Hosts get + +Esx Settings Repository Software + +GET Esx Settings Repository Software get + +DELETE Esx Settings Repository Software delete + +PATCH Esx Settings Repository Software update + +GET Esx Settings Repository Software list + +POST Esx Settings Repository Software export + +POST Esx Settings Repository Software copy + +POST Esx Settings Repository Software edit + +POST Esx Settings Repository Software checkRepository + +Esx Settings Repository Software Alternative Images Effective Components + +GET Esx Settings Repository Software AlternativeImages EffectiveComponents list + +Esx Settings Repository Software Drafts + +GET Esx Settings Repository Software Drafts list + +POST Esx Settings Repository Software Drafts create + +GET Esx Settings Repository Software Drafts get + +DELETE Esx Settings Repository Software Drafts delete + +POST Esx Settings Repository Software Drafts importSoftwareSpec + +POST Esx Settings Repository Software Drafts commit$Task + +POST Esx Settings Repository Software Drafts validate$Task + +Esx Settings Repository Software Drafts Add On + +GET Esx Settings Repository Software Drafts AddOn get + +PUT Esx Settings Repository Software Drafts AddOn set + +DELETE Esx Settings Repository Software Drafts AddOn delete + +Esx Settings Repository Software Drafts Alternative Images + +GET Esx Settings Repository Software Drafts AlternativeImages list + +POST Esx Settings Repository Software Drafts AlternativeImages create + +GET Esx Settings Repository Software Drafts AlternativeImages get + +DELETE Esx Settings Repository Software Drafts AlternativeImages delete + +Esx Settings Repository Software Drafts Alternative Images Add On + +GET Esx Settings Repository Software Drafts AlternativeImages AddOn get + +PUT Esx Settings Repository Software Drafts AlternativeImages AddOn set + +DELETE Esx Settings Repository Software Drafts AlternativeImages AddOn delete + +Esx Settings Repository Software Drafts Alternative Images Base Image + +GET Esx Settings Repository Software Drafts AlternativeImages BaseImage get + +Esx Settings Repository Software Drafts Alternative Images Components + +GET Esx Settings Repository Software Drafts AlternativeImages Components get + +PUT Esx Settings Repository Software Drafts AlternativeImages Components set + +DELETE Esx Settings Repository Software Drafts AlternativeImages Components delete + +GET Esx Settings Repository Software Drafts AlternativeImages Components list + +PATCH Esx Settings Repository Software Drafts AlternativeImages Components update + +Esx Settings Repository Software Drafts Alternative Images Display Name + +GET Esx Settings Repository Software Drafts AlternativeImages DisplayName get + +PUT Esx Settings Repository Software Drafts AlternativeImages DisplayName set + +Esx Settings Repository Software Drafts Alternative Images Effective Components + +GET Esx Settings Repository Software Drafts AlternativeImages EffectiveComponents list + +Esx Settings Repository Software Drafts Alternative Images Hardware Support + +GET Esx Settings Repository Software Drafts AlternativeImages HardwareSupport get + +PUT Esx Settings Repository Software Drafts AlternativeImages HardwareSupport set + +DELETE Esx Settings Repository Software Drafts AlternativeImages HardwareSupport delete + +Esx Settings Repository Software Drafts Alternative Images Removed Components + +GET Esx Settings Repository Software Drafts AlternativeImages RemovedComponents get + +PUT Esx Settings Repository Software Drafts AlternativeImages RemovedComponents set + +DELETE Esx Settings Repository Software Drafts AlternativeImages RemovedComponents delete + +GET Esx Settings Repository Software Drafts AlternativeImages RemovedComponents list + +Esx Settings Repository Software Drafts Alternative Images Selection Criteria + +GET Esx Settings Repository Software Drafts AlternativeImages SelectionCriteria get + +PUT Esx Settings Repository Software Drafts AlternativeImages SelectionCriteria set + +Esx Settings Repository Software Drafts Base Image + +GET Esx Settings Repository Software Drafts BaseImage get + +PUT Esx Settings Repository Software Drafts BaseImage set + +Esx Settings Repository Software Drafts Components + +GET Esx Settings Repository Software Drafts Components get + +PUT Esx Settings Repository Software Drafts Components set + +DELETE Esx Settings Repository Software Drafts Components delete + +GET Esx Settings Repository Software Drafts Components list + +PATCH Esx Settings Repository Software Drafts Components update + +Esx Settings Repository Software Drafts Display Name + +GET Esx Settings Repository Software Drafts DisplayName get + +PUT Esx Settings Repository Software Drafts DisplayName set + +Esx Settings Repository Software Drafts Effective Components + +GET Esx Settings Repository Software Drafts EffectiveComponents list + +Esx Settings Repository Software Drafts Hardware Support + +GET Esx Settings Repository Software Drafts HardwareSupport get + +PUT Esx Settings Repository Software Drafts HardwareSupport set + +DELETE Esx Settings Repository Software Drafts HardwareSupport delete + +Esx Settings Repository Software Drafts Removed Components + +GET Esx Settings Repository Software Drafts RemovedComponents get + +PUT Esx Settings Repository Software Drafts RemovedComponents set + +DELETE Esx Settings Repository Software Drafts RemovedComponents delete + +GET Esx Settings Repository Software Drafts RemovedComponents list + +Esx Settings Repository Software Effective Components + +GET Esx Settings Repository Software EffectiveComponents list + +Vapi + +Vapi Metadata Authentication Component + +GET Vapi Metadata Authentication Component list + +GET Vapi Metadata Authentication Component get + +GET Vapi Metadata Authentication Component fingerprint + +Vapi Metadata Authentication Package + +GET Vapi Metadata Authentication Package list + +GET Vapi Metadata Authentication Package get + +Vapi Metadata Authentication Service + +GET Vapi Metadata Authentication Service list + +GET Vapi Metadata Authentication Service get + +Vapi Metadata Authentication Service Operation + +GET Vapi Metadata Authentication Service Operation list + +GET Vapi Metadata Authentication Service Operation get + +Vapi Metadata Cli Command + +GET Vapi Metadata Cli Command list + +POST Vapi Metadata Cli Command get + +GET Vapi Metadata Cli Command fingerprint + +Vapi Metadata Cli Namespace + +GET Vapi Metadata Cli Namespace list + +POST Vapi Metadata Cli Namespace get + +GET Vapi Metadata Cli Namespace fingerprint + +Vapi Metadata Metamodel Component + +GET Vapi Metadata Metamodel Component list + +GET Vapi Metadata Metamodel Component get + +GET Vapi Metadata Metamodel Component fingerprint + +Vapi Metadata Metamodel Enumeration + +GET Vapi Metadata Metamodel Enumeration list + +GET Vapi Metadata Metamodel Enumeration get + +Vapi Metadata Metamodel Package + +GET Vapi Metadata Metamodel Package list + +GET Vapi Metadata Metamodel Package get + +Vapi Metadata Metamodel Resource + +GET Vapi Metadata Metamodel Resource list + +Vapi Metadata Metamodel Resource Model + +GET Vapi Metadata Metamodel Resource Model list + +Vapi Metadata Metamodel Service + +GET Vapi Metadata Metamodel Service list + +GET Vapi Metadata Metamodel Service get + +Vapi Metadata Metamodel Service Operation + +GET Vapi Metadata Metamodel Service Operation list + +GET Vapi Metadata Metamodel Service Operation get + +Vapi Metadata Metamodel Structure + +GET Vapi Metadata Metamodel Structure list + +GET Vapi Metadata Metamodel Structure get + +Vapi Metadata Privilege Component + +GET Vapi Metadata Privilege Component list + +GET Vapi Metadata Privilege Component get + +GET Vapi Metadata Privilege Component fingerprint + +Vapi Metadata Privilege Package + +GET Vapi Metadata Privilege Package list + +GET Vapi Metadata Privilege Package get + +Vapi Metadata Privilege Service + +GET Vapi Metadata Privilege Service list + +GET Vapi Metadata Privilege Service get + +Vapi Metadata Privilege Service Operation + +GET Vapi Metadata Privilege Service Operation list + +GET Vapi Metadata Privilege Service Operation get + +Vcenter + +Vcenter Authorization Permissions + +POST Vcenter Authorization Permissions create + +GET Vcenter Authorization Permissions get + +DELETE Vcenter Authorization Permissions delete + +PATCH Vcenter Authorization Permissions update + +POST Vcenter Authorization Permissions list + +Vcenter Authorization Privilege Checks + +POST Vcenter Authorization PrivilegeChecks list + +Vcenter Authorization Privilege Checks Latest + +GET Vcenter Authorization PrivilegeChecks Latest get + +Vcenter Authorization Privileges + +GET Vcenter Authorization Privileges list + +GET Vcenter Authorization Privileges get + +Vcenter Authorization Roles + +GET Vcenter Authorization Roles list + +POST Vcenter Authorization Roles create + +GET Vcenter Authorization Roles get + +DELETE Vcenter Authorization Roles delete + +PATCH Vcenter Authorization Roles update + +Vcenter Authorization Vt Containers Mappings + +GET Vcenter Authorization VtContainers Mappings list + +POST Vcenter Authorization VtContainers Mappings create + +GET Vcenter Authorization VtContainers Mappings get + +DELETE Vcenter Authorization VtContainers Mappings delete + +Vcenter Capacity Usage + +GET Vcenter Capacity Usage get + +Vcenter Certificate Management Vcenter Signing Certificate + +GET Vcenter CertificateManagement Vcenter SigningCertificate get + +PUT Vcenter CertificateManagement Vcenter SigningCertificate set + +POST Vcenter CertificateManagement Vcenter SigningCertificate refresh + +Vcenter Certificate Management Vcenter Tls + +GET Vcenter CertificateManagement Vcenter Tls get + +PUT Vcenter CertificateManagement Vcenter Tls set + +POST Vcenter CertificateManagement Vcenter Tls renew + +POST Vcenter CertificateManagement Vcenter Tls replaceVmcaSigned + +Vcenter Certificate Management Vcenter Tls Csr + +POST Vcenter CertificateManagement Vcenter TlsCsr create + +Vcenter Certificate Management Vcenter Trusted Root Chains + +GET Vcenter CertificateManagement Vcenter TrustedRootChains list + +POST Vcenter CertificateManagement Vcenter TrustedRootChains create + +GET Vcenter CertificateManagement Vcenter TrustedRootChains get + +DELETE Vcenter CertificateManagement Vcenter TrustedRootChains delete + +Vcenter Certificate Management Vcenter Vmca Root + +POST Vcenter CertificateManagement Vcenter VmcaRoot create + +Vcenter Cluster + +GET Vcenter Cluster list + +GET Vcenter Cluster get + +Vcenter Cluster Evc Mode + +GET Vcenter Cluster EvcMode get + +PUT Vcenter Cluster EvcMode set$Task + +POST Vcenter Cluster EvcMode checkSet$Task + +POST Vcenter Cluster EvcMode checkAddHostEvc$Task + +Vcenter Confidential Computing Sgx Hosts + +POST Vcenter ConfidentialComputing Sgx Hosts register$Task + +Vcenter Consumption Domains Zone Associations Association Changes + +POST Vcenter ConsumptionDomains ZoneAssociations AssociationChanges list + +Vcenter Consumption Domains Zone Associations Cluster + +GET Vcenter ConsumptionDomains ZoneAssociations Cluster list + +Vcenter Consumption Domains Zones + +GET Vcenter ConsumptionDomains Zones list + +POST Vcenter ConsumptionDomains Zones create + +GET Vcenter ConsumptionDomains Zones get + +DELETE Vcenter ConsumptionDomains Zones delete + +Vcenter Consumption Domains Zones Capacity Summary + +GET Vcenter ConsumptionDomains Zones Capacity Summary get + +POST Vcenter ConsumptionDomains Zones Capacity Summary getPerCluster + +Vcenter Consumption Domains Zones Cluster Associations + +POST Vcenter ConsumptionDomains Zones Cluster Associations add + +POST Vcenter ConsumptionDomains Zones Cluster Associations remove + +GET Vcenter ConsumptionDomains Zones Cluster Associations get + +POST Vcenter ConsumptionDomains Zones Cluster Associations evacuateAndRemove$Task + +Vcenter Crypto Fips Modules + +GET Vcenter Crypto Fips Modules list + +Vcenter Crypto Manager Hosts Kms Providers + +GET Vcenter CryptoManager Hosts Kms Providers list + +GET Vcenter CryptoManager Hosts Kms Providers get + +Vcenter Crypto Manager Kms Providers + +GET Vcenter CryptoManager Kms Providers list + +POST Vcenter CryptoManager Kms Providers create + +GET Vcenter CryptoManager Kms Providers get + +DELETE Vcenter CryptoManager Kms Providers delete + +PATCH Vcenter CryptoManager Kms Providers update + +POST Vcenter CryptoManager Kms Providers export + +POST Vcenter CryptoManager Kms Providers importProvider + +Vcenter Datacenter + +GET Vcenter Datacenter list + +POST Vcenter Datacenter create + +GET Vcenter Datacenter get + +DELETE Vcenter Datacenter delete + +Vcenter Datastore + +GET Vcenter Datastore get + +GET Vcenter Datastore list + +Vcenter Datastore Default Policy + +GET Vcenter Datastore DefaultPolicy get + +Vcenter Deployment + +GET Vcenter Deployment get + +POST Vcenter Deployment rollback + +Vcenter Deployment Import History + +GET Vcenter Deployment ImportHistory get + +POST Vcenter Deployment ImportHistory start + +POST Vcenter Deployment ImportHistory pause + +POST Vcenter Deployment ImportHistory resume + +POST Vcenter Deployment ImportHistory cancel + +Vcenter Deployment Install + +GET Vcenter Deployment Install get + +POST Vcenter Deployment Install check + +POST Vcenter Deployment Install start + +POST Vcenter Deployment Install cancel + +Vcenter Deployment Install Initial Config Remote Psc Thumbprint + +GET Vcenter Deployment Install InitialConfig RemotePsc Thumbprint get + +Vcenter Deployment Install Psc Replicated + +POST Vcenter Deployment Install Psc Replicated check + +Vcenter Deployment Install Psc Standalone + +POST Vcenter Deployment Install Psc Standalone check + +Vcenter Deployment Install Remote Psc + +POST Vcenter Deployment Install RemotePsc check + +Vcenter Deployment Migrate + +GET Vcenter Deployment Migrate get + +POST Vcenter Deployment Migrate check + +POST Vcenter Deployment Migrate start + +POST Vcenter Deployment Migrate cancel + +Vcenter Deployment Migrate Active Directory + +POST Vcenter Deployment Migrate ActiveDirectory check + +Vcenter Deployment Question + +GET Vcenter Deployment Question get + +POST Vcenter Deployment Question answer + +Vcenter Deployment Size + +GET Vcenter Deployment Size get + +PATCH Vcenter Deployment Size update + +Vcenter Deployment Size Status + +GET Vcenter Deployment Size Status get + +Vcenter Deployment Upgrade + +GET Vcenter Deployment Upgrade get + +POST Vcenter Deployment Upgrade check + +POST Vcenter Deployment Upgrade start + +POST Vcenter Deployment Upgrade cancel + +Vcenter Environment Browser Config Option Descriptors + +GET Vcenter EnvironmentBrowser ConfigOptionDescriptors list + +Vcenter Environment Browser Config Options + +GET Vcenter EnvironmentBrowser ConfigOptions get + +Vcenter Environment Browser Config Targets + +GET Vcenter EnvironmentBrowser ConfigTargets get + +Vcenter Evc Modes + +POST Vcenter EvcModes partition + +POST Vcenter EvcModes create$Task + +Vcenter Folder + +GET Vcenter Folder list + +Vcenter Foundation Load Balancers + +GET Vcenter FoundationLoadBalancers list + +GET Vcenter FoundationLoadBalancers get + +POST Vcenter FoundationLoadBalancers resetPassword + +Vcenter Foundation Load Balancers Nodes + +POST Vcenter FoundationLoadBalancers Nodes enterMaintenanceMode + +POST Vcenter FoundationLoadBalancers Nodes exitMaintenanceMode + +POST Vcenter FoundationLoadBalancers Nodes redeploy + +GET Vcenter FoundationLoadBalancers Nodes get + +GET Vcenter FoundationLoadBalancers Nodes list + +Vcenter Guest Customization Specs + +GET Vcenter Guest CustomizationSpecs list + +POST Vcenter Guest CustomizationSpecs create + +GET Vcenter Guest CustomizationSpecs get + +PUT Vcenter Guest CustomizationSpecs set + +DELETE Vcenter Guest CustomizationSpecs delete + +POST Vcenter Guest CustomizationSpecs export + +POST Vcenter Guest CustomizationSpecs importSpecification + +Vcenter Host + +GET Vcenter Host list + +POST Vcenter Host create + +DELETE Vcenter Host delete + +POST Vcenter Host connect + +POST Vcenter Host disconnect + +Vcenter Host Crypto Fips Modules + +GET Vcenter Host Crypto Fips Modules list + +Vcenter Host Entropy External Pool + +GET Vcenter Host Entropy ExternalPool get + +POST Vcenter Host Entropy ExternalPool add + +Vcenter Host Hardware Direct Path Devices + +GET Vcenter Host Hardware DirectPathDevices list + +POST Vcenter Host Hardware DirectPathDevices configure$Task + +Vcenter Identity Broker Tenants Admin Client + +GET Vcenter Identity Broker Tenants AdminClient get + +Vcenter Identity Broker Tenants Operator Client + +GET Vcenter Identity Broker Tenants OperatorClient get + +Vcenter Identity Providers + +GET Vcenter Identity Providers list + +POST Vcenter Identity Providers create + +GET Vcenter Identity Providers get + +DELETE Vcenter Identity Providers delete + +PATCH Vcenter Identity Providers update + +Vcenter Network + +GET Vcenter Network list + +Vcenter Network Projects + +GET Vcenter Network Projects list + +GET Vcenter Network Projects get + +Vcenter Network Projects Vpcs + +GET Vcenter Network Projects Vpcs list + +GET Vcenter Network Projects Vpcs get + +Vcenter Network Projects Vpcs Subnets + +GET Vcenter Network Projects Vpcs Subnets list + +GET Vcenter Network Projects Vpcs Subnets get + +Vcenter Ovfs + +POST Vcenter Ovfs deploy$Task + +Vcenter Registered Tokens + +POST Vcenter RegisteredTokens create + +Vcenter Resource Pool + +GET Vcenter ResourcePool get + +DELETE Vcenter ResourcePool delete + +PATCH Vcenter ResourcePool update + +GET Vcenter ResourcePool list + +POST Vcenter ResourcePool create + +Vcenter Services Service + +POST Vcenter Services Service start + +POST Vcenter Services Service stop + +POST Vcenter Services Service restart + +GET Vcenter Services Service get + +PATCH Vcenter Services Service update + +GET Vcenter Services Service listDetails + +Vcenter Storage Policies + +GET Vcenter Storage Policies list + +POST Vcenter Storage Policies checkCompatibility + +Vcenter Storage Policies Compliance + +GET Vcenter Storage Policies Compliance list + +Vcenter Storage Policies Compliance Vm + +GET Vcenter Storage Policies Compliance VM list + +Vcenter Storage Policies Vm + +GET Vcenter Storage Policies VM list + +Vcenter System + +POST Vcenter System hello + +Vcenter System Config Deployment Type + +GET Vcenter SystemConfig DeploymentType get + +PUT Vcenter SystemConfig DeploymentType reconfigure + +Vcenter System Config Psc Registration + +GET Vcenter SystemConfig PscRegistration get + +POST Vcenter SystemConfig PscRegistration repoint + +Vcenter Tagging Associations + +GET Vcenter Tagging Associations list + +PATCH Vcenter Tagging Associations update + +Vcenter Tagging Categories + +GET Vcenter Tagging Categories list + +Vcenter Tagging Tags + +GET Vcenter Tagging Tags list + +Vcenter Topology Nodes + +GET Vcenter Topology Nodes list + +GET Vcenter Topology Nodes get + +Vcenter Topology Replication Status + +GET Vcenter Topology ReplicationStatus list + +Vcenter Trusted Infrastructure Attestation Services + +POST Vcenter TrustedInfrastructure Attestation Services list + +GET Vcenter TrustedInfrastructure Attestation Services get + +DELETE Vcenter TrustedInfrastructure Attestation Services delete + +POST Vcenter TrustedInfrastructure Attestation Services create + +Vcenter Trusted Infrastructure Hosts Hardware Tpm + +GET Vcenter TrustedInfrastructure Hosts Hardware Tpm list + +GET Vcenter TrustedInfrastructure Hosts Hardware Tpm get + +Vcenter Trusted Infrastructure Hosts Hardware Tpm Endorsement Keys + +GET Vcenter TrustedInfrastructure Hosts Hardware Tpm EndorsementKeys list + +GET Vcenter TrustedInfrastructure Hosts Hardware Tpm EndorsementKeys get + +POST Vcenter TrustedInfrastructure Hosts Hardware Tpm EndorsementKeys unseal + +Vcenter Trusted Infrastructure Hosts Hardware Tpm Event Log + +GET Vcenter TrustedInfrastructure Hosts Hardware Tpm EventLog get + +Vcenter Trusted Infrastructure Kms Services + +POST Vcenter TrustedInfrastructure Kms Services list + +GET Vcenter TrustedInfrastructure Kms Services get + +DELETE Vcenter TrustedInfrastructure Kms Services delete + +POST Vcenter TrustedInfrastructure Kms Services create + +Vcenter Trusted Infrastructure Principal + +GET Vcenter TrustedInfrastructure Principal get + +Vcenter Trusted Infrastructure Trust Authority Clusters + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters get + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters list + +PATCH Vcenter TrustedInfrastructure TrustAuthorityClusters update$Task + +Vcenter Trusted Infrastructure Trust Authority Clusters Attestation Os Esx Base Images + +POST Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Os Esx BaseImages importFromImgdb$Task + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Os Esx BaseImages list$Task + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Os Esx BaseImages get$Task + +DELETE Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Os Esx BaseImages delete$Task + +Vcenter Trusted Infrastructure Trust Authority Clusters Attestation Service Status + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation ServiceStatus get$Task + +Vcenter Trusted Infrastructure Trust Authority Clusters Attestation Tpm2 Ca Certificates + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 CaCertificates list$Task + +POST Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 CaCertificates create$Task + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 CaCertificates get$Task + +DELETE Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 CaCertificates delete$Task + +Vcenter Trusted Infrastructure Trust Authority Clusters Attestation Tpm2 Endorsement Keys + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 EndorsementKeys list$Task + +POST Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 EndorsementKeys create$Task + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 EndorsementKeys get$Task + +DELETE Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 EndorsementKeys delete$Task + +Vcenter Trusted Infrastructure Trust Authority Clusters Attestation Tpm2 Settings + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 Settings get$Task + +PATCH Vcenter TrustedInfrastructure TrustAuthorityClusters Attestation Tpm2 Settings update$Task + +Vcenter Trusted Infrastructure Trust Authority Clusters Consumer Principals + +POST Vcenter TrustedInfrastructure TrustAuthorityClusters ConsumerPrincipals create$Task + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters ConsumerPrincipals get$Task + +DELETE Vcenter TrustedInfrastructure TrustAuthorityClusters ConsumerPrincipals delete$Task + +POST Vcenter TrustedInfrastructure TrustAuthorityClusters ConsumerPrincipals list$Task + +Vcenter Trusted Infrastructure Trust Authority Clusters Kms Providers + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers list$Task + +POST Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers create$Task + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers get$Task + +DELETE Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers delete$Task + +PATCH Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers update$Task + +Vcenter Trusted Infrastructure Trust Authority Clusters Kms Providers Client Certificate + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers ClientCertificate get$Task + +POST Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers ClientCertificate create$Task + +PATCH Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers ClientCertificate update$Task + +Vcenter Trusted Infrastructure Trust Authority Clusters Kms Providers Client Certificate Csr + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers ClientCertificate Csr get$Task + +POST Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers ClientCertificate Csr create$Task + +Vcenter Trusted Infrastructure Trust Authority Clusters Kms Providers Credential + +PUT Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers Credential set$Task + +Vcenter Trusted Infrastructure Trust Authority Clusters Kms Providers Current Peer Certificates + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers CurrentPeerCertificates list$Task + +Vcenter Trusted Infrastructure Trust Authority Clusters Kms Providers Trusted Peer Certificates + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers TrustedPeerCertificates get$Task + +PATCH Vcenter TrustedInfrastructure TrustAuthorityClusters Kms Providers TrustedPeerCertificates update$Task + +Vcenter Trusted Infrastructure Trust Authority Clusters Kms Service Status + +GET Vcenter TrustedInfrastructure TrustAuthorityClusters Kms ServiceStatus get$Task + +Vcenter Trusted Infrastructure Trust Authority Hosts Attestation + +GET Vcenter TrustedInfrastructure TrustAuthorityHosts Attestation get + +POST Vcenter TrustedInfrastructure TrustAuthorityHosts Attestation list + +Vcenter Trusted Infrastructure Trust Authority Hosts Kms + +GET Vcenter TrustedInfrastructure TrustAuthorityHosts Kms get + +POST Vcenter TrustedInfrastructure TrustAuthorityHosts Kms list + +Vcenter Trusted Infrastructure Trusted Clusters Attestation Services + +POST Vcenter TrustedInfrastructure TrustedClusters Attestation Services list + +GET Vcenter TrustedInfrastructure TrustedClusters Attestation Services get + +POST Vcenter TrustedInfrastructure TrustedClusters Attestation Services create$Task + +DELETE Vcenter TrustedInfrastructure TrustedClusters Attestation Services delete$Task + +Vcenter Trusted Infrastructure Trusted Clusters Attestation Services Applied Config + +POST Vcenter TrustedInfrastructure TrustedClusters Attestation ServicesAppliedConfig list$Task + +GET Vcenter TrustedInfrastructure TrustedClusters Attestation ServicesAppliedConfig get$Task + +DELETE Vcenter TrustedInfrastructure TrustedClusters Attestation ServicesAppliedConfig delete$Task + +PATCH Vcenter TrustedInfrastructure TrustedClusters Attestation ServicesAppliedConfig update$Task + +Vcenter Trusted Infrastructure Trusted Clusters Kms Services + +POST Vcenter TrustedInfrastructure TrustedClusters Kms Services list + +GET Vcenter TrustedInfrastructure TrustedClusters Kms Services get + +POST Vcenter TrustedInfrastructure TrustedClusters Kms Services create$Task + +DELETE Vcenter TrustedInfrastructure TrustedClusters Kms Services delete$Task + +Vcenter Trusted Infrastructure Trusted Clusters Kms Services Applied Config + +POST Vcenter TrustedInfrastructure TrustedClusters Kms ServicesAppliedConfig list$Task + +GET Vcenter TrustedInfrastructure TrustedClusters Kms ServicesAppliedConfig get$Task + +DELETE Vcenter TrustedInfrastructure TrustedClusters Kms ServicesAppliedConfig delete$Task + +PATCH Vcenter TrustedInfrastructure TrustedClusters Kms ServicesAppliedConfig update$Task + +Vcenter Trusted Infrastructure Trusted Clusters Services Applied Config + +GET Vcenter TrustedInfrastructure TrustedClusters ServicesAppliedConfig get$Task + +DELETE Vcenter TrustedInfrastructure TrustedClusters ServicesAppliedConfig delete$Task + +PATCH Vcenter TrustedInfrastructure TrustedClusters ServicesAppliedConfig update$Task + +Vcenter Utilization Connections + +GET Vcenter Utilization Connections list + +Vcenter Utilization Proxies + +GET Vcenter Utilization Proxies list + +Vcenter Vcha Cluster + +POST Vcenter Vcha Cluster get + +POST Vcenter Vcha Cluster deploy$Task + +POST Vcenter Vcha Cluster failover$Task + +POST Vcenter Vcha Cluster undeploy$Task + +Vcenter Vcha Cluster Active + +POST Vcenter Vcha Cluster Active get + +Vcenter Vcha Cluster Deployment Type + +GET Vcenter Vcha Cluster DeploymentType get + +Vcenter Vcha Cluster Mode + +GET Vcenter Vcha Cluster Mode get + +PUT Vcenter Vcha Cluster Mode set$Task + +Vcenter Vcha Cluster Passive + +POST Vcenter Vcha Cluster Passive check + +POST Vcenter Vcha Cluster Passive redeploy$Task + +Vcenter Vcha Cluster Witness + +POST Vcenter Vcha Cluster Witness check + +POST Vcenter Vcha Cluster Witness redeploy$Task + +Vcenter Vcha Operations + +GET Vcenter Vcha Operations get + +Vcenter Vm + +GET Vcenter VM list + +POST Vcenter VM create + +POST Vcenter VM clone + +POST Vcenter VM relocate + +POST Vcenter VM instantClone + +GET Vcenter VM get + +DELETE Vcenter VM delete + +POST Vcenter VM register + +POST Vcenter VM unregister + +POST Vcenter VM clone$Task + +POST Vcenter VM relocate$Task + +Vcenter Vm Console Tickets + +POST Vcenter Vm Console Tickets create + +Vcenter Vm Data Sets + +GET Vcenter Vm DataSets list + +POST Vcenter Vm DataSets create + +GET Vcenter Vm DataSets get + +DELETE Vcenter Vm DataSets delete + +PATCH Vcenter Vm DataSets update + +Vcenter Vm Data Sets Entries + +GET Vcenter Vm DataSets Entries get + +PUT Vcenter Vm DataSets Entries set + +DELETE Vcenter Vm DataSets Entries delete + +GET Vcenter Vm DataSets Entries list + +Vcenter Vm Evc Mode + +GET Vcenter Vm EvcMode get + +PUT Vcenter Vm EvcMode set$Task + +Vcenter Vm Guest Customization + +GET Vcenter Vm Guest Customization get + +PUT Vcenter Vm Guest Customization set + +POST Vcenter Vm Guest Customization check + +Vcenter Vm Guest Customization Live + +GET Vcenter Vm Guest CustomizationLive get + +POST Vcenter Vm Guest CustomizationLive run$Task + +Vcenter Vm Guest Environment + +POST Vcenter Vm Guest Environment get + +POST Vcenter Vm Guest Environment list + +Vcenter Vm Guest Filesystem Directories + +POST Vcenter Vm Guest Filesystem Directories create + +POST Vcenter Vm Guest Filesystem Directories delete + +POST Vcenter Vm Guest Filesystem Directories move + +POST Vcenter Vm Guest Filesystem Directories createTemporary + +Vcenter Vm Guest Filesystem Files + +POST Vcenter Vm Guest Filesystem Files move + +POST Vcenter Vm Guest Filesystem Files update + +POST Vcenter Vm Guest Filesystem Files delete + +POST Vcenter Vm Guest Filesystem Files get + +POST Vcenter Vm Guest Filesystem Files createTemporary + +POST Vcenter Vm Guest Filesystem Files list + +Vcenter Vm Guest Filesystem Transfers + +POST Vcenter Vm Guest Filesystem Transfers create + +Vcenter Vm Guest Identity + +GET Vcenter Vm Guest Identity get + +Vcenter Vm Guest Local Filesystem + +GET Vcenter Vm Guest LocalFilesystem get + +Vcenter Vm Guest Networking + +GET Vcenter Vm Guest Networking get + +Vcenter Vm Guest Networking Interfaces + +GET Vcenter Vm Guest Networking Interfaces list + +Vcenter Vm Guest Networking Routes + +GET Vcenter Vm Guest Networking Routes list + +Vcenter Vm Guest Operations + +GET Vcenter Vm Guest Operations get + +Vcenter Vm Guest Power + +GET Vcenter Vm Guest Power get + +POST Vcenter Vm Guest Power shutdown + +POST Vcenter Vm Guest Power reboot + +POST Vcenter Vm Guest Power standby + +Vcenter Vm Guest Processes + +POST Vcenter Vm Guest Processes create + +POST Vcenter Vm Guest Processes get + +POST Vcenter Vm Guest Processes list + +POST Vcenter Vm Guest Processes delete + +Vcenter Vm Hardware + +GET Vcenter Vm Hardware get + +PATCH Vcenter Vm Hardware update + +POST Vcenter Vm Hardware upgrade + +Vcenter Vm Hardware Adapter Nvme + +GET Vcenter Vm Hardware Adapter Nvme list + +POST Vcenter Vm Hardware Adapter Nvme create + +GET Vcenter Vm Hardware Adapter Nvme get + +DELETE Vcenter Vm Hardware Adapter Nvme delete + +Vcenter Vm Hardware Adapter Sata + +GET Vcenter Vm Hardware Adapter Sata list + +POST Vcenter Vm Hardware Adapter Sata create + +GET Vcenter Vm Hardware Adapter Sata get + +DELETE Vcenter Vm Hardware Adapter Sata delete + +Vcenter Vm Hardware Adapter Scsi + +GET Vcenter Vm Hardware Adapter Scsi list + +POST Vcenter Vm Hardware Adapter Scsi create + +GET Vcenter Vm Hardware Adapter Scsi get + +DELETE Vcenter Vm Hardware Adapter Scsi delete + +PATCH Vcenter Vm Hardware Adapter Scsi update + +Vcenter Vm Hardware Boot + +GET Vcenter Vm Hardware Boot get + +PATCH Vcenter Vm Hardware Boot update + +Vcenter Vm Hardware Boot Device + +GET Vcenter Vm Hardware Boot Device get + +PUT Vcenter Vm Hardware Boot Device set + +Vcenter Vm Hardware Cdrom + +GET Vcenter Vm Hardware Cdrom list + +POST Vcenter Vm Hardware Cdrom create + +GET Vcenter Vm Hardware Cdrom get + +DELETE Vcenter Vm Hardware Cdrom delete + +PATCH Vcenter Vm Hardware Cdrom update + +POST Vcenter Vm Hardware Cdrom connect + +POST Vcenter Vm Hardware Cdrom disconnect + +Vcenter Vm Hardware Cpu + +GET Vcenter Vm Hardware Cpu get + +PATCH Vcenter Vm Hardware Cpu update + +Vcenter Vm Hardware Disk + +GET Vcenter Vm Hardware Disk list + +POST Vcenter Vm Hardware Disk create + +GET Vcenter Vm Hardware Disk get + +DELETE Vcenter Vm Hardware Disk delete + +PATCH Vcenter Vm Hardware Disk update + +Vcenter Vm Hardware Ethernet + +GET Vcenter Vm Hardware Ethernet list + +POST Vcenter Vm Hardware Ethernet create + +GET Vcenter Vm Hardware Ethernet get + +DELETE Vcenter Vm Hardware Ethernet delete + +PATCH Vcenter Vm Hardware Ethernet update + +POST Vcenter Vm Hardware Ethernet connect + +POST Vcenter Vm Hardware Ethernet disconnect + +Vcenter Vm Hardware Floppy + +GET Vcenter Vm Hardware Floppy list + +POST Vcenter Vm Hardware Floppy create + +GET Vcenter Vm Hardware Floppy get + +DELETE Vcenter Vm Hardware Floppy delete + +PATCH Vcenter Vm Hardware Floppy update + +POST Vcenter Vm Hardware Floppy connect + +POST Vcenter Vm Hardware Floppy disconnect + +Vcenter Vm Hardware Memory + +GET Vcenter Vm Hardware Memory get + +PATCH Vcenter Vm Hardware Memory update + +Vcenter Vm Hardware Parallel + +GET Vcenter Vm Hardware Parallel list + +POST Vcenter Vm Hardware Parallel create + +GET Vcenter Vm Hardware Parallel get + +DELETE Vcenter Vm Hardware Parallel delete + +PATCH Vcenter Vm Hardware Parallel update + +POST Vcenter Vm Hardware Parallel connect + +POST Vcenter Vm Hardware Parallel disconnect + +Vcenter Vm Hardware Serial + +GET Vcenter Vm Hardware Serial list + +POST Vcenter Vm Hardware Serial create + +GET Vcenter Vm Hardware Serial get + +DELETE Vcenter Vm Hardware Serial delete + +PATCH Vcenter Vm Hardware Serial update + +POST Vcenter Vm Hardware Serial connect + +POST Vcenter Vm Hardware Serial disconnect + +Vcenter Vm Library Item + +GET Vcenter Vm LibraryItem get + +Vcenter Vm Power + +GET Vcenter Vm Power get + +POST Vcenter Vm Power start + +POST Vcenter Vm Power stop + +POST Vcenter Vm Power suspend + +POST Vcenter Vm Power reset + +Vcenter Vm Storage Policy + +GET Vcenter Vm Storage Policy get + +PATCH Vcenter Vm Storage Policy update + +Vcenter Vm Storage Policy Compliance + +GET Vcenter Vm Storage Policy Compliance get + +POST Vcenter Vm Storage Policy Compliance check + +Vcenter Vm Tools + +GET Vcenter Vm Tools get + +PATCH Vcenter Vm Tools update + +POST Vcenter Vm Tools upgrade + +Vcenter Vm Tools Installer + +GET Vcenter Vm Tools Installer get + +POST Vcenter Vm Tools Installer connect + +POST Vcenter Vm Tools Installer disconnect + +Vcenter Authentication + +Vcenter Authentication Token + +POST Vcenter Authentication Token issue + +Vcenter Compute + +Vcenter Compute Policies + +GET Vcenter Compute Policies list + +POST Vcenter Compute Policies create + +GET Vcenter Compute Policies get + +DELETE Vcenter Compute Policies delete + +PATCH Vcenter Compute Policies update + +Vcenter Compute Policies Capabilities + +GET Vcenter Compute Policies Capabilities list + +GET Vcenter Compute Policies Capabilities get + +Vcenter Compute Policies Tag Usage + +GET Vcenter Compute Policies TagUsage list + +Vcenter Content Registries + +Vcenter Content Registries Harbor + +GET Vcenter Content Registries Harbor list + +POST Vcenter Content Registries Harbor create + +GET Vcenter Content Registries Harbor get + +DELETE Vcenter Content Registries Harbor delete + +Vcenter Content Registries Harbor Projects + +GET Vcenter Content Registries Harbor Projects list + +POST Vcenter Content Registries Harbor Projects create + +GET Vcenter Content Registries Harbor Projects get + +DELETE Vcenter Content Registries Harbor Projects delete + +POST Vcenter Content Registries Harbor Projects purge + +Vcenter Content Registries Health + +GET Vcenter Content Registries Health get + +Vcenter Inventory + +Vcenter Inventory Datastore + +GET Vcenter Inventory Datastore find + +Vcenter Inventory Network + +GET Vcenter Inventory Network find + +Vcenter Iso + +Vcenter Iso Image + +POST Vcenter Iso Image mount + +POST Vcenter Iso Image unmount + +Vcenter Lcm + +Vcenter Lcm Deployment Migration Upgrade + +GET Vcenter Lcm Deployment MigrationUpgrade get + +PUT Vcenter Lcm Deployment MigrationUpgrade set + +POST Vcenter Lcm Deployment MigrationUpgrade apply + +POST Vcenter Lcm Deployment MigrationUpgrade cancel + +POST Vcenter Lcm Deployment MigrationUpgrade check$Task + +Vcenter Lcm Deployment Migration Upgrade Planned Downtime + +GET Vcenter Lcm Deployment MigrationUpgrade PlannedDowntime get + +Vcenter Lcm Deployment Migration Upgrade Status + +GET Vcenter Lcm Deployment MigrationUpgrade Status get + +Vcenter Lcm Deployment Repository + +GET Vcenter Lcm Deployment Repository get + +PUT Vcenter Lcm Deployment Repository set + +Vcenter Lcm Depot Services + +GET Vcenter Lcm Depot Services get + +PUT Vcenter Lcm Depot Services set + +GET Vcenter Lcm Depot Services getServiceSpec + +Vcenter Lcm Discovery Associated Products + +GET Vcenter Lcm Discovery AssociatedProducts list + +POST Vcenter Lcm Discovery AssociatedProducts create + +GET Vcenter Lcm Discovery AssociatedProducts get + +DELETE Vcenter Lcm Discovery AssociatedProducts delete + +PATCH Vcenter Lcm Discovery AssociatedProducts update + +Vcenter Lcm Discovery Interop Report + +POST Vcenter Lcm Discovery InteropReport create$Task + +Vcenter Lcm Discovery Product Catalog + +GET Vcenter Lcm Discovery ProductCatalog list + +Vcenter Lcm Interop Interop Bundle + +PUT Vcenter Lcm Interop InteropBundle set$Task + +Vcenter Lcm Reports + +GET Vcenter Lcm Reports get + +Vcenter Lcm Update Pending + +GET Vcenter Lcm Update Pending list + +GET Vcenter Lcm Update Pending get + +Vcenter Lcm Update Precheck Report + +POST Vcenter Lcm Update PrecheckReport create$Task + +Vcenter Namespace Management + +Vcenter Namespace Management Cluster Available Versions + +GET Vcenter NamespaceManagement ClusterAvailableVersions list + +Vcenter Namespace Management Cluster Compatibility + +GET Vcenter NamespaceManagement ClusterCompatibility list + +GET Vcenter NamespaceManagement ClusterCompatibility listV2 + +Vcenter Namespace Management Cluster Size Info + +GET Vcenter NamespaceManagement ClusterSizeInfo get + +Vcenter Namespace Management Clusters + +POST Vcenter NamespaceManagement Clusters enable + +POST Vcenter NamespaceManagement Clusters disable + +GET Vcenter NamespaceManagement Clusters get + +PUT Vcenter NamespaceManagement Clusters set + +PATCH Vcenter NamespaceManagement Clusters update + +GET Vcenter NamespaceManagement Clusters list + +POST Vcenter NamespaceManagement Clusters rotatePassword + +Vcenter Namespace Management Clusters Topology + +GET Vcenter NamespaceManagement Clusters Topology get + +Vcenter Namespace Management Distributed Switch Compatibility + +GET Vcenter NamespaceManagement DistributedSwitchCompatibility list + +Vcenter Namespace Management Edge Cluster Compatibility + +GET Vcenter NamespaceManagement EdgeClusterCompatibility list + +Vcenter Namespace Management Hosts Config + +GET Vcenter NamespaceManagement HostsConfig get + +Vcenter Namespace Management Infrastructure Policies + +GET Vcenter NamespaceManagement InfrastructurePolicies list + +POST Vcenter NamespaceManagement InfrastructurePolicies create + +GET Vcenter NamespaceManagement InfrastructurePolicies get + +PUT Vcenter NamespaceManagement InfrastructurePolicies set + +DELETE Vcenter NamespaceManagement InfrastructurePolicies delete + +Vcenter Namespace Management Lifecycle Content Libraries + +GET Vcenter NamespaceManagement Lifecycle Content Libraries list + +PUT Vcenter NamespaceManagement Lifecycle Content Libraries set + +POST Vcenter NamespaceManagement Lifecycle Content Libraries unassign + +GET Vcenter NamespaceManagement Lifecycle Content Libraries get + +Vcenter Namespace Management Load Balancers + +GET Vcenter NamespaceManagement LoadBalancers get + +PUT Vcenter NamespaceManagement LoadBalancers set + +PATCH Vcenter NamespaceManagement LoadBalancers update + +GET Vcenter NamespaceManagement LoadBalancers list + +Vcenter Namespace Management Namespace Resource Options + +GET Vcenter NamespaceManagement NamespaceResourceOptions get + +Vcenter Namespace Management Networks + +GET Vcenter NamespaceManagement Networks list + +POST Vcenter NamespaceManagement Networks create + +GET Vcenter NamespaceManagement Networks get + +PUT Vcenter NamespaceManagement Networks set + +DELETE Vcenter NamespaceManagement Networks delete + +PATCH Vcenter NamespaceManagement Networks update + +Vcenter Namespace Management Networks Nsx Distributed Switches + +GET Vcenter NamespaceManagement Networks Nsx DistributedSwitches list + +Vcenter Namespace Management Networks Nsx Distributed Switches Compatibility + +POST Vcenter NamespaceManagement Networks Nsx DistributedSwitches Compatibility check + +Vcenter Namespace Management Networks Nsx Edges + +GET Vcenter NamespaceManagement Networks Nsx Edges list + +Vcenter Namespace Management Networks Nsx Edges Compatibility + +POST Vcenter NamespaceManagement Networks Nsx Edges Compatibility check + +Vcenter Namespace Management Networks Nsx Projects + +GET Vcenter NamespaceManagement Networks Nsx Projects list + +GET Vcenter NamespaceManagement Networks Nsx Projects get + +Vcenter Namespace Management Networks Nsx Projects Compatibility + +POST Vcenter NamespaceManagement Networks Nsx Projects Compatibility check + +Vcenter Namespace Management Networks Nsx Projects Vpc Connectivity Profiles + +GET Vcenter NamespaceManagement Networks Nsx Projects VpcConnectivityProfiles list + +GET Vcenter NamespaceManagement Networks Nsx Projects VpcConnectivityProfiles get + +Vcenter Namespace Management Networks Nsx Projects Vpcconnectivityprofiles Compatibility + +POST Vcenter NamespaceManagement Networks Nsx Projects Vpcconnectivityprofiles Compatibility check + +Vcenter Namespace Management Networks Nsx Projects Vpcs + +GET Vcenter NamespaceManagement Networks Nsx Projects Vpcs list + +GET Vcenter NamespaceManagement Networks Nsx Projects Vpcs get + +Vcenter Namespace Management Networks Nsx Projects Vpcs Compatibility + +POST Vcenter NamespaceManagement Networks Nsx Projects Vpcs Compatibility check + +Vcenter Namespace Management Nsxtier0gateway + +GET Vcenter NamespaceManagement NSXTier0Gateway list + +Vcenter Namespace Management Software Clusters + +POST Vcenter NamespaceManagement Software Clusters upgrade + +POST Vcenter NamespaceManagement Software Clusters upgradeMultiple + +GET Vcenter NamespaceManagement Software Clusters get + +GET Vcenter NamespaceManagement Software Clusters list + +Vcenter Namespace Management Software Supervisors Prechecks + +POST Vcenter NamespaceManagement Software Supervisors Prechecks run + +GET Vcenter NamespaceManagement Software Supervisors Prechecks get + +Vcenter Namespace Management Software Supervisors Upgrades + +GET Vcenter NamespaceManagement Software Supervisors Upgrades list + +GET Vcenter NamespaceManagement Software Supervisors Upgrades get + +Vcenter Namespace Management Software Supervisors Upgrades Jobs + +POST Vcenter NamespaceManagement Software Supervisors Upgrades Jobs create + +Vcenter Namespace Management Software Supervisors Versions + +GET Vcenter NamespaceManagement Software Supervisors Versions list + +GET Vcenter NamespaceManagement Software Supervisors Versions get + +POST Vcenter NamespaceManagement Software Supervisors Versions checkCompatibility + +Vcenter Namespace Management Software Supervisors Versions Control Plane Sizes + +GET Vcenter NamespaceManagement Software Supervisors Versions ControlPlane Sizes list + +Vcenter Namespace Management Stats Time Series + +GET Vcenter NamespaceManagement Stats TimeSeries get + +Vcenter Namespace Management Storage Profiles + +POST Vcenter NamespaceManagement Storage Profiles check + +Vcenter Namespace Management Supervisor Services + +POST Vcenter NamespaceManagement SupervisorServices checkContent + +GET Vcenter NamespaceManagement SupervisorServices list + +POST Vcenter NamespaceManagement SupervisorServices create + +GET Vcenter NamespaceManagement SupervisorServices get + +DELETE Vcenter NamespaceManagement SupervisorServices delete + +PATCH Vcenter NamespaceManagement SupervisorServices update + +PATCH Vcenter NamespaceManagement SupervisorServices deactivate + +PATCH Vcenter NamespaceManagement SupervisorServices activate + +Vcenter Namespace Management Supervisor Services Cluster Supervisor Services + +GET Vcenter NamespaceManagement SupervisorServices ClusterSupervisorServices list + +POST Vcenter NamespaceManagement SupervisorServices ClusterSupervisorServices create + +GET Vcenter NamespaceManagement SupervisorServices ClusterSupervisorServices get + +PUT Vcenter NamespaceManagement SupervisorServices ClusterSupervisorServices set + +DELETE Vcenter NamespaceManagement SupervisorServices ClusterSupervisorServices delete + +Vcenter Namespace Management Supervisor Services Versions + +GET Vcenter NamespaceManagement SupervisorServices Versions list + +POST Vcenter NamespaceManagement SupervisorServices Versions create + +PATCH Vcenter NamespaceManagement SupervisorServices Versions deactivate + +PATCH Vcenter NamespaceManagement SupervisorServices Versions activate + +GET Vcenter NamespaceManagement SupervisorServices Versions get + +DELETE Vcenter NamespaceManagement SupervisorServices Versions delete + +Vcenter Namespace Management Supervisors + +POST Vcenter NamespaceManagement Supervisors enableOnZones + +POST Vcenter NamespaceManagement Supervisors enableOnComputeCluster + +DELETE Vcenter NamespaceManagement Supervisors delete + +Vcenter Namespace Management Supervisors Capabilities + +GET Vcenter NamespaceManagement Supervisors Capabilities list + +Vcenter Namespace Management Supervisors Certificates + +GET Vcenter NamespaceManagement Supervisors Certificates list + +PATCH Vcenter NamespaceManagement Supervisors Certificates update + +Vcenter Namespace Management Supervisors Certificates Key Sizes + +GET Vcenter NamespaceManagement Supervisors Certificates KeySizes get + +PATCH Vcenter NamespaceManagement Supervisors Certificates KeySizes update + +Vcenter Namespace Management Supervisors Certificates Signing Requests + +POST Vcenter NamespaceManagement Supervisors Certificates SigningRequests create + +Vcenter Namespace Management Supervisors Conditions + +GET Vcenter NamespaceManagement Supervisors Conditions get + +Vcenter Namespace Management Supervisors Container Image Registries + +GET Vcenter NamespaceManagement Supervisors ContainerImageRegistries list + +POST Vcenter NamespaceManagement Supervisors ContainerImageRegistries create + +GET Vcenter NamespaceManagement Supervisors ContainerImageRegistries get + +DELETE Vcenter NamespaceManagement Supervisors ContainerImageRegistries delete + +PATCH Vcenter NamespaceManagement Supervisors ContainerImageRegistries update + +Vcenter Namespace Management Supervisors Control Plane Networks Settings + +GET Vcenter NamespaceManagement Supervisors ControlPlane Networks Settings get + +PATCH Vcenter NamespaceManagement Supervisors ControlPlane Networks Settings update + +Vcenter Namespace Management Supervisors Control Plane Passwords + +POST Vcenter NamespaceManagement Supervisors ControlPlane Passwords reset + +Vcenter Namespace Management Supervisors Control Plane Settings + +GET Vcenter NamespaceManagement Supervisors ControlPlane Settings get + +PATCH Vcenter NamespaceManagement Supervisors ControlPlane Settings update + +Vcenter Namespace Management Supervisors Control Plane Storage Policies + +GET Vcenter NamespaceManagement Supervisors ControlPlane Storage Policies get + +PATCH Vcenter NamespaceManagement Supervisors ControlPlane Storage Policies update + +Vcenter Namespace Management Supervisors Crypto Fips Modules + +GET Vcenter NamespaceManagement Supervisors Crypto Fips Modules list + +Vcenter Namespace Management Supervisors Identity Domains + +GET Vcenter NamespaceManagement Supervisors Identity Domains get + +GET Vcenter NamespaceManagement Supervisors Identity Domains list + +Vcenter Namespace Management Supervisors Identity Providers + +GET Vcenter NamespaceManagement Supervisors Identity Providers get + +PUT Vcenter NamespaceManagement Supervisors Identity Providers set + +DELETE Vcenter NamespaceManagement Supervisors Identity Providers delete + +PATCH Vcenter NamespaceManagement Supervisors Identity Providers update + +GET Vcenter NamespaceManagement Supervisors Identity Providers list + +POST Vcenter NamespaceManagement Supervisors Identity Providers create + +Vcenter Namespace Management Supervisors Logs Agent Configuration + +GET Vcenter NamespaceManagement Supervisors Logs AgentConfiguration get + +PUT Vcenter NamespaceManagement Supervisors Logs AgentConfiguration set + +Vcenter Namespace Management Supervisors Management Services + +GET Vcenter NamespaceManagement Supervisors ManagementServices list + +POST Vcenter NamespaceManagement Supervisors ManagementServices create + +GET Vcenter NamespaceManagement Supervisors ManagementServices get + +DELETE Vcenter NamespaceManagement Supervisors ManagementServices delete + +PATCH Vcenter NamespaceManagement Supervisors ManagementServices update + +Vcenter Namespace Management Supervisors Metrics Remote Endpoints + +GET Vcenter NamespaceManagement Supervisors Metrics RemoteEndpoints get + +PUT Vcenter NamespaceManagement Supervisors Metrics RemoteEndpoints set + +DELETE Vcenter NamespaceManagement Supervisors Metrics RemoteEndpoints delete + +PATCH Vcenter NamespaceManagement Supervisors Metrics RemoteEndpoints update + +GET Vcenter NamespaceManagement Supervisors Metrics RemoteEndpoints list + +POST Vcenter NamespaceManagement Supervisors Metrics RemoteEndpoints create + +Vcenter Namespace Management Supervisors Networks + +GET Vcenter NamespaceManagement Supervisors Networks list + +POST Vcenter NamespaceManagement Supervisors Networks create + +GET Vcenter NamespaceManagement Supervisors Networks get + +DELETE Vcenter NamespaceManagement Supervisors Networks delete + +PATCH Vcenter NamespaceManagement Supervisors Networks update + +Vcenter Namespace Management Supervisors Networks Edges + +GET Vcenter NamespaceManagement Supervisors Networks Edges list + +POST Vcenter NamespaceManagement Supervisors Networks Edges create + +PATCH Vcenter NamespaceManagement Supervisors Networks Edges update + +Vcenter Namespace Management Supervisors Recovery Backup Archives + +GET Vcenter NamespaceManagement Supervisors Recovery Backup Archives list + +Vcenter Namespace Management Supervisors Recovery Backup Jobs + +POST Vcenter NamespaceManagement Supervisors Recovery Backup Jobs create + +Vcenter Namespace Management Supervisors Recovery Restore Jobs + +POST Vcenter NamespaceManagement Supervisors Recovery Restore Jobs create + +Vcenter Namespace Management Supervisors Storage Cloud Native Resource Checks + +GET Vcenter NamespaceManagement Supervisors Storage CloudNative ResourceChecks get + +POST Vcenter NamespaceManagement Supervisors Storage CloudNative ResourceChecks create + +Vcenter Namespace Management Supervisors Summary + +GET Vcenter NamespaceManagement Supervisors Summary get + +GET Vcenter NamespaceManagement Supervisors Summary list + +Vcenter Namespace Management Supervisors Supervisor Service Settings + +GET Vcenter NamespaceManagement Supervisors SupervisorServiceSettings get + +PATCH Vcenter NamespaceManagement Supervisors SupervisorServiceSettings update + +Vcenter Namespace Management Supervisors Supervisor Services + +POST Vcenter NamespaceManagement Supervisors SupervisorServices precheck + +GET Vcenter NamespaceManagement Supervisors SupervisorServices getPrecheckResult + +GET Vcenter NamespaceManagement Supervisors SupervisorServices list + +POST Vcenter NamespaceManagement Supervisors SupervisorServices create + +GET Vcenter NamespaceManagement Supervisors SupervisorServices get + +PUT Vcenter NamespaceManagement Supervisors SupervisorServices set + +DELETE Vcenter NamespaceManagement Supervisors SupervisorServices delete + +Vcenter Namespace Management Supervisors Supervisor Services Signatures + +GET Vcenter NamespaceManagement Supervisors SupervisorServices Signatures get + +GET Vcenter NamespaceManagement Supervisors SupervisorServices Signatures list + +Vcenter Namespace Management Supervisors Support Bundles + +POST Vcenter NamespaceManagement Supervisors SupportBundles create + +Vcenter Namespace Management Supervisors Topology + +GET Vcenter NamespaceManagement Supervisors Topology get + +Vcenter Namespace Management Supervisors Vsphere Pod Settings + +GET Vcenter NamespaceManagement Supervisors VspherePodSettings get + +PATCH Vcenter NamespaceManagement Supervisors VspherePodSettings update + +Vcenter Namespace Management Supervisors Workloads Images Settings + +GET Vcenter NamespaceManagement Supervisors Workloads Images Settings get + +PATCH Vcenter NamespaceManagement Supervisors Workloads Images Settings update + +Vcenter Namespace Management Supervisors Workloads Kube Api Server Settings + +GET Vcenter NamespaceManagement Supervisors Workloads KubeApiServerSettings get + +PATCH Vcenter NamespaceManagement Supervisors Workloads KubeApiServerSettings update + +Vcenter Namespace Management Supervisors Workloads Networks Settings + +GET Vcenter NamespaceManagement Supervisors Workloads Networks Settings get + +PATCH Vcenter NamespaceManagement Supervisors Workloads Networks Settings update + +Vcenter Namespace Management Supervisors Workloads Storage Cloud Native File Volumes + +GET Vcenter NamespaceManagement Supervisors Workloads Storage CloudNative FileVolumes get + +PATCH Vcenter NamespaceManagement Supervisors Workloads Storage CloudNative FileVolumes update + +Vcenter Namespace Management Supervisors Workloads Storage Policies + +GET Vcenter NamespaceManagement Supervisors Workloads Storage Policies get + +PATCH Vcenter NamespaceManagement Supervisors Workloads Storage Policies update + +Vcenter Namespace Management Supervisors Zones Bindings + +GET Vcenter NamespaceManagement Supervisors Zones Bindings list + +POST Vcenter NamespaceManagement Supervisors Zones Bindings create + +PUT Vcenter NamespaceManagement Supervisors Zones Bindings set + +DELETE Vcenter NamespaceManagement Supervisors Zones Bindings delete + +PATCH Vcenter NamespaceManagement Supervisors Zones Bindings update + +Vcenter Namespace Management Support Bundle + +POST Vcenter NamespaceManagement SupportBundle create + +Vcenter Namespace Management Virtual Machine Classes + +GET Vcenter NamespaceManagement VirtualMachineClasses list + +POST Vcenter NamespaceManagement VirtualMachineClasses create + +GET Vcenter NamespaceManagement VirtualMachineClasses get + +DELETE Vcenter NamespaceManagement VirtualMachineClasses delete + +PATCH Vcenter NamespaceManagement VirtualMachineClasses update + +Vcenter Namespace Management Zones Cluster Compatibilities + +POST Vcenter NamespaceManagement Zones ClusterCompatibilities create + +Vcenter Namespaces + +Vcenter Namespaces Access + +GET Vcenter Namespaces Access get + +PUT Vcenter Namespaces Access set + +POST Vcenter Namespaces Access create + +DELETE Vcenter Namespaces Access delete + +Vcenter Namespaces Instances + +GET Vcenter Namespaces Instances list + +POST Vcenter Namespaces Instances create + +GET Vcenter Namespaces Instances listV2 + +POST Vcenter Namespaces Instances createV2 + +GET Vcenter Namespaces Instances get + +PUT Vcenter Namespaces Instances set + +DELETE Vcenter Namespaces Instances delete + +PATCH Vcenter Namespaces Instances update + +GET Vcenter Namespaces Instances getV2 + +POST Vcenter Namespaces Instances registerVM + +Vcenter Namespaces Instances Zones + +DELETE Vcenter Namespaces Instances Zones delete + +Vcenter Namespaces Management Services Access Grants + +GET Vcenter Namespaces ManagementServices AccessGrants list + +POST Vcenter Namespaces ManagementServices AccessGrants create + +GET Vcenter Namespaces ManagementServices AccessGrants get + +DELETE Vcenter Namespaces ManagementServices AccessGrants delete + +PATCH Vcenter Namespaces ManagementServices AccessGrants update + +Vcenter Namespaces Mobility Virtualmachines Imports + +POST Vcenter Namespaces Mobility Virtualmachines Imports create + +GET Vcenter Namespaces Mobility Virtualmachines Imports get + +Vcenter Namespaces Namespace Self Service + +POST Vcenter Namespaces NamespaceSelfService activate + +POST Vcenter Namespaces NamespaceSelfService deactivate + +GET Vcenter Namespaces NamespaceSelfService get + +GET Vcenter Namespaces NamespaceSelfService list + +POST Vcenter Namespaces NamespaceSelfService activateWithTemplate + +Vcenter Namespaces Namespace Templates + +GET Vcenter Namespaces NamespaceTemplates get + +PATCH Vcenter Namespaces NamespaceTemplates update + +GET Vcenter Namespaces NamespaceTemplates getV2 + +PATCH Vcenter Namespaces NamespaceTemplates updateV2 + +GET Vcenter Namespaces NamespaceTemplates list + +POST Vcenter Namespaces NamespaceTemplates create + +GET Vcenter Namespaces NamespaceTemplates listV2 + +POST Vcenter Namespaces NamespaceTemplates createV2 + +Vcenter Namespaces Networks Nsx Subnets + +GET Vcenter Namespaces Networks Nsx Subnets list + +Vcenter Namespaces User Instances + +GET Vcenter Namespaces User Instances list + +Vcenter Ovf + +Vcenter Ovf Export Flag + +GET Vcenter Ovf ExportFlag list + +Vcenter Ovf Import Flag + +GET Vcenter Ovf ImportFlag list + +Vcenter Ovf Library Item + +POST Vcenter Ovf LibraryItem deploy + +POST Vcenter Ovf LibraryItem filter + +POST Vcenter Ovf LibraryItem create + +Vcenter Phm + +Vcenter Phm About + +GET Vcenter Phm About get + +Vcenter Phm Hardware Support Managers + +GET Vcenter Phm HardwareSupportManagers list + +POST Vcenter Phm HardwareSupportManagers create + +GET Vcenter Phm HardwareSupportManagers get + +PUT Vcenter Phm HardwareSupportManagers set + +DELETE Vcenter Phm HardwareSupportManagers delete + +Vcenter Phm Hardware Support Managers Managed Hosts + +GET Vcenter Phm HardwareSupportManagers ManagedHosts list + +PATCH Vcenter Phm HardwareSupportManagers ManagedHosts update + +Vcenter Phm Hardware Support Managers Resource Bundle + +GET Vcenter Phm HardwareSupportManagers ResourceBundle get + +PATCH Vcenter Phm HardwareSupportManagers ResourceBundle update + +Vcenter Vm Compute + +Vcenter Vm Compute Policies + +GET Vcenter Vm Compute Policies get + +Vcenter Vm Template + +Vcenter Vm Template Library Items + +POST Vcenter VmTemplate LibraryItems create + +POST Vcenter VmTemplate LibraryItems deploy + +GET Vcenter VmTemplate LibraryItems get + +Vcenter Vm Template Library Items Check Outs + +POST Vcenter VmTemplate LibraryItems CheckOuts checkOut + +POST Vcenter VmTemplate LibraryItems CheckOuts checkIn + +GET Vcenter VmTemplate LibraryItems CheckOuts list + +GET Vcenter VmTemplate LibraryItems CheckOuts get + +DELETE Vcenter VmTemplate LibraryItems CheckOuts delete + +Vcenter Vm Template Library Items Versions + +GET Vcenter VmTemplate LibraryItems Versions list + +GET Vcenter VmTemplate LibraryItems Versions get + +DELETE Vcenter VmTemplate LibraryItems Versions delete + +POST Vcenter VmTemplate LibraryItems Versions rollback + +Top \ No newline at end of file diff --git a/docker-compose.release.yml b/docker-compose.release.yml new file mode 100644 index 0000000..f91a567 --- /dev/null +++ b/docker-compose.release.yml @@ -0,0 +1,132 @@ +# Quick start with the published Docker Hub runtime image. +# +# docker compose -f docker-compose.release.yml up -d --wait +# +# Requires this repository checkout (gateway TLS + nginx conf are bind-mounted). +# Seed runs once after the simulator is healthy. +# +# Override the image tag: +# IMAGE_TAG=0.1.0 docker compose -f docker-compose.release.yml up -d --wait +# +# Clients should hit api-gateway HTTPS (:443). + +name: vmware-api-simulator-release + +x-app-image: &app-image + image: ${DOCKER_IMAGE:-inecs/vmware-api-simulator}:${IMAGE_TAG:-latest} + +x-app-env: &app-env + DATABASE_URL: postgresql://vmware:vmware@postgres:5432/vmware_simulator + ENABLE_PVE_STUB: "false" + LOG_LEVEL: ${LOG_LEVEL:-INFO} + TICKET_SIGNING_KEY: ${TICKET_SIGNING_KEY:-development-only-signing-key-change-me} + TASK_WORKER_CONCURRENCY: ${TASK_WORKER_CONCURRENCY:-2} + SIMULATION_TIME_SCALE: ${SIMULATION_TIME_SCALE:-10} + APP_PORT: "8080" + +networks: + simulator: + driver: bridge + +volumes: + postgres-data: + +services: + postgres: + image: postgres:17.5-bookworm + restart: unless-stopped + networks: [simulator] + environment: + POSTGRES_DB: vmware_simulator + POSTGRES_USER: vmware + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-vmware} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U vmware -d vmware_simulator"] + interval: 5s + timeout: 3s + retries: 10 + start_period: 5s + volumes: + - postgres-data:/var/lib/postgresql/data + ports: + - "${POSTGRES_PORT:-127.0.0.1:5434}:5432" + + migrate: + <<: *app-image + networks: [simulator] + environment: + <<: *app-env + DATABASE_URL: postgresql://vmware:${POSTGRES_PASSWORD:-vmware}@postgres:5432/vmware_simulator + depends_on: + postgres: + condition: service_healthy + entrypoint: ["python"] + command: ["-m", "app.db.migrate_cli"] + restart: "no" + + simulator: + <<: *app-image + restart: unless-stopped + networks: [simulator] + environment: + <<: *app-env + DATABASE_URL: postgresql://vmware:${POSTGRES_PASSWORD:-vmware}@postgres:5432/vmware_simulator + depends_on: + migrate: + condition: service_completed_successfully + healthcheck: + test: + [ + "CMD", + "python", + "-c", + "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/health/ready', timeout=2)", + ] + interval: 10s + timeout: 3s + retries: 8 + start_period: 20s + expose: + - "8080" + + seed: + <<: *app-image + networks: [simulator] + environment: + <<: *app-env + DATABASE_URL: postgresql://vmware:${POSTGRES_PASSWORD:-vmware}@postgres:5432/vmware_simulator + SEED_PROFILE: ${SEED_PROFILE:-small} + SEED_VSPHERE_PROFILE: ${SEED_VSPHERE_PROFILE:-small} + depends_on: + simulator: + condition: service_healthy + entrypoint: ["python"] + command: ["-m", "app.simulation.seed_cli"] + restart: "no" + + api-gateway: + image: nginx:1.28.0-alpine + restart: unless-stopped + networks: [simulator] + depends_on: + simulator: + condition: service_healthy + seed: + condition: service_completed_successfully + ports: + - "${HTTP_PORT:-80}:80" + - "${HTTPS_PORT:-443}:443" + volumes: + - ./docker/gateway/vmware-ports.conf:/etc/nginx/conf.d/default.conf:ro + - ./docker/tls/server.crt:/etc/nginx/tls/server.crt:ro + - ./docker/tls/server.key:/etc/nginx/tls/server.key:ro + healthcheck: + test: + [ + "CMD-SHELL", + "wget -qO- http://127.0.0.1/health/live || exit 1", + ] + interval: 10s + timeout: 3s + retries: 5 + start_period: 5s diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..5176306 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,171 @@ +name: vmware-api-simulator + +x-simulator-env: &simulator-env + DATABASE_URL: postgresql://vmware:vmware@postgres:5432/vmware_simulator + ENABLE_PVE_STUB: "false" + SEED_VSPHERE_PROFILE: "${SEED_VSPHERE_PROFILE:-large}" + SEED_VSPHERE_LARGE_HOSTS: "${SEED_VSPHERE_LARGE_HOSTS:-10}" + SEED_VSPHERE_LARGE_VMS: "${SEED_VSPHERE_LARGE_VMS:-1000}" + LOG_LEVEL: INFO + TICKET_SIGNING_KEY: development-only-signing-key-change-me + APP_PORT: "8080" + +x-dev-env: &dev-env + DATABASE_URL: postgresql://vmware:vmware@postgres:5432/vmware_simulator + TEST_DATABASE_URL: postgresql://vmware:vmware@postgres:5432/vmware_simulator + ENABLE_PVE_STUB: "false" + SEED_VSPHERE_PROFILE: "${SEED_VSPHERE_PROFILE:-large}" + SEED_VSPHERE_LARGE_HOSTS: "${SEED_VSPHERE_LARGE_HOSTS:-10}" + SEED_VSPHERE_LARGE_VMS: "${SEED_VSPHERE_LARGE_VMS:-1000}" + LOG_LEVEL: INFO + TICKET_SIGNING_KEY: development-only-signing-key-change-me + APP_PORT: "8080" + +networks: + simulator: + driver: bridge + +volumes: + postgres-data: + +services: + postgres: + image: postgres:17.5-bookworm + restart: unless-stopped + networks: [simulator] + environment: + POSTGRES_DB: vmware_simulator + POSTGRES_USER: vmware + POSTGRES_PASSWORD: vmware + healthcheck: + test: ["CMD-SHELL", "pg_isready -U vmware -d vmware_simulator"] + interval: 5s + timeout: 3s + retries: 10 + start_period: 5s + volumes: + - postgres-data:/var/lib/postgresql/data + ports: + - "127.0.0.1:5434:5432" + + migrate: + build: + context: . + target: runtime + image: vmware-api-simulator:0.1.0 + networks: [simulator] + env_file: + - path: .env + required: false + environment: + <<: *simulator-env + depends_on: + postgres: + condition: service_healthy + entrypoint: ["python"] + command: ["-m", "app.db.migrate_cli"] + restart: "no" + + # FastAPI process — internal only. Clients use api-gateway :443. + simulator: + build: + context: . + target: dev + image: vmware-api-simulator-dev:0.1.0 + restart: unless-stopped + networks: [simulator] + working_dir: /workspace + volumes: + - .:/workspace + env_file: + - path: .env + required: false + environment: + <<: *dev-env + depends_on: + migrate: + condition: service_completed_successfully + entrypoint: [] + command: + [ + "uvicorn", + "app.main:app", + "--host", + "0.0.0.0", + "--port", + "8080", + "--reload", + "--reload-dir", + "/workspace/app", + "--reload-include", + "*.html", + ] + healthcheck: + test: + [ + "CMD", + "python", + "-c", + "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/health/ready', timeout=2)", + ] + interval: 10s + timeout: 3s + retries: 8 + start_period: 20s + expose: + - "8080" + + # Publishes vCenter HTTPS (and HTTP redirect face) → single simulator. + # See docs/ports.md + api-gateway: + image: nginx:1.28.0-alpine + restart: unless-stopped + networks: [simulator] + depends_on: + simulator: + condition: service_healthy + ports: + # Real vCenter defaults on the host (clients on other machines use these). + - "80:80" # HTTP face + - "443:443" # vCenter HTTPS (primary UI/API) + volumes: + - ./docker/gateway/vmware-ports.conf:/etc/nginx/conf.d/default.conf:ro + - ./docker/tls/server.crt:/etc/nginx/tls/server.crt:ro + - ./docker/tls/server.key:/etc/nginx/tls/server.key:ro + healthcheck: + test: + [ + "CMD-SHELL", + "wget -qO- http://127.0.0.1/health/live || exit 1", + ] + interval: 10s + timeout: 3s + retries: 5 + start_period: 5s + read_only: true + tmpfs: + - /var/cache/nginx + - /var/run + - /tmp + security_opt: + - no-new-privileges:true + + dev: + profiles: [tools] + build: + context: . + target: dev + image: vmware-api-simulator-dev:0.1.0 + networks: [simulator] + working_dir: /workspace + volumes: + - .:/workspace + env_file: + - path: .env + required: false + environment: + <<: *dev-env + depends_on: + postgres: + condition: service_healthy + entrypoint: [] diff --git a/docker/gateway/vmware-ports.conf b/docker/gateway/vmware-ports.conf new file mode 100644 index 0000000..331f3a5 --- /dev/null +++ b/docker/gateway/vmware-ports.conf @@ -0,0 +1,60 @@ +# Lab gateway that exposes vCenter default HTTPS (443) and proxies to the +# single FastAPI simulator process. +# +# Upstream listens on an internal-only port (simulator:8080). Host clients +# should hit https://localhost/ — not the internal app port. + +upstream vmware_simulator { + server simulator:8080; +} + +map $server_port $vmware_service { + default "simulator"; + 80 "http"; + 443 "vcenter"; +} + +server { + listen 80; + server_name _; + resolver 127.0.0.11 valid=10s ipv6=off; + + location / { + proxy_pass http://vmware_simulator; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header X-VMware-Service $vmware_service; + proxy_set_header X-Request-ID $request_id; + add_header X-VMware-Service $vmware_service always; + add_header X-Forwarded-Port $server_port always; + } +} + +server { + listen 443 ssl; + server_name _; + + ssl_certificate /etc/nginx/tls/server.crt; + ssl_certificate_key /etc/nginx/tls/server.key; + ssl_protocols TLSv1.2 TLSv1.3; + + resolver 127.0.0.11 valid=10s ipv6=off; + + location / { + proxy_pass http://vmware_simulator; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + proxy_set_header X-Forwarded-Port 443; + proxy_set_header X-VMware-Service vcenter; + proxy_set_header X-Request-ID $request_id; + add_header X-VMware-Service vcenter always; + add_header X-Forwarded-Port 443 always; + } +} diff --git a/docker/tls/server.crt b/docker/tls/server.crt new file mode 100644 index 0000000..bce557b --- /dev/null +++ b/docker/tls/server.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIJAIbJhnhVx8uWMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV +BAMMCWxvY2FsaG9zdDAeFw0yNjA3MTIyMTQyNTFaFw0zNjA3MDkyMTQyNTFaMBQx +EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALscj7/1WDybjz8x01EvUFVemov6zkezOwfsOXKVyEOnOTxPjWruzDYnB8y6 +NH/5PojUns7GB1kuRhZWUXGY0FG/sSgF0X9nwEHoby8ekju2F55NUzzpu9BfM2AU +S17S8h5Oxc4Qi6d9RoeRG25YmMywPCyp2SMnuu14w55KTAt7Ir7mbTAv8ZIMbVhq +34tH45ONQvGftN4JNvwZr7Uf+EuupWsnILfkz1Cw1cj88adDZHwxE7Hkx7TiQP6o +DPDeg+XYH0vB2HR25JSP9z0uyeeF6n6cExgfwVZy2una7jQp887N5xLgTUGlnmFM +y1z2AO2+Mw1Lh2UC/OQrp9T1ztMCAwEAAaMeMBwwGgYDVR0RBBMwEYIJbG9jYWxo +b3N0hwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQCICPRCT+m+EKHkaWG2eY2AqQ7a +24Bd60ZsZxJNAloXAd1X8cedz5yq0rm9pqF5Fq883dysgCVSDylwqy4YzllhTWsy ++M3TE85ZyKKi6S7kR7Z0Exf0I4S7G9zTtrzEXn9kco1q5g/jE7aQi2E2z5poaIg+ +TlUCq5IePsS6gZCvzXPgU1mJ5dQFlqsOW6Lk1mOCjmKT2SaF4eL2hleatqHv667c +fJWYLotjAJoVQKrjItGeHXPosZEW5g17gFD88XZRMlUx5xN5/ioaKmLiyI28aNF3 +nNaukGC/N5fPsgghb0wkYmPHh+dFE/1uMIq0cOzNcyG6ZQkQzikiYhytWsOu +-----END CERTIFICATE----- diff --git a/docker/tls/server.key b/docker/tls/server.key new file mode 100644 index 0000000..5cc6910 --- /dev/null +++ b/docker/tls/server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7HI+/9Vg8m48/ +MdNRL1BVXpqL+s5HszsH7DlylchDpzk8T41q7sw2JwfMujR/+T6I1J7OxgdZLkYW +VlFxmNBRv7EoBdF/Z8BB6G8vHpI7theeTVM86bvQXzNgFEte0vIeTsXOEIunfUaH +kRtuWJjMsDwsqdkjJ7rteMOeSkwLeyK+5m0wL/GSDG1Yat+LR+OTjULxn7TeCTb8 +Ga+1H/hLrqVrJyC35M9QsNXI/PGnQ2R8MROx5Me04kD+qAzw3oPl2B9Lwdh0duSU +j/c9Lsnnhep+nBMYH8FWctrp2u40KfPOzecS4E1BpZ5hTMtc9gDtvjMNS4dlAvzk +K6fU9c7TAgMBAAECggEBAINmo2zjF3w4onh2vTgeSgQp087J62Ne8u21bwKRPXqF +TSSVmXKnELJW5ptXiNb2anwdFQmQ+EggvwegxsFH18QRIpBAxcb7TYD7gllM1tUo +I54AH5x/aG4E7Udj+So2aeHu3+q+o9STnZxGw0TS4zub6CZVgS+3DwcF8BqRgqXs +NuDIIJWosuchbb3DdlPygRajiN2teJtNfw9rcLfC4BY5i4y/H7RMpklM5VkTXiGc +NxyG4qkdHP0jlL9Z9wRa859uYeb7kVm+vhfgUXMbiRn9FcxrROOpPIwTAv76Y5nu +4EF/s0TPC+ei7hjCpN1WK2/n6dgiVYBVBUpWHalZBIECgYEA7+E2T5PlKuT7Kugs +qx+CHvZXm2hZ9NVDYS6gNAZt6kr5enbb9rzCF/U+jx14COPyGcoJeDOUW1yZGTgH +98JkEEHB6fgSPAU3pp2aMslMRNTZqfM0vL+BRpJT+fPbI9y8WpMzm/NpmnZZK8rh +xLbg+xAa7iMltscCcY2uD8NmhKkCgYEAx6+Ma5WQ0Enmju+XUANrOuKDN9aTXXc6 +iqlqtXfadc/Lc6E+lzSxRm5t95t+6AX2mYsNOWsuWRCBqHMFDxg31moYEeBQvQW9 +kwJQ5JsmOSCzMfDPUrQHihaq9xwxhoBxJXIRs3JlYm/nty8LO959R1V0IrHsPznH +BVs7pbAo6RsCgYEAyvK4t3UCI1tdoPyTpiffOADlN+d+jCTOf+8pvTpfTiUmk1Ty +XvtuH0TvK7gb8TGhh+4mOtswvmdGZE7CdvyxGgv4WtH142/qmH2okyU58NZAXYgV +a0d+wU1V3RhSpDHB7cOym1PCWdudL+7TOlIbYG5MyoNUCiKvT5E13cJM/xkCgYAC +WWNahKjuemAXAGSUUWX6jF2k04ZqTBPJO9MAjYdpaWdoVdZJqxoGzRfIGPE2Q5Oy +HLusGEG0VIhh9fByTAOkJx1fYHcyshWX3CgdeGHLvEG/bajSvUF1c2zReWhvv6UV +HrFsngTpUo20Tv5f1u88Xpn+Kn+wArr/qiIagecJTwKBgDPEa71fqt7WyjHCNuIm +hJeBCIjTZ8N1Jk0GUHyucbFPARWxYcn0zRTwHOXnXt+Z6GvAfuS7YElSXYVjw2Uy +wUVD+7zh0ydkWC1HJPnjalmHHVpv1RFNEJGAYQ8Vxd6G2EoY4ZFByZomWTxfXrvq +Dr9hsGtmZu1knNwfrOu2kyB5 +-----END PRIVATE KEY----- diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..97b3d26 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,31 @@ +**Language / Язык:** [English](README.md) | [Русский](ru/README.md) + +# Documentation + +Guides for the VMware vSphere API simulator. Switch language with the header on each +page. Russian mirrors live under [`ru/`](ru/README.md). + +| Guide | Description | +|---|---| +| [Getting started](getting-started.md) | First successful lab session | +| [Configuration](configuration.md) | Environment variables and Compose | +| [Authentication](authentication.md) | Sessions, `vmware-api-session-id`, privileges | +| [API versions](api-versions.md) | Catalog majors 6–9 and hot-swap | +| [API surface](api-surface.md) | REST/SOAP routing, coverage registry, stubs | +| [API coverage](api-coverage.md) | Broadcom universe vs implemented surface | +| [Clients & examples](clients.md) | Python, Go, Java, Perl, Ansible, Terraform, Pulumi | +| [Seed profiles](seed-profiles.md) | Deterministic inventory fixtures | +| [Domains](domains/README.md) | Session, inventory, VM, storage, networking, tagging, SOAP, tasks, … | +| [Web UI](web-ui.md) | Interactive console and catalogs | +| [Operations](operations.md) | Reseed, migrate, release, upgrade | +| [Kubernetes / Helm](kubernetes.md) | Hub image + Ingress + Let's Encrypt | +| [Security](security.md) | Lab threat model and credentials | +| [Observability](observability.md) | Health endpoints and logging | +| [Ports](ports.md) | Published host ports and internal services | +| [Troubleshooting](troubleshooting.md) | Common failure modes | +| [FAQ](faq.md) | Short answers | +| [Architecture](architecture.md) | Component boundaries | +| [Compatibility](compatibility.md) | Evidence model and release matrix | + +Runnable cookbooks: [`examples/`](../examples/README.md). +Integration suites: [`pulumi-tests/`](../pulumi-tests/README.md) (`make pulumi-tests`). diff --git a/docs/api-coverage.md b/docs/api-coverage.md new file mode 100644 index 0000000..772365a --- /dev/null +++ b/docs/api-coverage.md @@ -0,0 +1,135 @@ +**Language / Язык:** [English](api-coverage.md) | [Русский](ru/api-coverage.md) + +# vSphere API coverage matrix + +Auto-oriented registry: [`app/vsphere/rest/coverage.py`](../app/vsphere/rest/coverage.py). +Broadcom universe stubs: [`app/vsphere/rest/universe.json`](../app/vsphere/rest/universe.json) (from the public operations index). +Per-major floors + stub OpenAPI bundles: [`app/vsphere/contracts/matrix.py`](../app/vsphere/contracts/matrix.py) → `contracts/vsphere//manifest.json`. + +## Broadcom vs this simulator + +Public source (scraped): [vSphere Automation API Operations Index (9.1 Latest)](https://developer.broadcom.com/xapis/vsphere-automation-api/latest/operation-index/) + +| Surface | Count | Notes | +|---|---:|---| +| Broadcom Operations Index | **1348** | GET 628 / POST 422 / DELETE 114 / PUT 93 / PATCH 91 | +| Generated unique `verb + path` routes | **~1037** | Same HTTP path can back several named ops (`?action=…`, `$Task`) | +| Simulator registry (core + stubs + `/rest`) | **1077** | Core deep handlers overwrite stub entries on the same path | +| Core deep handlers | **104** | Seeded inventory / lifecycle / authz behaviour | +| DB-backed surface rows (`vsphere_api_state`) | **~540+** | Seeded for every GET `/api` route + lab extras | + +Regenerate universe after refreshing the index dump: + +```bash +python scripts/generate_vsphere_universe.py +make vsphere-bundles +``` + +Refresh live stats / regenerate artifacts: + +```bash +curl -sk https://localhost/ui/api/compatibility?major=9 +make vsphere-surface +python scripts/write_vsphere_bundles.py +python scripts/write_vsphere_evidence.py +``` + +| Major | Label | Implemented / universe | Coverage | Notes | +|---|---|---:|---:|---| +| 6 | vSphere 7.0 | 31 / 1077 | 2.9% | Catalog/evidence floor only | +| 7 | vSphere 7.0 U3 | 77 / 1077 | 7.2% | Catalog/evidence floor only | +| 8 | vSphere 8.0 | 103 / 1077 | 9.6% | Catalog/evidence floor only | +| 9 | vSphere 8.0 U2 / Automation 9.1 surface | **1077 / 1077** | **100%** | Deep handlers + DB-backed Broadcom surface | + +Numbers come from `GET /ui/api/compatibility?major=N` and `evidence/vsphere-*.json` (`make vsphere-bundles`). + +Hot-swap (`POST /ui/api/contract/apply?major=N`) changes the **catalog** major used by the Web UI / evidence reports. **Runtime always serves the full registered surface** — known paths are never HTTP 501’d by version floor. + +## Planes + +| Plane | Default | Notes | +|---|---|---| +| Native REST `/api`, `/rest` | on | Primary lab surface | +| Native SOAP `/sdk` | on | PropertyCollector subset + VM tasks | +| Proxmox `/api2/*` stub | **off** (`ENABLE_PVE_STUB=false`) | Optional legacy | + +## Auth & synthetic data + +| Item | Detail | +|---|---| +| Users | `administrator`, `readonly`, `operator`, `vmadmin` `@vsphere.local` / `VMware1!` | +| AuthZ | Role → privilege gate on mutate endpoints (403 `unauthorized`) | +| Seed `large` | 10 hosts, **1000 VMs**, 4 datastores, DVS, folders, permissions | +| Seed `demo-cluster` | 20 hosts, 1000 VMs (UI demo load) | +| Seed `small` | 3 hosts, 5 named VMs (tests) | + +## REST domains + +### Deep (core) at major 9 + +- Session / CIS tasks / AuthZ roles+permissions / identity providers / TLS cert stub +- VM list/get/create/delete/power, hardware, snapshots, clone, relocate, tools, guest identity/networking/power/customization, console tickets, template/unregister +- Host list/get + maintenance + storage-device + networking +- Datastore list/get + file metadata +- Network list + DVS/DVPG create +- Datacenter / cluster / folder (+children) / resource-pool CRUD +- Tagging, content library + OVF, storage policies (+ VM associations), privileges +- Appliance version/health/networking/timesync +- `vapi` metamodel service list stub + +### DB-backed Automation surface (Broadcom universe catch-all) + +Remaining Automation API routes from the 9.1 operations index are registered and answered by [`app/vsphere/rest/stub_surface.py`](../app/vsphere/rest/stub_surface.py) against PostgreSQL: + +- table `vsphere_api_state` (migration `011_vsphere_api_state.sql`) +- seeded by `seed_api_surface()` on every profile including **`demo-cluster`** / UI `POST /ui/api/demo/load` +- inventory overlay for VM hardware (cdrom/scsi/boot/…), host networking/storage, tagging, content libraries +- PUT/PATCH persist into `vsphere_api_state`; POST appends collection rows; DELETE removes them + +No `"stub": true` markers — probes require real seeded payloads on major 9. + +## SOAP domains (govmomi / Terraform / Pulumi / pyvmomi) + +- RetrieveServiceContent (+ TaskManager / SearchIndex / GuestOperationsManager / FileManager / OvfManager) +- RetrieveProperties / RetrievePropertiesEx / **ContinueRetrievePropertiesEx** (pagination tokens; `` plural) +- PropertyCollector: parent-chain Ancestors, one-hop `childEntity` ListFolder, ContainerView `view` traversal +- Folder.childType as `ArrayOfString`; string props carry `xsi:type="xsd:string"` (govmomi decode) +- Datastore.host as `ArrayOfDatastoreHostMount`; Cluster/Host **environmentBrowser** +- **QueryConfigOption** / QueryConfigOptionEx / QueryConfigOptionDescriptor / QueryConfigTarget +- CreateFilter / WaitForUpdatesEx (version tokens; empty polls) +- FindByInventoryPath (govmomi paths omit root `Datacenters`), FindByUuid/Dns/Ip, FindChild +- **CreateVM_Task** / CreateChildVM_Task, CreateFolder, Power/Clone/Snapshot/Rename/Reconfig/Relocate/Destroy/Unregister/MarkAsTemplate/CustomizeVM_Task + CancelTask +- Guest file ops: ListFilesInGuest, InitiateFileTransferTo/FromGuest, DeleteFileInGuest, MakeDirectoryInGuest +- Real task IDs from `vsphere_tasks` (including `info.result` MoRef on create/clone) +- `/sdk/vimService.wsdl`, `/sdk/about.do`, `/pbm` stub +- Type-strict MOR lookup: `VirtualApp:resgroup-*` does not resolve a plain ResourcePool (Terraform CreateVM path) + +## REST extras for Ansible / Python apps + +- VM power returns `{ "task": "task-…" }` for CIS task polling +- Guest virtual filesystem: `/api/vcenter/vm/{vm}/guest/filesystem` (+ local-filesystem listing) +- Content library update/download sessions for OVF push/pull lab flows + +## Legacy `/rest` + +`{ "value": … }` wrappers for vm/host/datastore/network/datacenter/cluster/power/appliance. + +## Contract majors (browse vs runtime) + +Hot-swap (`POST /ui/api/contract/apply?major=N`) still switches the **catalog** major for UI browse/evidence. **Runtime always serves the full registered surface** with deep handlers or DB-backed stubs — known paths are never HTTP 501’d by version floor. Catalog floors remain historical for documentation only. + +## Platform surfaces (lab-available) + +These were historically “deferred”; they now return **non-empty seeded lab data** and accept basic mutate: + +| Area | REST | SOAP | +|---|---|---| +| NSX (tier0 / projects / edges / VPC / subnets) | Seeded Automation paths under `namespace-management` / `namespaces` | — | +| Supervisor / WCP | namespaces, VM classes, supervisor summary/identity, infra policies | — | +| vSAN | Storage policies with `policy_type: VSAN` (+ RAID1 lab policy) | — | +| SAML / OIDC | `GET/POST/PATCH/DELETE /api/vcenter/identity/providers` (LocalOS + OIDC + SAML) | — | +| VECS / certs | TLS, TLS CSR, trusted-root-chains, supervisor certs/signing-requests | — | +| HttpNfcLease | `PUT/GET /nfc/{lease}/files/...` | `ImportVApp_Task`, `CreateImportSpec`, lease progress/complete | +| Guest customization | GET+POST `/api/vcenter/vm/{vm}/guest/customization` | `CustomizeVM_Task` | + +This is still a **lab-grade** stand-in (not a binary-compatible NSX Manager / real VECS store / full Broadcom device XML matrix). Perf/Event/Alarm remain answered but not deeply simulated. diff --git a/docs/api-surface.md b/docs/api-surface.md new file mode 100644 index 0000000..3fe6238 --- /dev/null +++ b/docs/api-surface.md @@ -0,0 +1,87 @@ +**Language / Язык:** [English](api-surface.md) | [Русский](ru/api-surface.md) + +# API surface + +## Request path + +1. Middleware assigns or forwards a request ID (`REQUEST_ID_HEADER`). +2. FastAPI routes the request to the vSphere REST router (`/api`, `/rest`), + the SOAP router (`/sdk`), or (if `ENABLE_PVE_STUB=true`) the optional + legacy stub. +3. `/api/session` (or `/rest/com/vmware/cis/session`, or SOAP `Login`) + resolves a principal and issues a `vmware-api-session-id`. +4. `require_read` / `require_privilege(...)` dependencies check the session's + roles before revealing or mutating resources. +5. A deep handler (core inventory/lifecycle/tagging/content/appliance logic) + or the DB-backed stub surface executes against PostgreSQL-backed state. +6. Long operations (power, clone, relocate, snapshot, OVF deploy) create a + durable CIS task and return `{ "task": "task-…" }`. + +## Two REST surfaces on one registry + +- **Core (deep) handlers** — ~104 verb+path combinations across + [`app/vsphere/rest/router.py`](../app/vsphere/rest/router.py), + `vm_ext.py`, `inventory_ext.py`, `platform_rest.py`, `tagging_rest.py`, + `content_rest.py`, `appliance_ext.py`, `nfc_rest.py`, `tasks.py`. These read + and mutate the seeded inventory/tagging/content/appliance tables directly. +- **DB-backed stub surface** — + [`app/vsphere/rest/stub_surface.py`](../app/vsphere/rest/stub_surface.py) + answers the remaining Broadcom Automation API operations index routes + (registered from `universe.json`) against `vsphere_api_state`. GET returns + live inventory-derived payloads when possible, otherwise seeded rows; + PUT/PATCH persist into `vsphere_api_state`; POST appends collection rows; + DELETE removes them. No `"stub": true` marker is returned — probes see real + seeded payloads. + +Both surfaces share one route table; core handlers take priority over stub +entries registered for the same verb+path. + +## Legacy `/rest` + +[`app/vsphere/rest/legacy.py`](../app/vsphere/rest/legacy.py) wraps +vm/host/datastore/network/datacenter/cluster/power/appliance reads (and VM +power) in `{ "value": … }` envelopes for older `com.vmware.vcenter.*` clients. + +## Errors ([`app/vsphere/errors.py`](../app/vsphere/errors.py)) + +| Status | `error_type` | Typical cause | +|---|---|---| +| 400 | `invalid_argument` / `already_exists` | Malformed body, duplicate name | +| 401 | `unauthenticated` | Missing/invalid/expired session | +| 403 | `unauthorized` | Session lacks the required privilege | +| 404 | `not_found` | Unknown MOID/path parameter | +| 409 | (handler-specific) | Illegal power-state transition, lock conflict | +| 501 | `error` | Only reachable via the optional legacy stub's undeclared-method fallback | + +All error bodies follow the vSphere Automation shape: +`{ "error_type": "...", "messages": [{ "default_message": "...", "id": "...", "args": [] }] }`. + +## Tasks + +Async work (power, clone, snapshot, relocate, OVF deploy, guest customize) +returns a task id. Poll: + +```text +GET /api/cis/tasks/{task} +``` + +Task rows commit in `vsphere_tasks`; `progress` is `100` once `status` is +`SUCCEEDED`/`FAILED`. HTTP 200/201 on the mutation request means "accepted", +not "VM already in final state". See [Tasks](domains/tasks.md). + +## Exploration + +- Interactive FastAPI docs: `/docs` +- Web UI method inspector: `/` → catalog → method +- UI helper APIs: `/ui/api/catalog`, `/ui/api/method`, `/ui/api/compatibility` +- Coverage registry: [`app/vsphere/rest/coverage.py`](../app/vsphere/rest/coverage.py) +- Path-floor / catalog matrix: [`app/vsphere/contracts/matrix.py`](../app/vsphere/contracts/matrix.py) + +## Compatibility endpoints + +| Path | Format | +|---|---| +| `/ui/api/compatibility?major=N` | JSON | + +See [Compatibility](compatibility.md) and [API coverage](api-coverage.md) for +the full Broadcom-universe-vs-implemented breakdown. diff --git a/docs/api-versions.md b/docs/api-versions.md new file mode 100644 index 0000000..343592b --- /dev/null +++ b/docs/api-versions.md @@ -0,0 +1,77 @@ +**Language / Язык:** [English](api-versions.md) | [Русский](ru/api-versions.md) + +# API versions (vSphere catalog majors 6–9) + +The Web UI and evidence/compatibility reports browse four integer **catalog +majors** that map onto vSphere Automation API label floors: + +| Major | vSphere label | Contract version string | +|---|---|---| +| 6 | 7.0 | `7.0.0` | +| 7 | 7.0 U3 | `7.0.3` | +| 8 | 8.0 | `8.0.0` | +| 9 | 8.0 U2 (Automation 9.1 surface) | `8.0.2` | + +Definitions live in [`app/vsphere/contracts/matrix.py`](../app/vsphere/contracts/matrix.py) +(`VERSIONS`, `PATH_FLOOR`). Each registered REST path has a **floor** — the +lowest major at which it appears in the catalog — sourced from the same +module. Undated paths default to the highest major (9) until catalogued. + +## Runtime vs catalog + +This is the most important distinction in the project: + +- **Catalog major** — controls what the Web UI endpoint tree, `/ui/api/catalog`, + and compatibility/evidence reports show for a given major. +- **Runtime surface** — the simulator always serves the **full registered + route table** with deep handlers or DB-backed stubs, independent of the + active catalog major. A known path is never returned as HTTP 501 because of + a version floor. + +Hot-swapping the catalog major is therefore a **documentation/browse** +switch, not a compatibility gate on live traffic. See +[`available_for_request()`](../app/vsphere/contracts/matrix.py) for the exact +policy. + +## Cold start + +`GET /api/appliance/system/version` reports the version string of the +currently selected runtime source (defaults to `8.0.2` / major 9 unless the +process overrides `app.state.runtime_source_version`). + +## Hot-swap (catalog browse) + +Browse any major in the Web UI catalog, or call: + +```http +POST /ui/api/contract/apply?major=7 +``` + +Effects: + +- The Web UI catalog, `/ui/api/compatibility`, and evidence reports switch to + major 7's floor and ledger (`evidence/vsphere-7.0.3.json`). +- The change is **process-local** and **not persisted**; a restart returns to + the default (major 9). +- REST/SOAP routes already registered continue to answer with their real + handlers regardless of the applied major. + +### Client guidance + +- Most clients (pyvmomi, govmomi, Terraform, Pulumi, Ansible `uri`) do not + need to pin a catalog major — the runtime surface does not change shape + based on it. +- Use catalog majors when you specifically want the Web UI / evidence view to + reflect an older vSphere label for documentation or screenshots. +- After apply, re-check `/ui/api/compatibility?major=N` for the active + catalog state. + +## Regenerating catalog artifacts + +```bash +make vsphere-bundles # stub OpenAPI matrices + evidence ledgers +make vsphere-universe # regenerate universe.json from the Broadcom operations index +make evidence # regenerate per-major verified surface evidence ledgers +``` + +See [API surface](api-surface.md) and [Compatibility](compatibility.md). diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..2345a24 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,76 @@ +**Language / Язык:** [English](architecture.md) | [Русский](ru/architecture.md) + +# Architecture + +## Goals + +`vmware-api-simulator` is a stateful vSphere lab emulator (Automation REST + VIM SOAP). +The primary design goal is **practical client compatibility**: sessions, inventory, +VM lifecycle, PropertyCollector walks, tasks, tagging/content library stubs, and +AuthZ roles are implemented against a large synthetic datastore so tools like curl, +govc-style flows, pyvmomi, and Terraform can exercise common paths without a real +vCenter. + +Catalog majors **6–9** map to vSphere 7.0 / 7.0U3 / 8.0 / 8.0U2 floors. Hot-swap +changes the catalog used for Web UI browse/evidence only — it does **not** gate +live routes. Optional Proxmox `/api2/*` stub remains behind `ENABLE_PVE_STUB` +(off by default). + +## System context + +```mermaid +flowchart LR + Client["API clients
pyvmomi / Terraform / govc / REST SDKs"] + Admin["Lab operator"] + UI["Web lab UI"] + API["FastAPI application"] + Gateway["HTTPS gateway :443"] + Contract["vSphere contract matrix"] + Domain["vsphere domain + inventory"] + DB[(PostgreSQL)] + Obs["Logs / Prometheus / OpenTelemetry"] + + Client -->|"/api /rest /sdk"| Gateway + Gateway --> API + UI --> Gateway + Admin -->|"seed / migrate"| API + API --> Contract + API --> Domain + Domain --> DB + API --> Obs +``` + +## Planes + +| Plane | Path | Notes | +|---|---|---| +| Automation REST | `/api`, `/rest` | Session header `vmware-api-session-id` | +| VIM SOAP | `/sdk` | PropertyCollector subset + VM tasks | +| Lab UI helpers | `/ui/api/*` | Catalog, demo seed, compatibility | +| Optional PVE stub | `/api2/*` | Off unless `ENABLE_PVE_STUB=true` | + +## Data model + +Inventory lives in `vsphere_objects` (MOIDs, types, props JSON, parent links). +Sessions, credentials, tasks, tags, libraries, snapshots, and permissions are +sibling tables (migrations `009_vsphere.sql`, `010_vsphere_platform.sql`). +DB-backed Automation stubs use `vsphere_api_state` (`011`); content-library +transfer sessions and HttpNfcLease rows live in `vsphere_transfer_sessions` / +`vsphere_nfc_leases` (`012`); PropertyCollector views/tokens and console +tickets persist in `vsphere_pc_state` / `vsphere_console_tickets` (`013`). + +Seed profiles (`small` / `large` / `demo-cluster`) build a deterministic cluster — +default **large** is ~10 hosts / **1000 VMs**. + +## AuthZ + +Credentials map to roles → privilege sets. Mutate handlers use +`require_privilege(...)`; read paths use `require_read`. SOAP Login issues a cookie +compatible with VIM sessions. + +## Related docs + +- [API coverage](api-coverage.md) +- [Authentication](authentication.md) +- [Web UI](web-ui.md) +- [Clients](clients.md) diff --git a/docs/authentication.md b/docs/authentication.md new file mode 100644 index 0000000..fab21ba --- /dev/null +++ b/docs/authentication.md @@ -0,0 +1,102 @@ +**Language / Язык:** [English](authentication.md) | [Русский](ru/authentication.md) + +# Authentication + +Primary plane: **vSphere Automation REST** sessions (`vmware-api-session-id`). +SOAP `/sdk` uses its own `Login`/`Logout` on the VIM `SessionManager`. An +optional legacy Proxmox stub plane (`ENABLE_PVE_STUB=true`) keeps historic +`/api2/json/access/ticket` behavior from a shared platform lineage — it is not +the default lab path and is not covered further here. + +## Session login (REST) + +```http +POST /api/session +Authorization: Basic base64(user:password) +``` + +Successful response: + +- Body: JSON string session id (e.g. `"a1b2c3…"`) +- Header: `vmware-api-session-id: ` +- Cookie: `vmware-api-session-id=` (`SameSite=Strict`, 2 hour TTL) + +Legacy wrapper (same credentials, `{ "value": "" }` shape): + +```http +POST /rest/com/vmware/cis/session +Authorization: Basic base64(user:password) +``` + +### Calling APIs + +```bash +SID=$(curl -sk -u 'administrator@vsphere.local:VMware1!' \ + -X POST 'https://localhost/api/session' | tr -d '"') + +curl -sk -H "vmware-api-session-id: $SID" \ + 'https://localhost/api/vcenter/vm' +``` + +Cookie-only clients also work after login (`credentials: include` in the +browser Web UI). + +### Session inspect / logout + +| Method | Path | Notes | +|---|---|---| +| GET | `/api/session` | HTTP 200 with `x-vmware-session-user` / `x-vmware-session-roles` headers | +| DELETE | `/api/session` | Invalidates the session and clears the cookie | +| GET / DELETE | `/rest/com/vmware/cis/session` | Legacy `{ "value": … }` equivalents | + +Sessions live in PostgreSQL (`vsphere_sessions`) with a 2-hour sliding +expiry — every authenticated request extends `expires_at`. Expired sessions +return HTTP 401 on the next lookup and are lazily deleted. + +## Seeded lab principals + +Password for all: `VMware1!` + +| Principal | Role | +|---|---| +| `administrator@vsphere.local` | Administrator | +| `readonly@vsphere.local` | ReadOnly | +| `operator@vsphere.local` | VirtualMachinePowerUser | +| `vmadmin@vsphere.local` | VirtualMachineAdministrator | + +Credentials are stored in `vsphere_credentials` (scrypt-hashed passwords, +`roles` array) and are re-inserted idempotently on first `/api/session` call +and by every seed profile. See [Authorization](domains/authz.md) for the +privilege model and [Seed profiles](seed-profiles.md) for how the four +principals map to inventory-scoped permissions. + +Mutating endpoints check privileges via `require_privilege(...)`; calling a +mutate path as `readonly@vsphere.local` returns **403**. + +## SOAP `/sdk` + +```xml + + + + SessionManager + administrator@vsphere.local + VMware1! + + + +``` + +`Login` issues the same underlying session id, returned as +`vmware-api-session-id` and as a `vmware_soap_session` cookie; subsequent SOAP +calls (pyvmomi, govmomi, the `hashicorp/vsphere` Terraform provider, Pulumi) +carry that cookie automatically. `Logout` deletes the session. See +[SOAP / VIM](domains/soap.md). + +## Optional legacy Proxmox stub + +Only when `ENABLE_PVE_STUB=true`: ticket login at `/api2/json/access/ticket` +with `PVEAuthCookie` + CSRF, inherited from the shared simulator platform this +project forked from. It is disabled by default (`ENABLE_PVE_STUB=false`) and +is not exercised by the vSphere docs, examples, or test suites in this +repository. diff --git a/docs/clients.md b/docs/clients.md new file mode 100644 index 0000000..96158f7 --- /dev/null +++ b/docs/clients.md @@ -0,0 +1,83 @@ +**Language / Язык:** [English](clients.md) | [Русский](ru/clients.md) + +# Clients + +Use the simulator from common VMware automation stacks: Python, Ansible, Terraform, Pulumi. + +## Connection matrix + +| Stack | Transport | Notes | Code | +|---|---|---|---| +| REST (curl / SDK) | HTTPS `:443` | `vmware-api-session-id` after Basic session | `examples/python/vsphere_rest_smoke.py`, `vsphere_lifecycle.py` | +| SOAP / VIM | HTTPS `:443/sdk` | pyvmomi / govmomi / Terraform / Pulumi providers | `examples/python/vsphere_soap_smoke.py` | +| Legacy `/rest` | HTTPS `:443` | `{ "value": … }` wrappers | `/rest/vcenter/vm` | +| Terraform | HTTPS `:443` | `hashicorp/vsphere` data sources + optional VM resource | `examples/terraform/vsphere/` | +| Ansible | HTTPS `:443` | REST lifecycle playbook (`uri` module) | `examples/ansible/vsphere_playbook.yml` | +| Pulumi | HTTPS `:443` | REST ComponentResource cookbook | `examples/pulumi/` | +| govc | HTTPS `:443` | `GOVC_URL=https://…` insecure | see below | +| Go / Java / Perl | HTTPS `:443` | Minimal REST cookbooks (Basic-auth session) | `examples/go/`, `examples/java/`, `examples/perl/` | + +## Credentials (seed) + +| User | Password | Role | +|---|---|---| +| `administrator@vsphere.local` | `VMware1!` | Administrator | +| `readonly@vsphere.local` | `VMware1!` | ReadOnly | +| `operator@vsphere.local` | `VMware1!` | VirtualMachinePowerUser | +| `vmadmin@vsphere.local` | `VMware1!` | VirtualMachineAdministrator | + +## Inventory seed + +```bash +make seed # large: 10 hosts / 1000 VMs +VSPHERE_PROFILE=demo-cluster make seed +VSPHERE_PROFILE=small make seed +``` + +## Quick cookbooks + +```bash +# All four stacks (Python/Ansible/Terraform/Pulumi-style) inside Compose +make client-cookbooks + +# Python REST + SOAP CreateVM / NFC +VSPHERE_BASE=https://localhost python examples/python/vsphere_lifecycle.py + +# Ansible +ansible-playbook -i examples/ansible/inventory.ini examples/ansible/vsphere_playbook.yml + +# Terraform — hashicorp/vsphere data sources (plan) + optional CreateVM resource +cd examples/terraform/vsphere +terraform init +TF_VAR_vsphere_server=localhost TF_VAR_create_lab_vm=false terraform plan +TF_VAR_vsphere_server=localhost TF_VAR_create_lab_vm=true terraform apply + +# Pulumi REST +cd examples/pulumi && pulumi up +``` + +Verified against the gateway (`:443`): Python lifecycle, Ansible playbook, Pulumi-style REST, and `terraform plan` (datacenter/cluster/datastore/network/VM data sources) are green. SOAP `CreateVM_Task` is available for the resource path; use a fresh seed if folder names were renamed by probes (`make seed`). + +## govc (optional host tool) + +```bash +export GOVC_URL=https://localhost +export GOVC_USERNAME=administrator@vsphere.local +export GOVC_PASSWORD='VMware1!' +export GOVC_INSECURE=1 +govc about +govc ls / +govc find / -type m | head +govc vm.info web-01 +``` + +## pyvmomi smoke + +```bash +docker compose run --rm --no-deps -e VSPHERE_BASE=http://simulator:8080 \ + -e TEST_DATABASE_URL=postgresql://vmware:vmware@postgres:5432/vmware_simulator \ + dev pytest tests/compatibility/test_vsphere_pyvmomi.py -q +``` + +Per-language guides: [examples/overview.md](examples/overview.md). Coverage: +[api-coverage.md](api-coverage.md). diff --git a/docs/compatibility-0.1.0.md b/docs/compatibility-0.1.0.md new file mode 100644 index 0000000..b8619e7 --- /dev/null +++ b/docs/compatibility-0.1.0.md @@ -0,0 +1,86 @@ +**Language / Язык:** [English](compatibility-0.1.0.md) | [Русский](ru/compatibility-0.1.0.md) + +# Compatibility report — 0.1.0 + +This report records evidence for simulator release 0.1.0 against the vSphere +Automation API route registry (catalog majors 6–9, primary contract major 9 / +8.0 U2). It is a limitation matrix for *quality / external integration* +dimensions, not a claim of general vCenter/ESXi hardware compatibility. + +For the user-facing overview see [compatibility.md](compatibility.md). Live +machine-readable counts are always available from +`/ui/api/compatibility?major=N` when the simulator is running. + +## Summary (major 9 / vSphere 8.0 U2 primary contract) + +| Level | Methods | Universe share | Evidence | +|---|---:|---:|---| +| Declared in universe (Broadcom operations index → route table) | 1077 | 100% | `app/vsphere/rest/universe.json` | +| Implemented at major 9 (catalog floor) | **1077** | **100%** | `app/vsphere/contracts/matrix.py` | +| Core deep handlers (inventory/lifecycle/tagging/content/appliance) | 104 | 9.7% | `app/vsphere/rest/coverage.py` (`CORE_IMPLEMENTED`) | +| DB-backed stub surface (remaining registry) | ~973 | 90.3% | `app/vsphere/rest/stub_surface.py` against `vsphere_api_state` | +| Verified / observed surface ledger | **1077** | **100%** | `evidence/vsphere-8.0.2.json` | + +## Coverage by catalog major + +| Major | vSphere label | Implemented | Universe | Coverage | +|---|---|---:|---:|---:| +| 6 | 7.0 | 31 | 1077 | 2.88% | +| 7 | 7.0 U3 | 77 | 1077 | 7.15% | +| 8 | 8.0 | 103 | 1077 | 9.56% | +| 9 | 8.0 U2 | 1077 | 1077 | 100.00% | + +**Implemented** here is a catalog-floor score for Web UI browse and evidence +reports, regenerated with `make evidence` / `make vsphere-bundles` and +guarded by `tests/compatibility/test_verified_surface.py`. It does **not** +gate live traffic — see [API surface](api-surface.md) for why runtime always +serves the registered route regardless of the applied major. + +## Implemented surface (high level) + +- **Session**: `/api/session`, `/rest/com/vmware/cis/session`, SOAP + `Login`/`Logout` — all durable in PostgreSQL (`vsphere_sessions`, + `vsphere_credentials`). +- **Inventory**: VM/host/datastore/network/datacenter/cluster/folder/resource-pool + list+get, plus create/delete for datacenter/cluster/folder/resource-pool. +- **VM lifecycle**: create, delete, power, hardware (CPU/memory/disk/NIC/boot), + snapshots, clone, relocate, guest identity/networking/power/customization, + console tickets, tools. +- **Tasks**: `/api/cis/tasks`, real ids from `vsphere_tasks`, SOAP task MoRefs. +- **Tagging / content library**: categories, tags, associations, libraries, + library items, update/download sessions, OVF deploy. +- **Authorization**: privileges, roles, permissions CRUD, identity providers. +- **Appliance**: version, health, networking (hostname/DNS), timesync. +- **SOAP / VIM**: RetrieveServiceContent, PropertyCollector + (RetrieveProperties/Ex, ContinueRetrievePropertiesEx, CreateFilter, + WaitForUpdatesEx), FindBy* / FindChild, CreateVM_Task and friends, guest + file operations, HttpNfcLease import flow, WSDL stub. +- **Platform lab surfaces**: seeded (non-binary-compatible) NSX/Supervisor/vSAN/ + SAML-OIDC/VECS-cert stand-ins — see [API coverage](api-coverage.md) for the + exact list and caveats. + +## Persistence principle + +Every create/update/delete path writes to PostgreSQL (tables and/or the +`vsphere_api_state` catch-all). Secrets may be stored but must not be echoed +on GET. User-facing "not supported in the emulator" errors are forbidden for +registered paths — see `.cursor/rules/durable-simulator.mdc`. + +## Known limitations + +| Area | Current behavior | +|---|---| +| External systems | NSX/LDAP/SAML/OIDC/ACME do not contact real remotes; state is simulated locally | +| TLS | Local nginx gateway with a checked-in self-signed development key only | +| Client certification | pyvmomi/govmomi-style SOAP smoke + Ansible/Terraform/Pulumi cookbooks; not a formal certification suite for every provider version | +| Provider smoke | The `pulumi-vsphere` suite under `pulumi-tests/` (`make pulumi-tests`) exercises SOAP-backed inventory/VM/tag resources with nonempty export checks; semantic depth still varies (deep handlers vs DB-backed stubs) | + +Full registry coverage at major 9 means HTTP 501 "handler pending" should not +appear for any route in the simulator's registry. Compatibility *quality* +(exact vSphere edge-case parity) still deepens with tests and observation. + +When importing a refreshed Broadcom operations index dump: regenerate +`universe.json` (`make vsphere-universe`), regenerate bundles/evidence +(`make vsphere-bundles`, `make evidence`), run +`pytest tests/compatibility/test_verified_surface.py`, and commit the updated +`evidence/vsphere-*.json` ledgers. diff --git a/docs/compatibility.md b/docs/compatibility.md new file mode 100644 index 0000000..6242178 --- /dev/null +++ b/docs/compatibility.md @@ -0,0 +1,74 @@ +**Language / Язык:** [English](compatibility.md) | [Русский](ru/compatibility.md) + +# Compatibility + +This document explains how the simulator claims compatibility with the +vSphere Automation API across catalog majors **6–9**. Prefer live reports +when the process is running. + +## Live reports + +| URL | Format | +|---|---| +| `/ui/api/compatibility?major=N` | JSON | + +The Web UI also exposes a compatibility panel driven by this endpoint. + +## Registry vs verified surface coverage + +| Major | vSphere label | Implemented / universe | Coverage | +|---|---|---:|---:| +| 6 | 7.0 | 31 / 1077 | 2.9% | +| 7 | 7.0 U3 | 77 / 1077 | 7.2% | +| 8 | 8.0 | 103 / 1077 | 9.6% | +| 9 | 8.0 U2 (Automation 9.1 surface) | **1077 / 1077** | **100%** | + +- **Universe** — unique verb+path routes derived from the public + [vSphere Automation API operations index](https://developer.broadcom.com/xapis/vsphere-automation-api/latest/operation-index/) + (1348 documented operations → ~1037 unique routes → 1077 registered in this + simulator's route table, since some paths back multiple named operations). +- **Implemented (per major)** — routes whose catalog floor + (`app/vsphere/contracts/matrix.py`) is at or below that major. This is a + **catalog/documentation** score, not a live-traffic gate. +- **Runtime** — regardless of the applied catalog major, every registered + route is always served by its real handler (104 deep handlers) or the + DB-backed stub surface. See [API surface](api-surface.md). + +After **Apply as runtime** (`POST /ui/api/contract/apply?major=N`), the live +report loads that major's ledger (`evidence/vsphere-{version}.json`) so the +Web UI compatibility panel reflects the selected major. + +## Evidence dimensions + +Per-major ledgers in `evidence/vsphere-{version}.json` record `declared`, +`implemented`, `observed`, and `verified` counts plus per-HTTP-verb and +per-domain (`auth_session`, `inventory`, …) breakdowns. Regenerate with: + +```bash +make evidence # app/evidence_gen.py +make vsphere-bundles # stub OpenAPI matrices + evidence ledgers together +``` + +Executable backing for those claims: + +| Suite | Role | +|---|---| +| `tests/compatibility/test_verified_surface.py` | hot-swap + ledger drift + score gates | +| `tests/compatibility/test_group_smoke.py` | representative REST group mutations with PostgreSQL | +| `tests/compatibility/test_vsphere_pyvmomi.py` | external pyvmomi SOAP smoke | +| `tests/integration/test_vsphere_full_api.py` | broad REST/SOAP integration coverage | + +Additional cookbooks under [`examples/`](../examples/README.md) and the +`pulumi-vsphere` lab suite under [`pulumi-tests/`](../pulumi-tests/README.md) +(`make pulumi-tests`) are manual or CI-optional depending on the stack. + +## Known behavioural limits + +| Area | Behaviour | +|---|---| +| External systems | NSX Manager, live LDAP/SAML/OIDC IdPs, and ACME directories do not contact real remotes; seeded/local state only | +| TLS | Local self-signed development gateway only (Compose); use your own certs / cert-manager for real deployments | +| Hypervisor | No real ESXi/KVM execution; no binary NFC uploads | +| Observation corpus | Sanitized real-vCenter observation data remains limited; deep semantic parity is verified path-by-path via the suites above, not by exhaustive production diffing | + +Historical release notes: [compatibility-0.1.0.md](compatibility-0.1.0.md). diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 0000000..6fa2a2d --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,96 @@ +**Language / Язык:** [English](configuration.md) | [Русский](ru/configuration.md) + +# Configuration + +Application settings are loaded from the environment (see `.env.example`). +Docker Compose injects many of these for the `simulator` service; values +declared under `environment:` in `docker-compose.yml` override `.env` for that +service. The typed settings model lives in [`app/config.py`](../app/config.py). + +## Core + +| Variable | Default / example | Meaning | +|---|---|---| +| `APP_HOST` | `0.0.0.0` | Bind address | +| `APP_PORT` | `8080` | Internal uvicorn listen port (not published; the gateway publishes vCenter HTTPS) | +| `DATABASE_URL` | `postgresql://vmware:vmware@postgres:5432/vmware_simulator` | asyncpg DSN | +| `DB_POOL_MIN_SIZE` | `1` | Pool minimum | +| `DB_POOL_MAX_SIZE` | `10` | Pool maximum | +| `DB_CONNECT_TIMEOUT_SECONDS` | `10` | Connect timeout | +| `DB_COMMAND_TIMEOUT_SECONDS` | `30` | Command timeout | +| `LOG_LEVEL` | `INFO` | Logging level | +| `REQUEST_ID_HEADER` | `X-Request-ID` | Request correlation header | + +## vSphere seed inventory + +| Variable | Default | Meaning | +|---|---|---| +| `SEED_VSPHERE_PROFILE` | `large` | `small` \| `large` \| `demo-cluster` — see [Seed profiles](seed-profiles.md) | +| `SEED_VSPHERE_LARGE_HOSTS` | `10` | Host count for the `large` profile | +| `SEED_VSPHERE_LARGE_VMS` | `1000` | VM count for the `large` profile | + +## Optional legacy plane + +| Variable | Default | Meaning | +|---|---|---| +| `ENABLE_PVE_STUB` | `false` | Enables the legacy Proxmox VE `/api2/*` stub plane inherited from a shared platform lineage. Native vSphere `/api` + `/rest` + `/sdk` is the default and primary plane regardless of this flag. | + +## Contract and catalog + +| Variable | Meaning | +|---|---| +| `CONTRACT_SNAPSHOT` | Optional path to a normalized PVE-style snapshot (only relevant with `ENABLE_PVE_STUB=true`) | +| `CONTRACT_FALLBACK` | `error` (default), `schema-default`, or `fixture` — fallback behaviour for the optional stub plane | +| `COMPATIBILITY_EVIDENCE` | Optional evidence JSON path used by compatibility reports | +| `CATALOG_ARTIFACT_URL_6` … `_9` | Labels backing the vSphere catalog majors (6→7.0, 7→7.0 U3, 8→8.0, 9→8.0 U2); stub URLs, not live downloads | + +Runtime hot-swap (Web UI / `POST /ui/api/contract/apply?major=N`) switches the +active **catalog** major used by the Web UI and compatibility/evidence +reports. It does not gate the registered REST/SOAP surface — every known +route is always served with its real handler or DB-backed stub. See +[API versions](api-versions.md). + +## Security and tasks + +| Variable | Meaning | +|---|---| +| `TICKET_SIGNING_KEY` | HMAC signing key for sessions (**change outside toy labs**) | +| `TASK_WORKER_CONCURRENCY` | Number of leased asyncio workers (1–32) | +| `TASK_LEASE_SECONDS` | PostgreSQL task lease duration | +| `SIMULATION_TIME_SCALE` | Accelerates simulated task durations (higher = faster) | + +## Client test hooks + +| Variable | Meaning | +|---|---| +| `TEST_DATABASE_URL` | Integration-test DSN | +| `VSPHERE_BASE` | Target base URL used by cookbooks/probes (`https://localhost` from the host, `http://simulator:8080` from inside Compose) | + +## Ports and TLS + +| Endpoint | Use | +|---|---| +| `https://localhost` | Primary vCenter HTTPS entry (curl, browsers, pyvmomi, govmomi, Terraform, most examples) | +| `http://localhost` | HTTP lab face | +| `localhost:5434` | PostgreSQL (localhost only) | +| Internal `simulator:8080` | Direct FastAPI process; only reachable inside the Compose network | + +The checked-in certificate under `docker/tls/` is disposable development +material. Never reuse it outside local labs. See [Security](security.md) and +[Ports](ports.md). + +## Compose notes + +- `migrate` runs once; `simulator` waits for a successful migrate. +- Development Compose bind-mounts the repository and enables Uvicorn reload. +- The `api-gateway` (nginx) service publishes `443`/`80` and proxies to the + internal `simulator:8080` process; it sets `X-VMware-Service` / + `X-Forwarded-Port` so future routers can tell which listener was used. + +## Open and unused example keys + +`.env.example` still lists a few keys from the shared platform lineage that +are **not** consumed by the current vSphere-first settings model, notably +`SIMULATION_SEED`, `SIMULATOR_ADMIN_ENABLED`, and `SIMULATOR_ADMIN_TOKEN`. Do +not assume an authenticated `/_simulator` admin API exists today — see +[Security](security.md). diff --git a/docs/domains/README.md b/docs/domains/README.md new file mode 100644 index 0000000..0d6fd64 --- /dev/null +++ b/docs/domains/README.md @@ -0,0 +1,42 @@ +**Language / Язык:** [English](README.md) | [Русский](../ru/domains/README.md) + +# Domain guides + +These pages summarize durable semantics by area. For exhaustive method lists, +use the Web UI catalog or OpenAPI (`/docs`), or browse +[`app/vsphere/rest/coverage.py`](../../app/vsphere/rest/coverage.py) directly +— the runtime always serves the full registered surface regardless of the +active catalog major. + +| Guide | Topics | +|---|---| +| [Session](session.md) | `/api/session`, legacy `/rest` session, SOAP `Login`/`Logout` | +| [Inventory](inventory.md) | Datacenter, cluster, folder, resource pool, host, datastore, network CRUD | +| [Virtual machines](vm.md) | Create/delete, power, hardware, snapshots, clone, relocate, guest ops | +| [Storage](storage.md) | Datastores, files, host storage devices, storage policies | +| [Networking](networking.md) | Standard/distributed portgroups, DVS, host networking | +| [Tagging](tagging.md) | Categories, tags, associations | +| [Content library](content-library.md) | Libraries, items, update/download sessions, OVF deploy | +| [SOAP / VIM](soap.md) | RetrieveServiceContent, PropertyCollector, task-returning operations | +| [Tasks](tasks.md) | CIS task ids, polling, workers | +| [Appliance](appliance.md) | Version, health, networking, timesync | +| [Authorization](authz.md) | Roles, privileges, permissions | + +## Persistence map + +- Inventory objects (hosts, VMs, datastores, networks, folders, …) → + `vsphere_objects` (MOID, type, name, parent, `props` JSONB). +- Sessions / credentials → `vsphere_sessions`, `vsphere_credentials`. +- Tasks → `vsphere_tasks`. +- Tags / categories / associations → `vsphere_tag_categories`, + `vsphere_tags`, `vsphere_tag_associations`. +- Content libraries / items → `vsphere_libraries`, `vsphere_library_items`. +- Datastore file metadata → `vsphere_datastore_files`. +- Remaining Broadcom Automation API routes (the DB-backed stub surface) → + `vsphere_api_state` (migration `011`). +- Content-library update/download sessions → `vsphere_transfer_sessions` + (migration `012`). +- HttpNfcLease transfer state → `vsphere_nfc_leases` (migration `012`). +- PropertyCollector views / WaitForUpdates tokens → `vsphere_pc_state` + (migration `013`). +- Console tickets → `vsphere_console_tickets` (migration `013`). diff --git a/docs/domains/appliance.md b/docs/domains/appliance.md new file mode 100644 index 0000000..19b3754 --- /dev/null +++ b/docs/domains/appliance.md @@ -0,0 +1,35 @@ +**Language / Язык:** [English](appliance.md) | [Русский](../ru/domains/appliance.md) + +# Appliance + +vCenter Server Appliance (VCSA) surfaces — version, health, networking, +timesync: +[`app/vsphere/rest/appliance_ext.py`](../../app/vsphere/rest/appliance_ext.py), +[`app/vsphere/domain/appliance.py`](../../app/vsphere/domain/appliance.py). + +## Endpoints + +| Method | Path | Notes | +|---|---|---| +| GET | `/api/appliance/system/version` | Readable without a session; reflects the active catalog major's label | +| GET | `/api/appliance/health/system` | Overall health summary | +| GET/PUT/POST | `/api/appliance/networking` | Hostname, DNS, default gateway, interfaces, proxy | +| GET/PUT/POST | `/api/appliance/networking/dns/hostname` \| `/dns/servers` \| `/dns/domains` | Focused mirrors kept in sync with `/networking` | +| GET | `/api/appliance/timesync` | NTP mode + servers | +| GET | `/api/vcenter/certificate-management/vcenter/tls[-csr]` \| `/trusted-root-chains` | Machine-cert / CSR / trust-chain stand-ins | + +## Highlights + +- Defaults model a realistic single-nic VCSA (`vcenter.lab.local`, + `192.168.1.50/24`, gateway `192.168.1.1`, `8.8.8.8`/`1.1.1.1` DNS). +- `save_networking` keeps the focused DNS mirrors + (`/dns/hostname`, `/dns/servers`, `/dns/domains`) consistent with the full + `/networking` document so both shapes of Automation API client work. +- State is idempotently seeded once per fresh database + (`seed_appliance_state`) and persists in `vsphere_api_state`. +- The TLS/certificate-management endpoints are seeded stand-ins, not a real + VECS certificate store — see [API coverage](../api-coverage.md). + +`/api/appliance/system/version` intentionally does not require a session in +this lab build (real vCenter behavior varies by version) so smoke scripts can +check availability before authenticating. diff --git a/docs/domains/authz.md b/docs/domains/authz.md new file mode 100644 index 0000000..ccb567f --- /dev/null +++ b/docs/domains/authz.md @@ -0,0 +1,52 @@ +**Language / Язык:** [English](authz.md) | [Русский](../ru/domains/authz.md) + +# Authorization + +Role → privilege gate for REST mutate endpoints (and a decorator-style hook +for SOAP): [`app/vsphere/security/authz.py`](../../app/vsphere/security/authz.py), +[`platform_rest.py`](../../app/vsphere/rest/platform_rest.py). + +## Endpoints + +| Method | Path | Notes | +|---|---|---| +| GET | `/api/vcenter/privilege` | Privilege catalog | +| GET | `/api/vcenter/authorization/roles` | Role → privilege set | +| GET/POST/DELETE | `/api/vcenter/authorization/permissions[/{permission_id}]` | Principal ↔ role ↔ entity bindings | +| GET/POST/PATCH/DELETE | `/api/vcenter/identity/providers[/{provider}]` | LocalOS + OIDC + SAML identity-provider stand-ins | + +## Roles (seed) + +| Role | Scope | +|---|---| +| `Administrator` | Every privilege in the catalog | +| `ReadOnly` | `System.Anonymous`, `System.Read`, `System.View`, `Datastore.Browse` | +| `VirtualMachinePowerUser` | Read + power/snapshot/clone interactions | +| `VirtualMachineAdministrator` | Power-user set + create/delete/reconfigure/tag/content-library privileges | + +`ROLE_PRIVILEGES` in `authz.py` defines the exact privilege sets; a +non-exhaustive sample of gated privileges: `VirtualMachine.Inventory.Create`, +`VirtualMachine.Inventory.Delete`, `VirtualMachine.Interact.PowerOn`, +`VirtualMachine.Config.CPUCount`, `VirtualMachine.Provisioning.Clone`, +`Datastore.FileManagement`, `Network.Assign`, +`InventoryService.Tagging.CreateTag`, `ContentLibrary.AddLibraryItem`, +`Authorization.ModifyPermissions`. + +## How gating works + +- `require_privilege(*needed)` is a FastAPI dependency factory: it resolves + the session, loads roles (from the session or `vsphere_credentials` if + absent), and raises HTTP 403 (`unauthorized`) if any listed privilege is + missing. +- `require_read` is shorthand for `require_privilege("System.Read")`. +- Permissions can also scope a role to a specific entity MOID + (`PermissionSpec(principal, role, entity_moid, propagate)`); the seed + scopes `readonly@vsphere.local` to the datacenter and the two VM-admin + principals to the VM folder. + +## Seeded principals + +See [Authentication](../authentication.md) for the four +`@vsphere.local` principals and their roles, and +[Seed profiles](../seed-profiles.md) for how permissions are scoped per +profile. diff --git a/docs/domains/content-library.md b/docs/domains/content-library.md new file mode 100644 index 0000000..ea6d342 --- /dev/null +++ b/docs/domains/content-library.md @@ -0,0 +1,38 @@ +**Language / Язык:** [English](content-library.md) | [Русский](../ru/domains/content-library.md) + +# Content library + +Local content libraries, library items, upload/download sessions, and OVF +deploy: +[`app/vsphere/rest/content_rest.py`](../../app/vsphere/rest/content_rest.py), +[`nfc_rest.py`](../../app/vsphere/rest/nfc_rest.py), +[`app/vsphere/domain/content.py`](../../app/vsphere/domain/content.py). + +## Endpoints + +| Method | Path | Notes | +|---|---|---| +| GET | `/api/content/library` | List library ids | +| POST | `/api/content/local-library` | Create a local library | +| GET/POST | `/api/content/library/item` | List / create items (`?library_id=`) | +| POST | `/api/vcenter/ovf/library-item/{item_id}` | Deploy OVF item → new `VirtualMachine` + task | +| POST | `/api/content/library/item/update-session[/{session_id}[/file]]` | Push-upload flow (Ansible/Terraform-style) | +| GET/POST | `/api/content/library/item/download-session[/{session_id}[/file]]` | Pull-download flow | +| GET/PUT/POST | `/nfc/{lease}` \| `/nfc/{lease}/files/{filename}` \| `/nfc/{lease}/complete` | HttpNfcLease-style transfer endpoints for the SOAP import path | + +## Highlights + +- Libraries/items persist in `vsphere_libraries` / `vsphere_library_items`; + the seed creates two libraries ("Local Content", "Published Templates") + with OVF-typed items (`ubuntu-22.04`, `centos-stream-9`, `golden-image`). +- Update/download sessions persist in PostgreSQL (`vsphere_transfer_sessions`, + migration `012`) and model the file-transfer handshake — not a real + byte-for-byte OVF/VMDK store. HttpNfcLease rows live in `vsphere_nfc_leases`. +- `deploy_ovf_from_library` creates a real `VirtualMachine` row and returns a + task id, mirroring the SOAP `ImportVApp_Task` / `CreateImportSpec` + + `HttpNfcLease*` flow used by govc-style `ovf.import`. +- Requires `ContentLibrary.CreateLocalLibrary` / `.AddLibraryItem` to create, + and `VirtualMachine.Provisioning.DeployTemplate` to deploy. + +See [SOAP / VIM](soap.md) for the HttpNfcLease progress/complete/abort +operations used by upload-heavy clients. diff --git a/docs/domains/inventory.md b/docs/domains/inventory.md new file mode 100644 index 0000000..e7b5ff7 --- /dev/null +++ b/docs/domains/inventory.md @@ -0,0 +1,46 @@ +**Language / Язык:** [English](inventory.md) | [Русский](../ru/domains/inventory.md) + +# Inventory + +Datacenter, cluster, folder, resource pool, host, and datastore/network +listing + CRUD: +[`app/vsphere/rest/router.py`](../../app/vsphere/rest/router.py), +[`app/vsphere/domain/inventory_ops.py`](../../app/vsphere/domain/inventory_ops.py). + +## Endpoints + +| Method | Path | Notes | +|---|---|---| +| GET | `/api/vcenter/datacenter` | List | +| POST/DELETE | `/api/vcenter/datacenter[/{datacenter}]` | Create seeds host/vm/datastore/network sub-folders | +| GET | `/api/vcenter/cluster` | List | +| POST/DELETE | `/api/vcenter/cluster[/{cluster}]` | Create seeds a `ResourcePool` | +| GET | `/api/vcenter/folder` | List; `GET /api/vcenter/folder/{folder}/children` | +| POST/DELETE | `/api/vcenter/folder[/{folder}]` | | +| GET | `/api/vcenter/resource-pool` | List | +| POST/DELETE | `/api/vcenter/resource-pool[/{resource_pool}]` | | +| GET | `/api/vcenter/host[/{host}]` | Connection state, CPU/memory, IP, storage devices, networking | +| POST | `/api/vcenter/host/{host}/maintenance` | Toggle maintenance mode | +| GET | `/api/vcenter/datastore[/{datastore}]` | Type, capacity, free space, accessibility | +| GET | `/api/vcenter/network` | Standard networks + distributed portgroups | + +Legacy `/rest/vcenter/*` mirrors most GET paths with a `{ "value": … }` +envelope — see [API surface](../api-surface.md). + +## Highlights + +- Every inventory object is a row in `vsphere_objects` (MOID, type, name, + `parent_moid`, `props` JSONB) — see + [`app/vsphere/inventory.py`](../../app/vsphere/inventory.py). +- MOID conventions follow real vCenter shapes: `datacenter-NN`, + `domain-cNN` (cluster), `resgroup-NN` (resource pool), `group-vNN`/`group-hNN`/ + `group-sNN`/`group-nNN` (VM/host/datastore/network folders), `host-NN`, + `datastore-NN`, `network-NN` / `dvportgroup-NN`. +- `list_hosts`/`list_clusters`/etc. filter live PostgreSQL state; there is no + separate cache to invalidate after a mutation. +- VM listing (`GET /api/vcenter/vm`) supports filters: `names`, + `power_states`, `hosts`, `folders`, `datacenters`, `clusters`, + `resource_pools`, plus `limit`/`cursor` pagination. + +See [Seed profiles](../seed-profiles.md) for the default topology shape and +[Virtual machines](vm.md) for VM-specific operations. diff --git a/docs/domains/networking.md b/docs/domains/networking.md new file mode 100644 index 0000000..2b39d85 --- /dev/null +++ b/docs/domains/networking.md @@ -0,0 +1,35 @@ +**Language / Язык:** [English](networking.md) | [Русский](../ru/domains/networking.md) + +# Networking + +Standard networks, distributed portgroups/switches, and host networking: +[`app/vsphere/rest/router.py`](../../app/vsphere/rest/router.py), +[`platform_rest.py`](../../app/vsphere/rest/platform_rest.py). + +## Endpoints + +| Method | Path | Notes | +|---|---|---| +| GET | `/api/vcenter/network` | Standard `Network` objects + `DistributedVirtualPortgroup` | +| GET/POST | `/api/vcenter/network/dvs` | Distributed virtual switches | +| POST | `/api/vcenter/network/dvpg` | Create a distributed portgroup | +| GET | `/api/vcenter/host/{host}/networking` | DNS, default gateway, `vmk0` interface, routing | +| GET/PUT/POST | `/api/appliance/networking` \| `/networking/dns/{hostname,servers,domains}` | vCenter appliance-level networking (see [Appliance](appliance.md)) | + +Legacy `GET /rest/vcenter/network` mirrors the list. + +## Highlights + +- Every VM's `nics[].value.backing` points at either a `STANDARD_PORTGROUP` + (`network-41`, "VM Network") or a `DISTRIBUTED_PORTGROUP` + (`dvportgroup-4N`, tagged with a `vlan_id`). +- The default topology seeds one `VmwareDistributedVirtualSwitch` + (`dvs-51`, `mtu: 9000`) and 1–3 extra distributed portgroups depending on + profile size. +- Host networking (`GET /api/vcenter/host/{host}/networking`) returns DNS + servers/domains, a default gateway, and a single `vmk0` management + interface with a deterministic IPv4 address per host index. +- NSX-labelled Automation API paths (tier-0 gateway, projects, edges, + VPC/subnets) are seeded lab stand-ins under `namespace-management` — see + the "Platform surfaces" table in [API coverage](../api-coverage.md); they + are not a real NSX Manager. diff --git a/docs/domains/session.md b/docs/domains/session.md new file mode 100644 index 0000000..7d1fa04 --- /dev/null +++ b/docs/domains/session.md @@ -0,0 +1,31 @@ +**Language / Язык:** [English](session.md) | [Русский](../ru/domains/session.md) + +# Session + +Durable session identity shared by REST and SOAP: +[`app/vsphere/security/session.py`](../../app/vsphere/security/session.py). + +## Endpoints + +| Method | Path | Notes | +|---|---|---| +| POST | `/api/session` | Basic auth → JSON string session id + `vmware-api-session-id` header/cookie | +| GET | `/api/session` | HTTP 200; `x-vmware-session-user` / `x-vmware-session-roles` headers | +| DELETE | `/api/session` | Invalidates the session, clears cookie | +| POST/GET/DELETE | `/rest/com/vmware/cis/session` | Legacy `{ "value": … }` equivalents | +| POST | SOAP `SessionManager.Login` | Returns the same session id; sets `vmware_soap_session` cookie | +| POST | SOAP `SessionManager.Logout` | Deletes the session | + +## Highlights + +- Sessions are opaque 32-char hex tokens stored in `vsphere_sessions` with a + **2-hour sliding TTL** — every authenticated call extends `expires_at`. +- The four lab credentials (`vsphere_credentials`, scrypt-hashed) are + idempotently ensured on first login and by every seed profile + (`ensure_default_credentials`). +- `require_session` resolves the session from either the + `vmware-api-session-id` header or cookie; missing/expired → HTTP 401. +- Roles are attached to the session at lookup time + (`vsphere_credentials.roles`) and drive [Authorization](authz.md). + +See [Authentication](../authentication.md) for full request examples. diff --git a/docs/domains/soap.md b/docs/domains/soap.md new file mode 100644 index 0000000..55c481b --- /dev/null +++ b/docs/domains/soap.md @@ -0,0 +1,68 @@ +**Language / Язык:** [English](soap.md) | [Русский](../ru/domains/soap.md) + +# SOAP / VIM + +Minimal VIM SDK for pyvmomi / govmomi-style clients (Terraform's +`hashicorp/vsphere` provider, Pulumi, govc): +[`app/vsphere/soap/router.py`](../../app/vsphere/soap/router.py), +[`property_collector.py`](../../app/vsphere/soap/property_collector.py), +[`pbm.py`](../../app/vsphere/soap/pbm.py). + +## Endpoint + +All operations POST a SOAP envelope to `/sdk` (also `/sdk/`). Auxiliary +routes: + +| Method | Path | Notes | +|---|---|---| +| GET | `/sdk/vimService.wsdl` (alias `/sdk/vim.wsdl`) | WSDL stub advertising the implemented operation list | +| GET | `/sdk/about.do` (alias `/about.do`) | Human-readable "VMware vCenter Server" page | +| POST | `/sdk/vim25/{version}/SessionManager/SessionManager/Login` | JSON-body login variant used by some SDKs | + +## Implemented operations + +- `RetrieveServiceContent`, `Login`, `Logout` +- `RetrieveProperties`, `RetrievePropertiesEx`, **ContinueRetrievePropertiesEx** + (pagination tokens; `` plural), `CreateFilter`, + `WaitForUpdatesEx` (version tokens; empty polls), `CreateContainerView`, + `DestroyPropertyFilter` +- `FindByInventoryPath` (paths omit the root `Datacenters` folder, matching + govmomi conventions), `FindByUuid`, `FindByDnsName`, `FindByIp`, `FindChild` +- `CreateVM_Task`, `CreateChildVM_Task`, `CreateFolder`, `PowerOnVM_Task`, + `PowerOffVM_Task`, `CloneVM_Task`, `CreateSnapshot_Task`, `Rename_Task`, + `ReconfigVM_Task`, `RelocateVM_Task`, `Destroy_Task`, `CustomizeVM_Task`, + `CancelTask`, `CurrentTime` +- Guest file ops: `InitiateFileTransferToGuest`, + `InitiateFileTransferFromGuest`, `ListFilesInGuest`, `DeleteFileInGuest`, + `MakeDirectoryInGuest` +- Import/upload: `ImportVApp_Task`, `CreateImportSpec`, + `HttpNfcLeaseComplete`, `HttpNfcLeaseProgress`, `HttpNfcLeaseAbort`, + `HttpNfcLeaseGetManifest` (paired with the REST `/nfc/{lease}` endpoints — + see [Content library](content-library.md)) +- `QueryConfigOption`, `QueryConfigOptionEx`, `QueryConfigOptionDescriptor`, + `QueryConfigTarget` +- PBM (`/pbm`) stub for storage-policy-aware clients + +## Highlights + +- `Login` issues the same underlying session as REST (`vmware-api-session-id` + cookie/header, plus a `vmware_soap_session` cookie) — see + [Session](session.md). +- `VIM_VERSION` is pinned to `8.0.2` with ≤3 dotted components, since + `hashicorp/vsphere` parses `AboutInfo.version` strictly. +- Type-strict MOR lookup rejects a `VirtualApp:resgroup-*` reference from + resolving as a plain `ResourcePool` — matters for the Terraform + `CreateVM_Task` resource path. +- Task-returning operations create a real row in `vsphere_tasks` (shared with + REST — see [Tasks](tasks.md)), including `info.result` MoRefs on + create/clone. +- PropertyCollector filters, ContainerViews, and WaitForUpdatesEx version + tokens persist in `vsphere_pc_state` (migration `013`) across process + restarts within a lab. +- `Folder.childType` is emitted as `ArrayOfString`; string properties carry + `xsi:type="xsd:string"` so govmomi's decoder accepts them; `Datastore.host` + is `ArrayOfDatastoreHostMount`; `Cluster`/`Host` expose `environmentBrowser`. + +See [Clients](../clients.md) for pyvmomi/govmomi/Terraform/Pulumi connection +examples and [examples/python/vsphere_soap_smoke.py](../../examples/python/vsphere_soap_smoke.py) +for a minimal raw-XML smoke. diff --git a/docs/domains/storage.md b/docs/domains/storage.md new file mode 100644 index 0000000..2ee78a1 --- /dev/null +++ b/docs/domains/storage.md @@ -0,0 +1,37 @@ +**Language / Язык:** [English](storage.md) | [Русский](../ru/domains/storage.md) + +# Storage + +Datastores, datastore file metadata, host storage devices, and storage +policies: +[`app/vsphere/rest/router.py`](../../app/vsphere/rest/router.py), +[`content_rest.py`](../../app/vsphere/rest/content_rest.py), +[`platform_rest.py`](../../app/vsphere/rest/platform_rest.py), +[`app/vsphere/domain/content.py`](../../app/vsphere/domain/content.py). + +## Endpoints + +| Method | Path | Notes | +|---|---|---| +| GET | `/api/vcenter/datastore[/{datastore}]` | Type (`VMFS`/`NFS`), capacity, free space, `multiple_host_access` | +| GET/POST | `/api/vcenter/datastore/{datastore}/files` | List / register file metadata (ISOs, VMX, VMDK paths) | +| GET | `/api/vcenter/host/{host}/storage/storage-device` | Seeded local disk devices (`naa.*`, capacity, SSD flag) | +| GET | `/api/vcenter/storage/policies[/{policy}/vm]` | Storage-based policy management, incl. `policy_type: VSAN` lab policies | + +Legacy `GET /rest/vcenter/datastore` mirrors the list in a +`{ "value": … }` envelope. + +## Highlights + +- Datastore rows are seeded with realistic capacity/free-space pairs + (`type`, `capacity`, `free_space`, `accessible`, + `multiple_host_access`) — see + [`app/vsphere/profiles.py`](../../app/vsphere/profiles.py). +- File metadata lives in `vsphere_datastore_files` (`path`, `size`, `type`); + the seed pre-populates ISOs and a VM's `.vmx`/`.vmdk` entries + (`seed_platform_extras`). +- Storage policies include a lab `RAID1` vSAN-labelled policy — see the + "Platform surfaces" table in [API coverage](../api-coverage.md) for the + vSAN caveat (seeded lab data, not a real vSAN cluster). +- Host storage devices are per-host synthetic disks, not real ESXi VMFS + extents — capacity/SSD flags vary deterministically by host index. diff --git a/docs/domains/tagging.md b/docs/domains/tagging.md new file mode 100644 index 0000000..9b50e20 --- /dev/null +++ b/docs/domains/tagging.md @@ -0,0 +1,31 @@ +**Language / Язык:** [English](tagging.md) | [Русский](../ru/domains/tagging.md) + +# Tagging + +CIS tagging service (categories, tags, object associations): +[`app/vsphere/rest/tagging_rest.py`](../../app/vsphere/rest/tagging_rest.py), +[`app/vsphere/domain/tagging.py`](../../app/vsphere/domain/tagging.py). + +## Endpoints + +| Method | Path | Notes | +|---|---|---| +| GET/POST | `/api/cis/tagging/category` | List / create (`cardinality`, `associable_types`) | +| GET/DELETE | `/api/cis/tagging/category/{category_id}` | | +| GET/POST | `/api/cis/tagging/tag` | List / create under a category | +| GET/DELETE | `/api/cis/tagging/tag/{tag_id}` | | +| POST | `/api/cis/tagging/tag-association` | Attach/detach a tag to/from an object | + +## Highlights + +- Category and tag ids follow the real `urn:vmomi:InventoryServiceCategory:…` + / `urn:vmomi:InventoryServiceTag:…:GLOBAL` shape. +- Rows persist in `vsphere_tag_categories`, `vsphere_tags`, + `vsphere_tag_associations` — durable across restarts, replaced on reseed. +- The seed creates two categories (`Environment`, `Owner`) with `prod`/ + `staging`/`platform` tags and attaches `prod` to two seeded VMs + (`seed_platform_extras` in + [`app/vsphere/domain/content.py`](../../app/vsphere/domain/content.py)). +- Attaching/creating a tag requires + `InventoryService.Tagging.CreateCategory` / `.CreateTag` / `.AttachTag` + privileges — see [Authorization](authz.md). diff --git a/docs/domains/tasks.md b/docs/domains/tasks.md new file mode 100644 index 0000000..1f78d0b --- /dev/null +++ b/docs/domains/tasks.md @@ -0,0 +1,37 @@ +**Language / Язык:** [English](tasks.md) | [Русский](../ru/domains/tasks.md) + +# Tasks + +Long-running operations (power, clone, relocate, snapshot, OVF deploy, guest +customize) return a CIS-style task id: +[`app/vsphere/domain/tasks.py`](../../app/vsphere/domain/tasks.py), +[`app/vsphere/rest/tasks.py`](../../app/vsphere/rest/tasks.py). + +## Endpoints + +| Method | Path | Notes | +|---|---|---| +| GET | `/api/cis/tasks` | List recent tasks (most recent 200) | +| GET | `/api/cis/tasks/{task}` | Status, progress, `service`/`operation`, `result`/`error` | + +## Client pattern + +1. `POST`/`DELETE` mutation → read the task id from `{ "task": "task-…" }` + (REST) or the SOAP `*_Task` MoRef. +2. Poll `GET /api/cis/tasks/{task}` until `status` is `SUCCEEDED` or `FAILED`. +3. `result` holds operation-specific output (for example `{"vm": "vm-104"}` + on create/clone/deploy). + +## Highlights + +- Task rows commit to `vsphere_tasks` (`id`, `description`, `status`, + `service`, `operation`, `result`, `error`, `completed_at`). +- `progress` is synthesized as `50` while running and `100` once terminal — + this simulator does not model fractional progress. +- The same task store backs both REST `/api/cis/tasks` and SOAP task MoRefs, + so a Terraform apply (SOAP `CreateVM_Task`) and a REST poll of the same id + see consistent state. +- Simulation durations honour `SIMULATION_TIME_SCALE` + (higher = faster simulated completion). + +See [API surface](../api-surface.md) and [Operations](../operations.md). diff --git a/docs/domains/vm.md b/docs/domains/vm.md new file mode 100644 index 0000000..85a0b3f --- /dev/null +++ b/docs/domains/vm.md @@ -0,0 +1,50 @@ +**Language / Язык:** [English](vm.md) | [Русский](../ru/domains/vm.md) + +# Virtual machines + +Full REST lifecycle for `VirtualMachine` objects: +[`app/vsphere/rest/router.py`](../../app/vsphere/rest/router.py), +[`vm_ext.py`](../../app/vsphere/rest/vm_ext.py), +[`app/vsphere/domain/vm_ops.py`](../../app/vsphere/domain/vm_ops.py). + +## Endpoints + +| Method | Path | Notes | +|---|---|---| +| GET | `/api/vcenter/vm` | List with `names`/`power_states`/`hosts`/`folders`/`datacenters`/`clusters`/`resource_pools`/`limit`/`cursor` filters | +| GET/DELETE | `/api/vcenter/vm/{vm}` | Get / delete (must be powered off) | +| POST | `/api/vcenter/vm` | Create — `placement.{folder,host,datastore,resource_pool}`, `cpu.count`, `memory.size_MiB`, `disks`, `nics` | +| GET/POST | `/api/vcenter/vm/{vm}/power` | Get power state / `?action=start\|stop\|suspend\|reset` — returns `{ "task": "task-…" }` | +| GET | `/api/vcenter/vm/{vm}/hardware` | Summary | +| GET/PATCH | `/api/vcenter/vm/{vm}/hardware/cpu` \| `/memory` | Change CPU count / memory (privilege-gated) | +| GET/POST | `/api/vcenter/vm/{vm}/hardware/disk` \| `/ethernet` | Add disk / NIC | +| GET | `/api/vcenter/vm/{vm}/hardware/boot` | Boot type/order | +| GET/POST/DELETE | `/api/vcenter/vm/{vm}/snapshots[/{snapshot}]` | Create, revert (`?action=revert`), delete | +| POST | `/api/vcenter/vm/{vm}/clone` \| `/relocate` | Task-returning | +| GET/POST | `/api/vcenter/vm/{vm}/tools` | Guest tools status / upgrade | +| GET | `/api/vcenter/vm/{vm}/guest/identity` \| `/networking` | Guest OS name, synthetic IP | +| GET/POST | `/api/vcenter/vm/{vm}/guest/power` | Guest-level power ops | +| POST | `/api/vcenter/vm/{vm}/guest/customization` | Sysprep/cloud-init-style customization spec | +| POST | `/api/vcenter/vm/{vm}/console/tickets` | Console (VNC/WebMKS-style) ticket | +| GET/PUT/DELETE | `/api/vcenter/vm/{vm}/guest/filesystem` | Lab virtual guest filesystem (Ansible/Terraform write-a-file flows) | +| GET | `/api/vcenter/vm/{vm}/guest/filesystem/files` \| `/guest/local-filesystem` | Listing | + +## Highlights + +- Every VM row carries a realistic device shape: `nics`, `disks`, `cdroms`, + `floppies`, `serials`, `scsi_adapters`, `boot`/`boot_devices`, `identity` + (`instance_uuid`, `bios_uuid`), and a synthetic `guest_ip` / + `guest_filesystems` map — the same fields power both the REST hardware + endpoints and SOAP `VirtualMachineConfigInfo`. +- Create requires `VirtualMachine.Inventory.Create`; delete requires + `VirtualMachine.Inventory.Delete` **and** the VM must be `POWERED_OFF`. +- Power/clone/snapshot/relocate/customize all create a durable CIS task (see + [Tasks](tasks.md)) rather than mutating synchronously in the response body. +- Console tickets from `/api/vcenter/vm/{vm}/console/tickets` persist in + `vsphere_console_tickets` (migration `013`). +- MOIDs follow the `vm-{100+n}` convention seeded by + [`app/vsphere/profiles.py`](../../app/vsphere/profiles.py). + +See [Storage](storage.md) for datastore/disk-file semantics and +[SOAP / VIM](soap.md) for the equivalent `CreateVM_Task`/`PowerOnVM_Task`/… +operations used by pyvmomi, govmomi, Terraform, and Pulumi. diff --git a/docs/examples/ansible.md b/docs/examples/ansible.md new file mode 100644 index 0000000..ef3cd2a --- /dev/null +++ b/docs/examples/ansible.md @@ -0,0 +1,23 @@ +**Language / Язык:** [English](ansible.md) | [Русский](../ru/examples/ansible.md) + +# Ansible + +The playbook uses the `uri` module against the HTTPS gateway +(`https://localhost`), with Basic-auth session login followed by +`vmware-api-session-id`-header calls for the rest of the lifecycle. + +```bash +cd examples/ansible +ansible-playbook -i inventory.ini vsphere_playbook.yml +``` + +[`vsphere_playbook.yml`](../../examples/ansible/vsphere_playbook.yml) covers: +session login, list VMs, create, power on, poll the CIS task +(`/api/cis/tasks/{task}`), write a file to the lab guest virtual filesystem, +power off, delete, and session logout. + +Reseed the simulator (`make seed`) before relying on fixed VM names/MOIDs +from a previous run. + +For the official `pulumi-vsphere` lab suite (nonempty exports, HTML report), +see [`pulumi-tests/`](../../pulumi-tests/README.md) or `make pulumi-tests`. diff --git a/docs/examples/go.md b/docs/examples/go.md new file mode 100644 index 0000000..7c520ec --- /dev/null +++ b/docs/examples/go.md @@ -0,0 +1,21 @@ +**Language / Язык:** [English](go.md) | [Русский](../ru/examples/go.md) + +# Go + +Uses the Go standard library (`net/http`) against +`https://localhost` with a Basic-auth session +(`vmware-api-session-id`). + +```bash +cd examples/go +go run . +``` + +Override defaults with `VSPHERE_BASE`, `VSPHERE_USER`, `VSPHERE_PASSWORD`, +`VSPHERE_VM_NAME`. See [`main.go`](../../examples/go/main.go) for the +session → list → create → power → wait-task → delete flow and the +`waitTask` helper that polls `GET /api/cis/tasks/{task}`. + +TLS verification is disabled in the HTTP client for the local self-signed +development gateway certificate only — do not reuse that transport against a +real vCenter. diff --git a/docs/examples/java.md b/docs/examples/java.md new file mode 100644 index 0000000..0e151d1 --- /dev/null +++ b/docs/examples/java.md @@ -0,0 +1,22 @@ +**Language / Язык:** [English](java.md) | [Русский](../ru/examples/java.md) + +# Java + +Java 11+ `HttpClient` cookbook using a Basic-auth session +(`vmware-api-session-id`) against `https://localhost`. No third-party +JSON library — responses are inspected with a small string-based field +extractor suitable for a lab smoke. + +```bash +cd examples/java +javac Cookbook.java && java Cookbook +``` + +Override defaults with `VSPHERE_BASE`, `VSPHERE_USER`, `VSPHERE_PASSWORD`, +`VSPHERE_VM_NAME` environment variables. See +[`Cookbook.java`](../../examples/java/Cookbook.java) for the session → +create → power → wait-task → delete flow. + +The client installs a trust-all `SSLContext` for the local self-signed +development gateway certificate only — do not reuse it against a real +vCenter. diff --git a/docs/examples/overview.md b/docs/examples/overview.md new file mode 100644 index 0000000..2f53e53 --- /dev/null +++ b/docs/examples/overview.md @@ -0,0 +1,53 @@ +**Language / Язык:** [English](overview.md) | [Русский](../ru/examples/overview.md) + +# Client examples overview + +## Bring-up checklist + +```bash +make up +curl -skf https://localhost/health/ready +make seed +curl -sk https://localhost/api/appliance/system/version +``` + +## Endpoints + +| URL | When | +|---|---| +| `https://localhost` | curl, pyvmomi, govmomi, Terraform, Pulumi, Ansible, Go, Java, Perl — everything in `examples/` | +| `http://localhost` | Plain-HTTP lab face (no TLS handshake needed) | + +## Auth quick reference + +**Session (REST)** + +```bash +SID=$(curl -sk -u 'administrator@vsphere.local:VMware1!' \ + -X POST https://localhost/api/session | tr -d '"') +curl -sk -H "vmware-api-session-id: $SID" https://localhost/api/vcenter/vm +``` + +**SOAP Login** + +```bash +python examples/python/vsphere_soap_smoke.py https://localhost +``` + +## Task waiting + +Never treat the mutation HTTP response alone as "VM running". Power, clone, +relocate, snapshot, and OVF-deploy calls return `{ "task": "task-…" }`; poll +`GET /api/cis/tasks/{task}` until `status` is `SUCCEEDED` or `FAILED`. See +[Tasks](../domains/tasks.md). + +## Reseed warning + +`make seed` replaces the PostgreSQL inventory. Refresh Terraform/Pulumi/Ansible +state afterwards — see [Seed profiles](../seed-profiles.md). + +## Runnable tree + +See [`examples/README.md`](../../examples/README.md). The official +`pulumi-vsphere` lab suite lives under +[`pulumi-tests/`](../../pulumi-tests/README.md) (`make pulumi-tests`). diff --git a/docs/examples/perl.md b/docs/examples/perl.md new file mode 100644 index 0000000..3cdc4d5 --- /dev/null +++ b/docs/examples/perl.md @@ -0,0 +1,20 @@ +**Language / Язык:** [English](perl.md) | [Русский](../ru/examples/perl.md) + +# Perl + +`HTTP::Tiny` + `JSON` cookbook using a Basic-auth session +(`vmware-api-session-id`) against `https://localhost`. + +```bash +cd examples/perl +cpanm --installdeps . # or install HTTP::Tiny, JSON, IO::Socket::SSL manually +perl cookbook.pl +``` + +Override defaults with `VSPHERE_BASE`, `VSPHERE_USER`, `VSPHERE_PASSWORD`, +`VSPHERE_VM_NAME` environment variables. See +[`cookbook.pl`](../../examples/perl/cookbook.pl) for the session → list → +create → power → wait-task → delete flow. + +`HTTP::Tiny` is constructed with `verify_SSL => 0` for the local self-signed +development gateway certificate only. diff --git a/docs/examples/pulumi.md b/docs/examples/pulumi.md new file mode 100644 index 0000000..338ce1d --- /dev/null +++ b/docs/examples/pulumi.md @@ -0,0 +1,31 @@ +**Language / Язык:** [English](pulumi.md) | [Русский](../ru/examples/pulumi.md) + +# Pulumi + +[`examples/pulumi/`](../../examples/pulumi/) is a Python Pulumi program that uses +the official [`pulumi-vsphere`](https://www.pulumi.com/registry/packages/vsphere/) +provider (SOAP/VIM) against the simulator — the same provider path as Terraform +`hashicorp/vsphere`. + +```bash +cd examples/pulumi +pip install -r requirements.txt +pulumi plugin install resource vsphere 4.17.0 +pulumi stack init dev # once +pulumi config set server localhost # or your gateway host +pulumi config set --secret password 'VMware1!' +pulumi up +``` + +Configuration (`pulumi config set`): `server` (default `localhost`), `user` +(default `administrator@vsphere.local`), `password` (secret), `datacenter`, +`datastore`, `cluster`, `network`, `vm_name` (default `pulumi-lab-01`). + +Same reseed caution as Terraform: simulator PostgreSQL state and Pulumi state +are independent. Pin the catalog major for reproducible CI if your workflow +depends on Web UI/evidence output (see [API versions](../api-versions.md)) — +runtime routes themselves are always available regardless of the major. + +For the lab suite (inventory + folder + VM + tags, nonempty output checks, HTML +report), see [`pulumi-tests/`](../../pulumi-tests/README.md) or run +`make pulumi-tests` from the repo root. diff --git a/docs/examples/python-requests.md b/docs/examples/python-requests.md new file mode 100644 index 0000000..04b126f --- /dev/null +++ b/docs/examples/python-requests.md @@ -0,0 +1,33 @@ +**Language / Язык:** [English](python-requests.md) | [Русский](../ru/examples/python-requests.md) + +# Python — REST (requests / stdlib) + +Raw HTTP against the vSphere REST gateway, no vendor SDK required. + +```bash +pip install -r examples/python/requirements.txt +python examples/python/requests_cookbook.py +``` + +[`requests_cookbook.py`](../../examples/python/requests_cookbook.py) +demonstrates the shared session → create → wait-for-task → power on → wait → +power off → delete flow using `requests`, with the session id carried as the +`vmware-api-session-id` header. + +For a dependency-free variant using only the standard library (`urllib`), +see [`vsphere_rest_smoke.py`](../../examples/python/vsphere_rest_smoke.py): + +```bash +python examples/python/vsphere_rest_smoke.py https://localhost +``` + +For a combined REST-create + SOAP-`CreateVM_Task` + guest-filesystem smoke, +see [`vsphere_lifecycle.py`](../../examples/python/vsphere_lifecycle.py): + +```bash +VSPHERE_BASE=https://localhost python examples/python/vsphere_lifecycle.py +``` + +All three scripts default to `administrator@vsphere.local` / `VMware1!` and +disable TLS verification for the local self-signed development gateway +certificate only. diff --git a/docs/examples/terraform.md b/docs/examples/terraform.md new file mode 100644 index 0000000..357c59b --- /dev/null +++ b/docs/examples/terraform.md @@ -0,0 +1,32 @@ +**Language / Язык:** [English](terraform.md) | [Русский](../ru/examples/terraform.md) + +# Terraform + +[`examples/terraform/vsphere/`](../../examples/terraform/vsphere/) uses the +official `hashicorp/vsphere` provider (SOAP `/sdk` under the hood) pointed at +the local HTTPS gateway (`https://localhost`) with +`allow_unverified_ssl = true` for the development certificate. + +```bash +cd examples/terraform/vsphere +terraform init +TF_VAR_create_lab_vm=false terraform plan # data sources only (datacenter/cluster/datastore/network/VM) +TF_VAR_create_lab_vm=true terraform apply # also creates a lab VM (SOAP CreateVM_Task) +``` + +Defaults (`variables.tf`): `vsphere_server = "localhost"`, +`vsphere_user = "administrator@vsphere.local"`, +`vsphere_password = "VMware1!"`, `datacenter = "Datacenter"`, +`cluster = "Cluster"`, `datastore = "datastore1"`, +`network = "VM Network"`, `vm_name = "web-01"` (a `small`/`large` seeded VM). + +Provider plugin versions move quickly — pin versions in a `required_providers` +block to what you have tested. After `make seed`, refresh or recreate state +so VM name/MOID assumptions stay aligned. + +This cookbook is a starting point for lab CI, not a certification of every +`hashicorp/vsphere` resource/data source against the full route registry. See +[SOAP / VIM](../domains/soap.md) for the exact operations backing the +provider's create/read paths, and +[`pulumi-tests/`](../../pulumi-tests/README.md) for the `pulumi-vsphere` lab +suite (`make pulumi-tests`). diff --git a/docs/examples/troubleshooting-clients.md b/docs/examples/troubleshooting-clients.md new file mode 100644 index 0000000..9eb5163 --- /dev/null +++ b/docs/examples/troubleshooting-clients.md @@ -0,0 +1,15 @@ +**Language / Язык:** [English](troubleshooting-clients.md) | [Русский](../ru/examples/troubleshooting-clients.md) + +# Troubleshooting clients + +| Symptom | Fix | +|---|---| +| TLS certificate errors | Use `:443` with `verify=False` / `insecure`/`allow_unverified_ssl=true` **only** locally, or use plain HTTP `:80` | +| 401 on first call | Send `Authorization: Basic …` only to `/api/session` (or SOAP `Login`); every other call needs `vmware-api-session-id` | +| 403 on power/create | You may be using `readonly@vsphere.local` — switch to `administrator@vsphere.local` or `operator@vsphere.local` | +| VM not found | `small` seed VM names are `web-01`, `web-02`, `db-01`, `app-01`, `jumpbox` — not Proxmox-style numeric VMIDs | +| Create returns a MOID, not a task | REST `POST /api/vcenter/vm` returns the new VM's MOID synchronously; only **power/clone/relocate/snapshot/OVF-deploy** return `{ "task": "…" }` | +| Provider create vs task | Poll `/api/cis/tasks/{task}`; many providers (Terraform, Pulumi) already wait internally — raw HTTP/Go/Java/Perl clients often forget to | +| Drift after reseed | Refresh/recreate Terraform/Pulumi/Ansible state after `make seed` | +| Session expired mid-run | Sessions have a 2-hour sliding TTL; re-login if a long-running script idles past that | +| SOAP `Login` fails | Confirm the envelope targets `/sdk` with `SOAPAction` set (empty string is fine) and `Content-Type: text/xml` | diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 0000000..5b06029 --- /dev/null +++ b/docs/faq.md @@ -0,0 +1,57 @@ +**Language / Язык:** [English](faq.md) | [Русский](ru/faq.md) + +# FAQ + +## Is this a real vCenter / ESXi? + +No. It is an API and state simulator. Hosts, VMs, datastores, and networks +are durable PostgreSQL models, not ESXi hosts or KVM/vmkernel processes. + +## Do you really cover the vSphere Automation API? + +The **runtime** always serves the full registered route table (1077 routes: +104 deep handlers + a DB-backed stub surface for the rest) — see +[API surface](api-surface.md). The **catalog** majors 6–8 are intentionally +low-coverage historical floors (2.9%–9.6%); only major 9 (8.0 U2 / Automation +9.1 surface) is declared 100% in the catalog. See +[API versions](api-versions.md) and [Compatibility](compatibility.md). + +## Can I use this in CI for Terraform / Ansible / pyvmomi / custom clients? + +Yes. That is a primary use case. Seed a profile and point clients at the +HTTPS gateway `:443` (REST `/api`/`/rest` or SOAP `/sdk`). See +[Clients](clients.md). + +## Why do some NSX / Supervisor / vSAN / SAML calls "succeed" without remotes? + +Those areas persist **local, seeded** simulator state (see the "Platform +surfaces" table in [API coverage](api-coverage.md)). They intentionally do +not call a real NSX Manager, Tanzu Supervisor, or IdP. + +## Does registry coverage mean perfect vSphere parity? + +It means every registered route has a durable handler or DB-backed stub and +is subject to the project's verification suites. Exact edge-case parity with +a physical ESXi cluster can still differ; use `/ui/api/compatibility` and +your own client tests for certification claims. + +## Where is the Web UI? + +[https://localhost/](https://localhost/) after `make up` (gateway). + +## Can I deploy on Kubernetes? + +Yes. Use the Helm chart under `helm/vmware-api-simulator` with the published +Hub image. Ingress + cert-manager Let's Encrypt is supported — see +[Kubernetes / Helm](kubernetes.md). + +## What is `ENABLE_PVE_STUB`? + +An optional, off-by-default legacy Proxmox VE `/api2/*` stub plane inherited +from a shared platform lineage. Native vSphere REST/SOAP is always on and is +the primary surface of this project regardless of this flag. + +## Which VMs does the `small` seed use? + +`web-01`, `web-02`, `db-01`, `app-01`, `jumpbox` — see +[Seed profiles](seed-profiles.md). diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..105126c --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,175 @@ +**Language / Язык:** [English](getting-started.md) | [Русский](ru/getting-started.md) + +# Getting started + +Bring up a local vSphere laboratory, authenticate, and exercise a first +read/mutation cycle against the simulator. + +## Prerequisites + +- Docker and Docker Compose +- `make` (optional but used by the documented commands) + +Python, linters, and tests run **inside** containers. You do not need a local +Python toolchain for day-to-day use. + +## Choose a path + +| Path | When to use | +|---|---| +| [Published image](#1a-published-image-docker-hub) | Fastest lab using `inecs/vmware-api-simulator` | +| [Helm / Kubernetes](kubernetes.md) | Cluster install with Ingress + Let's Encrypt | +| [Development checkout](#1b-development-checkout) | Contribute / bind-mount source | + +## 1a. Published image (Docker Hub) + +Uses [`docker-compose.release.yml`](../docker-compose.release.yml) — PostgreSQL + +runtime simulator + HTTPS gateway from Hub. No source build required, but you +**must** run Compose from a checkout of this repository so `docker/gateway/` and +`docker/tls/` bind-mounts resolve. Seed runs automatically after the simulator +is healthy. + +```bash +# from a git checkout of this repository (needs docker/gateway + docker/tls) +docker compose -f docker-compose.release.yml pull +docker compose -f docker-compose.release.yml up -d --wait +``` + +Pin a version: + +```bash +IMAGE_TAG=0.1.0 docker compose -f docker-compose.release.yml up -d --wait +``` + +Make helpers (git checkout): + +```bash +make release-up +# optional re-seed: make release-seed PROFILE=small +``` + +| Host port | Service | +|---|---| +| `443` | HTTPS gateway (primary vCenter entry) | +| `80` | HTTP lab face | +| `5434` | PostgreSQL (localhost only) | + +Migrations run automatically via the `migrate` one-shot service. + +Then continue from [Wait until ready](#2-wait-until-ready). + +## 1b. Development checkout + +```bash +make install +make up +``` + +Services (see [Ports](ports.md) for the full picture): + +| Host port | Service | +|---|---| +| `443` | HTTPS gateway (nginx) → simulator | +| `80` | HTTP lab face | +| `5434` | PostgreSQL (localhost only) | + +Migrations apply automatically before the simulator becomes ready. The +internal FastAPI process listens on `8080` and is not published to the host. + +## 2. Wait until ready + +```bash +curl -sk https://localhost/health/live +curl -sk https://localhost/health/ready +``` + +`/health/ready` returns HTTP 503 until PostgreSQL is reachable **and** the +latest packaged migration is applied. + +## 3. Seed a profile + +```bash +make seed # default: large — 10 hosts / 1000 VMs +VSPHERE_PROFILE=small make seed +``` + +`small` creates a 3-host cluster with five named VMs (`web-01`, `web-02`, +`db-01`, `app-01`, `jumpbox`), datastores, a standard portgroup, and the four +lab principals. See [Seed profiles](seed-profiles.md) for other sizes. + +## 4. Check the API version + +```bash +curl -sk https://localhost/api/appliance/system/version | jq . +``` + +The cold-start catalog major defaults to **9** (vSphere 8.0 U2 / Automation +9.1 surface) in Docker Compose. Browse or hot-swap majors 6–9 from the Web UI +or [API versions](api-versions.md). + +## 5. Authenticate + +```bash +SID=$(curl -sk -u 'administrator@vsphere.local:VMware1!' \ + -X POST https://localhost/api/session | tr -d '"') +echo "$SID" +``` + +`SID` is the `vmware-api-session-id`. Send it on every subsequent call as a +header (or rely on the cookie the login response also sets): + +```bash +curl -sk -H "vmware-api-session-id: $SID" https://localhost/api/vcenter/vm +``` + +Details: [Authentication](authentication.md). + +## 6. List VMs and power one on + +```bash +curl -sk -H "vmware-api-session-id: $SID" \ + https://localhost/api/vcenter/vm | jq . + +curl -sk -X POST -H "vmware-api-session-id: $SID" \ + "https://localhost/api/vcenter/vm/vm-104/power?action=start" | jq . +``` + +Power actions and other long-running operations return a CIS task id. +Poll until the task finishes: + +```bash +curl -sk -H "vmware-api-session-id: $SID" \ + "https://localhost/api/cis/tasks/${TASK_ID}" | jq . +``` + +## 7. Open the Web UI + +Visit [https://localhost/](https://localhost/) for the interactive +console, endpoint catalog (vSphere majors 6–9), compatibility view, runtime +contract apply, and demo-cluster controls. See [Web UI](web-ui.md) for +light/dark theme screenshots and the full feature list. + +## 8. Try a client library + +```bash +# from the repository root after make up + seed +python examples/python/vsphere_rest_smoke.py https://localhost +python examples/python/vsphere_soap_smoke.py https://localhost +``` + +More stacks: [Clients](clients.md) and [`examples/`](../examples/README.md). + +## You're done when… + +- `/health/ready` returns `{"status": "ok"}` (or equivalent OK body) +- `/api/appliance/system/version` reports the active catalog major's version +- Session login succeeds for `administrator@vsphere.local` +- `/api/vcenter/vm` lists the seeded VMs +- A power action returns a task id that reaches `SUCCEEDED` + +## Next steps + +- [Configuration](configuration.md) — env vars, workers, seed sizing +- [API versions](api-versions.md) — hot-swap catalog majors 6–9 +- [Clients](clients.md) — Python, Ansible, Terraform, Pulumi +- [Operations](operations.md) — reseed, migrate, upgrades diff --git a/docs/images/vmware-logo-reference.png b/docs/images/vmware-logo-reference.png new file mode 100644 index 0000000000000000000000000000000000000000..805af0bd79d26d418c89d407f2214bed0aa8bd9b GIT binary patch literal 101111 zcmeFYWm8=J@-@7X!QCB#6WrYrEChE5PH=aJ0fHsCyK8WFcL^5UU4pyA!^w4D=X{0d z#lNOzrfSdBR8RNnUaR}pJ5)hV5*dL20RRBxPf}t^006ZQ01$R?FmG4r;T5+40D<59 z<3|N^BWnO~TTEAW)rh^t5n8)7MpgSTe^!-fcl)??7Y388C00!UCFhu$SLlD%k zu+h_`RD1nr5Tw#WHnV6OO+~+lX#G&t<~bo0D+ZD2@jsdZ>FwB3xPlMo1) zFOFTt1?F>zis6882q2kOk`hv+1<+UZQ(}PZ>;|$*MaY?;JIf)!n)Pgwkl;2D;1Zz` zg({*CfRjHki~?jlkibV0%wJGsGEiA8QyuHYdUk=0QV>ArNc^wF&r|GJjqwu%t`}$P zo9{Net*Sm4;L@R)z;BbMC8knfO6@_(j3EI4!Tn^{3y*Nr-tP9suF0O&=~Z9Oi{+Uu zxzM}wwU^c~NN4~}Zv1pnZ)ax~%5DIn(z(O3_zSS82AHkg>##4uXK5i!c-;SR=Xnw# z$;eh16d)!-Ktw#IGR$sc+4>>$%D!Q{{=?_y?bDYfk2AnNMI^bbGdJMb-oVDCTq$C2 z1o{K3&Fvn=%Rr#-a|GSwCP$Sv1NQfGjnGB~a@hg*CZ%YxcSG@;7ze&==cEbG@UgDQ zKxvSCr(8X3-H27E&j|$N4-}0l7eK`4k}-?`F&aQK zp{607MVg983BLDdIZirppz44Vax5naYDoma^*M!;pZA@e0PpV+M&L?Rg4P=h*TuuPIQ{8D{?B;x{lBy?f+lu`cZ_|v4+B-$i>*Zvm-N`KY*8Sg@x z^w_&G>Ehhv=M!^Kl)yL6FshV*MbYrb1&_-3wV z#pb}~CFk)!Lcfg;-4Ecehp$l%RwgB{t*>&gasQmoo=%c-vv9z1Md4eq@)(_sMj7o} zCYd)*o_*UWLLV_}j_x(fo&1zb(@1?1Y`VqihAU)JYD;8T%CTy^Y$;%1XwJ5j*PGY3 z-A?x_&N9WMd9wDm)9C0R!*c0->CjOG?@XFyhC%y6>(WzrV7_=-pY#u|9|H-C30@R=g{7(E{4o=RaE>?D}hj|+uJ;lAnJqPNh zgr?b!>6e_i1)rlvFcMu7ah0tLzZcqMdW^*H5S%nm)&0KCO>IeCE?cmkUKtha^DcRm zWlAL+(&-UA6}>vU)!4Kj-AXS^E$qIG+GEyr(bd#_Y$K7cNu$n~Ww9Py>ix3bHsYzz zCnRY6Fm?bX)Gq{?>5&=SUeHdyCfH8lGwYM=1N)Tm$p0|%9C_EV;eLU0E(g+w=z`dR zX!9fRtAVnFB85(d&WGg$g@amPn306AKOn&)Ymz#|+IHez5Z)WHFPk!?OkxkirDJOm zKCp~Z%aF{XM+A+-t)cnY7Tn7mjMl@2tV>#jG?JR*C*$6GW6`~5`^of2u~ym1-szTM zwsc$b(X=h%JhC{fiGRtW-oeGR)WS;1%IGMy5#0E*(a$aTPW(I(!wHiT{y22IcfMCJ zbjuNP&nksIZ97FJ!O5t6XE~<{clTgyB*RrelT$OwizhG%Be7a|CxGmO0yCccPN9t~ zG3Ld$)IfRh_MGq>#j1uzX@QvCbhY>!o)v!Yj}K-+@)FMd?C|nR^zPC4F-;VgvT9

acOaBxk||93AOZdEDf{`@+S23vB=x*yVk>mvBAT)+Z6YXmrK}Ifijc1 zwMyj*C^$0AMf7f8@V>Y;O0`L8O|!3=y!^SRK=jA)YKy8=XsoQ6Z*I!AnQ+|YcoE~lE9F#xntL7rBTvV zzAq!vGv5>TM*Q^9!pYWZxuT<^8s1uoE1X1%&u%9bY`d6xoZ?z%r}ZACTXd(3X05=> zb4y`Ad#q=<=hs@YZ^Jd*p_DuQ6kmsPDPyj6mSA?<>3&#lI_gk5#WJ?`Ioi@{t;~B!ZPA4)AdbdNDt9y|; zXRUTuVR#n-Xejl$|e%<*9#wO98;$CACZ z=gr5@;~G!%XNdPd#yiU0i!U8cONuM_1}FwdTgTi5&kLT)#+JNK8&8|p2HHrIX`e)1 z6fP$pj0OrP|gj>F_3jhJ8{3Ir- z;)t2g*135- zZS0%~6{%mJg&GeHN0HaEE{1EbHMa24{m-rBt(5{miB(y#db`=mFl8k#FMm3%e60fU z0q)&5wEuhgKOg)b4*q|Y2Ad!%_7E<-sy|?)9R`e8;z|M6>}L4PM}>?)prOi5S0MO zkhRo5fd-5+djip3CG!PQQITB?jI9|hyu@WGa%-FHNl6y#@lQLBq&;V!-0zkvd;?pA zuM}ScpVBNlp7jRte>`6B9{sT@Je*7Wyf>B_tdiX+jlSm{@KZxZ7wvB~IrmM-EB|&U z9FjcHPQoH2xH1){gWR&u%-=9?T?TtTApbZ{WTqfzq8|dbV}OnY;Wz%ky8h; zzSeea?sfgb--*=ha_#PPo|1SrieEDi5p{{6ffG86NcA_pDMfHUJXv3q`BA^M$^6rW z?N#VW82FzUEP-q zUiB}ZYFf>YqwYVJ*$d`Uf5!B_mS%8z8fl6p zYV1ONFCqn0+m4-|LJxH-R^4anl9Y5!AUe5W$|?GU{;9r@PVaixz!}@L1=PbLV)Ls@ zx$TZ?ZEka%a|={E@b7>0;fwT*B?NGvm|J=ej7?^8|1T`X;3dK?YD5WX9TG(3DU*=E!eg|96(l^e8RxgA@J==QxEIZ!hZ?FovM!nLVUjAL? z$wmi;lctMOnx%qG!O~U|1Mu1Op?8knh!GCU3j&zXN5cZ?Y~ca(Y)K2S6h_{immwn1 zkOhfUEDa_WF8x;zrsX=0YKMy{bZco}xN~hKedQ1TEFQGp>^4m92|uB?I$a~cfTOK& z;;E=EHWB{X3O^Bu#_aPe8ELn7D{JYbmt9?_pdJP3yajg@vB$jB-SD+NmBf7cdiMH} z(Bj7Rw#aW1s~VJ<9x@Ug@>vY)MA>w+lAj+ln3ae4ydNEUQ@}@kW2k`u62N{k9RP=N zT%<(bT!ek_vp~;>?!1mSE-q0|<8>PP!?`BxJ2Sil!2y{y?z`i7l`_|gfGT+I`Iz0{ zjq@wLEQ#N!zIFb8vHu~Tc)B&aiz6c&XYeT}&StGWw%x7E-K8jMT2*eL`|;+abw|FX zVWrakbajEB?+Z^MmiE9-ql2i}a5p#^Y215g{11H1YBOWCqz}U#MYpXx=|^9B z+S=OO78Wdb0&)MEh>?Z(PFKLg!CfX?0sxcj?<*WWJ|6Fl^8`SYYR)a)?(%aBdtdg* z3kmJ4E08*jYL{*0h0<2wxf^EzjiUf2-Uf-|dLz`8Az1jH)vc6Lh&G1C4DzBUmxaQd zC$DR}@`8~qnX*MOe^)l$gh{Wd`MC}^wmxk?-+i@nw&JJTKJ`8ma$ZptYr4XWAkhZWVj@s{a_h;pla1nR=mj+KVDQj+&a(A8v7p?AMkh%2 zyDN!_e_dV;TRi_P(LLz6NI4YpnF(ZmWCpHcU!O@m9>Z+GGB+(J87wG=$v0OPG1qM)g|{8W>?;wtVYPe=Z5|j8-*D#Gl5P65pXiB0Ih7 z@P#GPV9};EL1TSlQ7}dLIm+1qCWJCl!gWRIphj^?t5LE8&J++{*5NqdBv_N+hGBe% zVxX#-I4<d z%4xdrm9K9WFRjTbUYq5AR);2Dc*j{FYl)gI#^s!zEPg8a`Ti&+rP%gKwdaNOC8sLi ziPqNYlfZ}X0){={8IfK;_KEP(mvk~V1qGwWF8A*A&LBOK({MkCDCCq*LXd_bPf!+P z&u?g0qz2(YCpOS8B>$9J9>4?*4u^n1D2Xx5W#i60%T`#M8U7da5> z*3G)()20Jr-$ZF+lC?(1niMW)0&dq@2WN5YRj=d2?QZnHX8U5-ra``Y;R_=OsJ>nH zA78N(91@%0aTLd96y?(iW2&bVgOj{(D4^8xCol_lHmm4;P1 z+^GK|_`I8VaPK^(@C_HPbuBr))oS0d*AC9EfuRf{hEs6`Eh?N?mC1E8o zs3@qTxL`R^gM1CaJ~3GAn+O1FXYWKW%g0ai8&`Sy+Qs_ITIX(9zz?z_n))t72=gdp zNGAj+Cj{4S_TrREoudR5r zXiNQd>ZbUwXl1hAA7A9(2XG5Hp*}sKk+eMUd8--cLsTBYdb+;cEb+URnvuN2jO>k9 z3<{gH3xiZqFpwSYMt4LqVeE>jx=K$mnwlx%|3tv(pV*8t}h5hkR0q zQl=3H8!I#huVMt$7Pz?+MV`7XqIetc|2a81$$WiYYujSnD-&u#)qfu5Zd(L8JNMBn zhK-R@|GLo4J_e~7joC0f8Oh}JPokN{X+Lv?Z&~|Kn`Vg0C(9+*<(u#_el-`9p}4-B z=5@EP$Q+A5sZi3gF8FB9VdFIr;97#4kLO=8OPkk225} z4XH^QhYxM_&Wv^dy3ZgX!#}f-fmV&6aCQ}?#_0A$9H#ZbpL1_T*l{szdZfaq>8D-| z__gsxblG!h)Nm8#2kyn7j=rW6cNAFG&QE=jcj7+#kntQ(#U zmrk&~CGd%zYx9Y)TI|~3u6!PR2?JYAmc%j7s zRB8jsDX;-8HuOrV8G{Hj%r-PuORpb<#+1S=s>A-U--V;dD@5mK|GFTf{uf9dZLA5L zGvYVMD)CQNY#uRp#@{Ce5jZ?VyiZNH&hIknIcDis~Z_ zZ!WOYMh-ZyNoC$omI=4~p%;EwtbmZw5pu0+J3Dfmi8G&ZbKBzEZu8gv`u|`m&bI&N zTvqm!DR<5a4hsl|*WHYj25;xR1nh$_%gyoQsG+RobhuuyD)bNiF%MQ4<_KryjWzYrO0mk)ECZ3zO6iaH?sl&b zX3X$WC?=&)l_{M>Uw1hj6$nU$*v!M7xGewtEI2^zxXgU<8j(Hqp#Zm+XA2RK5F3ai zeBNV-LX`c>_pN49FghW)$;T9*oNjJ&7!wOvc=Vosv_0BB&(=fHKOhYE>Xa}NiV47G zKq4##S0h!UU}4r8uo!*Vyq_?!WLAi(MtPyp-c;rqjHn?O^Ng*8D$Y7e!vg$OgGU_@ zUnNN$FgHULUoW#5KYoD%!C(fauQ8TVyIG;phaP7530<~jzTS@bxQ|>hT_yP2%`CKpFvbUep~fZz^^$)OUvsqU5wcq-)C+4qGD~i%Gp?t??7Eq>~URx zjT4;#WHkDnYO9x~gEk1Rl8=_vwVS|E9-Rn=CFz3=CA?t}If#kNBb6wX^xi)5fUFzg z?(BS^dbex+Ngp#WH5JQi2nrNv7x}KgvyoA4x&2!jva@5Q~SkIL07fBf%B+az2j2P z*30TLmihJG_j&ncPQD{oZR|_L?1@X$*qq@r7DfN1wM+loEOy`{(j4@w zp|*byf(seEtr@gjRot`NK%>3FPn+zld(E3H(w+4re-LyZfL*h{VP6ATC>eXzY-zLq zFsa`0Sm3YccC|r6qI_H|lF+UVBj?tuQkhCx)h(KHBV#$9!07Lwb`Wu#!u%USYc zYj3EAY=+V-G2({<4$!_xRJ@6a2s##=2_^EIxK4za<(R!YZiI3|V`w`AbYwMDD&hKD zu)|D;Rb_nF%U;jsX;yEm4gty**cNk-Yo`mCNdVM{!4rN_W4t}u5g<{b4feQtAO0({-%1h`*DhaxhYP%?pI$5yrBrrS2 zSHn)W<$R2wHv}W=`Unr>C6P>iBpv>VmKlE8_Vu+Niafo$hYf*q=5(e7PYQF;;^zL# zqam*&5`%qy>QD`Ju@BzDTU}j~h$M$|6?C6R`&4ww=f^4bWly@5ab#ZTg!`*HQ}EkA z+GXnp$DB#T*ky}IhdVo~yF4*}LtYyo5nG6L4}%UQ^Bmh4y{@vpkeQHC2vSs1`XCFX z(|DNeDePNWbMV}8e|h{=^?LVBi`AC*rFCQ6LG-WhLw-w0F9-63SND_I;vWZms>|Ur z>dL?DxVjo-K9x_mNlO}GOuKJKsX0%T-rcp?OI9K$6Uq+@ z!R;5oyCYNiT{O>s^nRU|14{(y7g!PcBhrAvgh+Znlqa?j32W#0O|G6usOQ;L&k-*K zS8E$KluHhoLIc7X7Sf*A^9|vPO%J!wW#$~@{@QG10M3}sAP^N2KiEh27sqnELs^LS z1buZuBVzOgYFZOv2dK3rdcx_9ZCTTorJPLhy_T%L!|&tx;G;fK7-EIw>d%UHeqlI3 zQSL*6{GIo1e}FRVJb-ua8`%V`=t8A>tI`A%MP&emLY~O`v}!qM!_F#bHN3;+a_ZHu zaFsOY5y}E6gf7mcj|&?a-X@*OU9n-+QzVbO@`t2CxAmUBkIZ7c$J0B{c|FZ) z+kevXy8Nk>CdlbCI>7Qrb9s{Qdx>d(5fgziF!S10X#4!ibTssfQJj>$~uo5ZU8IAnLk9*fJ7c}A-!HT zYwFus;S5E}0B|6ms9Wrx%X;5^@QNd`7+TL+uvbgq&4CjFZh3dXge(%$BWJnK6j-jx zUR`lhw@>+ziA`OVY<&q?L+}I1bd^<7jqsx-I{veM-cpZrW@X^2jGYbjzMGwaAO7eT z5mab+8RR^9olv=NQ@1z-_B|_6u`D|q-rqw<6Fyh1clLrRc*Qlw`(|+uQ=gVE_k?vE zel3pZIi6D7KHrQzo)-9epAKlOivA-SRAP~u?^35?)K! ztQ(#PJwQ(0US|y5ZoG{={qqkTzEO${KNq6W5TcAS6B8@aYjfwO9$?qU*z$G- z^+rssFT1qDE5DQ}C>m_Y!jQzEy`$ea5n1p8=TWaz(O2#`tE339NGB!Mx-3{UXUxdW{lC_I}A(x51h~1H>JOZGNz2 zHdYrEELAiuVMiDYVwLPuX;f*K)0Bg{>3f8Sbsk1x)Q<0R-`u11p?J@=#oSlO4Fza4-zN@5k2oVOE^}4vyZ)t(Sp?$`?VWF*~9#Cq0MDXkP0=6Oy%k%5; z{>$aZ^ww6fCM*4+sxBV(N*E20rhRqgD4AI&ZPbX=gE!Co8kmD7TN}2r3y-xAD?-!r z1>!-&>zC*R0Yn#}OgBpYI$O{CZ!41!*eATgM-XzoIy;oG`#4+pKAHYiR^=e1!QBOQ zQjeaswcEf*?_C&R)i2%CeE7*+TT_eCmgBENvzHzuaXMG0(K%DtTa`$r=5P~rqB@QORxqZDBp)`GEn5K8;!9M*?)GV}){vL*6Grvfw4HOlWXeVeU* z`q&v1J1%)9jQ)}LGLF1`o|`=+#2Glc+0~r|R&S-acl)qk%vFzNTY{z?V1YrUiGA4s z1Cg%-u8HiRoo%ZCV1AA^d{*D)*s%8cRI-2tfd`=!E}=)$u&-&KC@xEx$0wZD>IH|( z846EsK6J$qoJ4g8mCMpY#{-li%<`-7;669;)n(!dkR0Rk_h+u_oEX(Cgs#)(sLb}n z@^k5WWVIYToV1s(SueB&tkzu+SL5pZt+r`wF`~G>sxZ}>apFc~kX%l+#p2jA0#u5_ zK*4pv)EuXYgpE1=zTRr8j07xW&#gC)^hZnM0JnJT{U&BlM3Duu&bmB+Tr6s!ONN-w zfzvL|j|#FRE3(-*=(?0GLGc6)Co!wiL85hURO@>1=S9pdlt6Vh^JnBwpP4h!C1pqJ z023ci<=Yk4TYgh<1BTAwLRvU#S_)z5<>Bx8))Rs&_VD-}sIr2{QjQ3-stR^pIQpt! z6F{Oz413v+Hm5IHF{h&?;Ci3w&cW&MgKnpp0GB3|#JA=nGS|FVZ|AG(C2cBuR2 zIQT}1rncAnNJ8q{hiv^#s{DtoQ=ivUVW&&sHhdB4*k5Q+X|#0l+?oHd>;Yu})609O zy=tB$qP~o6w4aFff5s^f!Xuw1>({PG{tWFgEibH`lUfgLAo9h~jcGtdaWT<-Z)QRl zNzep&7Md#s)a>E58GJx?W3f%^v9*ixS4)A5$jwetsO%R?e&4us`&g6l$7PkTf`R`z z{~B9Zuz~A*>9Qc^-uW=3JcqJifTChSwNsPM?9hU?zAL2mTF)QCz*x`jX3mFMCKE9Y`mYEHx0a$pVx!j+@M*cC^t&rr>ey~%6Vbs~(D94zY zFW)%*m6JqK+l3a)t?I+f7z#Wen(va4$6Mdu_K)`U-=SKqHmQ~g-eORkiu{vX@84R+ z*8S^85{yL%h}yD_M3gJn%Z1;j7t?MB*!(aaLe04yd!u981zZE8_TO2OLa?OpJ$u1V z_t5*XZ2Qs>G9d~iu!;1!K#&tfl|Jx4v#K9?@<*vg!a;aU^o*VWLteKF{FH~L6{QM-Yui) zBwhW)o4v5OANWrGCWIyvs`Gu%+r|?=Tzg9C>~ub1Kks$;+?NxUd+nqGUj?=l^&CP> z)nsG2|55!s#c%VzbHmyAU!59=Yg)sa1>(j#E<17NKls^-Z(sAv4n~$9J=AVJd_n`@ z63IT`lrpd$*x9l=PB=eJRAkb7lGv=FXjLk+1b>O`iqZ>GREAW2irm0*NQqK2A*U4+ z0mS3wVXT@F7Oja!#}B0oR?R-U_r*=^AGM(1*q9NH?JI%s#6tD;iJ;~hMQeShKdO)^ z0ZVp`$xxQ?lTujulX%rl91dx)fn6NzemclBvHrpnP$i5Un6<`u;tB|z3Ir}J_+NKt z?z}Fu%*eFo;R2kTr}Uf=#tkZ6GeSjc!{kF|c0e9>J?E$sKY zQ04bHD!IARYGk4)5s4W3pou&O$ONv>M`B1|SlY4l@edZ12oSj#2z=-+6ZbBYFvx?_UAG2*t!Y_EePp8$Cr28m?!cJ6whTWsYVsTUp@<2i}2kSJ#&|W)E3`SSf zNsH0*#)r*&e)-J>+gSv6A?>#gGG6Hi#k$`BNj#%z^x!nIuhgjD@n$I~mkCD8bo?8Y zA#P{~PaLZRpWW*9{5mP{&-5{v&`Z@SUAk>-b9(xVu}3yv)yxq=;`N@Dwl}0C4_m@3 zPkyc&hr%x;vSn%Hw$lFw>OYBm^ck7LR$w}=S2don3NZAPglT`3vHbnZQzBTi1-=mp zbmRZL{a(Xd2}a)xtNUh)Df4O9F!=q8z(*KpWMo`1klBrh(0VMj7)Ku+>E^)XC--@8^$74n>R1)F>rpsVE#iIom?I;DvxSL#9MF zdqyPj4Nf2_2p^%j4ig>AKiUF8axjX$U;6&uw$TxUA4C|c6ucD9H##oXoNd^ugVVU{{@<=x8ap_7|Y9fh?A^ z9+|g+O0$83IBT86z?`su8J+osm1i%u@uCaB!lX^xvq8JTB!j%1XBWK6lh=L6JLT(1 zBAkScRwaf%KA*Ai;{M2wl94=S+(2w5M2pP%7kuBK_cvb?nv;IK6PAzH(gdoAKYFiu z=iIL^rLdVRW6-Hq%CuV=z)x_|8t=jT*++fkmP8>p-%Jed{Ss`l1P`ue$;+DmPy<2> z1c9jbwXINHuUK^O1##{{k_A~B0i9<(D^xNtIC2U(Ht=95#781?3*vHOmJr!HD{VXb zT|#U$kY5c|k=zbAC90TYQ?2*hucpx#aA4$0fBA$pZXY1YtH4TK%Jpt=XFf*UhnEoC7 z`EDVM-p!oowp!m$8(zhmN$0oUJ9&;Q5jcKQ-i@Qx(SOea2EE(7%u70w65TQI%%|ZB z^DG~X=m}#q$D?I|eaESZik=!+!Rf^lZ2C3_;iyiV76x?W+=~0<7D5 z_K!YM2*(6b!w$nd&RaKfx6LgDeIizg3J4EPe7Wz`%o!jvDqOk8P4@?aQ$H$T6UpS6f3Osz2vC9 zzn@JZT~r;9hkv@FRZO9Xm3|!ToWy#<9GTK!R)Z0O?+<~oN zkl{GG30=Jc5?+26z=4!gS+t240&hQ@*=}MUmaFCl`#J;>8?;Fj!r?{SCo(1?{#l{f z>>b;Xk3t3@Te;rzzF*#wrdFTATLT;2%2*)+k%m~ZoD$*=pC^w-MW%H^0=!jogwEte zi-O~d#9n{AP}Xp|#BTWEPE>B&;YyUxAt%K1*1oW+7)W`-hrdRay%#J2DIBX-$2d+w)$ zZJG|!Bcawwea{JRR_1qa8zD4HJ)cOg;lqzV;$K$>!XN&*py#fos*rymKsQ$D zGPr|ogt3ETL0MOhI-uM%{S`yX_}yD*qY%PRKVsedcRT2ty;~y5nDzoNVqdO4- z^AM#y`qujK5R-_hZZ3J21xffc2soyIhQIdh5A!u zqU*iL1PcndK>urs5u6x_M*73^Vqe>41Tx!WA17p>zDN^tfHo}aRRN+I{dQKiLNu$? z1JXxUH>(XZ-271KZ3!ijt^jgDF2RVSgQeiNyFB!|Pp)KaSXRgQ^m%9#@-oi?Q3=-k z zZyElhoFP{@7K#^)5}*qO))1vfX344z(9ncj_)3tm*CSeKy}mF$iYQR$MiMEHG$MK+ z7>J0foi^@MJLQLYUDKtHLU>G9hLFr4opU~tbgu*)qBzz63}oLEsJIfOBd-tJe=5E@ zetpKUX*x$3yWa`nbp+gy+{k_=5c>W5$I^TviH|-yo}zhw<-(KmI?!qH)JvsHhEcb4 zn}tMR*&sUFBx2cQnWs$aMK|pluMrc?GC@Wv)+gb-=Zd)K~W+#a|>^A5${n7fFC1@QCVF{71KQGdRaDJimHI`0eJlF)1-tp?s^QO>s z?A3HAwtw3mw4r~HA1X{Nd@91kC%!@?T7-d7bOs15IzyAC#ow$uw~;Hav%<^Ht_+Hb zx(|_=_esv=D8rb>ML$csuZopfEq9To<e$iMrCBRO!3k$zMs$Or7~7oULd1T6 zTl?&@j&eXXtWf=)J|qz67Y;Py2p7XURKCO-W7@K4+RtR^GF{Af6L}HsccQT`dwGIAo1a-$ zbDy_&Pm1RSnU2=W@hWFK!w05&2s3KOt(Goa`ko>_CfWHD%EJnZPW-KehVX^Ki7djz5gGv`!963aWF@r!i*L;n%?QGCpoK zt97Xg^z3f-wN;bozhux`Y=A`ZOQxZ9^8-}YAH)ui^%&C|=dL3mk!Ufh^5!QDx2AU* zm|UzB-&Xo*>In;f3)enk(U1Aj0PSoFGIq)9bg(*20uR+fN#tb4JxXqbT;ho1@!c9^ zT3;7Fmqky_ik|rzb&%{WI#i-<N6)!Dz(LwgLoFB074I@S)K`4kw0Bl|neSBeq@CSSc;it_c4&7+c5A<5HUZ6oXt;bb{sAwf|Sw%55|7{Um9 z`ZZSJNL$9mB~rvncf0wx6}U6dHo(Q4`Ht+ZD4h`v;q*8`TG^c-@ZD(zrmwOWBO%-i zNbycsZD=shKV{WU$ze&0>&N>OhE^SZ)tIDpxEKBE5T3HnY*&2pq~zMy6mRUfs!5P} zdptEiLQ=-qF?)DyyO257aE^(LyHN_tRIUr9PfA{BfU>*BYV!LpkV9)4+ED3D<{-g~ z)g7L?YD?{<|K1CZ>HsuCyj&ny`~Q=wrm_T^djW_UNDEC{ks*AA~|^TuV)>eSeRT z8<`d+HKG=R(9mm*Y0*ln2E$DB5rwq#AwKIHy1j>FYDZBxqYEZNIOCC+)gqr&zzWXo zlp*n2>gl;>qD0IeS(aLu`)q`o@_k-hkTV|lnGe0?>g2#w-~|h?A$VrQuu1XA=~(bfHju43j2c_tqaC=bo`fW3lM1nJJYVwBo3lUGta3uQUV+^{ys0`(tih zUUqCOSYKP?RYf&D8`Zrx&)JFZThTy|kJxl~R$1ENF&AvKG-hJzqn!bAdS)+aM#srL z7%y9b=Uw;jVYUu&mUZscoHw1B0}!eRR2 zT_2aAKwg4MYkCUINoQ`jt)Hpnb`bf0JaW!0#dnJG6F%O0e4*VG?Ib^{)caD(Q>$yHM6t8=N*82BphONBLNE zEBn8L{RTNVf~VD#Dry;=E=c&TdV zGl+9`CEc4Wb}U=rEL*CJMa1IhJ<-yuZI;0hYz@>dWY}=ed&EAA(gOpQYPQ_6s zdXU;MdAxUb#8+-POVX6L+jVym+uF-_WAx-cr=6Ev;yxX2AqNQOSMMXVSuL)80rRE{ zgQxZ(o2vesC{=_cBwemA=N2$v-{-E=;bxd%G<%9lEA;6mSmWhc0-kb2n63IHUsxlg z@}@ry+m3X2mRVgJYhB;EmXW?etb`79ezH;Gx^Wx~Hi82ORp9r+Fwx&Fipv*(qf23@ z2)@GwF~Si5!4TAuoYt9FQKCp5(-8K3KqAd3p}JNsM>HH;KZw-hi6hP5`1?mWLE%@b z#4Ut*cf$rZ$SP#XCr~_S7TR;ndpww0@Bj$di3pwRzkBgTNWD1En*;|(AW*VgU|CUz zkZs1ryo;;}45%+|;h#)hyjv~aG41eixsDgsQF=yQgPvHOe$5)c)>W+(L^+26@mNj!ZO3mX*;x}}sj=tW9ws}xLq8^?XeCkrgE4face zh=auR%Ld5jtE`UhvMQ_C?)4pgE1kM-c*n#22@u~i!a7cU#(*yhfzp%JKy*jf{UX+7 zPw(v2z?DCJC%g?#%F5FB3Ya!S$k+?FhIKo!1VEVjn>P2EI6p5=w zs7|lV9*)0#y_{@sU!QFIPn!%Tr@0g47+b!1N@gliG{NK{tl$kD$EJq;ONIjDBG8=? zyDk==sVC#56KiRdjTI13DDV&q7#QA}eKkQ2ar2UI{=PB0_CkUxbVVzTxdY(M!f4)B zwNg@;b;#22`4=d2xuyeVFkXFtrkF-o5iOsC`_(SOSAk43nPR6Bu!R zjfg_nU1gjXYksF|(9PRdbLvXUKYKrWnNyrIPEyaYk%zkroC><5gRSt^OosY4~kW>YQ}MLZ2&8Y zZZ(ELtu4Yk&d7Hd?s{#W6OB}1zuHs^f&go)lNaAeS{i|Kc3F9CvVHKEO zZf{!7)_Wo;aG0S!25PRXkISwuc^VoORpD6D*mIKY6P0Hr>q})*B#O(g2IRnn;EQHH zo}se!v#kUhTZCqrIj}eGVOHY=tZWMRoi4D95Xn z_A~L!ftm9D;iyUkG&G4qx?FNjF;Ge-v}|XCqOR1Dt6mUllGzJj{T}ZEYpM*#dn5R04uZfmJ-+1rnAAu1kyv5 zaZ`XbwzN6k8dP%cC-Ck((0)!V5ri>8XIDbCc78d$iU; zTBU(BDr0SJZLv3|V`gb7NgYeVANVGXbXGVR^x7fm)fo2h+5a#AU)eO{5)z(NR~{uK zBouXZVJz{jt&e}!)x|eAH&3jsMP_He3yX;8zJ2Z~KX4Q9|M}BGCY1~M`ueSfF4@v% zGIeYsvaqydwOwt+bnv?OB3W5kp=D+cK5U+znaNK{O`Tj>3D3wNK|)4;7dsS)sDkH7 zN}G=sE}^KU<$rO3prWpBG#p2l#Op|1Ae(BD+_hkZbA8P&Ki_n8NZ8r#ja*cm>|b3C z?dd_RNPP~21eG84krAOA~+%D zJ~pB8p?t>)=^nI?_6k$k_-Fk&pZ)!jA)U#i5I(3JOXw%tJ*N8tJv}28UUUfe45d|B zRZ82T$y=e1wUOB2-#D|u?oxi{6e@w`4}T4N z9=g%**by|>;#+z_>pYRX{HUvR72F|LY7ZS5CFHW7U+Ji`Qh?!QbMie(IN}kLk%@o) zJZg(T+`%jE|3BZM{2Eef7c4bjG!0zw!E?l#r8d%uN8EkBFZ0&}W{jMd#$?hNh-h zuCA`V?ux^|pU0p_khj7omfTn5Q$N_(MsNHqP|aW8pnSY$6W;b-xx*tSC;wKHI1I4D zUN}Q31byQTtAK#O_=B=ais<5cYC^9CE-@Txh!W(;O zNl&T2qtZ;)aW|J`OCo}h9YTPKDxNb&)O|5OH}@?(+(~nw+Ioh$@ezSOHa{Pz$rwC8 zUr>KOE(_uflLk2^nug5}5djmdw_D-^f!(Pc0siko+lAUU2{K00#ai{pf3X~UNUV!h zFvY~ge)78yV<9{nbnOmYUy+dHfe_u>-R*8~huq$wvvP8V+Hl9bb{H_Uv}D~$MG>L@ z=<51%{e)O|MpQ!LU7kW(`0cIMPj29@KjC?0GJAz1BfIgZSl|Mm&&%tU&Gie8PsYjl zgkq65yoIQ=VCyRs5_M%NicX#%iEhxKp@hTJq&zmU8g?nVy&uRbTqH}rY0;{MjK&5!WQkhXH0Z-c6BvD53!58 zd%?pUUS@@(Fdu)@$<2r#5;b)v5A2uoVYStST-NHF)S>ls@1wkLSVYR6o~W%?EpVf; z>~EU&4$r?>=WCa6u_tqa(|CvRtoNQoGgQ@hL@7N{U6NR2D#`b;E6(744W9UYLsR89 zHYex8QMA6Nj5X18(Td0aZ8}}=tSELwmC+gUl>BWu@aeK< z&g^{o)4}w$vPTI!F`+oxAgSkyXa_QduI5Yh!O+j#d3*2mxvPzbb?oKEiJ&jq9hTwB z&|TURb>=)8=8zl(#qGH(=)poAUaa(!nwpy5@!8|!Dp-c1s;XzM-dEhSmzQp)Rml~o z_%l(4^VL?(F1sogC+pvWVx>3TAjwBZc6=V?$+EJt73M>GL|ZL(S4T@f1--dtWMv)U zEmwux+cb+#1H#%6JLV*BJt-;JIe1A~o1cFmUM4=r4reV5L4<^|p58Zl)h`XLzUnU9 zgIceC^lh5NN`EaZ%sYnrx;Hi6pAIN%X&EJxH0UBcq0&eD`%+d`PphY^-QhyF<4LVu zZ8t+@;Yp{9rtCNUwYA(wySt+H_AJ4{!QThASRFYHpIOQcW+vqn7GiR7ae=O&`uTIh z74j^ef9q*N+3I=(OP=#EZwNmh-}Nv*yz6e|5mAwOXBiw4qOAPf$6=+(z3hw4VvH0e zw99u-^^x-3i>K4tdXozacR!+|qkRkvgmLijqRd94PO|=@>X>8YVvJd0hl!JX`BLZ! zo|%H4-qI-OLv|?NQT^?q`%Trx-I#o^Usbbb0uMjw^JxuU`XGn1d*O}1mRE}D5Vo!{-CJ^UrZ0Vp~Sur&8|;m0%KUc^1Q`y!iLOmRs`ZcmTo@Rn2k?OsuZ%kDVQ zxz80`IMk98Gnb&Iu5Mzv1&5dzkgD2U8;<{lB7q;vOF!Nb)Z_4D$$C`Q7;0j1EULet z#l###g9N?ZCgeXXi5IDtbPXnR{G4-QPU;0s;LU%sti(n|kG^(Oc_NY;bf@=9@M6VX zs9BRg`ty^mxM0ktO7yXvSeCI9=6Qd0OdEk~eO!BwA)NZte%aWOyl2(g6RXDO-3rf^ zRoR~Lr9+l7KSbca$kbugeI+1lfEpt%cbp*UP7~7li;^38rhEsYa&#* zkE4i1Rd#RL(b{!48IJtD|1PbcqlFOCZ)}l%des8+1YwBGkyBf%-o4?7mDyTUWPP|j zlxiTz%6i>cTkCcNhv&b>z!uuHJj^UC{9!TpQ}k?mXoy9t@_NDPJH zH+TMLI?mc7hd`BoGBZWTAe-6T{C9eC^3Un%DO2>u{c$9RI^JOFheuI}SWZsP`KTD) z#$PNJV-rR%uSUnqIqPT-A98Z?pKK;*kpCcx2EZCHMd)4*w#ZA&Z?f)3iw&7gO?SDi z@V18h{19|>boyjDs<^(_sY3zM@}-4u0{0t3C3EQL=|!!qkj>1VmX@T+XiwOF{`?Xz z-LWT`X=}?Y26DVGKmVty3QPEQ?CPctTmxV;UyYAN#LV-NbuuO;<#kXCfDJX^kFMXt z1vflrWM5t? zXtyC)uEF7Vg^35You%0u_x*U+?QdHEzq1Yr4n99VrjwKmX5-@v_Yt~={unX`esFbc6^t!zrX)_kYgm2QM25T-2ZTBXlM_Bpb7wi>%l9d8^ZsK8CTbd zpv|##=w1gpWjngiv7+0@XZmI(4cSdi7NDoTy1KY{lT7xFP3W_lT5Iv|-|`qbY|^xGtm%{osl3bl z17pbN2d@VcLslcBUs%LDU8;1S-5(X4NrvBPAMHxL>pmfrMgxSMtK@l zBKTZYeqK}4zU|NulPm~9UW}gS6b9v*D$THHc|nX7>W(!nf*FmV_MfXfUz0g3Mi(2- zNUg1{{c4T7!&~W9^K5{Ees_83HB~s3h~e}2aJ2zOuCE)G1eo6{W}GZ7L(_e4ts1ve ztZj%{^*mSGJGz&a(%`oCaLuvF$w3s9Akz}FUPqc1g9x~ZbthWR7oSDb6EDsl5qi{K z$3J;_q_T;O7vKlB)jF*GW#X`y7DUeUcH#UqXM+YNA)CmKX3w)|(mxheT3yC$E^cmP zktCwu@4E06mlqco?;G;+^1{c)o~z540C2_WhiKNb07vpT_>1?92+|mol&WA|zOcNk z0G_2O&1M@X7nfglg<~59De1?z>rPfyf#xIWX(eSDH&dVxBbFT(q1r{*kjTi$ z%*x7B7v@kT5ea+y$5YyLO+RM~iy80vg@xD=SVLi9xcN}Z6u-rAvtQe4;906k#f}&x z7)gmaX~SU*_Wkt*L`G)afh>fSl+^0(QtvWRXIT$>(R}mlo3)phS3z6b%H{caPv|w; z$XTgEu8MR%$3Ihc>HG;3_?(YWj4tzsS`4Y*N-8g;-oB7C59{5Kek-G_tZXzeFz}g^ zbSb+Ap{}=t4LBD;ZT)mhWQWI|sC`xe-OSyIeao%>glX-bfB!HFixh31`f#U82mmAQ zM4r6P^5p2~agCt&<)k^g7TQl485xhhAKleXTj2&}T2gfv_FC2Mzc25#l>Yk#k#b6=tJ8}7QY)V(C={@FXycr zs;lF}$_v~4R@ZB5Yr)$bT`l_u|DItF(tO0~|VM83QAaIfld`ZwFP=UGAr18nq zkH{{LUiYUJUYtSv%mS1BLD-ZmJX`vvjaqPMYX`#i6Bp~<&5E(v4C{rY6xVezs}h|*x z=>A>B_z83=BcG2SyuKGhK0jGqZ9v&w9f2eUHaD!V`n=CI5)6`ik5aZu&Ru#afuG6I zQ|tR|?)BXWMAbq5u7}D*PxCaB2h)KJb;9-wK5XBN!>-j;yL;>Ldq3sqyVyb_b8BM% zB5TFDJE5e3fMj~Y2sZyMbUcdty_^`K+i>|*Zmkk7tC9lZOpY_n?J5sMg37T#OcYzS z&0OW*t)#Z|iGf6>J3fD(tnWFNoWAo_9t*X$A@DnZ^@CHmZBtN{xcKPI;S4dyxsD_@GZq9SE!5Gf1f`*1}^D16|XkLK!X(U-B%A`}Hgo~ zV6@bMt$(i6qw@hO;WP@4Kd%u?2o5%-59X&`=+;cHObjDM_4LS@v?`xWw2^8I;6b_4MK|Od&aPY&I%Y(UT z?Xw>tl)jrp`!kPbM(-0UwXIcTI*5Zlc5E~_!wMNnJ+uaRVZU6F{7ci*g;Io|P9k%Y zlY#yHGS8lu=+s3Q7QXj9oR1)Bzc*#CaT`e&?6cwaPJpLgou32PcKi$n8~Zz@QOA&iN z-bJJW;Do?#7q~y>|;NgT&-7>I^cAUZc34Q{THb{VMaJHi+f!{(jEFMd68fzBc&Ap}k_hnC7yZSY>CosegJS`vq3BdiA0LLkR{wxZRbZ%uOX1cK78x6I$!*-UlO>Yxq zTFopiuTzGH6&9A3NgxBv3+M9xX4S(YhpB`lDg)`x z+Z#j5?9Y&biq&lw)EyI?wZ4zQ0)f7yg(v8VH?6E>B=!MZ1-zOm%rC!a?2Aou{#wL6 zcF^5qR zOyDx0Ne(bL7EPf^`$43EMovum`k%cgJZL|(G=+uL0!3eQbvu$28FR$Bb|b5xcQ zkFCF1u=Kx<0X>@L=6w6bT!;h>{hM9THhj_B=@gtVPuc^5=m;?X06HNhb7G%_Em%vdlEtfqU?w;n)eewWb{HBpild={{>$p?EvpG; zGas)|)IF%`7*qhv_cu_j;{b5HIRvSWVDOIxtp3#OtYw1APhmfV5&3yCN!xXISwUlC zibk=fZ=WC_?ymrjeP2Dzt!bfxAIK3?V%7*Mc&!2Sg6naoaoFJUa6t+b)rQ}jlNxm( zXQ>~=U+q#6hcyco$E_v<>3((>k^+%2SLRDTDdvGM;KG+#Sl;n*X zGczkkWZ#-wJTw^<>G`}DCf<$a#$lxwgX0A0}lyuzXP!@j{)EJ&dhsvUlj zZb;EJOmKwO1lzcR?v)AQ#T6d2t(BE0)X(ox2bXMiWNArIjgH{^2+XMDn@V`63^Ct0 z@<0|m*@5!$&D94vZ4480?w)5HosMK(vN9g?lLY`>E)E0jYlKm!(Zkf_a$@4^7?Aj`7gHJw>x6;P(Zdz_T0r~?561*Sx3J*7mM+*dvVU-J-v!i^f!n*g zxhtG+9X#l8_(@?>7_|XMahmi#zwtG^Sc>s^>0D^ zGae57ELU137k$ojJbNM=t4Lqr4O&}SJ>(}QCdxK7^4T&csrC?0d)bU#mv>LD3vNkY zwXa`wcE7oVW{~v)=-3%guX<2vHZb{%*Vzu#v1Q?=(ur1Q7&9puS=Z4L&aWYJ$A^m< zLoltpV7;fL)m!YQ*MFY<$pHUb?m~GcYf<0%J%v?q>>S8J+{8% z;md#K5bKuA0+PT=o7_o9vb!*?F=MLhaNxto`zR$85r7;NkA;JRLP>h`yGp_&XMAUN zeaX1ix|!%E%#$21^#jF$AnjJ>?`G^>HJ-qsU@6h_z+rOo+GBre-*(^94IIgd0>j}3 z``AxtcfOxOyoWQkc+(MAxI~@r9O@(S4~kGR(3BHU-h>Czw@XoAw?|nDexEZVo%cIK z6J!wO+OlXBE9zHceDQ7@+oA;}vrr?(1Q53%497pXaQmd z0!MgyOMgoOC z2>&y$8kjET-RJ<4E%)FrEqi{xdCP}e+R>@0sHE0&b`Al7MwdrKkG<_&rP(2%Kc~+G zXsE{Lvrh0b=+G!aP+?MfBBTRKMNd~4gwm->xFG6>hvaT9E}P?~?9hc9Slgxr7UAF> zW$vUxZy2D~oLbj{XErK&DaMoKE`I=4{mN#kaqBa9*Ac`fJfu+_uGE|qUneyA!^5zi z;G?Xqqi?TY;o=O_E>VVxbcu@#@bG*^r>M_pYHC89fC0MpzX2g12KZHWKE6VbT?Yst z7xAO_nf_QlP5i*-UjURtA27LEf4b%?3QKs?adGgSjRL;3P~Hd>XLFi3QTAjtFhjEC zpWa?TgE~5l{*wr>{rdq!f6$DAj;n2M**j)3r;@8i>_Mj@<7{By_q(YHc6J8KccaTa zvbDF**Q(l6+@(r}-OScle;CRT&LEd+Yptt;3xZ$VvC^Ym5=7>~)7orRhj4fq0GJO~ zpvnwE+;Fk6pFx<-8&nH8-@V8!j@JfLh(LZz%R?F{E`D{^Gj{x(oEQ+($TjJ=fyNLi zan6RoCm}XSBz|~`&4_ULmKfaG=(~cS)YirB?eTr%FnV`cv z8KOy-`=_SnrT68*iTmOFHxM$qE@Ki9e?X7_R{5m%`LnXEEfWgeg}~z=Ie%@Lm6g@a zI-mppt1%586lA?j%%56lAv`a_o-lk6;O%p`zN8Q; z4zyf1~}B#W6dM$u>;ldbwZc`O&198a-X^ zJ(;R`M9^rUV0S4N&NqHvcRWVM(w1!}f=W^KIE*#KE=<_X*5=98)9{&4CMp8Xuls!j ztlvMB&j$n|RXsgBB{0vx!%>a!c8NK3{*HO|BmFuh*|_}qlgL4A9?W-PDyEWgnT=;(f1kO9CG>qZT6Pe%f z9*g^(19=IsZbTl9mKhu_{|&nyPknkqru@rT0Y_(8Y^?7PV{vja87C9ndM| zX>B_@yFx%mWDJ?I*Zl&D7<~W0rVVu1M_lM}P@N`Z;1Vv(bEfEbJCJ_~UumnYtLuHA z`_GY#Z#=ubOK?$Y|IER%w(uH;b@iY1897`9@A;7=5xV}%g356R}n)m&Xum_Yz zu)4&IUZTyFU6TitO5e>`DTg_;q^O4n@UOzMG7HEB zn7qn>Jj6VG`|T|y}V55MV2!H~;L zK}>wF%a`U_?RGtCOWb|BwtfR1c}z)ZsRH0ofPY2M!nquO$d#OvlT%4b3LVhJKT1lN zLVGu!JXzqtZNUwcV5bD7geGG|hwAU@>gw#i+@^!Dhpe^cI5^Ab!<=A^EJ6 ziBE>UyF*YqraM;Zj}7l0VSyM&hg2aSec~q+|3E6--jP7awjqVBw+?zEUsL|{%m~8B z&(FYVcl;eZgUzIerL^VpW&OkDLP1ec1Q;ei={j_v_WCGP%@x0AV5ov@TU0fa0exea zEc59I^nee7eR@L%2__jGK4Mmr%QwZJiXcj)qYl&Im9qlC5F5=wv5{zh z53l|^!uZanQrVJ{lAWU?Up)BKoHL?@V^jYYpL{*{^Y zbxYvnmCyN^@9e(xMiB#cF#f@VgcIja=TdrXIt&vmfpd-WlMs);eVK;eGG+ti2uf?q z-^b{dK1t-P<_;ClDg5y8`m*|Sv+-23A5X8geg?hEF1;D-=BxB*QNZ~p{^eduzd+*( z;!tUz%>H%cjHlAPJLni6BYMvW+*TKXs8|}U2WBh_(&EXc>`x(d3=I75%0$^T=?O45 z8%t52Eww$i_kOTjJWmFvP4FtIVBHtCKEd1U@;JL}A$8|_f?{rOk0*S8+*#8K_w%!~ zByP}Mb2IUfFxhCO6u#YQbiO=V(!t)N#}L2yL$U?qTc#$TSo7Nsjlk`~UT*Ow!u)oh z4AdbL0M>7k*=_)M2%Zr>8|;DGFE!RQD$x<7wvDYNJc;v@5}5H6Ogz(PD$?D7FC!!>CpH7Mpm<_yYLK>=|L#Aje{&&4VOp&$+6$;zGkRN{kFy7iKWLe@^?PThoRTETMS*giMItIzA zPXnspSRg8p*?`4HsK#-l$2!Avn`Hk9&tUO*?0Xp+G&?D6V!rC;mg^R3CQ|uE${$D- zq;115zj-eO8n_G%$%8tdQwfOr1t4oP+s>A+!GPZi|6#@tnk*^#quJda1>~dCAk0;u zz2?h(eawAwalIh@tb18jO>hlix`mRmvOBD*CK=w=#*qRzn zYpSoR+P?*+yvM?#((9PBVg7vd_JEHastott9#g%0&F;V(BG7I0Np$X`#|m$Mh>Ff)&?~g}Prl<`ZoeS5LCU6EBtBkP zc|gKm-O^~mzL6s}#R*+>cw~-2Ux`Cbr_LSBfLYL>35>5fS1J**I;=9Fq7$NhO++@~ z=~d$UX^W#ix>ot56Kx5G_aO2F!WxG-yg`GR{a?o}>Hr*W1^;$Yj+%oRK8Q zx;*=}|Fq)``b>KS7mqMwU0EOzNB!4MY=xgClh|EIJPL$bD4K5VbZ`Ffe27`rE99pV z=CeM^w`UBSwtv-cqdt{uk#WAQ5ET^_CnG=|`)@WRaUDG^EIAp5p%#|Rn;;`~cYE6k zoRl^BIXN3^(7Vfmsu7{Pc+SH9Ehj);fb8xB-W5@wvs42X_`$*L=!By1Lozt;*bO?j zUt#YyM*POxD;Pt`--t;?Z#b|gSA&vV^yY8fh`^bgFEIA4+)b(~rmc*R+tf^dY3_KQ zmS`<>KUx&Y24YbxcfT>C9^mX@y;h&8D@v%#(#$JT(xRvn;PBhC9J$y;_urVw->Ba? zI9LZivsJ@7YJj=v03WzRfzRYCAhLwqK7f!Hn|-=;Sdpoo;pQhQOx%a-T~AUL2pv4j=*nZ5xn+wgp~669C4+|>owf1E2(r8 zF{!%~`EX=96v)&R7d8a68m8)6)gE?VVoxS}M73 zn#aZ!Z3Wr}VD>9_dt<@QP@9Z8^G@Yx&JJT^l^4DCS^N;;8oFXY_aFJAMCah`%^z*H zKk}8vI#D|LgdRsqhg{fatGTokw}-f}ECbbCeWCWyV+C+9XH!5Wlqjh&i4u)sJBD)X zQh0v7>zciJ8fg0Qm^hl0ocu;hOKX>?wE0wJzT9YHRw~a&C`9`0&nFeoI|c0)uXiY# zRqpUsMWK@}e3q3KZ;foFV;UgMtoQInL>_DKq_Nc=~ACAMxUy?Z*lmrs$uB>hYd z2??n%8%W$Q;hNF&Ig!}k9!|SElJ2rq$e$>zt_H8clgppzwk6@3p2zT?woo(xYVkJ@ zT#me`4<|p>b&ym#LY&N)e4HRumbI&_hIu)DGJ+p}lA`Tli)gXJGHXzJ6IX{-YL)zmG(=YvYA;{tRpov7sHjOpEWwNv)RuH!JM^b>Q{s8ma$kJ01~kHnvAUFj+^e z>Av}=`2$m@LyKt$ZykE--Oufx6Rd|xyB#$!SrK1Y>kVY(@XXbEgdx0k~0 zXx?~fouo$scl%^=CbM<+27O?dB`VWvx?};gCz#EKe zPjsF6&J+IXkv$8Wo4C7z_wMZM$VQ!vz~PkA*R8#c*EHP)aCFD(dTy#*GCO;Fi(bcN z9TgSh5#h&s#s9QwF%%S(&~9ToCMF5MOg>!sJ-UbYZg`hAY^V4E14JW3f{bESq85F& z*uZfFIh>!LpOux>eVf6+6Z$LEsSJ8(ts!D4T1o$9vJx=U?_ zh?t3)CItiX3Ajc1n?-uV_F9AUzTn82LSF@cbVQ4{dscovK43no0k$?VL83(*oK%>b zlJ_dVe3=0JGF$MQK1E+2Ll2LyLicN#j9!MBeg|-%*CvCU>e^7QOzf4+l^39t`j_Iw zcAWB4Pf*1{|A1SF4d1}${%OSb4ThPuPEAcZ+@mDmH;04=FvAxcsu+{ydQvd97A7XdK$$W$pKtaYU;-1% zq{gdPuW|+rdmYtITzOqq5Y88y7$|PTTa|7-k$g2@res_@amuRy^Vp$cZIe&emt+~W zfjrDbb?AsDZ}N3|e86J_h8y#h4;VBda(0()zccJhw$_)ua|tAI72<^}f6Dy`XL7-4DI@~b%{ zF;>=m%^Ts!g>hemv2In2FQ%D*RIeQbArO$Hc(TR1bq39=fDuK=7^}7lwA_y~7!S+c z^Dbw^%$|+) zSm%eknC8Y1Jh3hT2B5mSItD74uW5h6c8-I!^G%)y{Fx<-qI(hM2uzoX$?RK+KqJ7t z2c}BIAaG1gP#ZYrZ?43zAM4FnSQ^tO*eViAn({%;`oE7Z(>; zdoJ#;{(D&iEZti1@{EB16Bxv61_y@$+ov@%HpW(KaoJG%oQlc>8{|7(>JUO0k~ZjL z;pf)|GLx^M_sG+;y2f=Q!r&el?Q0V5FYDapc6WFEr$vRo87t{G&k*s)B*n)YBkn!z zfb;5>$=;IzmyAccTWh*icsX_CN)R_tzODYd%dAV-)0ZM-y7{kjImvnhHh4nCbuAAg z6Ba{Wo?=M73!Ect%FIzZ{ysvaG)RXY^^QyWdB?bB#Eh}ngO8AKt%z}n#M>8HAK&!K z%gb+-?)!4Q2r~hsqi?$OTe_qHYQhMLD{oHSOs~W%=@aJ&wAi4n0gZ8BdQDEQaNV!< z^E&OzZ>_c%N&hpQ5`pzq0v~zhsVXI|b$V~Nu+9O$vdRm0^)meqSh}~uqm=M1+x^W5 zUUqRYS-J)>)~!2ySq$Vr)$}}8t=-aP6_6`k9A#y(LUK<`X6oQ~CQ~~2GV^oVSSHxK z(PA%OZiRNQ1CL%`??#2&Oq3?DqA-#@JG~JAb8slk^J3RU#-fVEw2Bw_S=K|jQ#9EP zd=A5ryvq+mJb`_An%Mi>hPZFD$4Q`jVnRX-)*gdBDLRLGxqKOnG6Fy?EHqrRP(IOrL?!}1;*z1TmK zHNJrV(X3vTx)OA-9i^Y;_aFcF7vI-1B=J4PsnJfo`eVX)`7|*9Id1`HAgn~I3Jr^} zc&oK_IqvpWU1P@3!2ttL=(_wCSnffZh95Oz%{dmNV(Xo#Pkw9em;Y zU`q9dpGgQ_ctx`L>P-&BAJ=e<*6VAUvlGxC(#G*H5TfDE71Sm3`H=;iDAepA7 zq*yLDdltuk1o}Fl6(O^{&f6}%8?TC-8}6$RWF=f+4Mn2Pc0swpsFPy{4(~1e4C(|7 zc85kyZL)Rvf&C1Ij)s06|ivmUHJSzv-HUT~%gn+PMR9jD6*`vkd;)bW^{VKY!p?MErd6yrrH}=~W zN6T5Z8<`aks2!z0UB79=3&)}$5Mq&tm3FZaeH%+BpYFMxat>?@7ZInY;VjT2=ZqX- z#7WEnVELou4bAVjSQJMy9`Dh8E~^Y09R?ChgrUbBA%t}`HCi*SQ(Z64j57sJ+?8h; zpKDte{-GO?%g~=`@;EUD&#je{Fk;0(<;7$CzGQvCt5zYt6kW&F zcEn-;3i_|s*49Sw{kFs?(_W|FFU8>YqWJP5fM+m4@=e}ozNbBdjd;Vhk_;A3N5%YJ zoA>}z7YY9~>mLn2=M1y|jM|eC&rVR`ciGz9RbMt6BSvo4<11%N4#jwfqK#?tD)Jmz zJgTbSUk)R8{tZFzol+v}CU-|XeG;Y7d~a6Hi&d-t-BnmLBZEXll=n3;9Xs70jK*=) za~R1eGX$j^Ee^9OM6uo|qif{28x?Ikt_~jW>4cxZN>my6|9cStWYi556o3-rd0+GIJYj;lReY;oy0z`)%ojg|IImc87O`ru*X1$P#4CuG<4pK9m}? z33;A$6ZwIbbCV3T1z=}|02hKAnCK?Q#wv;mc2~Xe!@5eSsdFZHEm3^C2CG%VfyNN4 zkgtDQ5d$@S?%%V$t&S4Bam|R>y9es^z`&%9i|23f4Ljz zJ~@T1yw6pminS~#NxKxH`jY&?o{LR-P3B$v|i8AbsKJ34Oa`!~a zXPyY)mF}x}dV=)KW`*9KyFed`2QnfvvoJu1Rhn8^(aUEDaj9#3c;E-?ZnyR$XDSeOP=jAX05@f{J(&E@ zv=ZpfSU`FvVz#wee9V!e)T^t{&HZLl@iV3V8S9Ba@C-jnM{Vl(_>c4T?g%WvtUm1a zCk(Vn{x+%5jE7(&?Ff$>b3lOI*#*gi!M_q11-yt1d@7m%{ouD!VbVL$*yxo#XEROT zs*c}FMA2vnJbGYlqc<_Wi-m=W>85A8L~;4aYpar6uzo{9LUMPLn2ZCm^kefXoz4gA@{uP;q^!s-lGl@x2y{^Ar(!2Uw z+2LANk9ni}!UlIP?o)5A2`+#jp{T=J`(M1Q$8FWb8_jfPMls z)CWORZ}%0*r^bLvtONG7d6R8F8Y-}*SYH}(2lx9<$f)^mu+|oF|E;04^vKxUPGzI! zsrNX2(f}|QuHt}s%nz`8RyKBaSt%)daZVLa$bUQ6@0SX%I%nMZdF&PRQZX?xvG$BQ zyVqw39KGMkTP{1hxwl>cBCR0GD)3;vX&1EW1#Mour6p}}5Dv`8a3H4u@9$)6Ay`=g z(Fcakj>69j!Fzjo-00L(DKw~BVdC^)M8jv$NdM%#J?ZCrv6o;rc)1N^TL+)B#GFzV>+JFvn?KkjpqPR0uQwmg&(A;V*L>L` zPfJ^xadUO`bAt`1Rcvo>11%f1ogJ0Nbok;obS8S^j}5mqFfr(Y?^j^IyWKa4NVW5# zZhbf`Gg+u*`p;FZxPv@>4Nav2Go1+ViwylI%AeNSF05vsD8xu2-#!KatKKYe5D@Q? zAgvcA@Z-Vcs&cQ3ehELs8MQM|aKZL7?L%p@hd{TvcMq|6j(060t+82f~C+fTb(jX z1h-$`e9w3SzTOD(k+}Y=cWgq@>K`6ozZs~5Zj?1xjdq&DW?XP6g`GV_g`f18&ilg?zwD=om4XKE7cfe%4{jGU{MkYJ z8s)wuG3aF-OXN!m!;km^m7&B~^0>2O|A;AN!0perwa$i1{CSCKbBRMWzTC;y$`>_d z9EovCF6%uBz{lC8kRkLELa_wu93I2_{*|E)iBcMFOfO&gb&vICL$sej2OR-Bg?sbX zWgSUv_n-BfE{#pA=8UBd@$-PN1~%tg!8Qwr|Je~30o(TX_81-YEY|bdEB0IKdAMrF zIcr@dg=8OU-s>0jlWQ8l}39BZ*8g2xm|l z**O^0-%88vqfki0*4B(1cShIdLEi8)H#=}}+s;4fO%7j9@AD?6pm_0!fK#e~%@=fi zMC!`oRYyQTfK!Pps>y|NbX7mwUVa12i5KWMz8(Mm%`%DaP*6~0m6oPgjrV~o13+M} z7`eC*fUP_2AJUN;vIX%OX{>P`gN|f0fqx1MNp)(zT)>dthGBGPcfWM{ymi9I%Zmvy zA=3BgSOBBJ=t9%FnV49RCzT<{jhh7vs0b&wLN-X+ZAFFb!E8e(IK8A)$`SfVO@_vi|(a-6+HWRPGXB37Jy%C@9Ji*xjmeoMs?U_0| zZ}5v{{kufPN)gLaQer<7rRt~8JsvPv#-b+&x|cYxUsT#Ac^Dc(qM~qKQ{5kj)G1l- ze_XEKZI*9)IJ6i34@Db#q85khYUras*OZYMv#fR)lOQU1MnYv(d?pJkp6DPsnxGipbFu3kDPg%}xkSKiAdW+XSC5+D z#J*ES%K}bY2^t4l_2mz36ka=PZNP%YukoEI(eGB-bpl+`|Ki3c9n4~_z!q}pmwr(^ zu+r@N(1@T-pZx?&Z;FNA%2if9l0Hk}kR*(Q7`>!?ICm$VpdKR$~2? zCidII0t)J`f4BGd1)f(umLrwMN3hJSdZnU^+BG&k10hHE8a-d_>vj^c$8S$W2l3x` zQ0jQ=qJiJFh)+KU`1WZ?lxjaRCwy~x?=p`qpNFp(1W(;d4)+E|&~M-x+1&d=}Xz}-zTc;OK&ts-erxQHTyhj7p@{{F`j9{u}w zyzSGPiQP$nK$|Sf_?0Nxx4t|4$YVdz!HM0OSy90TX7?F$^R&=k;4Tk4TU$}O-zRv! z$JE-5E}x9&Dsv6&ZEaghfmLe>UBh=bCd24SedC6S$wqncc#->ohYziP1|^@%PtsSf zhOfKQ`b-@*|2^M4++-`3EMu7lVY@=05ixAyoh~KrvqRYf932SRC zK*onN4Qw|y@@Q)l{yK+(x(Ys?*(hfe@VryIEd6tFV_wlPFj!dtOIqLa#`1vJ=~LTu zr&O~+N4RcD)g~k9q&H*rh=2kNG{n+;+FwKg1S+zWpVHq|!bj9@LKP9alF;r^_tvu# zzw2(6Bd^ZmV^(xz(Y2)J&oaNCKb@@|5)YJ{5CO%c#%`%G_VTjUoke%HmH!!Q6NG?i z;IH7-{R?sN01*+es- z2FzgAzy03l+{5#4jG6{XA&%(sF z(Nu0Z>AD+qqi2e>P#~Jk9u+@-{)C7?8Pr{t2_m{diQUTu{Ann_Li!B~*Uk|eJg@&p z(piRexn+I$Pj`2Rv?wXvas+8ay%Mal5b@-~mF$|+dh$qiK37L#KPw@v^ zL*kgp)WkxgvGM^eXMWO4WnWJ+PCwP68@<^;|9bSVOkVkG?OI**cGr6QlXfq%He5V% zZgY>C?gB9kqNHlh%yqu<1PW5*U~_+>?!Ap9qb zkFiZ-?v?8?B1SAz+xwsEU!>GCJP zuy+D%rMF|41d&z}NKq|`mJJ$W9bRvJ?nBebMI2A)^ywg8q-X{8bkEU;*Rf(JOVBFF z*&u83eg3qgYE8%TB;-ruKawn}R%ru*z~`hAcgYb3jA+4%GNb<4C6UC|zn#uUY6c!q ze7&rg8}hagIm2vqK8OfZ6m(zr5DKdQFgTsfZg-Yv_`&qqh+eFd}16nI9^ zwZ=pZ+-0ry?yhjB)8;1E=1+bqB$X~wp#4Gm-xf_a#HIwKUdl5Q&3LXE^Wvf;8oy5d zJw8s*!E3WBkb(1g2tg*#0{_#0oO$n{-0VSX48v({VIfmPsZgMYl`-!-NJ)g;#r}Rb zCj?6nVQxwK^vN}ij*-KI>Mq$hSDrizaVI2@Gq>*dz47sp?CK`@To%oMR_S|GJfEq} zRoK;qKGo!Y6GLe6S(_`XxtR=xT>od2U{YI$ukEw>z0@3av z{Jo`y;IVAQgbMNSaMQ~_6d^PY9-~pp_ZzH0sMBGh#Pz$Cfgfo0R(5-?9_;I2XcksO z==r<}q|SNqC?ANEGSt-GUltHxI7juCS9&ZcB-COFXr&5xW_fk+dI+h$q9|{wd^Rxf zegZT)M?=G{rjOhPGi12vCx~)~)+_ucT3UC-#HL>LuqHB6;_@N#;^jrWT_62|rxN^F zO6um`Ha3dECmgyGEq#5OVswA)uAcUxxjXu6pDQu$;_vX{^9BvW=dfX@`Fs?i1nS3f zY)ua&Rp9SpvG=EwU9#m?1ITV}HUT2%O@#50P{dA-I?n`4O(}PE8 zuLbD1$ykvj1O?^PCHB6j0F+1! z5n*$as{B`;5Y;Y+HJObji>wrr`jp_fO_TwciZ+|yZZ@m$MYO%(VpT_k>vqPdTQl9m zpw{`Ns)sOP7>-Y)`HSqpT+jbnE+`(qG8s2_d!x9hmAjxz>zXA5Ia8vZJqw2fUEB;y zDIY&mdT&A6bn>jj5rwjM62q4Jil#K$7(07ZorC}t8Td5^gwc8^ZF*aqFUaB7yqP~) zr6M28Lh99@mgKhH;z<%qOG}ud=Fd0O{VK-=-;2Xd!%oh#BVzgFP_r;t-FM&RFhbq? z={SxXK=hT@y3>eCAoTPAqz6cZQpnziP>Z`ZDEFt-X32hgjO4P-Kq9(>Gpjsn2ZLp6BP# zJs4fk}+>(lEq{;AuFS zGi|;bn|i=^{1re-1O_0GSkAsf?u zKadm3s2Lc7mNFMhWOZFBbZ58P%@$-4kdO1rKR@@{%ci(W zvv_XBPo=HLkgELs6{Q@<<)&UMIgpkTib`P5j&N(kzh*dFpQX9@eQjJzd^YyFlYDb) z%VVj_Me2NJ&E$#`kq4uQEwq<(KC+6YslhX8HJB7{wGxOXeU;@t7x$C$3&9-Ruw=NH z(6C&ptzMyL3Cak4(okL~+sz*%eB>+40s{AcX- zZ1ef`?*jiMd5?>_U%Qiey$MTEe(kHuoPhUtM_D!`yZpgpMvO0{hgFQCLUc&VG7WqB z=BRCqGuH=AOmqPmtT*N(I8j5L(OBLR?^dh- zCjBGz?CtTSP>H&sx0Geh-+3Jla@qTFLB`y&#iU9n{CK_dXb%JWyvlPCs-y5<>@7yH z@x!*i!!N=4MZq@n?&PdJWg|Y5VDAAXf$HTeTg%`1!iUk4r+kGUs+~u+>NT6r4nt`H zzqQvvAk7Wh%lSA|ysTYaQ9&~$#4*=oB@}EqcDapmil-hT_GLul=rYklnNpL;+qnIh2z% zmzIIEL@Kqq&(;%twZJmKWe5u;kJN7Zc?a+3ii%i6kd30diLgV=DaGP7A^N4rHVPK^ zBR@X|vPiA|<*NU})X6{V(RT}~_FC~zR9UO9LYhkZez;0zVIh$c=k*HDzpSIJ@#hv5 z>+XN{8WW@5zvpqI4KpU@c(k&=u-Uo=vF2ba{-dFr^D^OMRnj^(MaFQSId7owy)^bER*jR8zh=}v?1=tA%!PUC^ZqN)U zM258zY7ZaYx%@^U{5D^w=ka$8z%qu530ZI+ z%Iz=k96dU=@R91b7uq|lSq5gM6Z3635|p6s!G2*WSD4eC^2~sXQm`}S!OKSArriLP zrSuJE+wgeHvD>TdnsInD8-GSPK|ETVGs+rz4KT>l0KM)3c3T61#BSSoV-tb>;nXq* z=MXkKD+V%Big+nQU6%91zNvnU}~ac65ss_~`Mv*OwB z*&?$>Ixb?9RkD`j+lcL`W%*S|RD{A=DbZ(+j=4Em&xq`KlLRL|FyWG*6YYH6qF+ym zT9f{VP5Ks%X~O!*MK>@Dc=|VFM|lqzX^l%Y&&Vx4c$$pR@F9!b!zfmU*J!kTEb zuaHMLxWfORF~tp_{?aK{56<|1Nc{FSrouYvPE*&;wH0%msgD&C*Spjm@6>y0IQ=dq zg&IF3&@2>VxJpn$!h)5UB$7DdyF#slPc~PwO4`vYUCs^|r7LVkn4jJ@#FqBXrEBVV zZZV2QP9n$@ru-m95k~~CZ*2{g>5rVv?Cd;roN9hkhaDCq$C*wvqE)c`qxck`3>%I2 zAR$C+Tgcwd&kKVt9L*xO_H_kUnjt}iH{=&>rI?M!`k2S^i-;qK>wi)Pk! z*KFJ!CX>hqFLl#p+X&khGE*H)xya%Gy0DwvZatTyi5=h{0S{*qBAB?BMUDkyOho75 zgb2WN^xKQPaX@Wre)zD%+Un9%jRpFJCmYApenq*<<5!UWZ+7so!3?z>R`De=Et{$2 zj_TgB>3pjb7pr(kfcTr0MfAef)^`e#>b51cFr3u^N0;~Rf-F)S1g}O*daU*b;L|dL z983Z$xAjIr{Lq>XSHfRf8XDN3$?Q3u^)So^K!MhW*OEWQ#k>Yz(Y^fm3@$^iS8%b> zO@Rnj=e_;%<|1`u!tmxILhJBvN6OV# zDr2eFIj0vl>#dYBFws_B1}9HV;Zo;A=vQQGH80Wq`~EGY#QKs-Ew<+|@55(RqF_*X zK`#3^3b<Ih|N$+FsIP0a-O zP7;jC80!bebq*b@5vvE%NM~#AcNp-8FZ>QU=tTJ2rCTB+GqfiQG!UcmC7!h^Z{bI@sJvSLR z>52$$D!EZ}^ql&uHTR&l`kkpYM!g>aiypSyS{UVzQS{qc+L+Bm^qlXkJ!*Rv6y~2e z@GtN{Ak)u#>eP8?{(*T?|(BZ7rWR)&3H+!ER`E}q9s>6 zJrgb{SI^{keb8V1v(7`MpXRM8FRzaOq$u6OtTS4<-ZYCiEwlv;4z5Jw;p1OkW!y;Y5LqtkUefulM1WUBRVg>+Vg;| z1!!=7-Tkc-jc&zRwkcPCtxYRTlzbO~bFIN)MuoKn3s$1oGH(Xa*qA>- zvsb^>ch(xnq+f3kF+eKI+}z}nIu~)Pb~3+<;sNEp`@e@ZPF8QFEV=^u1SPtJ!YTGQ zCB9WkoO$-*coFh{ifU^=4xz;4eNfd@x=)IIy+#~Ke((IVExHtz)7^u=?-KeQNPRp! zD52VyI??LKKpcU!xkUpYfR2k3_mSzj*Kx>Bv$O6u`>LQLyUeww=6|t-I+YbA`cCVO zF8~(T8-+^xzYWR%SaF6!$bpg}L!?ZDV@_N|#N$!!A8@E*daU;Hczo#H=Y80vE+&VJ zKKA5Ni2jUiEPd(k#BTH?9qgxYFvCXDI^F z!P^Ax!BG}Ocl@$7IDRv{d`2Oc1C%dXiHWoeurq_Txk3PHf%y2WT~PH?q3;7jtf+ij zCt8L7a`-AFeC2gG`RSSb_YgTIIEk*;YHEdij5r?vaaE-y@cY*Rlta%8 zn%eCpH0@O6<0yik7>+(kKkn~QnEEy#6V6G0Y_yxcKAgU(_H*s%Ft+@CMTO5wnjxFZa6%umZ6ls z>1;+|8C}g-2i@ytEhpYtll5l~HDu-C)#fnk*YxLQN@5B@uHabOd;4L3zjcF~>6s~w z*W2X{o>tSdRO1!nHyq>vaRYK>WT>iW3KMrl8QCzI6$@jOt(ojG;e*cMz3b6o+(Fu@HSpPA~jo+)Ak=t<91ZZxladTa#| zNYU1EzkHf@RVYS&^_qpbccl^%D#<`jLPO+f5@l&TKJLUn?vY_6o=Yu#D9Ub6U zEBW}WBA;${J_0i(f8_gj)VG~~lpPy4@@Eka4O^v6LyAwGvoxRu@#aUZvJupld%l1F zK4m9#w_~wfXxs-qsC}kLr?{5C_!I{6ndBa;>g1swM`cddqr*cG_g`@Xt1wM%6piAO z-;|4jmKI5^<9q;Qh?C&F@c1_;xdaEq@Pk>?50aWs)T6Wr?WR|qL{uQX-3)fNI}!&3 zHxePpb5)HdDE}QC@Eo`fHS{ZUmnh)h`3Lgcm!TDB36kGuOT)ab^bnDT$4!D#9&tEk zv}7$Be7?V_44dv=sD#vt&~`t`w|zS}I2e=&$Y4XT)=qqq`;+SbytOWdoV%;odsgL- zpMExg|A$W}#{Xvif{RY1k%;;Xi6F#qjG&AzHGUDEg#l zst@bA&?85k-V$ejSXbv0G!AlRao(WKU6Qdu{_^$kI8KqBV&!$RPt~i&=6>rvHkC2~ zAFf_pN`HS>GOWuM-uLf@0?bG>l`WVr3eM3&D1MPEZ=_r8MBBXdTue5wllZtC5rK6* zchbTR@55P8vk9Q?+iC??pF>&)E^^JJ|D4gg*?zF7Y%DB@H(WQL3C|vm8814WwwPXR z3dgGzP$592P}@wwKo14t#@>EnD>`@#7-07_n|piz?R6E~{{6H_OZEM6S#kub{e)8# zM8Qr~`ID(OH^sgHHmJwrD^h+TXCgS{sN3pKVl5UTDX5Rk0-rTb+)zW?&hD6Yg-V(Zrv9UxI>JI8r& z$@qNSLKPT=ujv8r*keWqBMoO`l zc+5G;iwmVGny2;UM^`;ojUe$}uk`eMM= zXY|-rKD+L7F{xad$Sy3jy$GQ&IUU^DDV^u1=uFU)QYIo|j^+Kf_=7VeHJOt>S{d=X z^C}#)ze&hj*m9TM7^~jr0@ie&^qvB?06Rni z@OemP&f8NDGQezCw1Xn|8wog)Z)~$PE*lB6{p{>6wTsx-wr$N0 z?k9Stj#mCW3cg>AlO=4(Y{)fJ-e5d?&>1b?a`+h!2GL=n3$hxY@!JrZC1%m|qEvQ! z?a`K5`h_VX<;pClC(dj-+k9vI!239e3UjISjqm$uhb9VHe)A+YJ6l=HKs1!AGYMie z8h<2K%I{Ii^a_pL=Q~;{o;4{j;gA-_wM1u=X0(%awjtNtFTMu zb?Me z^!%sZ#z(`JHM<#)L1BQgP0`?@KTcB%qLt(+k0-9s=WcbFof>j=t@gu}dF|vB!=L;K zNEe;Y5{<=hFdtO-UWrxL)yXO;c(yg%QWZDg8}SjPkDfMpv%4We#C7Ldj?nH+5ldg$ zb{YI*m7NYuu?tNdo!>EpavYs5AEFzUP3{0hncfiQ9SBk)9UUL1k&C#~V%+970e{D! z`Oj-yJUtEKvJzrq*v8}5s)Y%f&VtmPo4;S`j~~$;9l80LG`)V09oFGQYpv^~ARj;Q z{P*(mawo*l^+1~>fn%0qveu_}JWVOj%z(TFu&)8(y!`ymK4NJG1{|b$IJ#FMKN91# zH8d;CDYNtQ8zI2G(ub(@W$gd=bJB()u4D6Nzc@@x{;Jx0ZRk2w>TejLR0 zEW3d8WqGpW^Zm=QvqFY9b&Xyzb<=W^Wf_WKUMTlQ71(?SQZrzf02E(i|t z$lK`6WNnaKmXiTB_zr+WZZgm1p%g15yTdf}k?=5#tjxeKl z%Bk^r3KBS13%B>ml+Vf4js~~_KxVTa{RHM!m>j0QF4pX9*eKZMagve>!;pWo5q#%) zu~l`32?3KApl|oq#xM=b>yEskr(a_*ZA$Cj-YRW9Tf9?tb~P3>zC$$_`7WoT6w81n zKtmIYMhp>HN*e#j%)&fkjWje!8X;e&1nFGU^W#F76oS`` z%DCECJ)d;G&Eeb#w9k5oW>LSC*cxDl!{gP1L-;H5$5T&Qu1B#vk1^AjvdolZu#q3u zAFZ)GA#eDPH9&mGSCV~qY>!BwZMm{nV4-sGP2us|dmLO1_FJ(t1G7@ya6c&opB;D+Bn%>L?4mL6oItkdfjmq(v^GipP+9~ls2pxL*Siy#u(;zn8WZA ze4}UxHXKJrMRoFsKp48=da#V@(>*y!J=bQroMf*z7r=PQzMFn?xpqU;#sGC5c<4$| z_0UegHk&5@w#fT)0~L$NYwzZ2-d%`|7z^aMc+Fuqy}-ZPv^etLQ`kU4B716S*>OTZ zC+6(o?QI0lZcio57(%J6)ZMPM6s^Qd`A=qAwgn$7E4Vh-ZEl`fT3$Uwl-oRMx`ew5 z)mV6VX2!MO(%3b&uU}FsT}HyB0AXj)>~%B?&Z#3H#`%NV8P&)N^a4%leB8b~t>J2R zUMWgFIFo~^N4*%VB*>3^E-MpXt$@oow#N#{1;5~VQw@O~d3aP3z)5o6D9_AS;+Tf7 zaT2XHS;r+j)>yg+I<5^6{BG#D zDayhe=-Sf-wA=2osz`p9ODMqg9Ree$>3(9LiHiIOs;8b;Nz7d4OoEW5QMi4Os3KSq zFGjLE=fgX*9hD2JYSQr~2kbgDIOKhNd_4X{l;psN0e_y&ec~#Tip|XzaAji(&+Og; zc!~hkCM_l*ftwef*dA!xzkPj49NEP|UpB2{YI<`I@nUO?eH|v5H&Y7K5#e=qp6_lo z4iyQLlNuoK`hmSyTJ`0p;D?Hhr5}(5{=Tqa<}h7bBI2Bjp=au|vLQZZeI_iUp#-?j zU-0AcTDUwIYT7=?;CY*p62q0CRDUuz|4FFHkAw8qRC#n;Qk7?}2?`3rk;{rHxO%wq zuBOoLZrw|6qlpwFXk!W2InIBqv@a~tuaE;?C%_xouS8#@gu-JYG}H^COd+K&@s^gB zM7&RVFEmpX#Lhts9ey*1!&yeI5)Wx{(c_s|9%DRhkEZvak;Ox`6+k6LMTugxu?u>f zX@g|f@WlCfO4O(trNd~2+r;|v!Ub+4r(y}JrvCy$Tc-Qo$tAXDJO!CI&AInF zLIV7l7XOAf+bZ6#_^B?iQ49G{!c+Hgj!ZbUYA=ExO%(wE)d7utl*O!#k5FnUiF*Dj3 z51-hh)NhOf>mHx{zTHjx&g`2yJc8(OaF-NoYSQXijPEBZh|vDYxLg)Gzi4fpd)n%| zt#^G}{k8P=_HK^XJZsotPYsohGiYvXq%PJgdp!R8_c~(u=g)5>BukLi*~6j}Adh59 z{v@xe`X0s)1mYnMId^@B;QPeo1GHIn94RvE?uv7ZJOK0S`ARi7U#O#b_JY!k$E?Gsq80y^uF z)9AE-y**CG*v57X88(zTm!92pLgnMd$@X-ZMFsD`V{OrouCobpeb1`|`T5_;Ge2Qd z5vMs&Db)Uxr%W*o_Si)$Y(}}xFn&Fm_lK3olPIu#fl3sfFj@NCY)D_uuKxMm1jfdi z+oY)VFF#-KM51kNoveMY$Px^--2Y&^$_qDRD6ew>`h{%BdsQI4(wYiCY-D7leb0jq zA)yaNC3g4pXv9qx`Ae?CYWB2yX1W!Eur5yc^YVAFcJ0c#Vy1r+l zC8wzV{aATll;F6)_q1*CyR)(IuLm!w;~h|c=qmZIXnXOiW6-Oh;t_wpztw<*722ln zgc!?384xT8Z&rK#S~SvbxgXc&0i$71q1{9PVXoc7EO+6Z78m4XGQEI9#vhz=&Ztr8 z0bS(CQAlCfgvx_4fi(2*)E#Gqg%(wTA$u%6wi ztCrOk{6iWqikuf_#B^IP_KSCsF|)R2D|duDb=qx?m+#QgZ9f6@#sgPQ|?n z{omtIZqFE^oW`Il#1Vh5%I@>*f7(rVo-da2~X6>fCA|4%hFN}=3 z_)kqInx24h=`jiMP2>RoT`l%JD_ZfU!*xsStoB!SuW3`qN{t^vTGCV$#QiKtWZdSP zIHZ~Vg!+pImZACryWxt*-2y-t=oQ-_sZ{)~S~vsN){U+@ut1yv;tHAb0GS2X+&+lX z-Tqr(|N4>15Fq4ph@v{P+1*MWJg6~y4)Iq%W++_5YH%E$nen>1WodkIqqR=)o}Dc3 z>hg+LS~)y1g10OI{DMvks=iEV_@EQ$nla!58LcJ9H`CL=PUfzhd{HQb@9JQ~*^`^F#}Rw$EPggJixaHjmkE_G8on<8GdYj@us} zF;Z;i)Pb{BH7LQ)Jx^JsiQxEiQjlyQB!>x&A5bZ1B|K2!_FLh9CxAC-Kdrmxkp_ji zm7H6876f1W$}Rq5S73euPWf)zy6q%iA+j`*$9Hybm1!L-~RuxuV$`P){^ z@GMv6B*K#;KOKV;kDHPjsnV+bOR<9Y0da0|ZC0aHG=3HN&--#Q!NiEF)v;twVPc5` zqtQb9--UG-w8oB`_H^IHFj+;YWjW{w|MQoll+bTm+$N5)Rf}%X5fNEuDGM8H(=tD` z@JGl7X^_WLF^O9<`Tr`uS<*56O4fEQc}GD$fZ#KsTY7~kd-A96jczX+AX$Rw9^H5c z6=%Jcur+O~@7|+=w>e#if3%3jDjK!E93N!xIVv{Is{6W90)iCK#zQUXU&6-)WhAIQ z)Yb729G(!gSXwYQz!JtH4GtDAtqPxVUw#^c=g=1TZc=NvK?ihADmNr~JO&95Oy~qk zEgigJJuN9JBF?v!%G~GsRhYRn%wHx4$$z(1QfjIsPPr%VpQ^r zy%m&Jj!tdYV7CV3WQHc7fXoZi4LDVbEY2Uc$=l$tQ^G&ZI{$*#O0KYu3@@e2kL+wCcVzPa?imCNu4D^Pf$ql3N+M^{%DpHzC=cX?#^ z+gWGXioM>R>U5uZm5S`|cfB^=(KnL`aZe-!)MpfkB0Dv7bV3>%Z}(OG8W(1yexF^$ z1*-+A{{#DOKm5@h_>VWZ6+Zz*kpia4k`|&AQSMthj7HR6X$Mh!7UDaKd79R=nHQs} zOCs4dHAijvs%w6Hv6PahP)!Mid|T<7z~gVVuz~1ZbaYNuR@TJ)JVAFXDQ41+&^H1` z4=NWW&ZPVZuv4BGk4w9q?k;A{&6&UhKQW`3`7*BDPAKwWnAbv)TX-YD(zgMfUDd10 zfAInfA2M({>O--gGM?;di_@&y-zLlq%G*_t?ya>F4c!#1EhsyBrLTX+x+|lzO?%h- zsO|I7Nzi|~->h_TVfM*-jMcoHARPDUC#Ig@f8%lv)lV!}{u^e+{b0tn%>8JPZQX)v z)-#`$EFo{0D?p|5QPLVRtw3H?J#zZNyNo2Z$GTVx5y}oMdcy5d@Bg+jWeP@7qpZ() zQ4ki&UcMFX5DFYt#_h%os3s1^MruS4bm=8ba`HZY^kA!wE0ezI9vfy%Kclhic+WEl zjG4oiQdkI|%FiF8wnUT3GOIKgp9IIC=avvU6h53jcguW=K@ulcxxw=JexS#2FlVGw za3Bko1(H^ykJ`vPtu$0;Ng^2u>-|uL35DTBOe`dvK*|p+uE_6VkP7v92QE0bd=t94 zM_i>s42#RUbS3=5WgDZU%5yZAxk_<`!#Fs72IU5c2StE)=a z(%wy-Wp`A^ojZ5_0N70vg2yrYU-Ie&5FkH+A9VRgxaHMB(4?I%gfV&a$bx6s?Xolw z5IpgItIv&YJRWV~E@hB^rZjoKgE!cGJ>Py>L#e%%j;Wz_4gqQRl~82`o3%`3jP=f+uoWEI1+G{)4KxFl=c!Y)^H( z&WG5f6h_`<|9cWoHKxPk3kv3ilKbt%YHmq?JcHFX*qYLq=!V;@$Jl=LVvClK-aN5zugL4C2ce zxuD@St-0kc6@3OQS^^W&1q*JNx3C~}uhRxs&ULhVyV03?p z`vLR34uhhWv9V<5k{gI( z+)SCCyIiI5ZM5pq+zzF={x4K6E3Vf>>?6$K0L3S*&?kfLUKLyxNBT?Frb)?Uf&(&d z-n`L~ppUjqDUOwbs~Zi6Tw>+opOeTtnAl+d7jj!VTp<{8S;MTpSl{~h{vf-`vBlvf zKi{1KzS|cJnN4WCskED!Ne%ojQED1VmJouVT9_5KJh753F2(BMc3LdG{?$$JJ|R8r zg9Z|clU0l$Ic5wRCoLjHS%7WAO_yKRQ@;a4F%YZq!?Os!G}1PF*AKkuegF*zljIn|-8eZ$%HZ4=;Tn_;_vV8% z{`+No=E#Ab&3G4QHbO>&2$zQVoYR_-f#*#|^uhf%Lo!;+74FLAiuH+Rqb{U3kfM@C%&P#5%#k0=WNVpkATP^(ode!#3t_uz$WSpr&-P$Oc8s;iaL~-`S>{pxS%FqEXuNjf56r4E`5duULq4 z^|_BPbc%KTh!M4RlXB3PmCExh*5_V?oE>zg0^?O~bHmL?C60@5s%$pRU)?wMSPa2s z#9lCHFcRABx0X_dCw#1m8gsJBA1JsmiAK4~WobOLw;#X=85T=Q#_Pz{EIbXlzP>i4 z38lY%*JNjpaKQEgP#NLj{(fpo3_t8)qxt$B&0dTLs&V&iZm{j9<$QdC>K6hBVl-d0 zn`!hrY4@*ih%7Bt?@!cjXO@)U!D`X0DM8iS;Jz)jITYd{p>#zhnqf`}yHD@H?+h<* zl5&B-uppgMMZu*DsSLaEcnJ(C7x0aXAV73<0n6>0xIfkJmwW4lB#4a+F#25&0VNCrxl@4yWEcUqy1b0%^9*)YH@gqH} zCvp&Y`^!=qMI1k+)K?h$5ovj)KR;7v|JF$wc0$p*t5NV^LHL4>!H%+rzYNL*A{Xm( zOdngRcsJuK=>W7#{f!ImD3oiRXMIikO_|gp0uzN$=Ku71O8TPDmdXvOR64%G?>g88UQ!RYm zpM&oEznjM5W*>748yiB0u5dN7rK}liLDh$BaqY`i&bE5v*Ld>PS6wvH9^aC|s)fy! z6HRrI_ghYxAurTI18`s$h>nMvV=`!83}V-rB!ZT1{~Dre1W4rw2oV($XHvl8k-fHC zqfV>Pbt0i$Q}AGtCNyGhP72COV}~T_cAXOwlpx4K=_yjJz8SXF`Xo30grsOCaF$Z? z^>(E+COH{Vv$QJ-qlL3_avr)qpev z@k8V=!#Yf!z99qgLWCCoC7_Qn1#S{cX=W?*wZDQ72aAFBs-Gp$BWe5;yhnkF$~`~A zZQ9&omZ4*UUd&WF*PNqd$-Xqf&!4?b=dh=fI95mcTZYU zI%6o2&S_Mj6w^dC6%!o=rQK|O9!{yB^N<(k@$6B)&i4Q7-r_=&l9CO_Wr!{MAw+tC zEt^>N@cGBq(=9muv?uMRx51J$`Y^Y%Z0EGm>qhmT;r?{# zA%&N~)N?}{ewksimyG{0K0#ItvLbnlXvhBhUy!%cpvvg?I<5fDpk99?Poe`7ouzbo z$+9GGPx7f3`Gt6N14d~R%2&rP;xc8@S*Viwq#qNy7KHy==iN`{cD=V;Y19!wEQG)c zl^@1sx;mvpZ0PTPs>`%OUDUsh$a7yq)v{H^ymtFj6YRW# z%Wj(}qmabQtcuSC#eZpn7L&5t>!_#{ba|TOS5A=qvN+oOy=hlqz_9XC3{Uk4db`C4 zuCFhC7cD|FHCB;DaWo!7$P+y=kc~h2UGMX%MBu~w1}ERp`-7(Qqn1v}q)}R6Y3|Lx zPH6v%K3`p_oA>Shla;k-Yh|0jD5KPqr4a+7+(V!q{zHp_{vZVeu0B3c?SP6a>?b)Y zglD(Au&{8M8cP>Xt^LL`gi3TiIx>d8(SbF*6)5E%lOz>O#a6F)28DY$LcyBQfTlFY^vneT(Gg`G&MygktyU<_*r$O z-s{u6y|~?cQrI+%jqiM0jG3EjfugqDMJJDM7PNs)KP^OU_Pm-)el7#O&AZdJU^I$^ zqdvc*<9b0V%NYUk1Q61mrRJ`&PyA06$2*?Tpx5LxaXYiHmsOQ1ZQk&qknrHx%ek&L zvfDt)i~Fhn*nOYO-vT8UGf*OsuPEGFOVn~KGGE_HhHfTU_hx)&fo*-A@sk}^?F9|urgtE&99WAlA)#sGd z9Zc)ay?bqcpKA~{iPD!c$TZ+niz(N2wG1|*yhoEsS?mAF7$0cS-Gu*dD*gL=q&L>2 z+D>_RqL?y)!6@&s{>GO-FN`=+R>{(#z8B#OY#zz%AHU80Vu`I9&Z zh@AcL%)G2K2T^PuItz;+)HHVXo8pJvd5IFxhMw0ZFE1A}?k-7BF=QYpCKi|`?mjgz zpeKfaSjSrk%Pgf2y`uF3USA&~rYCpal$$&wb>O)UBOxJu&W&IuYo5HD8_GwXf813K zolATBYhB%a`zF=CSLcdQW`+Pb5$1Z;MsJ+`w35=rGw_VNcA8IiXqp-u%bi!SMWU8a z#tcd{e%whNcp@eJ4e<^3MxGC8bGgaF7O4>%?b9fx#O%lY0=d)de1>{zpr(sBLlV3EqBN zDnf^%8&b*>exc7l`S@wXzSup?Bh8J6;laYrP8-p7eI+KSDu{+0aAWJ>P(eeJD$kXG z?P0%{tI9$KJVUIs5CFjFH+#A5LPn4jpF!%KKKJWKX=qWFOS_AA%I#@j;E{UFI)LUy zryx820Lr7iwY6h`gvfMs+s?4^*6)>z18DrzG+Rhcz{nW9KOd2D)N(1M%R#Eay~>m) zU!k9rVRl=_lAPU^$;T|Dlx3^v`Xl#lG`s5h|FKIwPuAq_C;PsZE|K`C^oyQ_D`|r(bz{Ezz57M{ z!v5{F0VR{X6S9Z zU5j8OJJebx=Jlhp0ZT#M`Ril%|9B~V&9MXaTPyJ^5S#y$mTwC!4|B( z=>T*bxA#fYP0iB$_4c+TytWp;*xrIpy5Y-$j1mfB49Jq678XCJRYo6I)u?B(nk&y70QkKzfdhW#&GUaZ*QQb?xxfL19q^|<(GZxhR#8*)=w7vTTe_~{%#+vA z`2{G^i8UVKmQ^tUy%*MfaLGvmMW9$gq5EBL_4K}A87Xdu3^QK@NZ}%P?qFF}u|jwG zPiW{V-!yFDu!LQt`ZX`m5c*J!>;=Od6BT*1beh4mu{1}!vc9Dy3ifzhTT!kiMudZq zu2z5lWJH0Xqtv(wC=E2Qx-$0@bA3eLMYU_{b0cg0ef5=HIc1}eL2Cm*`j(X z+aC$2-oB)>Wk+QkWtqK0I)gOV72cfpnX35}YwRCY*w7@aB;IOEKqI0 zD;b2cRnCYXt?%qkv|ngK*mren^Uq!GzWWrSgS2Z2mUa5v+4|h=wf3agoo86DZw2Df z$#VfT1g`4nXHg3dgpS|NWA9?&lIzmXVR>ws28eJn*WGH;(G4XN37xxZS9|iBYz-F9 z1-*n4PMYrq3Xp%^6=J&Y&&(D17Kdj_T2v^|jvs3_E;jYGslCk@Hr!tlYmb({nWH)j(HhGrw#A^+&W7USu&QEIh&)G4c%nwi2^{jn5< z^FAdNP^+G9EL)4dF~k45qc=CIRYS!X%82!WuWm-Z4@D`6jjA~DQN@eL2&;nG)e%Z1 zEW(h&brH(szj0xq$9JAk%J{z8{9=C$aJG?|87S67d|!qdcu-%$hvh2O4BWf*40x`| zZK`~Hd|9Dk3Z=SD|Kb7Lb!glzz6eZ-f8A#E&1keH3 zzp#zx?jSou%g7bVJy;ZqUyyg0 z;VyY3FYeN3v6p_{lePDt?eGP%DQ@GxABZ6cqsRC5Xied!k%gTwxDOTF-Ro=|95fM| zz#!V)=w_HdcZX&bS*OKZId`h0{fkp#{cFin7uA*4yWPGkb2h6-+8>$*E)7N=k>Mj| z@7}!9sh4n46Ie@S@BBZK&N3>>wu{0u(I;ZAI&Z0a!5qA zK^PYx0|W76lA4lwV&;4_w-R+J9=OHN0)69?u&5lXHGW(hMaU77>Yw&xPOhxCTl`Ko z4Q`BW({Z|DjGO#H)At(!{~9a1c8nFOv@k}QH{V!^L>>Bc9=F2ff?TC-I3=Z&hsUX3VP^A8(V6>$sdRG|uKtfc@9@nrbJ<2?zw1!&btwO3& zyY)*|R+Nx|FGAQ{N;MF6stSTq$Jz1)A)M_FE^_jUR?(JBB2h)^qGd@!%(L{R7?d8DPmjxe zyAm&MSE#`r6trC=6(2OSut4fEu!eARJ4nxIeElu|u?$F*6%`fN+Cy2_i{g0|Ab`6p zt)Sq3Be?1UTU<1}04=yws3gFe6|$A6&7TLH6=x+^;kx2zIDDSthW~0JHgp1r&rZ#E zN5p=n13PQO4g<>jL1&sw>EzVkG_bzkPQ&GK{_kIB18oC?r zhf=_RivsNoCa4L}>E!0t4@L1O!dvwMiWgJBDw=WWtCrn-($=%I>TaO4eUq&9WRPxI z*xHJ?KkJMIIfK-A9SRJms)Ag=^WYI+G_ClDvGwpkFSFI+YX|*cC6M~uz_OnP+`K6e zC%|cDlVQyO4Viy7gT3E?IyF9y6?nH`Yz>+C*GF!1Txjf03C4ZR{+Y~NO&&i%T9N_p z(G|p9%h1#J+4LnElA%T>-mo+^VVX`9VM5wLxf1h55$2i}{?Jy~)w&_FXY`xkI6AN&X8G^kVy!aQiR#R7iQQFSI zVK^9^#(f(WIAHO-HI82YQSs-dIaaL#VW=)~xB2qQ4-8YlwePDR>YrQ41Dj>Iqzr!! zQ;ylxQO}scFHa2lM)So6a=yfze1oS!hu7st&iy(#N5pV{>CV<-2gooj6f&NZ4H@Ov z@eoAed?wpbWH;&9GR#q04tkAQ$YOtE5^C(k8;ikY z_jjix8p^ZLFGj2~j1uKK)@tMjlM@ZH^e4+raK#Iwg}vMg1HJo%w^2)aPAL>w}tZ&MJuCu5v0J zf+9()9oGxm>#^-kn*uTCNt2sUmk8!uSY4rQ1H&1ExR~E2Guz$8?JMDZ|4#yB1lH8z z#kNQe3mx`G=OkuUK;mj=vfi5jUuG-LsJj$ko6SeZm+x47a4z$2Cj9fKVD~Ua{@tJL z9-v^=mA{&Mls=x(55}bGyuR)p1X>TNs<)}V<#3}9H*!-54hzy0CTBpO;13i&QPnMf z?V2}eXU9^$K46ewuTCnkUHW3Gfvll*AE89E+HUty<}P;N37S|I(Lpo8h6r7Z=WiQa zc^Jx2CAU8d_CW*0TTeR>FaKg-vu-v+o|eEpA~h=u=$N!V>u_u-*8u&lcGe7LpX>Pa zw8mo~7!!#~7t9|x5ul~_SnUON>**1* z37;z23de~GH$W|byAy9nRY zm*UCoCav>X=z_l)NnEcyXP}2Y4kKEVT7%Cqa*!&427u(#Cve4&vpblN<$stG9m}t$)*? zCj^Mz>wxHeIcC!#wg&Sn@>x+S6Acf}hZh3eejAX-#D^4=FAH}#)hTOtFNG{`05I*;?qC z{Oemc1VRCigM!)j{d?^CiSdJ1G4#8TttFS3QgC-ualr z)*%_7bqpxn%Sm~lOr^B%*uznEaXeWTdbsxD?B=oPcFxL^l+dyk1ItA=U%JD$XoTi~` zkNXa|NnC>a)^*#=?CcXrGGOmLkgsBlG?!M`f*XW@@S80U0Z+%^r}kjL41T(mhJX}a zK+YrjhhN`aJPtzs=Xv<(cfBg}8n`mk8B2Ah&|T}EIq%)V5~%?jA8d7dy0vCEZ4e?q zAkI+%Di-7Ib=$hJ1>VkkHK>lO~&^b@~+Sw8Nn zJnN2OxSKP7CnnGT@^(Mih%vG{=rTBYKIx-!QS&BHVkb8``C z%-SXTdg)M~%y)=bfiJzRdcnrA``bRh5;7h1bSHAZ29~4|;1SMOI+hK7yc!m8Z+rcx z&S9rX+KB*ak_{z_;&_gZ6bHiRH1zfTH6-V0GjMATao!K$u?&f`W=IL-zL6gw>2ozx zYnm{!0+wXZm5?|0V~mR`^mRD#k!>dF-j08NS?Ei0ti#yhtbfIQ{ zZD9QjiD*El72$qgpMi$05keio4K)-+B^`#cJ3ty{r4o&egE-^6Du$!$$%C!-ZV#-_ zCgX&+{>q0Dl+w`k^(Kv#n804SF?X1}8)yl`3F!TX%Z)^qV9J2j$QM?~A%=wo zlT2O;LguF9HhS>dfWx-Yg2us7SYe%_kFcih7hA6`oZ9r2RfSqZchjPa%iUJ9yo`f_ zn*4)FxckBW;x(#gGl5m|vJh>IqZ45yrBz)6TeuoBv++`S7)~);->-luOd$kD+4r{U z)Yaycfk0BRy>3-BytHvliFw`s*w*hGB!IU=aP{pL^G!v`rp8LBAy{xt9`({R21Sxedo{Y&r8H?dVG-rgESkHYFF%=#OV-+~ z0ud=o!aMqDK-_D|%^ivd%EVf5sw+(?3q-mj6>~m&_ADM?u2?}#;}G10yLApR3y+45M_shJu=AoT1aT^ z-G^21WBNb3(d=w=R*A{d1siZbXULak94>r!#%mY+#}lN^RUQ+lR#H};)L%N&Lc&`5 z?tBa?rnR1%0ALJP9Y#m+nJqA@Wh%5?yZiM^^ToriN?Y{9-OqP$Pib4>=b#{w-_HG> z4E?(3Hl*@oJzHhS2DbPEtD}$R^64C0f{Edx6ry0AgXnCgT9;Mv`9FVbW`6wwii{QM z1y*t}Hsb**&3QKHM+Z`+DIt@*P|JA+0tKpMqOpIgW7>5C`Tamit|A>{nmjcSy9?x& ziBp0KN+DEjAS@NfXzwY7shZb4=odFQi-=ZTh)#W8a%SN*+eL7-Ho810bPhewB+nf4 z{6fDs7s%wudQ>uq4y|r|etC(ZCuGECuoQlCY4KlSKdEO9bs%q$N~=&%TB)O!JKQ7l z;EjO|LQvpz{N9_RD#CG9W~&523yOpNd=7Ogtm)yVx6fFWUp;H!gsj35mf}$$C~9Sr zk&D01eOW%j^vDq);|YE?Si?hPK2BeuFdW=gwSc87g}ic1gn` zA|;+(zCW(Rm*)e{tnCqg&vi#JY*kF^zYQhjfOB)Is9mg z6(Oo>YkfGR11?cryr2RVjEusuQ99I|93jlcf0ccS(KTk=>0f;`YE59I^5S`^84^oj z5+0GrqHR7aiGq&dNEx;|r%D!rhbqqDf%xt)mjY3uCZZPywF&Kd>>%#0u1O%*20h8bppuLeQ zl)je&jZe>N|CjJKLV!k+5gi?!v3c%$%~M_8bfYQ%&wBv+$5mkeZpLUY$;bRKvIUUz zTZH9pV$@Wie?vtOzYdgNq&ENtow)~+b&{!N=D0_6U+rd>QD!L?{k%&;z=Bi#{muUB zO|p&B6g%)h`v_q|_D)v2&{76UcCAb*i+RuF8J+8m0n(NrI?EHH3_xlQdvL?34Te?T zJRraR3!wOcoTcZ8?0*KIM^%wBr3?@)E-uDr>QYl>4Q(dA*EhEU%q@73o}~aSu$!$~ zR8X%-Wk**sCDGhT)lH8C-E@G*_BjhYzH8rLHokfH)ncHN-|{O!R$l?+z!2DBpf7S} zmq1mP4}zR$(dy?}ki$FbShAO2*GrBPLja1+8kmbm_kLA=2bcwK5VL7XO0tKcGJkh*zvKnv7Qx5SCfP*$Wd@&_bja}yJtAuFy416J)N zbs<_&@mcIxN#Ij0umuEyVcj>S3`0|s9-V8AzkQHCKE$Wh3mN%#D#{6#;(f3R5fBuN zk0U?P)~De46|SZB`@kkA(y;NwvDr5m#l)bAFf3Dcw|m zt~Adsa^?3++bUi%$08c^-+-f)+mW{@?5P~bLJ^;%Ws6Zt>fTHZRy$Hp+aP={#1nru zAY)x_TnQ%%pa>yqZy01n>mdZ=pUJdX6U^q{Gt6Zn)Nh?a7+|um9C6^npo|bPoG=ej zM!rEf3aE|hAb+JJ4r~X8p!j&6{{kCW?qVa+7J{2hyKaO3rGvxazwMxJxjA2mkMXgv z=mzeCt2*n~=bUgMAdIbKN)FTlNDwoiey;?VA&*o<=(|e?ra3ZebYAV~S#b2&=>c`L z1vkken&{DTTkuT(M)SjAW-3l1@Se(@fTt_r#pB5W2s(StmnhL;f~7WC+#Zc3ju%f0 zQUQiAp9@{z0I5~mCXmeO0AR=zoupOoXs+Nq{7!G7#A46DfZR@#a+u`2_2HFqX=+?g z5fu^o66w3y*8G@_jMfXDW*|1&m=}8o;X41hbP1KDGPnop^7II3b#*}699R8(&ZMU! ziAp5>1QW=~qN7jQ=1)9#vwD0~6z7N3IDP;}s2UR13u59MGXTH-WWb6BuydBa3YK&^ zj)FE04())5(A_PG1L#>-qBL96dTncQ3dz7hxH+hdgf$O5c!a<(^z`0>bD)eEQvZQN z-8XUY?u|Sp7OWqJn zaR7GE&YfTz8e0MLLjjZTbj#Hx|KJ1*H=KC~Iy94?Sa8+;i~H@vHcmz>!QY1JKIa2H zDxmRw$_LHP&KHj^!P_7LD23G4cQRA}8-((R^O1R(add82U|4Ag=3wKBN0&7Q%1?1$ zt9kdmEBR^brrr!y3C$j=a452Z?n-upqwrruhVo0})_XdLKBSY0TtpY~dM%-<$ceM4hB%xDc!*&n1%VrEQ~e=1w7o|ZF(?E;&X>dx#U2H&_Vmd2!9 z1>>ksTUl#ajpU{p7RXS*b|kR|#moZG=RHuPT;#f8L54Ut5exOy3uhQU9}qrP{9Yq& zTE|46bD^NX=7!6hdvuqboN&1mT-~9p(G0Q7WG6Dg5BZW-z=%?aKoOS&BlAYhZ@g#7 zzH@$yTWv3LD5U{6C^6F=LJ_vE1DlyOS&iah?=24=!D9u}P&|qH zE{ehqYyv#{@k6+omnfz;briB?t4HuQ8MAf76iwJ3g<& zT!<>q;p*EH>*<)P=sWg4H8ih&!Mpi$a2Hy9Gm{|dry^WjO`-h!n zpg8~@0SM&xYFG4Z`BYZOkkc~`QXN+^nVxkXaJW8}G&Sw1&l>q-09Sn-+a>Rm!veH` zlAzMe3Wz$q=Rp>SF$W*tMyM}c=@zCeFxzKmXLkc?<&ogi{rT(p$vP821$cnC?3Nw^ zB7rC{{(h{g>Ma*}$VY|fr$>seboVwnE;}# z2~nomPK%edA&nwYB%~jHG&K!+#opsZh&HA_*z!8NNJz9a0P@knd)oMAEp_$t7WGAm z|5K#P=jzfU9h3`(FxPMw;I4l+o(TyXBqVWF{IIdNu(1r=9aOWaHX}{z#!pLWM^Qnl z4>ipH)x;@$gRabOP_>OjfdF$d?ZN5ztmsqZi(AXPJDzO_gD3-rMMjOCE*^6R zk%{$W;5&2%b{$zljdV+RD|XV%M60FrZ+*aNTjHVsZ}%sSs7J4VN( zHa&LIAe1p`U6z}B+Po)j^T&GP0we^qst0IaO>gCR%a^_viADrMQ#e8Iqli?TGX9?y zsaSBp^v370lhkT4V1@{pcOU>Fwaqc7`MMtD9Xs&vHi}akD=$~S&AF=ve8tgGOE53h zyaGWi<5wy9_Zri`dVU$K^JWZDqzv4l-`0XctnKpO-4hgMq)}q^wc~e~_zMl1AW9Bs zX3>Iv`kt44j}q@V@;`py0bHJ1uS1fhAFlA*=e|{6zDTeT2$#M#CF)gd^P30PJD{Jg zYJ2RN1~7`_fb9>vXG3gBkOp~1`q;#@N*}M;T2YD+2i`j#h=}{P%lhYGSD@(8#0LW3 zmz}Fv=v^VHbz#~ze*9sM3&2Va+(DkjAYaPI`*r@2xz*IKdP0>hehC+I^WvH5=}hF4 zkFV%t<*kO?OtR0Doc=qBda0s9DI0n!2~aQhFt^thanG7yXc3(p993sECGe9T!57*# zUOB#^eX6Rh)Hye)cE#JDUS+o?y9Q^-he2#;L_f20ypA&vz)*KTR)=O9T68)Rv@J$(wrr{pqqmwn> zpAmkU6!7Cg=ACpyaYFE%?7nLa5Cs2buAtx4Zl%w|UBdxG6BlD$Yj|qsWe+GY6SB3LbA(F0u+F=+6GG0mI6FpzT^t0unV8NL?Xi zt2;PFdH}3ERes&Q?#I}#*J+ZjuPdgzyCZo?LbW$;CXgEpjQ^4yNKvdH5wY8NMMv*eIHJC3)r~Xs`|s6R*%q8%hY{KMXiN56|hHot>S?VO^Vua+&SfDb>#K@R(0;j}PFh4)`rBI9=QD zkyXV@n-l7%mkJqYB7a&W@um`|;s^zCrMwV(=t1*ly8he?<5IO)5X96C*+W9Q6-kjV z)xwWQ#In^uISWitb7LpM12y@xDxKQ3BYbA9l@8<=U^fu3CRX(H!~kNYXn?DOj007} z?E4X`!u?y08vt4g1OFHf$l+ZI1RiZmXQc55kg_>5D(GAcbPJkb;r0SIndxe0r1h6J z4fdz{)VQl-ksaKwNT{h|+NJPKvWDTTDht6C2x%}@0F>H8{A!;_AyRBZr72Zy?f9}X zX^?S-iZE;|uv34bZe`_0#{50t=KV7EL_1Ig*=`Qv-+LtRfiLzSG#*^a&u%%;D7R8y z=6wH8=oYH={%!N&c%7aE6n2o?-zLD!_`Hr*!iJ`jO1A8*h71i$ARybetvlmHW6+Dt zAO7{ia=HEcrV0H7Xa^2%F?By(3Oo0RCDalLWwp*I-!#@vjCJZ`De?Hc>(opmLRbVb zI#tU9E4#i;>(*k;Fayhn0(<86FJ8rG!1T_?o7?(NeA^0mV^Qgdc&Df z6D&NnZ#Y<*biF%ob(o}2otPP2G#t(rCy6A&qsA&L6kh>la4>W}f}(3GN!!JKaDF}a z1cvP^f7vdzjj)>be0cAgKfWwA%u(=hH%echFrWqmE&(rSN6b zPIpK6B6D=KjL6KNKi8qa&94nS_=h6Ee)-c5r)*Upd-6LuJ6uE9~zscF~oBKh6@-4cL^ACnOiH}YmFre!ro zVr^!7EK_ETSb-R-(1X2S%)-1^V)xg5-&cXK@%3)gC?pK*_AfyCS0h8pKqou;nY#bH zHa1k1Da{8Uox#-Qv`{5*Z^|Fc6;W=1!?S~a?;bpN061dxI2#;zZVqlHI>+tpD?I@C z)K0C(96Sm?OqI`evSD#{Pc7rO)NJ#nPYHf7wWdR5YfMMmp6Kw{m1xi)x(y95R zR5ju#Rs%Th)P+uOEMT(yR8{rZC34?2^n&cgi{cmeE73A?qndia9Rk2oNziFv4!Obw z{mUV6phS$@utqtT;sHl!t;g=9v4QVq{Ssz@{Xzrz8X&Bv9_eW7e0Mrb`R&cEwBp_N zbGgmvQp2|4+MS6@Z0f>ATl*CNKI+CR0|ooc3;~N#GYk}Mewv#2sb_9<)rghLvjQRI;wwcWmmpt=g)e3c|q35nIiY$wZwVFD2kDvAZS~U@>>UDRozRp z78XLOso`zx>~f8BwlG5U-5rULfYd7_4IUwz(A%}BU7&OtSn<%)qW?fJ$$BR*3L^jR6uypY}0Ra`!&+i zau-n+nQBX7qSdFV_a@F%mp15bVOi|hcdV_rN$+VU{iVuhUUc)8>L2V=VrBc;@^tFI zfislgrQUQ0o)L(*C_%tP6L2BCqEx7aF{J z@G}&^80{RqOx|(-5-S@)e6Eky8sq2}Kr>$ha8S5*>RKI#pQbycTW-HmDf?Z?fLZFJ znw=6K*$&`4Z}Xk=ES&%KVCPsy2yUUva%KNgsdZxKob%ZW*5$w)*}Z zt+Y&%Qn~3K9Nb`w45fi}=(9&68N;WF5Be?D2oek!WlW)RaCi}p5vt?dHaP6zly8rl zaBqG-pK{9wtSgiSAZKCkrIo)k>lu?c0FU zx&$=_gD&ismMN&-$IU5q5-}upoVaJqe_q`YYun`F20X%ho1IzCD5KKck*vJlCEh(k zgUrF%(xKwDht|?Wozsf$Q0yX6kSV27-x@$;%AdSRK->|4eiWt(#0~f;dyF0sT-Vcj(m1F2w-UHz+Qws~1$SkDM?d)e zt)BnGNFYZ(TYv}fo^_bj!U%Of>b~Qc&DjuUVI_)cxj(a2MPc%>(O3lIG2a$fl#@H z1}T8!vW9$XX$d?&K7L`4Jw~`=e&o5Ay8K6RaJh_w*zgs z)Y27*1&GvBzX_-faI8l}$jkx*ny;V`GJXlTX(`r1>p1^J2v(fBSlDK@G(Vk18@hnG@S}WL?9C);$>csyMF|xhT^I_Qg+9y{&U1o2EE~x! zb!bP~=?h7k>s%@ee#+2f;Ju&W>%DR&m4hkzo2(D}^Sp~P@Ya6`s8+*te&l%;?vLwG z3Uh`S*iFJmA<$t^Kof|&(P_)(ddChvA!5;Fa)Y?WRjpZ`=+q#b~aaS-pQDvzgh_Smb_LmAX9_fT>)o&_d)L2fJy}l*>)52R6=aI)hn-O z-5X)vli~f8Zy#cXqR^z;T`bSIE5xu1WE<;z;}$Vq;=(Xt1Ur(XRXH0JWj<&&e=$Z; zLCR|$lRaR18=#Q>yQpPp_>&MhnSolT`9mgNt>h*ePv9R6Wk$bdQE z00dBpAg|Eipx|_>f6M&t`vJ*=2N1AhmAD{N=zpw;wpzf>zd2u3htN9)p`-$H_D}wP zentpC-oNNEiv^U-E=U-l0=z0!tGMhjgNnn>)RP|u`jNRVFI~Z8>FeJa{o|fwYIp}C z0jB-=chMB*DRg=Awm+M~l1dIxAqo5o7HsiJ+>TeAVE{Fra9SZUQsFMmwRhXOmV)XR1 zwkKT^FdsM0L&)$qlH&CB^uQu^d14DX9qMbnYIzaU+Y1;#k7s*<<#`-sh?<$i)`B_) z>C#_(a&v2`C=gD7R4?xFuI&jqRMdrqBq5D_v3_Ji9Hu2d0a7q;fzQ@nmlh1L#y2d? zg3hx3D<4!6EaM5_lCTmZ6+2KFXhlnWSLA=3nTx|SBdXhcjF-aVHfV6q@5!?Dk`?Eo zTA~l%XClPi+WoLR&-*8>Aka?zXwT^9?dHKQAF~aFyGQnIB2|i_II}a>pL*O0jg5OE zw8hx`$^8bt}BUoI4;45Hd0c$hI{ zH7=?+bRMN0sej+PYsyv>hQ;PT#5sKW$W~S?(OB;G?%)#Yj5L8)P!efk&O_j&1J8xy zN^9P%h$vznX5%IA_4Hgrs$PY5>pWIwVrUn^-NHmPG!1bQ0abpb-3Jq1DvT3u{KrnH zHq(_eoi^+Em&F<7Rv8U4>nc({j`!kFIrJG+EL93(C>n-?YzVCfeYmCqmCm=XNF^+@ zx;@$ZHX%b@?3($;t{mO!YO*JNG4!wdhnrv_CP&EQ`>aI0DSG>v@}=W*a~n_Dz`wSu z4ZM%iJW7O4Q>SucVvpNAN+8O1MdW_<-Ckkzb2UhTZIj^llL6~VpJWeSbO``gTxbI> zv=0waiPFUeO!MdQlg%T0LS|M0z|KMlBrg88pr?8RSfr*4e{<$3vdi88MWgpsVejeb z=_~jc5XE=$unf%Kq1u-9jYy28XBqZXVP^06G^dC{Kr56)x5;Awa1h_EE*?J;YH0qV zAQ3+O=%T5KuBpkVpqW6#qBk81 z29ze?J^uzu(?QI_`7IDuNY*Fj?CcCw(p0~eMZ#KJ#inO^x9Ri$zt3-wa!J&+mj};8 zUggh*h!0HQaZ&VZYQcq5u5?PniBWyTwJQ=s;0XcWXdJT&JsFJv)l}cK%v%Hy?x>4OH=2v88WH@Q;1PrhTbKce`w~nV%@>&sOro zlu*&(#gJjdbiLk7k;%rvWY~gGrOGfG75W^EId*I}n1Emn4{}%WPSx6fU3`JTh%gX+W z8O|d9Fb|#7e2W1%$@sF-7dgth4&Sy>Dtt5bZ3%Fcp5u*0Y zLfKzA{rT9rsx#8xe~m#+-31Z|fZQp2@l7=_D98IWAAJYDr#6sI^Ad#GbY5QeAsI9p z@NBY$*Wap z(CRiw-r-*Eekn!MN^>sRH={&2w6Y;E7xdNg?#lab7V26X`i#}~6 zaQAinedU+HIN3XNJ{1T#YT0{L7ZWrnHC9*mUt_Z!!l&4zv~fC8~Y$uK7c;{0m%}pNdOx zUq@Aoeco@<0>j^LUWa@60+{y0Z&ew(fuk?SICaZWnF}2rj0^q|v?)(PkmZp#kSKWr zvlLL=<)NrP1Tg|DJ(Jm3o-iYX_*k`2lIrv~=t+)x2w-S0EF7;FH75dT;IGNaFwk+d zXai6n%jKIps|FlGPq0y8>@JXSJt>`27j(bCGyYSdyfxwWYJ5X`@GPhhkz(CE#*5v~Gn-)OUSyfsQNMK%K;f)g`;A_EorH_Y z)mjNdkgm71xPRx~@0&UFGD~m!Gm$EKE-VSOC5!v5-jDON&w3EJv!~~{+z2tr4qhu_ z2!ydBl6BO0YQNKCz%`{#j1|5z-)U8$&>4pJLw}3MUH4`ZqHlx6v?0&>VtewT>Co*i z?Yu|joK8sX)q5wspVTiA_A6^$y6ko)u*f!lWWh;pqEY-{^s=0}*9~|+<;G-#Sra5Z z&K@o&n!L69O&^OUIXtu_7Du{{U=H1f4BaR(Rt@Vwx=4kj5Lan`Cym+~G=$8dVwB;m z-$S(`QsJ5`O&8VRE7MVA>7SXA!_m>~s&0e~{Jjm^O1Nws>oD?)RAt3&?fWJ}`AJOT zGkiQLZ_zg|d~v^DDX%kL>ek@_ZsL7EwLVPL3K+zVK^tT@#umv$mp5Nga8%%VWM+NP zsf8kADNu2P>ho)HQ`6RyM=ppSdIg}-AhhXq8^g##4lf^H9LN9zOlUd~^qB@4aE1XB zMN;(wXG}5cA9YxOoY$lSxOkaYJ|SvcU0gJSK9k zaHtVMZ>UY^z^+k3LS94T)fKNpkd3eV%D>Id-=~a!6xb^A=~KD27jHFH;05X7!GVYO zFED>T^6liW-d4zZoUlO$QHA6IYmy?s7viO2Yr6{#p~XJ^{Nnb{H)lY-1M_k~tU?N@ ztsSUX?^7wMng8ljZI}D5nfjp}T2k>meEVDB6^7x&@@|4S07e;e+&BLVUW^LRtUSiCKl|qV&q7}6)=_7-ji31&?3S$y?n9-VU z{zYf+3VV}qhRy^W%hejeMx?BOgaj(If=4~}p*}>?PWpPq`Y`7XjuVFkccY6hHPO!_m!~XgHZz~L#E$at5y(P_ z^>k`XSNeCjQyC--<E4`-qLT3gLIbNg#hhxy=uTg15hv7h=~!IzgRIv2n%5&UN{ zu+9~vAIQVvzs-Cdr@IT7O|Q{*4dOrb{eFa1tCq*YD3_yGYt}QCsf(3d_4#x6M6t{S zpz#GT;JZq5^UjDfMt-x`KAkLegq#ckY3u?(FzC&Co(E1wW}}J20HUP4-1<{rAN?bk zPCXhy7RQ9@J?S!rs7MlSX*c0QFjIwMRvTGor!~~6lCMXB7K%+ou6%0E@c5QGkg=N! zr#5M5^JJmzVSy@HHsEST-`P;#$f#8)O+Gqq!5x-jsmsm7lK{-EtU>cbP66L6b+3RQ z(3yyg?30Hfp&E%tcKF*T#dTR4DkdhT2B5ANL4l;>uh!L_xi3`~W;8E%9p#EGAf0oL zA$*w!5N~PT541yZLdWi<_4T;VgfFo4^z|Voeqau)KJUP5>}R|pXpAKkAjeY(%;=_1 zj}Hdg+Q>t7gEG=luJ_k(WQheG*+}HkAu9lD*j=H%cEK7%T6?-N%@qdr%N!H&(ekVpqrrxSg)%@0DYZR(f zACT?xd?E&oDEKM3_1AOcD>#Yph~Br@9mx|QO!(tFnL;6Y6_?oj7F!Q#{SMWyiI8_h z;|LO^wMD|Qqos5!rR_|pVvxB=%yf@Q)G&;YVhH!weyBs+qt-W>}W8|1QG%dRHT*oHcn>n z@N|Hbz{=t`xQmOzAdViGI{Uz!gmrHYB)$2s`aTB;y&vGI0xi7iyzJ~wU}Xbrq*4AO z)s0b4a$zp6`i;3-T%cZSKHoSw>CXp=nQ6?W^Xvp_&a)JgA3uMN*xnrr-c>LTu(7g| z2D-mvAvVLeoe#08oX6GAm+sDI%^7JeIf-Q%d6zwB7mlGWU)$R9;oeo?9b8o}mY6Zqf|DQ(U<+=T^3&ejJikP6;(My5BAM#Z z41&LeTIbC>P55~b1p{uK_19z*m zyE_+X<(EKBOiUmN2~tC&83J*%M{Js5qv#nt23jXNcX5Z!5M307nQ)fM(JK>FQQsKZ z(6~t)ok?x~@-S|y@Q!Y*6aTla+0opnLA}J5aEOr@{p;EaZ0pDFcX=eWt*R%Kf`8@9Zt+QISEw} zb-`q^6PF0(hZ1|>t7le3g-pZ3UbfQcm=64C{Q+;N+LIt^vLN=gi3|uzJ7l|8_?3+g zjVVrkzoe;0T(ddn+O;Mf(zo_UwV@2;D>)Xh9ZI=X|X8d3?nVl%=cRlK})jU0Xw= z-StnvU;o0_-CWhQ?zz+iZtwZ7?ygH~64wWR|89Cz`cM@hL^gVRyN2{B22Dc9D9myw z-4w(^=rnz80d5^%F^+DRM3N{d5WZdPyxHYD+5$+wV45O2s~PvnnGX23S##`)y1Kf) zfQNrrq3_&+0isIRY`Fa1%b$HExVwl~T) z@lKMeAH+a|a{{UT8mLX(8yvgX-%d?0NDvZ~;<4%0A%M#RYujn>hZ?8F+j9crw>@Sz zR|+&Zzfb&Ew-EkrS^lyGPdwK-dDZ^C7HbCJ>a3hgdpa)kf}B|}D#F%MPkkZavBAcb zw2yGfttqxPKN?V@69ODZ391BLk$M}qdl_+F}tNp=qda1Wla z-^Fz_7eEl~`|$;4 zUI4Yg$M4@W3}&T*gM(c=Sa2?=jB>PjF9a{Wle5#D@p=$skRCpk6vA10bsVHfS+T1Z z94IH{#b?rJWTaED(ng@xDN<5CyN#1@->)$+Vw+aL9A+ArG+=7LdXx9T^BGx==ZWuN zmq#$0TgrOU3obO;kx_|)34#c`Ow){W3~-`FLAqzR{q4U_=&xvlI=lNvNA zBKU#CiaYAmP^7nCIA2sKBQ!1*+P_)9jyKJEU0i}zm77`r^5@D2AtISV?2Di7Oa1!( ztVN!iHim5^sWFtr zA+X$86wwEX$EoKXnxAY74!FvwyK=gViBTOoZyl+u8jaWd2`JHlC3SUnoF}*|Xs#(g zKD)~^gCsV}Bf(zzdxH{Krd{l9KAN z+^wXe0*=<~<+JoA3>xC&digV?Wa&HB^}3)DJR@{I+@SqjBuEI`YIa-u z$8{)sn5ERm)>bEHkSznkXf1W>t(5Y7^3lMCy82yONy*ay7IrM|y|t1%Ljv~I%*@Or ztCkp2PZh5TtZu1dkDPjMh513-!5 z|tsl;nwxgXKG&EQ%xg?uv=vY=K_SlA@Gx_l}ScD9U~Rba>Vkj70ucbmu;7YU9b#{f0T*miky4-2BkT}GnGoO3zFAS6OQ z_n9*@PRoqpLA2NYqx_@vJ>w@Pos<-#yu&s;bbs&J5ClI4j6|F2r^U>vL$Xvm5mS&m z5N1`enBWwkEN(9S-8~I>*SrBC1g{?mS=#l&=f#@KaK2P(i%V1Y`-P72vsdoDh`GZ5 zdm1eu6e;eHw&}VpOIpKr(l;j0lskHDZiVrYOcu7m4RAvQO=ajxDDdei;j3~##KR(^ zIzmuHu{*+9KI-%Bm**~inXGvY%`K#H_x>I`E+IJNoe(>dHCyO2o3OtS~!k5!~;5Ty(ElDfHF|b5) zcXM<2F9wZNZ}j!UJ32Zm*%SRT-* zzJE1#ZsGD7ZK+wl@z2tdoTVlHlN+Fi|9SQLHD%EL_n`A;#~0?cIzLWI*G{|FAx7{n zB{kOmK}DkS;1yiKR$Q)DD4G-KnQ$z9Uw0TC^%o+Zd#SSJT)+o62qZpx$AFUi@GsImZ*o%YZ9+mv-RHF;U78)K<~b8$AXANu zkcyFylZ=S}Jfnz|%(g;nJ#ZsV>bF(kpnLtn|BH#dxD;p9X%?P?N+>!!1o`F1QAbglL@ZzTPGj%^Zssiqw4? z>cA%){5^)F7ZwtRRAAC>f)Url-f~POCv!$cz*W;7?`BVf>xwkL-rLKN zG!7ryKz6xz^ZbHm#)EI8`yEHR8#Rm@V*AwOf<<=PGq8mu%f01an{WOZek<=dnMt$MZ{kaR7{iH$_1G1^^>^8B#6S)(9kewFlS?A?7`PI=$JJQe)&~P2B;3%i&8&vps#=Z zB^clY+U@`bkcy7tTG*~@I?$L3GPJ)vKi;u9Hmo({{}+;pHejWn-m`q&`^pBy35S3C z_U%}nMqZ%2T%Gxw7D-4Zn>4A_4Kfna#Dd`XsePN541P%Mz<@2tmGo66AfEMHZNfzF zD(HLej|$o~hrb&ZUkTst6z4C1GX5JN0O%4J#*7>)AjV3f0Dxa~4Y=RAU_Jw;wio<< z7djv%$I38?0k%LGfrTXwRC%x6HZpaMj2=(lzemWtnUdW2dwDqp@B=US-O$O&74mcwNF&{?QqmwLA=3Gv zbcu9I2na}*bl11M-;6(;aa70%&w=^4eMt2&PC}wbS@0iODI9d0>?@~= zD()%&dm&ziNO&V0DyH!d{)Uq`p`|rfJSfNHFD6;)Ihql9a`)?Z;(lvxjy}(R4t~_Y zIlrQ6j*xqFqA0JTwk$pI6qWzo>R@l~>Z!Y|dQ!V!B50T~9dVLBH z7M$#(%qj$59#>Kw(%$Ta$w*6I;X~k!*h_6~H@WS2O-=hCOt+qH7Sm^>Pn7^rt~NKME$0f~Xr%kw{bc zKi99l+!w_czufJ5`)|hlb-x}aij)HXt(r)CXR@NvWH4hk)0Miu_rM@s(6Qm?LL_Qq zI2o;EQh9;JX?>VwM|9NF9iH&FisHomM3~+gzl2!Yi^Bwo&oZ)$2_NHX#WNaXA$kt3 zN<5G>`wp6yCA4gglY)L13*noucn^pQlFcdE*}4;~r?8U8(S@&i|DcXOe3zxTdXn|P zpjPjsYBnC1g?}N=zgvjQASRK^EP?#b2^~7^saO1@t^yAd{zqfQpOhS_V9Nh9@Y~grrREdPt>X;woa&abUj6dBxF=Oj z#8_hTACc~1b`ee!9El-doAG0J5E#b_bwUV47JMk9%a(L_A=D4F2%^WVE=>rqkW7|`o%8_(4klU`{mYGot4E?hk30sP+GV)2Kn zd{~2Rr9(>(>B~O|K^!ALw_G zo(nYZcia*P%e~LAPa+;6>Y@A&N0ADKmqvKAE;6>=FneKVfElS~0Tu_3((Kswc=FoW#t7V!T8 z*ZG2s7QCP~3JY0bFbQdMD-iEJ6`Cp&X+DWWC0s}-Yfx>znDq-DA5YA*pDe!~g{mWA zgGQ${Qy|nzizsJ*Co;JBAk(|YdnvX{%y(;Y?*xe}EiLUAut}q6#pNKuz5^z5PGv3! z7Z;Mg_i=GV8|&+Y(94a@%oHPZ)?Lp3J%aG`C2;+_=>7Ph{!x4RBp2?2FbOs?s&1mJ z(qr%vqZM`ALfxLMz_~b~W#`!9G$B!*G0OSLf*;j;+H&HhU|wS`oh((%4a%jeG% zwqY3i4ATDA^#7~o1yMtO*#n{owZ>J^9pcQ>j=2p60nWdgp#8q> zV8+L_G3fzOuMBjPmw*3^3l%dpaQjlIsyL8>yG;907BUVe za!XGT6V}~sRF!tldkirBIWtOW zT{s5Msxl!RNlV5%cRL}t`8b%!Qp1=iJdYx0Bg93_;M_MD?e)kJd%3RSMQ6rthlO44l zytt0n9$91z|7zBI79ur(G^ZCC4v+9dRAj|xz(f?(c>cUlMD5dfv!|}9z(MCdl+NqU zcS)1*M`9kA?qwJG0<#g3kxPMrI%Fp)3nAxsKU(?{2C9u_)>YeBq@wHTlR2833-$DV z^nw;BGfIZR8S}?f;L{LYLxw<2V7I$M3T!4rj+fERxiCv?_@?FOKnYBU3}iI&yXu#b z!H-W&^eqA{N40TV3in{PmHsXu_ofwfHsmW9@GtuQ9v_zkhnESkPr~$;IfZjfgG3I6 z=e&JoB~hA*iAh~)Gi3bzF8QNgBEWPS-tJ`lcR7zCelCwF0hyRK$IFIrP`N*qkD|`2 ztYlPGQ!{aQpDg1Q#;+?StJdSH)J>~>Gb;z~Wb)F|C=+92a$>syC*zNcglW8YEpLwJ zgYdNn`ueOG=-VTKxDKg|8dpE$e=FihMuTpbQV|8 zwQU$mGI{8Tq+lCzFvbgVf?|{M5AM8CeWe$V|2`aRIFB}wj~fy~lfw<`2q5K@_?u{inijt7R*z;`1Bd4G4sBa_&t`5iqi;5ckQaJy4l2j{f z238)IBQJid`*DWrmz6Sa!^hI>gi52J^HY;r{)aPxVnlv0s^cAFtUD{_0i>c9vV=ZF zckHBa@DlkIa1?4=)Q#z{Dn?n0H`patO_8?qvxShuTe{LOh2wq>W?Ya(?F%3e>++l7 zB8alowYm?n{H(?vTnZZs2flu&Z$ZhHp>Y^xUyv?*9XP#!rmcC}XW10_@89g9 z+Rb4~^wwlWk%xoB8ei0+6=C^duk6U`$q#Pn7uwnpz`5xJ#BcEWdS{O5df7;<=n9>| zpmvZk@Q9lC?PcV`NC+yK8x5o+svfc>AufFy#SwI=sEH^zoTZD0uqGRANXf za?uj|VF=a5j~}o~<~Kk2C+ZK5*G`80gXoeE7yzC53x1jipN(fXKbM!yH^vH|LGIw{ zkkq!pqLIRg=%6&vjld{^OiD=L5o@oR2l=Odrf{ z5P!h5r)L9{I1nO3jxSN|r)6+$I>=Y0GMRQWz>NG|>wEzn)XjcH7Y!!`Eo~X3S=y%N zV@@!X@WpFVN608(YS1O06eYd2dAB6pO5;?%(=fkN<=+iwO3-571J&mbs7kOm=K`m8=-wnY3~$x(n+bXB z`uh3_tORfVtF@oYpr)c?`;?Jkk_S%Fxorq-9VX&GpG!9#6%_-Y2-p9BHQo||Vtiu8 zLylG1z?U8GoT#LND~h`k2(b{v?Qs_)5+(PMg03{zcnZbBYIPTyaWZVemy1526!S9V z%g8EH6R-0+WgrK~{-@o0z;T?gz)JT^?=*5W_rPL1fUG){0CoFGG6kiCg#~)(8iH{i3JmDLf>_y+-d>Q+a7N8OKN*YV+Ux+-x;+`M^ zlHahGmv`ndXuZ7;ZHz8n??A-NZ3kk-yOCMhD#Op2x`pxfTtv!)B8jibU~{XgVoXz#U{ghOhKxTk#MJa4 z6Fw8JGON8VnS~r@RSuF4T`Ns49tampWJf~CBxo*c_J9s7+=`RX zWbFqvzw>9Op!%e50yjkwmy7K(pD@kyX#jl7o-0|?Uv8lIMMZe`T3EHB`-A_JnEP(l zFxV)!0{x`P92DS8??@k=o0yp$7%8&mjq4F;pttm08ta5lH2!l{L}*x8l<-+{7f#O4 z?;3p)@!0ckVDgE2PkloZ@2CO09cwX?^(#-|- z@-p@)DYfue3o0Qo`sBz4JgG@$@@Qi4iqYs3m%3D`r$@^Yd5;@Sm!>3%zMK;>_$2eo zV-Anit8{x&&QISjuDTp2jg#XDv&k)vuW?0Rl^uVGvPGez*TQ#ivMp$xg3jF` z*WVw9W%=YkoXjKa<##3SJ#r1D)cr*-+TNe0IAit@zgiN`7%aK#+k{!4D}5~~axzFp zw11#wPDeK{@poQ<^rLTv?a#qbUhPL~-o_ef*XfOl%Gtv&+LZ#Ng>|DHTUWV7` zY)_Pj{^%huzcMZlro+Mu9BP_4TStm?C@0xh*|g=iSwdTyLDdP$!?3_AN3|y2`mpii z>rrL)O5`9-is$Z_&PH9`*L9AP5;BX->7^ycoMFtwN7Ef|=dQe9Q^H3(-RSk=s72y$ zf9d9HWGu-MTA`J9scJZ}k1bZ9^M}311wawUWljHF?Xxa+nqLSmUhFdK~65 zKX(g@Q0ba8=Y&;dR$UuaU_QE8TmKD0(BKZdFzQK0&uoQW5An4~|9H;(p!d(8iHU<* zIG?4C)M_}ArrBr0UN_`Rf>B~_TgjkP_UZ&I_zCO~~{?T#c3M%97J|=0l7Y(6g(&cHG5^o`M-MqnLFB1i}maPjeP7RSa8&mkUX zW`3Ry`jirvC%^c4K1Stgjuw;HK&Ggl^%ZH@sH_6(m$+RQcGA00WW~IGZKajd@F2 ze@KquQc`~W_@mUoLCcb5fOI`ODeAz<`wJ=irn&EG7P$0?WmE5;Cqe>kG*xXXNW)ds z#J-Pbssrk1r;T;Eh|Cps8p+!Aa;|^T$~=6DEs!KVrYM0O_`nX+P9gxYAoU&fdCM7= z|LSD;gm#wemC{cglG4SG&MV)jSX-Ut{hDwo77yQhnq;?on;Lz2CoZliSYUP@;_xk~ zpHMPDSCZ=SD=iXvxhk%&c)VSYngi3(o^GBTXU_UMC?%kpZ*x?~#q@OcA*1lzLU_XKHjN8Nm}Gh#kH2zP@x`&|8?Fd9X~kJLzKCC0)r}`t1Amuh^)a7xGWk z)5u>1N@yiE(d`7O@2*c)EW*~L=|h>{l|BmG1}~T`94=2C!N|c1jirQssgp0CsgyBTBws?K^hQHlo4>(rJ5{=MB{qbB z*XYBk6f&MnuoZ78_(PA3po$EJn9FkbKH}cjRe=G~E%_I2*M?NMr@NR5dPI1P3iG#I zMkIPvKwUVj4L)`=_Vn~*#RGFpas4BfLHRE|lZavhL8BI-MwzJ>yhOKzT-{26w-?c2=l)?;@O0hF3K^er0dZF*PIO4HY$Y z8<;Ene)zEGH(ZEqa0mdx+@c&q?6%Cl0@vV1IM=%1pI=HI@4C9WW}g*&2N|xBnwnZo zf#&+d>DsAUJ11&+u)Ki`p|*>k&H1Q#BA-+eBY+(I{REhLmp%+4Pi6dQzV|z+(@U|C z)XGS*h`5{!9-KcT_ZJ=&N!ej0NPK@mvA((*FgrCB0mMGjDemUqrXb=?0iwoLo}J~t zVLhMh|NgU&9e+57oELv5(9dbW1BtGkOUI@k_O?Kfcn==ld|=%;+31DO-mAAHIH1&9 z+0fI2U0IB2Fwxo3!Dv&$PT%1)al`=ljuIcbhdNAm>mFGqEm znS!WF9+oCaSASsTK)bWGMPlzYt?yyM9J05E1$$+Z?x(R?WP7H;ibS7lyToV2IpUb* zNPl%i52$zwEOS(Zb2U5Snbrhi4N)e>vv4XJds|=&<#}^DmmBG-X1g_T@+Oi6q0pfP zRPUoLK@pt5>vsgvQtkR!@TkGNNiG0 z$iTdvgoZtDo|1`x_YNMh5+yWjdDC}N! zPKLC-^S%|dIHr%|_1Y22_C2|(7ooLdJ>x(oR{1Qb%%)>4yhLh+j6awYG?w0kR) z!{-IvzGr7&2UX~7y@RU|wCaKLb=?RvHy*@#i3te_GBQcUIx_%}6Is5ow%*H)2WxW~ zhS+!ePdI)aM#ja(89)vjM@zI1q*M1+z5>lTgz{uHHPI*)D){-;|NhTDQ|D)u7k%JB zAJiC4?vzUxJG)xz z{F;}?M1(FTGFYGc6`!H4`{OJyDvc476=rGmzE?l+Z&fX2#w)4-5e@qq3B+pROz)jd z7^>5Wv<*rJIO35xA>|Y&`hP;N?r^(#GTO8EmC>e?N_m78-S!M(8185AY@pOCt}z znTA}C)9tjJi~LJ~hc^C3EJ4XbRrScMq(t?^@1L`g#~=?di@rhc!0(w+^oUKVuPJ0s zDuAPe4=IalZS8yMz_Js_1kic(5&R0Qk3~e{#Erytx*QCXA{21w>GFba3g~fBR>zDn zcPt^>L`y3iUXZ_Q-(5F-?I9BTac^WeZ2$HqCsEV#BjDAGWGuLCh#%j#z^tA~bn+Pq zX4?B4VY~A5!FGIWIr2jn!Yg;lZWd>jv3w*_^$d(rf-mfkI!{$db(f{EkxGQtn)8rH zO0Fv12L@kZYFRAS-|v<@L8C5h;= zvQk=7vp?WwsV4XQ`1%y(o}K^x2%St&5fyq(ym&HuHfy!2{!hj0OaAFxEE)Q4ftH?N z0-6>fyR~4QVV7rWHcm$q`X7s8kIv7uEZ9;PH(w6f=*xy=iYBL~{ump>6}{ZO|G>Us z?}r(*DZtn{eEx=PSG#FQ;#Hl=NU8@+HPvrsQ?H<5y3I97sQsj2ZoZtfot_&H9DDGA zDFS6o_{xgK#`bpS&!0b;SjR9@Oy9hDlM4r2Ls^-})9ZrZT_=YxiirYLuum$ZBM3Lx z*1iWE)%5l2ht2DaF?3R2_=sZsZi9b+E*@ve@M9;vI*5$i zZ>G6-k1t%NDaSOs0(Y#jFgrW8=b_b_|@6#nO4<;ih5hbNtN>)|_mBdMrZ zSyfT7cON=ckCDou3XBsfC~5%Qx-k-+arqk|Lt^W!Ibp4SLml6Z?xRP_y#Bx&E4vi! zt!!csuDkUerq_Mx;NAZ9oiPpOC~x~X?x&}gTs%A|6Gz6np{&6g%gxL&v*s3qqk2k6 z?Ob$u66~Z*7U3~5WTj}5%y;!{v|dbvQ@yFHeG9164mst9M^>YcEP3{?gFwdv&ogPw zpSw5&hq~if8N@*ki^+w0zut{eKZw)U;IQ09AddfuO3@p!qHt~-yQ&fy?Er?1rv$D9-=y5J{ zD9{NNJjiKj0FuSdCqX)rRNtV|TqHw(iP<=unrn|Hhnn`cJU+0MVv-=dD~Ei}kJffn zc9HEGH{&^uysAVFNiJ%5Wm5yKqLtl!4gHW6J~oL8Oxxu)%yUs!opI%ymYAX}d2ggh z!6G59ivyvh3*6YFGikjwf`hh)j`(L4m?M{zxd}J;+=11m)Rbx_6|oZ14A|@6>8zT! zVzBhAV#eqOgNA6d-DE0kA7|ae7$TD4&YJffdnbW8vTdvxU?CGABob(bg};^VGfw1> z?Y(*R8v}`~^ilbjeNXn1<~>EkqOW=xy3gkm6UV=iWS8gs+}!BB+v+)H)3dXu7~h=~_d%tgDmh~y zDWeM@7*lAJ$f>A;%nfxcnzC-vRY!B7sa^Q`wFe&|h>qBEKg?l@4fp2TmZ$NMfgsT3 z9F5Jw{QS_ZrKMNj7VGK=dQ01~K5Tx6RbU%9f<8bT5)y*&m&3+>4az6jsmeo}G|;ga zQG$nevsE zlc9NA#!tGEHfVX&EXyK0ZH^1%V!&eLQhnxk_?fm7!p{V%!H{Lp=z2e?`E!2$3M8r8 z*>7%dj|S}0^m9HoTFc0M+mCiYZ5VWE6ZCC<#~kOY^FVfei=ItpL6cRmqX|0cuZ{38T4j{SDfce~9QAMR7){!JQ*SlE=H2^iBCafZx zeo2!j9Cg@KRYX4Bw)E(ib64jI_UGM(n+&R(qY#>m4k8&25|ZFZ>DQrVa!BJtO84Vf zBwz3NtUU|vEITF8Y9P^LQyARABx7F?y7SldInW5PNggkFVu!|nU2?K97h2?!7@AhA zL;9mM)m4g>6xt=08IHai0lhU82QjaA&M#-)d6pou4k%@t)Sd((wh<#TdW;S(5dXp< z`HbOCi3@=iy}KlzLcCq^%S4$AQ{s#?^lDB_d39sWvzRa~=5Q=_5i3FCaF4r8XiVGe z7M*`rK0QU6#r@OX+^aaL?x`ogY&xvvdNjH`K7x;2{_GD+r+WVcf5W0|Mbob_tz`ir z_=qt4?{j)h;q8FPa2$XNdls!7(NVcK+1Jf&a~ev{($b<3Exd66qy8C-e+1Y*M#`{9 z$=y%7N>>>L;jeH~(gUPgCJMQ8n=^*vyTi(TwA~@g9`vlhUXHrRn#- zk!)4K2#7{1FUYr$@$lG>`!n3S6sZ0R9S!p>-FZZLD=W6Ve;@_7u$@lU-bK+97;;)aCiawcgO|j%D5839;SX~Ez>ziq3BnoVP&+AJ| z2R;HnYyQ5EkF*QWG%HsNTWH?6{UeP#ymVH^gDIuI4FmwPaXrt*acz4mH^YQ;&|wyKHW*F6>ty z;bHAUl6mw0Z%N6NGY!+QH)H0m$Jd0m+d1d9&du)oa0ts&1a5Q zx)x$zzv8*+zTMyjVh3$YTb7a5>!8(m@e30JQ=ly<2KU6Fj;WCH^WgR)R4}>errIax z=_+|f%U|shuvF{!R_#l)rnYm>i9Bz_9P#0|kaPZte_>cJ<`{@>ZA7PHg|3YLPI;2^ zCGs~ihwNb5V1d{Wwnuf0bRh_7$yhmd&4{gxiy;hr^RlZO|2T9BONrlst9bZk*a)RlGZw!2)*wdHaZTRmC2NKg z=aF*|zu;=RL|>7!ayNCYlc|k7k>br{c}Ax1IYm(T(^;3%5BjR3?(M{CBCUEh{Hh1< zNtG<`M=7y_3CtKEmQ(s~zAX|1;q*qXEi4ck6fci{p)JoJqYU!XEp<{Hn?vytO!%g@_4Pp;(3RUqvsX|Eqa)Ef^RXRar@- ztz@X4@0FbumQgY%TIs%*)BLj0^Vi%hDzxyu^p0r$pbZ{ruS9mfL^xXp9Wr!-!V6~0N-G!>)AW@8Bthk>>f?&I|) zkWalH*iMt)A|+ruOY%M0q9l_zIX!~Wc=(q%P3L2dedqB>Tz1X6HFekxFq=oqOzgU(RVy(q=5Ch`_JyV zZvkInOMX5SPNO(Uvw zaeU9y8+;?8XT1;leM(A7GR3`59VS2veFO<`#>y-UNll|d0(d5_onY__ufT#c69M&7 zVxp|+a89S1i>s@*`BddV`;_g!3RuWyudL*Y2o1g(`BGHGMwEIh2+j+oN>jnLFeolI zKDvI8e0}z05vMSC_zBYyX&~*-`Sw(E2J*!MI#%o_~o$)v>?6&ov3_(Kc zM^9cfmdPdv=_DopBa4bM@R4zUDk3KvseIwZ3lxHd>=-0GGAUw)J<9j@Jjo+bU(cOt zESWOLi-zd<+y#ZVqzvBVOH#(m;^LvEdFo7AiSW~z0*6wQ6*T^p^wm_F7G%u}?MJC3 z$s$%G#tX<0jQ-ylt%}RKnb$ELiez8P16=GaTwd0g0uv97SKXb%!?>tvRxBqm!*>*j z$JwJl+c~0U2&W9DZ zJcG8YD$M=))|v{WSGcRifp4-;oKAf>l19N7^=}WG0G|C!-5ynY`~5{|%J)zA%pTH2 zo54(+^eO$KYu@Mt-hqSbD-2v#*&RHAncX_;RC}MTimnBZhkhIf-4e--c#6K@7G-88 zT4L0E%mcE?a~#Ao`DmIvQ10|fjYGsPJPiXf!T06wbc2D6Pl>6+l z7b|6dKE-XBx%<1e2v0hk&qn(Ld`Sye01@4wA$WLrSROrUWbb+yJg@aI1W>Bd($cde zwz7tv-sMWa|11ap)NMYoC1>uZY95XM8bSci1?ZGxU%d2Kj#}=0;cb3#-1xV4`pq!l zUH}MSKg!_HFGokbef##AvU2Y!RIuysz~X`8b^XfLHl1Dh6wMIr7g6bER%K-%1m}oX zd3#K(BE3>e7gS6%7b`&h6n;xO06Sapc}}180|&zs*zV5S$jQt5+FLO9Cz_*CEQ=7D z=8?dvMF{%sb9bN%w!fVjeh(ddlU7$iRSBp(r}2DugZ#RI(Je2lrWUPJTkJCkjElKv zMn=sQ6&33r;L|7r<2o+(O?4ue>K6rWErQ(x*tv%~b^yskNxy654DfBhHk>%8ioE4iKbFYIH6Xsj0$Q1Wqfe((8Ic8lEq zEcC2)gpAINB{Gl&S(=p*7o|p#?j3JvgLNOSo3sTF3q}BMKtzzHXb&-$s^x+vPJ-T` z+WkHrHE~O)-1!Mv0$cxa0u^<}7EOOE=H$sUKAb9q(o^Si64v@`sZSE6f0&jVc0FKK@nz*>v2vWp8Q{$<PPwC2YK*VsS0rM{q`;Ejmm-?1_v;IZ~b#z5*hdrzDA)gKL2@L~P|=T6LZ+OF)B+`sU? zd=zG0wV3Cj)dKTPj>d}@A8G4>`mF+8_{`hRyPH)~L#r8{8!5|O(X9ao;&(m5%a*uhZuEc7y>(L7>wLn!uk0M^2+ZOak^z7MmNtZ2q9lcdMq2Yg(>; za<6@;W;-3K83{4+Ux3c;e9$j&^Xu@i`Zk^}?EC^FI9?O!OiT|Ru!J=JlAGm6|IHk- zA{J+73uK^y7_g{HV#IcLT>65JI0dTJXCPtW-^LVQs`IBk2jY31jgyn!1tS?9!?B1O zWO2!q88!cV2GjiB4$>0LSwJ$j8+>h?&GmD9Oe+E!`}wehgsHn8#WO3F7}l>mQz~rs zJsj?e16=Yq=jRg?$-8%#D?gh}-59w3x(i}0sx?vfT{_6@1K#YZcX;Pz@ijm}3pNxT zuft$W54dDr=+L*ZgzA`_CEczG5-1UXDQaah*#IT+3}$! zec1N~?glIhH61kl@DDX1XP{Ao6-NN<1q&-H|N2o;QTb^a8U4qX&?9zrII3@L^~I>+ za#;XOQPzMho}HHmukDfS{yrP_!#k~Iq(6B0ADWW7MJ;!jw2%DvWADdR`?23)-ZvE` zt^ft%R!kbk$X74x(^rYPpWvt&x7-gjmI_8Hxl6zodqCp5-+t2>AzeW5fy!5x3u}$b zMu9}9{I0iYjCl%=BgCNhKbR*oJ<^~n=kDG1$+Wt6IPsA=Sq?R5R?WElEv>Q60-@2E zVVBFb_q9|u-Q`azRx55o4c*C76tng1FLevQB;IEkCOjw#M6#MAPLquZS?+CaNjLJU zL$7F_GST$S6qPsLpm@dHgtvB|PANS$!pp@X>L~)ZY1b_E$}r=35&p&1imJEi{_6Wf zw5429E)o+}XFUEgtAI*NI+qT7g;*R}X3WGnCGLWhdEDW!Dnj>{I>VnL5boiQcWC6Z z@%n`ZKl3fK@%;C;@$964XS%7v#$9~&_ukFkyOL@jdTMcBYQW~ZU&TQghIB>6wEPOI zoj*Q)Vq9FiRB#-|fgWaIq3K{qHgbZG`|EA20%P6Ruc-iny#@8RpV!gGb0c&vejy=Q zI5LCNE6zY@8k?MKiB+iH1KrDI{ldb+9B6kJySuS^mTiM|73dk2l!*=W^pv30eF^1H z+zzxQ_AtI~P2KnO@`7z?-O;!{=X6Eh=z7D+TYLLvxYEBgM|$11Ccja>+3V% z5fRCGR``Bb;Ka9HiI)=0Ea4_6O#lAAwhDPjH__n9cJq|+Va!uCE(G-x7jjS$CvEHC zQwxRz0TVbY8oZR|7X0x4`EAa(O49;qQJ0&WyKQuoXG!p>Sd1AtI#EP0(20#|4F2 zJ=nk2pw(%JjEwZFKi^=xp5-+QyIza_=hnO%!nq6lTmE-i z578!`!{?f@ijG8;nX9Xfns41w$=+f5xMLBEgOl@tg=_Tq`5*WKpL}!Q`x_RqwhmA0 z_nYgBZ?&~@F0LgIOVx<(ZGS3-7tq#s+0oIV54P23YS6mi6>6o{Slq&lu%H}sP9LMZk1Lduv&m$8@6>8`irYWUj#p@w0sL>CL#_=Ez7c3!AcUeO1+_ z^ptHW6fFs0>sqyQ?S7wVJVv{E5BRkEs_+fM-uED_+~a_+`t6SI_p_CxbrojSScP~b zTOjf_n|DQh8qHXpK_8-ez|1W4X#k$`5WCfR%l5mr!epq)sO-JiJpX`?FX^R(+x-eF zyyL&>6?tJ{VFGbrw_B3?X_wWQRrkRz{{M{+;n0jt+caRsX}>5{uePT&^I2Cx*u7 zjjH*OVCJAH#LAbS);qS#^O!0nFzPJa$pizof+L zPy&Bb3BrKzOlQmbzyV|~WtKwkN5~^wuBc2YBspf{GJQ0`D_r0&>j?65TAZcd6ZIY&Z|4Ui@*9}Cw&?K)P?sjWhuXgGh}u|z3> z6{9{BA7p`LN*s5u98qom#C^p~aGDx3$Ks%fC>-e#FL$Wi%!kSq-d_=wh0}?)m!C6f zJU8GN{EaU2t*V_zpP)O=F`AQ;lT$Y|#6ui{=|d#sI_n`R!0y}S-^@22Cy1W}wehmR zhzW%$w{Fz$-;~8V6>$Q#lSB5Yawlnj4*k~d)1DFkE;o^GBIAl>@c_dMFb4uC0wK|S z+R51g=(bZ{%~KjMvgiaO^|g+OMHorYCC-YUN=x4ZJ5LoVfj2IY@P2|Q2N|X$9Afso z4x5+G7v|yv-QC@nb>Jiy2!nf!N}?l}XWS}9$smsDHr1fbRTQ-`3B;^0irt5^GX8Hv z&jY#T6cQ7a(**2+n0bD2QStg$YOilG@TVcs8mjy0mgP+X*bFqA<&BMqdL57b1AiuH z#=*?y%q>iZJrtfP80{m0mP(_XHxdNX7|E#%4?;yv&1ih&IAj;(P5>VhgAE7YE&m3$ zB{ex&#}#<&5ERM2u}SqQH1xYDVrw)*bnt!?EcM$DMBrz}Aad+(Z-4Xk`r0>0;WcZB zt&M&<-1TXkmWyRh+H8meak8_+yB@sxwkRb2r?8L&zI4LqF2Z-6YrwFpwwvY$oOf^h zziZluk5sw+_lX}wy*)Zi&xLUZcmXD!PeN3f!wfihx~#Kv83RD^2e#hv2??;DKrbnI z2Wy!#E}rPrd`YlAW-|gelfPiP)(Ml~muBnV&fnXq(}%s*9(eiG6%=6Dd-UoL{r;`R$RbOEbzb(+!a!~YK_W4} z^9ScTdLsPuvt#ic@}4HI7XC?Y%%;x!k{et#ePrp&33|Zj=0@nJO$wy8n}l)kri3K- z80VfO?|5+pzPH}>!&V3(BIA}mYs){eZai{+_79s#DlKMr9$RXR*uQ(oCt50++Mk=j z@`KKh5OqtYDw;cU%MflqvlDZBkD?YW_dKsmtdBJDOq`&S>9R2e$^OMKrqPGY`4bQE zumg?J8HvzPButD@(xwCoT*h?XztSi4rYBPGWCHGA&HVMucr?PP{wm}7qNO3-m(FWT zGHn|cz4EsVYxV{6-<>jc2hVKxecqs@8ACu~K*be@=gHELhu0&@(hu4E6*SMg@33_3 zqlieMrQ%bvV_q9}SvHk>bA*a*x)Yp_23=_kxB2f^zfi_9bDoWC784w~S~Yj=Iez2^5XY&YoGh+!XscW{1#a-gs_Jyx8es+)BQD@&W|e0x(f61QW8cW z%WXkr8iXPpt#QydPkc#yizkN-}-%mj1L`%{LHAac|}AL;&^3cA6hV zSNQV)iE>bPA@Phx-tE1WMxkGhT(5qImJNKkuOEmEN<*^F(aA|rxDIQ`+r~}9TW&ep zDDT2|4nBVV7FR=Hnbj?XZf2e=(om%V3m|CIGdVq-04@P9jr%;3_gSye7{X!olYJ}v z7`Aad2XB8Gr{Ict!-MKoMkWlI8B;5CfLA zDJei)emCfQe6Y4I6ao;@M8nF_Uyu#UqO_czlE9{S(8IgdZnf$t44;-1h()A;f7_Cy z=NDK8;k&xljE#==>e(2)ovncs;}4v_S35!L0{tajUM`HAL-4UUY)vYb#D_sw4JwQfY951F?(Q`OQ^xbJ(V5$i|s0i3a0Za}W6dYjPYx zf{aEcA>*BaFFRZ03XK*|di9dyNRm}VlP>!*xh)USPO=D@ko1W&Qc{0B?h2M5TD*^< z;EX-;!DROpe&xq!(C+O9w+)rN^{ZWa21Qk73|0jo_94vL(OFf*_5R) z5{o;s1D}Yl;sj-oO&VjyI2d~n6(da$gny-AM876ua-)^7yc5L|%rxtrieMw8JKPcv zut->zCgK=~HB`sx7tS~eILXS+i@=n9>|lj09VW^}oH+L~;CB(DmY%7`_VX|AUE7?| z=nM#073};KQTc6>h(2LGjk=tdbB{+x?bHj3ud8rdzMiNxa(v+LgR-tj7+s$6^Mje< zx^h`A2Ut*oq`mtU5#mezMZ6%)e^O;{CS0$MsZN<9fwJ=D%NGg#X-yZ1uGOC=!b1=f ze*{jd`=3F}!Hh;Q66eBI?267L0YE_B-kwvlFy8M|h<`jXST0*xS=~nQmP06_EF%{m zUr1=^YJR38EWOq?H*u6a7IW(B({42>5c$ZG7g*^S5f{e@wHdrYL-}mRH=r~gM>GW~ zFz!?LMYBs)6bA(Of(BmliOU+-ZHex;I9LM7a#nFMu5u##kH4MDlLrP+x=QQ+{a!Vv zfleYPCkI)H75o&W?%?6I9*8KgY8V>615)btcN#F%0-yT*!0!)$<_&S*=&X1f|NhaIU{!;$0R;`-~N>YkI%&iX{k z%gZ}1eh@I+O$I18=j&JOjMasX2;v;@T&zZitEX;cRK}BnyXqta#wc0E>}PTAZ{9~o zo4LD_!zTmEd}yX*;O745>Uu0H3YnTHAY$%aj_H1dIMw!o+>IvpED3I1ARH1gel!PJ zv@FCyjq5pcB(?7^vqduI{*O=I=Wfv!+9jcEp!rOO+rJ0p^VFOmSK?V0QWqBM5k&KxWm((-By9n%F3Yn9*0Gr zB~DdD{r$RO?oQT~P2nVhiY6!YU4RdAL6jGlVjwlfr?L{M{u<;b+pUL6Lz<1G zcf0S@DYZ{Lk49U-+R5P*`v<!DuPZ>_2tHRr4`$B1Gr_-9x{3oMAbtA^?@y%ZPRTD^{0 z!^D4WXzu&oec!cFS{bk8$+7E_z(b&bK^bQXj0Y;iB&Q`cfMzf$QqWEz#a`@yupWXK zBG6@=Y9Y@$Y#6h0asUUt;0sVq7|KcL9&HG9mSITG3X(>V!6+U#=YGlAkXazp{Utgt zDXh-ZXw^fh-rv+2E$=6&78p+!P5>o>E$T{ct6=(NSFbJyS8sOV#SEU47t1!JJ48N1o?qDp*# z=2({bw$Q>u~Z6S*2#tA=Sbe`K= zeHKWP6Y%ggw|{;ErU>i@49SJAlS$@5y}Z!z`LUIRGK_45^4vk_KPUM@vxN)DO^e86s$jLFGh4j;1&&sJ{+n2@VG0W^sc!}F^oQ%`#YwZme z=C;*I-m2lc@S@HW7U`q4$JECpVI@6G>AwW%^=P9r+9gO2)rE!h3Za)sWb^=V!nx4w zWnoyjOm$F9b%PKt)C(0-I?bHWDx(C5ByjrEmE0A_ieQAu(HJ-O^+K_4B<%&OTla*3 zEG#4gVT-OPU56fuF{nOimVKVtG2Z=K4i<#vuYVCn$)hN16JG3lS`O-+#Mb0z1jTT6 z@3^T7pSV*~t66jm4+ais#&i(IM6K4|r&% zW-r5M!k?&seFT%>c#yb=ShE4q4pD^qbEyn|M5l!m;|1_$D^Et2@D9j4rCynjBs;k!+?S+t5D*+HY9-P&kqX?KF@|MgcMW3@G&)N68pOrgj7c< z!`MKo4uK89v>3sHp=p6auuAD76nCEuE=0^?>eeu*~}B7zaU+1PU`p?Aj4U~dJ}yS zTkAkv$p7@-exO2eH=;3=1bw?pM#dGa354L$5{Z)qDnyVGBy-kUi-+V_;>M9XOCy-c z%fz~{DP5~&m|+dSfB8GqSXjpJHdKG)nckG<5qKi6CN%> z4=3pop9jF@emLTW0CWMQciL32$QxLkH&i10J9-g)8PtceWsW)oX7c&1A7-$t>Qf4zU zs$RKm`2(j9H4{LEwKV$9zwHH%;weHCETN#eBgTuW!bqDL9FUIC@xL^M-b1iuAt8y~ zt2^A7%-YO4D9SR?ZtB%EsNEbJN%B% zN^*|}tOm5~a(^S*pZVW-_0PVDVzru#1^^mT^b+6+@cTJpVs;!kOA>!yIoDJ7?ANsz z!>aOe#6Ag&>cPNp4goS0O)N|YR1)ZSUP{X0f){&Tk$T9x8fpI&E5QoiEUI&74irl0 z0^j81Vle!@2<04*t>{~DR)*~Ibsby&8Oq9-zv}T#pS9PRD-sT=d3 z)4DS!jQ0nf{xcqZ#EV9CMwW@D%rn#aqfOGZyMBuLjU^f!tQtUMgA|1b3Y~Zcd`Ik) z%*qc=RqhXy%!+qKpA>^dXy=N$)e(tk2$(aLp2d$Bt+?yuy^wI=mW`y?1m?G@pPU&F zZsEKLGIGS}2#m5O=SQ4@{w$~I&yL5v?C;@iz~;v7DQ(fQvzvBlEgL zHgsz;H2(tbwH?7=o<#k73DW5&8+&p!vKE{NPGlk^;HD`0lNcH<4+^Zp6dTYKHs@#5 zhYH-Enx-XqH=1UIspYZK!X)ttoHK!11^HizPwE&cH>L6KHaCnCG}^(VMrWKiNQzu3 z3g2*k8|Cr-@o+Q>9qR=%mX=S#hO`o))c|ZaP)1yqmMuRbZ-@t|8!Ro2^llATmf3hc z#aOR4=;=@qVA!CrvAV)W6RqdP z8F^|-88L*_L=Xpc8`46 z@#r)3@MYGQ3UM^GWTEft5f&D#QSF5y=bJ_m5vFk}lZL#l(K`^Ld+>)Y|yKPNdzg${|ug=kokOep6$ zwbePbP7MS#F*uyUVmRbBB+q3j-h~VyfOpj?$^h4^Bky#VNY=}%RJ-7kc zXKO|3YI*r;;t>Y|QX03Na~5!5cgptaPr3;Bl~#5m3usBH3#*XeW+9}~k#ouaAM2L0 zED9Tff2r17L+9pcFs*=-TJN{;n#G4`Nj;VO1RMWQ--@ot}q)zH!n z;d(DWw8%ia6IOp7PuVvpcpX#CqH2ii(AL4M&>spX5WauOz*@3=eq zU*HI(Zuo-s@5Z~Y4it{IFSQ?jN*&yrHL{4wvuMhSZd$3oNh2a{{_mI(2^GlO_5O&| zRFYwEo*>=z!5+s&H?OXwVA@FPOy5!GXTg&acfq+%o%BKGXT?UM;s-LaZ_R7yyTdPG z>goi?n9gXcSf3n8u6H zSFH5&9tPY!%tC@w(bcSt9mE=K%F3sTnV3ZF+8}V%jcJw=C<7---ClCLb=%UzsKm1J$ z8GIdb6oxSMj#ow~c)t63R+BGo8JSC;_3-(My_gH{)FvG$4t_%f#>C8arJ~~H@^hFz zJ*c)_IZrEl{=3%to5G{_Hg2V$>r2K+rjy0B0-b*Y%?XNvMt^%meE~Z&5O6nGj|l$! zl@a$@DcsfJ``qd0so$xo=W=Qmk2RX!)kojU2ekC9tfaB%xoC%ygBt*f92v^eb=6Cb z6y)K@^{Jvr9RG8wQk5w{sRQLg#Z@u*;rWfCW!DxC#!^yLi2OqAz@Dn%RP z?MW6Uc2a(q#{e-Fo!3jh%!LNw#is#|H2?PjYV23-4j-gWyiBo+@uL|gHxdI2g!7&! z8NsfB7+B8`>-u9wKJWyC?kVypaPw54HaVw#MhzqrNsKKqTO{B_6F(*H54*%F&TUGS z9#}dOnLn=Iqi5`ezh5IwGQtWJL|_6_M|zlPbu`zWvhQ6|L`Tai?#ZC{pK%h74^CJo zNil=D-+$~#fZ27j%XBr(xQ5Y)Cy+x0WUAWDE=KXJfKS1;95p5zZl8N)Yxo*+m3`}g061Gbcxo@{f72kUKb)R z5P`nA|M-dM7^yYre#01nrWe|BJh`%j%dUVK%$Y$O13o~njjlW8hTSM12Ltkbtx?rb zpkzI-$wdeph+}u&zI|AqpQ*a{q|fs9Jx*vYam+*sjCq#;rSI>r{CCh<@K0A*IYQ17 ztiXq@p!u8xv@Eh7^(V8ksf@AqX>s8CslAr&vAKX6;(vb`S$EJL;mHpSu0e zDB@|JDrg*NEYuXo@ae>Ddm+?{SP4ASO^fWHs4(6npt5Gy_ObU$yOK(Ctq<_u}qKM)P3n-Q;Kli;8r@WcQtIm0!LH zUNy3DNz$+i+LZq5$uAf@yunXG`!&4WZ?9e*J}F2%G>yPFD|To`Bt&4Rdbp6&dlg>`1xBD0<+I^RljJdh%@w2aws#nB z)n0Yyy~8|x{rdrsI39f%#^55#dL6%wj;9EuB@@NQMf)`hEa@u$E@4ANKKq@!#yU6! z^(BZ4Ei~N2_*oLTw$bwY^=o(IfN2e#GhzV$ptXE|QW85ZAmoyfyr4hl>^}jP=|fy| z?n|1{ma@nMlHy`7uOX6LZ)eP>^Qc8*ieZL;cd}aF=jTRu77r66uV_B@T(pZQgIh;s z8)@UQm;oP+tA0w)#3mBJzwBCzGx4h){Hm4)Jxm4vsm1LjurZnn4ASDRBh-T80+swf zREL9xLQ!ms$qd+R=7}5ArRmA@2R`#Pq$wSi@%p^*oN-ubZrGe2VJBqpiMu)q*y@W} z7E59AkLIp*H+}#uH1HM=f$q%;+fBv^1xASX=f^o%uIo`NX>}6 z?O#WJI`0ohFh}QpvK)>YsmD@b*4Tz~+{0A+P*c=9PMgt%%Ss}eL4y&s>6hx{F1w9P z4i8Ed;%Cu0k(ayOE^#gfA1yR=AhrZhVVm^Hz%+tqRx+@Q6lYZc_~|m zYj8S8QdEFxV47P%U!7VHDgXvDJ;ap$Ayq}?JT0&Sb*2RH?9Ds?)RU0|OG zo+mD%OOO|bzvka!}+qOpW3{Sg|p?oy=SK zp$S88r}Pa^KA#fY{IW~K{gz+9K5oFjeD@S*@3*2xeSakuhiC7g*v6KcV96*4_u8*0 zNk&%{$`9j_Z${Y5?5!%=3dPW|vPwNW$6i2*eh#^LSV^MPgZ}Uwl3wA(V3vajK_Y6* z1IfUf);&K#4L~Js@orjXuegxSruhQ@df+&%GbDp1$xM+++MtJDg0=2pViKIMJgM!+ zq?|k^y1l?ETdrrYSaa}K&Ui&nWA0cE@RQ|(+R#AVTL-)J%;(vWf7ei6|NFp3UKPmQ zvzsqzltJ(Lc9TW88sok7Oh|uFG3N;mo$mR)z_oP$ol~oN6SLk??Zam*w38v2{Jhk@ zXWVR&p~zTf4$Y|lSRg3FS3~HJ4~&olt_ZUUiwpv0v=AlLVzL(y2)ZO!&<{iwzfN;3 zXQTKUc2fRPr%`oQzRwYWnw8lqdG7wo+TQoNiigx`xq*y$aTb51E1`-&+)u zIvHS6=|ElWN^3WiLt}BPqkmk)cy@n(6wr7T#Kdx|CSR8_UF(ISt_izy1j-EQ8#cek zJ{{f1fJUGgi<;W2W9Yj*ZFl4V?SOQ|oEbY3JNZwFBxz6pAE3Dd52ysa`@@)k!Mtfl zNCa`~22Hs9aQDIeTb($mkG+HnwT>YJmosHx<@~wkqA(%CXA|z#`sBg%^|i5ruAp(| zqF(Jr?QE(;00Q>uKKJ1&dYq}Ero8SYYFF8C-T!PH0OpZHuw{ z30GmS>*ol|D^OU*b7_4gHgnBF)v>%UC7&t?OZ49kzxi4_G@p^k6pVrBVUgNXe^NkR zi22)*nsgQrd`uH~Cxgul;0AEeIukZVzZ*Ha_BtNQYj*gV%YWASd_C^#&0ak9?U|G0 z`*X`SdAiE{K{xyRz)2z?2GcU#_g150k;c$KoOzIid_j?JA)}?t$3QNTN{)$M-7|TU za&b3!Z$E(>-s^p9L7)I&4D|dfgog`AD9w*HeBwXbd*4(9D>ubhbBFZs&|S?An(;A| z+GlGCaq*PrneG|XUX2TKNKKo|b;uACta#ghfR3==7-G;A)7tn~@@bKseYw33=LY7|(tyl{RZK`bw zD-0baeI0&r9hp*AcpYCn^B?td*o!^4QxUQ?^x4UI-kbXMpdSrsh4$YiD`c$3YHk*@ zDSmHmV6H@IlVU)beY$g}FmN+HAE1ZIwsii`*(>Yxw#`2GstsxPTaooP(Op1Zi_K+y zSnm9E{2iB~^N|I~2*=vCZ@eibb@y>YY-=4WZrsG`e6`UiV9hY@{Qk$)rRu}()BWl% zOTxiid3t>y0poR@m*0dIku`cPdLmXLVFb8^^`(-HY)?sEsKn4R;RO3Cs{e|=;(|z} zC`)idI}ZI$zLW$SBMHa`9flGmI2sYA$A?9~dzX!a<-EhhbIL+&75N%=j%%ejH>8hJ znfKcsT@YWo+Gx?Nv)pbr-l?)W;8|ezQLZ?f7(2Vy%4m$giYvc=>zy?KrrYEsBlqnS zaOUxJ^-aL-M!v$)Qr&i9)}LK`6^=RiK3YDIuXPKoj9aQpnn(1NzvZ$g@SY;-l7!bwg=zqY9TKPPKV zJn>S%JQ%?djyhSE-5+Ettp-*#`?VlU{nurI`gNBDiDC&o4dHR)o4~2wrM)pu0J4BW zCs_Kj1VH#P&j}Oh!ZNtJgYy*cqV|KJ2G{6)l59Ez()xEu*-V(bu_$$kp-k`>)Zkav zOgl0dD~V4gqR=W9D3Kl6k7mo`5Z`JsVm+h>t4(L<@6^EV$8;8=Qt^)?bp2bc z^504d&mv#AbKNC}X8VyRW;|38D)if>H`t-Y)~b?lg=3A>b>Y3qD&6%ny#_qo`E(Qv zmJC*Yws?KRbMQ|wg?<%+Y{2CJqAdYWwwqz@jPk?EUzI*H&u7uxo<2^HR7 zvd*BCMbLRUdV^7|8f6#{$z>eXT=Z#`^vW!btlS zXbyZi8t0txRaR6%o1}Wn@^!S0XvZ-1o8wx0($8B_sNu3}?WPGU{PeXruFuWwpW zfB#M~a~_Ry2?b9LGm(JvnY8m{CRV$eB!=XBSvDXYx{V6x0u&Lf01H{ApgwI%@f=wJ zRK=v@p^4V0KA4KTIuW-(-Z**oHCR}jxyz59r$22ew6Kt(Oj{4w(Q^Q6po?qQ**WYu_=4e<7)aY z*H+5wZ=hg5Tc##IXK^=)-1jxi1`Ewe+Nux}cYMr#wm@;X8=H5$Dq_`(yyR6EAV^78 zixsEzY(~W8pH`52|yvVWy=XsBeOE^8Ayoq1AxIUDyyP}pb^CG8=W!A%# z1yB=dCs@uxQvwmd8lW6V&AUcmLe#uITmgg`sYniyB@Z8oc>BkCPzgpD!a8K1i_vna zvJ`fN@AxZ2KLybKw*Ni;d414VSVA&72QL3xx+K*eLB3ZX0}47k`xl@vAk zT37DHi<#ICkME~W4mM?v+Y=8*6Kzk&sZGbSvLS1K7e&##roTjs?v3jIX-Jk|ia`ZX zkx2wzJ&j>FtMratcjfv90y)WZDODvsy!M=q4#m7wt`@#qqQ3E~?LLuQcttMXhp;8% zq=P{cdLRaCgAaZPzm|LSwJ)hN?9IJ{AW0FoWNdV*Pi zAx!V$#zsuiH^M6zH>Z+{HDzjJZ8&?}nJ#7^4rIHm#vaZNzq1NC>~#H@*a_Q!MIDb9 z)zgVdz31I89@#$fGb^ZYS^ShYf=9ow`gau@jueH`=&R;##kf;9)JKnwAnHAKK~x4XtYFgf-ehw)y++1&Pzq2l zE5E4w3xT~4w_H(49GtRAh?5!_s0=@~*5$7$5O|$NYG!x$CY@n7VjWUm9)McX&q_YpZU5=?|NBn%=_0qkbYJ85WgZMEO=j+j9PkbVYR5Z z2e!`&Dtsq8jKw`GNG2}HhW@G;@mwiEs5`4`BTxy0=@`_~}@u!v`S+ z%M_g#ZjrOED;7cuwO)~Df1mCDSo5FoR1g87=6~G$a8)Sq_D}2Uk=@<)yAz5RD`2x= z;LQDgqC@rF&o9{l*OMK;Ii67;)FM^1*K5fXim-x7q6F-Fj{@RE3F6Lu_R;JxZF{nS z^daPF4uSBzJUl7GgTxgvE)m+5wI$H+BZVt0(am>?T*^cdea6?nX{JoRlaqtxHm-^= zlq`{(Ad7P|C8cr-PcE|T>u2A;X>&{u)s8mbjuz#{Oz-1S+v4vJPX+Ho4o&`k{#>*f z*^GYA?f5=X#)n%>7}`q8HOs{+t$DvuOSAsq8IWL@{`L6D{|*?HrGY*v0F{_={&qD~ zF~C3V^mE=5>h5-}NWWdu#ymK^wy>;0`RfJf#U6?bN)M@;o5{aq9ELraty& z3}9C?r%sMI2pW>DYd|SZ6#kr?%BsR#I{&S%W&0MH>&)lBS6foP_tX6ywa!$xK^xd$ z9u|MUFH80^cJ<5N5s9w0X+Jr2{0ZyZ@)JJ8YvTWdKL6xqL?;9?<1YBTet%jdSXy@n z4XF!T7uo&h?M#4HuN=jG-Zj!Z?x%OQY_E3PHPT3o7V@*b%XAx!aUO*-@#Ycr3K9vh zWkAhJz;FzszB-TtnR=fqrYNCoO*q(M@#0K+vbV#tJ0a`7!<*iQ4k2sz%YA_$yt2Y> zWBiuAHNV8_c&?=XNdK3%=R|EJ)(i63=Bu2)gxSQ!&9z^0fX8JA1MH2^GJywWvdO+TqMwu^yOKLrMf7we%74^fmM(%5Si=841eRIXsPY14_RZ z*KS9pRt*2jN*DhzV|3P;<;p`!)c&kX0PyX=r&E4}LMPfVZMnxik=&8Z$r2U4PBgli z^D_N^ZY z_De!~yoqlFJ*H@XA^FEimDRJ#CI_V+o>t3O=jOV#hS*^<4UTtr-9}(AKdJS2(34M& zYfb^{G)JkaQgyaSCWR%#vxd9%A0MdOZzlg(5jIk>ttohmc=8x!DyOsX^ncym&B)A* zZrO9KZTLpiUT5MEo#qNYua3T8=;duRlZ}aWh&eE9>TksDm5b6F6^Sb)8o{r4#`}0I z)=A@|;1t`R8kS*_!+rSEL-;cOa6;tow*~ze=3yRYsd{>_!uwzjWFlRnC~~hX;6H!g-zIA$TVqJqMaM>(Njx8MxMCy zo)C0;KBn6NZNfx$OmptzEuUSD=SALq9%()7Z$zpdoA+t9 zu!KAFtBFs_3Z~Z{;!pcmZ#MgJ+~GWHabx%_ECJ1E?&fwICOq`Sh*Ua@JG629=jgWntn>Ftc*A3fW# z+aA)rtLa2)_i4dX_jYDpAG-VeP%I~NYuVn4><(&Dmg>HlHZ5L$F~YO6=vv_b1|8Atvf;NE_wVCuuD-r;wtV1#QdEsm z>pP5$Bs1=m{A^#8c7u(FG5Zo4;unvTZ8%aPvaVMA&!VaAhJp^}Z|2HF<1AcR98=Rg^qdKE)DW z4&U9N0$oiG-?ETXvocLz!9=*!;3oltDafozCwV{A;j+e%vGPvbWfG@TB< z_fz{lOWG|BMt(PcFxEdldvrVbh;(YapWqFl548xxU8oa=~x=~sx)qMGnJiKWVj%v&K|BoqCsLSm_{lG&!pd`w4~A?l}mBQ zSNXk}@%wk&eI%-FOJZS*-X{C3#wPnPUsRA4|3xwV?TA$+g?;}**XrL0hTG4 z{^PE~<$;Kw*V)#5bi{T}vp<`p&X;H@;YV|~*7mi+yQ|W8#}$3gC_dAi+-R;b`F%=i zA*4{-KVLV0Qcr4b;{`>(HP}7M^_TR!s2x1*_VE{g8h3hlx8$;S_>txpm59(MuZz?c z&uVVT$%8bhtGV(K4yT;fg^$^pzjU^5zi?>jzVYzjZp~)*ZeL!ki2FQ@ub~h{DN?0V z_hL_e!${8aN?m|j81nluBGCp(Ic0Dn*Uw!%==e@xRj?@ie|G;UMjehGhdpO0o7V1A6_erJQ zYu|$Mo2#jIyQBEszDoamuCJ)yLHSD6vMx3azQ&iaSrhoOpxCd6(V5Mkr)$L{H}^L< zydomR_57|bejY+wTU&)~Gm+Y)KU5No_vsa&_0(if? zGLCL(xyi`Rj=u@(-}zDrA7=B`7?>ID7oRaACG7n;-P+bP*p+X5fpi;I&*^B?J|v@x zHXIP@cYcB$&b5EDv(Vb7q>4+Vm$Pp9Xn3&omp+k`@Sl~1N)ypya%9EQNL1@_;{#7& n>rXIt0sQ~x|G^(vMLn)|i6^5h7({&j=k-c*ui#%~5W)WoaTAvy literal 0 HcmV?d00001 diff --git a/docs/images/web-ui-dark.png b/docs/images/web-ui-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..fe2a1dd40de09207c96fbcd93a7bc40a092deeb1 GIT binary patch literal 54717 zcmeFZcU;rWwl^BPD4;Z@E4}wnq$(wl&`juEI)rAZ0t!AV5FoUW&=DcD(0fN7rT5+u zq)J!16yc3qefK`k-upf0-uwP>Kj%1U>o;Z1tZ!DC%*-!mV`m=$Hz6P}2ypHk0C0}* z0G!R88v`pSm_3APg1~A@KML9agmh650B~}4cZDg--_fB*b9 ziNJS%>m;P) zH%UmzNUvYNdFv(_1tk>~74ePR)VC<9$tkHQzcV>^fzamSC8A50h$u;}lTiLYPG^4t z$gZB}zX-T+ju~*C?A!&ib7xHe1_IpYFPtN!U(y0DUcPYY%GLAdhzP~HHvxc4=g(ih zbmjW_3m30mK6eRljzC-@yG(wCf{IByn(~&ARzLFtsCyI|b5&SGOvk*WbYO56@yBfz zc~)1qVm6?tgaSVTLixJg#P~4>)*Tm8{f-Ut`bV`lM$@q0s*qC z7cO1CeEtGqXoONSawegR<`1BkD3}p{M5TTaem6@g4=e7!OvMV+vbc4dMZ~rAMadQP z*4YGr_yR#JvI}GYIl$JCVL4EWnaKl z*sJ#zp+*~yZtg8v#3ke;r@kW-RnyWG4k%*xKXE-RN%;1l$odR$;veF$cSCQPW5GHQ zSQxOn%U$m0$1o5AtHc+7Fmm{Vt1ODfy2OpM?SL~_53JvYdR0$x@&}bhnuW1e=E|U; z4Fj$!yBqY%{+etQQgCi$j+{Za4jlY7B^GJg&aw& z)fy~pyd*(wqblN<(6(LRy4K?!Myv`>XV(MC{RB_#DZ^eXLw@9YUCO;;T`>)! z$(54$tX2(WHliRyzJw6b1Zso9ek~+WYSk3>?aA!>g#8m zEB*xbe=xen)ShX|d2W?n3FkzY~K6h!2st0u;p9ZDmD zt^;JHTX8&9jWs)OK1Qwdr1~w|y&cgvBmsebQo~jA2)^40XX)ltT6*N_qFPez<4&j4jfFHVVY1#CfJYLRyjb-VH0NvX2eV_dmGJG26I z4_4Q?rDkUrtBFIaXIdraxuQ_LCygS-Z$9UAI}cV5o@yL9^eZu=_N7~OK+N4~_s#$c zAKQ>x;j{xOOv8*YNceH25jxR$)3ej|y&NAs#dd6?Xr4?)mc=8(A@A$)4+?}QlAP}` zY`^Il?LwDmD_bBqmW1z|Q%*g~O%{i$_2wo<$7M=nRZRQWht<`kc$j4z89md})K<<5 zMFi(~=QcDRxHarNiKQ4>)2ZidHSx#*#SM)la<=%Xa`os!p0RyuNGY@ETZ+l4p=gC} z>D-bw5WP(O>=m;CZ=d2C+_ASErm+AK;roX358s+nvkv1zDqanV)l5(?C?s0ss&-2C zm*IlJtfHB_3@W3py$vnul7@!T+GJUzw^+Bk5q}uIl}}V(n$lgpsD1`G3>tH%9A)66 zG_G7-VxhI9AdBFA^6cph$LO$=-JTTe>ONMW)G$mpW*XBe+7%$da`yEa^IV3s9q)P8D$G-r@3 z40%*EX9KZn3${{p0Nx!^G(d$u3oU7k9@x#$#x-X(hB0#6Z|Ng~m=d&|+Ix3~W^JZz zE!NBPtK1Dof;pq+`WHmie0afRth_NNLFC7|iZb>zZ#uc7Q~W%K?2Dslj8$`%&4^%g z+N(T~pFrGN*F&kNx1(7jCl>gWC$U_H;{JQ8efJ7>M_gJGF-vl4l6)TGjvBc-7JiEv z{r(-LRCeg(KqlzjL6U?^8tUrkXQVvFE|s}P8V1(x*6Zcrr-*=FtcJLW|K(BGy0&gn zQ*|_TVic&FAN=HluQ4c>h6b->!8~Q@Brfm1jBPKX(!gkdbF~xG%QQHL+36f<#|-6m zqH+Z=CY414<|a3b@@R}b>uJXHF(W0J@6fX)v(cO!3@nZZxk6lA0?KyFgT$h$_7SH# z6bKuloLNIglEyJctRW`29Md;};C?-)DMTLTAdO_1R#8U=klVy?N6)FfSl73OL{X7J zHCc1D-?1#=8Fku~CVfLuPZ@&X!*+ZR8sV<;Mf;=930;-i_!7$WD4?E*6x+Q~tIyJz zyh1>^S3~$^KdxdX&9d=ESHte*Ty2(TZ5xX`d`-Mztg0L35l=qV4vg0eiF5TxY_yzy z!+Gx4B#u~Ee9-TeIXrS{?D;6CtqYBv`E=(czUwb8>A!S&Lw*ErD4KSX!Wq$NkvuXH z#yW#SbnmI(vlar2xVP4Jc>@C3s1Yx~=l8JbG zZd7UaLVR6TW&Ct^#9ct<>ox09;O9WQDqA(;!MNu`wBm>C73L!SJ7NyfEe0vR-mynv zR;Io;tDhE@dA|^37R>ol!mOAq)Sh`F0f$B@LME3BcroRNa5f20niLOT8#2^C>Ar>p z$S5pXBginLVqro1O^w<;HYjouNS^25yvDp8T~|2nFR{zfk)kL8d$B|hx*9=}5ZZ=^ zM3b_NFh6fkg?=#gqVh;k9}oeLdpo0d4^bCCcJ{@Uf*zA?`@N5jZ@if{XIR$O-4uNp zAyE%Qrzd34##(6Q0uvsBd4s_T*gC8JC6wJZP#~Ojba`k5u3fRnmJk|!^}`BZf=Z$& z+oZSyqxR}(ewQcA3GwMM*~`0t>rBhN=-1~Ose6f5NOj=Jq#3%;a}ZjIG2`_XhAAV9 zjw!Zc3u&KHJU3dz#^^wX`~}Oeqb1!lEi5k!Zotxa^`=YRHVPCBybcA#%Ea<&OWBks zG2ZT%5FZ@tRl~}hUNYI4%78mW`D11uW)Hm4W$6`(mh{DILd>0LdlnSo(0I0cPM_Xx z>_-)u2IyqL`KdBR)E%HYaYLDJRJ^mDg=5<0O4bT!Vv04$G9ZrI<0iP)=Pa6T0uSfZ z>1ILPTob$8&U8)J-c!*GW<%K$;)D6hCnTf2DD7cU4NTeJWDy)xc7sY^+(mfE2j~Mg zSziX)X{u(ZMB3O2&6zt(kCWG>=W`=?G~sG>qdeZ)7w4XK)$?ngkRXBaI9h*gE~x!5 zt*Qsn`XHkL*Ep$I!*;L!78zO_6VD>7?IrwnoBm+&`YZb?4pr{Vfsofo!hEXbgOudM z06Z%kl4v;MBya{0@gBzXmbG%R_zy~M`+*<$iBi1%v!8DCDw|Y$I{UOEC+(6ezJC3>-`hBY8@QESers2; z=eW!J44`?VZe|y!iW`LY?{niYdgP_U!fDX-U>mR~jYNqQ78Snu?W$YO8Q@zX$G5pN zKos$$dlmb$#naS6ESu|s#7<04Y4v2055o<0x6HHzejQPZd#|kI@I{19S&AaPX$|A4Wp@cV*GUX%p&&m3?L0ad1;sqygTCUhip}_1jB4X zhAx%|PKLOdBJ9}OQ4q8WP(s%*_7o?Lmz}&e9S$^mk)v-l<@(2ECs7Ytoakz@ykCJ1 zQ6Tb2Or9;u_<*6CyURDEvEwd57iC^&yjiXUQJE06a{IIu!npBf+finfC)bKIswrAx>r%@Q(DF7tbxj!2m9GWHpwvI_@|#WQpg@9 z-<~yA#>MMDtMOw`wYXN7xgZMluv)O8oL6Cg&6-z|j}yO&_2ooj>%tp5?|!vV9s`k?I@#&%b}i z?}BjBSMJdCV}qA5(jq##lsQA(L$a9pFS9DvaL!y9Y_?$a0eM)7LHuDpB2VK=zoHY5 zy;!tZY)n{?c_q?5$3in&luz)bC%3kP-1ao$JqwGa?*(ATxGfn-2x>tBE<)a9$?2}_8lu6C__8yWo zXTctrThw-}qA{8APUN$|9w}*VR>AJEh)|uzhb)P&Tl}X9-^45@P&;%7DBIc2)D=>! zV%GZ?ITn^o&5~tVxQ2Xjeb&2ua|f?=Xv3_XJ|rgwi4~jyCL;V5PswR2RvxPzcYaea zRnWZo=ItZoI(;h~BmfqPi%3rlxbx2sw4U1$&F{93BA zovLf!&)r=K%2o-z=Fl>z2~qUmdPN%y-Y{Uzcio_myMmXhYxCK;v7D>aUsn1s9_gtr z`^T*aKn^8#h%$SN+f^GQIjE67l(8C>_c-L!q5->az_|`~#ztD+Rt#R>GYHyL2A_1- z$12s$)~&g?C)ODlv&Q3CywyUQYZfg3AQ-5Tfcyz=*X*TW3`rwe5YyqicTFomrGOF) zTKy1(cj|U+J0SZsifgYnAev@BNh-5UOR~oKbSu*hr@bo>5goym?db?3p)#QWB+Q=_1`9Lw5he7VjM5NbRq`xpTDFtA(ME^_`Ou{kK0gC;F5Ybpm6 z@=g=cR8=w5xn@WM%xA@B_o3MY+UrAm#3jU)s;+s4Fn9Y!Uz)Hi>&V^9Q{wgmm&JF} z9`U+Ys4~ykR9fji{bb3s2%w7FtT0W>S)RPC+=s)8W$zATvXGQY%5rkGxX$F!rK=*H zK9wU2lH&Ol4GKiDA?!rW`Zz^xo5y?XVT`p9=M0#M=mGg!3CTDoXLZb6@WpynFb}qE zs(xMiBf}rzOQs!7H4Ob894bfB8MS>0K00t7ijN5~@9r^ZNW_ANxZuF_V3K(L1^*>3 zj(VxGU1P4)nw~i9JtYW;>dgSlYnn($w4-r%+;I6O;B3j`1QR&@;=50>-#MjpAQ!FT-s9)Up3_> zp||l)6)rNELTj25ko5|b%)6C%uv<6?G_cPR6o^aXyHu?g*ywD_DrOIkvZdH(W-zf5u{J{Nc`nD?E707NOXu_zas(650VBTqe=;G-CuMcl)v*%l~0hvC{9Lnfl zCA0k#z0TEdqS^&Ew+W&}aJb{S`4+6KKp>MCiq6}*6t_gKX3KW4r0(}+#@LzaRZ2%g zU7(z(wzjTKko6}rAxu*_4>Maf+8eE0wc!wX0w53aJY*Z@5=59-<;Hm?8sb1NYSItb zV4kmDwS;5&TH+xQEH;a6Va>OrErf-qB}Q11uVo?O(Og9pPLhgQCSliQ{lW)gYyx+@ zx1*xWHpvK12k=2+fFazuA~Q)W#=hs}l)aQ^)M48rvasz)z{NM@=9;cVRf?FZ!2ny@ z#|2m)xibJxYvfARlc|OU$v+Qn(8ZnvY6TwHH63$>TQ+2ip)^b4mTHdzL-TGt-m3O* z^Y~+vQC#4VIL<{!mlaqBLUt(_&}x^_VsI=Q%%U`t$0Sbz{=!a;{rO+B9=%6ocOeO( zp;ln&&WqdnjI;BuXMo7H3sch0X4^C`i866g#$6j#1?T@oS^M|tPke^bnDvChm!2i2 zpF<)ol4)#NBxpdKV8Xv@_U3oR-|+lZ&weY#Z=3li=ktGEDM%h+hWRab4?a~=ePU8J zH1d>xXfp}d*+yf>K%P?m4=6p<$?YYhUKR~ogzBcN;c&@x22?X^Nmc`#KvLKOd?ZgCUfsY12=Eqx)ct-Gl1Z+FQ}?STEE1k(L;B> z1DFw{LuM7LuH=r^nA|k#Xv`VeZ2&iy(Q7gmUd|@`9@$!An$HwxV&7(3)wT7~itM(r zf$)w9h{x%Cc`ax0hq&@*InCFrk9SILvvJu)=&KswSwrK^5TEN`o`0$SelMi+OZ-c< zSfTOEG*qAgENs0&iZAq8-Tpd-#qtiNM*PEII?`cQNLD;$1ub$e=3Vke60#t1Y{PGo zdUlt=U>Dh{6A z?PJjLU@AfU7QD?Uv}Avs_Vf>qAg?JwYJlxB`4g{ajimo?udR)hC&75fDom_>0x{C! zX6%EgH&c)i&WIqIWj7v8v9%0RsY49fsop$lv%Fj8l}T3Bqs(P^1JqoT>#;cyI^QnZ zg;u9ZG3*;~eikAsmR7t^^1(~vYc%;NPWOnkK#Oc9e7xc$mhOS%NOpG_zLC8v)Z41q ztYRM6Eve^lqtmr8aAi*eOUrVDX~aZcH+#)+U=~ej3d78WnOg1=$ybGuTCiy?slb@a zPV}sWtN3NXkr~Q74OqF=4&`U9D>PPin&hqKSXyTO2h}vyWMoY2y9!ZG;JTDu@>15f z^TI6UErxGng~ALY#FCt)sPF>|oiSD2_-jvRfC+uJOUh_PFpu*_)ws%_j>n+ZMqio; z485StO%XX5zqD%!No0$0U|*FdF;FS6ze}~wi*IV55QyGQQX!xv=3<4QzBp;YZ4Yo{iVuH4)AgKC4ioayg;Cnb{9Nc{JP&_mSG8tfG{fjKuA4D2QF&Ja4TkkMFE&D85k2d9B(xrSla!q zxBC(8U7DkduNh_@H@*SSemEe$4ETNh8;}11`q0`jCp)38YTcAxtF9t^m-_idr2DuB z@rPSH+pZ@Ysy4O$MmO`iv}mwt?D!^@=VN>D!hP+TAhYKlzlh$E$y3h5vOPVyKtJ`z zBoVrV1wCu^uO45o{GH0LJb~`W==9E}L>pgN8Hs5OacbhKB=>}A>k7-&1+@)F3XIug zaF8sw;Po=A`?+oP!YI<;gx&*Yni`~|j`{6W-h}3von9Y01Dt*gJp+6lxN=92raX8n z!T(sHFe5%RKH_Tb86XdL1_+gC*f{jtdUEA!Y3S)p?C0Chli!Ri^RIxANh(l{7-#N9 z=?(g+HlGr&GeESg(Tqo}a_aKX6l0HI>OIrdk~Mzw!;WNfpro%O@Q|xs12)1f8RO-~ z70?UGd~u?O9bSl+3LfXo!@ChKU7FZmMIIu~~I{&$c5zXm~CeS;d7Ju?># z$u##eMs~Uk)Ohf}o)4T$a^hx%xAhe=pF)V+DpS(E$Ly6gE$WtrTpRm6S!h7Z|Q9dSN%S3&0e=VB6>zjBEgy7afg1jPtBK=g5$c>B)kl{r+lZsc%Tw_sBgc@m94e4aWQewnxaIgWKu)MbQWE?7_k(Gh;V?vmw z3gtkyqIqn_1GgL6Se7>XAoSYg!DrrJR))5o{aw@+?(~I;;9xGV}RGX$Kog69=h;0S;JM z{8T|nmx{1dL zX>h$G{#o{?I=>5R`BYk9&K&;ih`v;GoV%^Nw=u_jQOKY$j^1{t+(9?MLG%^4KFEwuZ=Oaa~a=J?6#FboS9npbSGV@F1@gL-Pq2? zt^=L}7KJj-v$7^VIbA|F49R%M(%&2D$2Qe>2~G%C#a0JOF1lS;N?U&M63L07)MoS( zw$W(jN=UCgZ>|cYxH!&<)&;X5(z|v(u`o0BZM`K0#cW~abA_z+v$e~-)Du-AVS@=K z;Os9C4{4URlho6fAeA53{mhN?gW|+c1#Fw-0nN`K$CTiW3f zFud$s8XHD1fSlI5l2_BF+XBIkjZa5*J{gg39Ft-=1H3>c2jS!V{*Z}{!w=zmIg_-O zqXc+JX_F2+SmyFqJ zoDvGG;O>cbvA&B=@89ka<47&btPuik#6Kj9P#+ZJ56zi?>)tS7ySY-fDrqaq6tAJ; zlPmNv!R?{F_`^h7!>&l|-ClO%Q6av3(ns)QBNf5r-Ft!`UQP11c#*R?fdZ9p7_L%g znnBBOrn_|U9W7uztZzBT4c?8v2}6S83HFV%91L6b2gFdkFEK-P3Z^@H60kst!;viTeRDTaM>a?Z2un>js9XP%Rj0E z*`F7~{syA?kC7+?$p3?4(gRd}SOVSO0BL%B?ss$QAC~kRI)d%}e^eU_bzy=J2eCx1 zqO-`cY^ow`WXUL0L|M?%9oM*F3!xDM^f%t&7-Ddnx!ZTyk)J}L7v7USM8nmZXo0QY(-Xk4CFdRY#fF|yk3ftn|` zHSpD*n+*<3Yt}GH6;vOpOL*w2wkoIZigfqb7 z6N}zd$?&x9+fHg0+3_>Z>?}J6UVfEcgSU813WnQKY%IiP;(8Z9yFO=-ksu8dV9kD* z1?E#r!Ys70cayf_vD#T3)2m;0apy)1 z6g0q@Vrv~>{gHgj;OcMt;M@E3SA8fJi_ZW}HH77JJLON(())6mawR*WK6IJ!r?+=n z_tDHU0z-=aHwCnj5kqAUbRx)N*;JIAc{=Pdv_mTFcfdK#OEqY{<2I<`gbw@}$&O!& z&{s_w{gKANm%^uw%Py0NW%j`{LULTeC$C8oqnzt?Kx1)-O|47q!!-@#Zhj1Y=YA0v ztWQ}j3co49zG9yQeT@of*dtM$)0yKsW%<^in=*R__^|8XQ>k~%@6uTKr{pifv7rg2 za|XzUn~@jZJOhvm>7AzHpF-*sPLz-RvcCEsJfl;4GBH0QxZnlLoUutHBP}Z_iOkEW z>g@7=JU;it^)`|N&nuChm}SXI6BX`$(z?*D9rW6$5N{CHoUWT!mo>v5o5-qvz8~FK zyGi{`jpmZ8L{B^o4ULuDxzwLENq;mHfZrA_$E;ZuzVaXQyRiO7 z7DKK@HODOV8JuzkShlNKF*!Cg6KpKN&Xi~D5W7#U_#~Ds7i?NibtG2clbYpp-r#C_ zs0$Or_)5gcEMaO5Bl0h)+l389q{w&+{HGk*=0fVeu34yq6uJsOF*%5^&=!vl=)X>w z4o>-;vxPayRHAEor~K2NT+-QwQA{oLtC*7>VMlb-(Mh2~E#e@JP{ z9Ww>oMGdgG#Y~bkFpVaLhZ%7qY|@;>MXkYi%#FL&P2Gf8oO|bV)&&5QrC+hW*Z(Ac zao+Ps%X2?DGhMv6Q7ad$S5$Z5XVshcHGb9>TR&wpegEa$?<(IR{Ef^17-dk*fl)4M zFvCC@bZy1A_n4x8n8vxUHA9Q3;CnnBX~mNso&8mpi9*=ap0;g*=1{1H?1NA3QA1Lx zj&f0od3Xee<+}9hlw3+$W8iL3aM4p+mVSq5eDRd7hbY55gv2z_)2!5gN>=$;eOdK& z^76{ch8|^?4n+gKnx9L~Y0r^Gg#4a|S+(LYg<8wh4#lBdCLR{;OM~rbwcH?XbuiwT zG(RC6x}qlptJC}(w=Tad4chyL!CcK)9h!YIY0GWG!C;S3|3c-_BRS9+AfiTK7k=cg zx9f;%+f=qZcd~j0px%ul_$3GFX2NPqYkI^tRf8p-KjjvCO-}3Ym@WIaez<)k`b;i2 z^=WyM{B9xyq78v@@u86sMSDH3&j9OI(nstgIeXVOz$@iom+qvMGeF#KKthcFP?!9j z(j$)46wt0%4J4$}i${EvtcU|rji?&1w|5xze5&n{T}=>g zE`!|D$&oNDKaa7(Qm$wpBtB|41Mc8ilMi@YW)Q3EdfQ=tQl}{EAH|=q+7r`()IzhB zY%-gMrPyLEQ_E-yB+;lfm|9nI7rMKyR+*&r$lQz4jz#$iRP+c_y<52o!MAvSQZJRC zdNfZKpB$s8ViM|SRx`(JqlI)U|A+#O+)?s&zm~@7a9A!X{}{*ftWqjgz>kLJj! zXfM_vhT6R^!<`iEeOfUG{;JNhhmc1#6)}&)*>RTa^G$)XY?Ff=H5GE>qM$4~qgUfu zq8;mKZN*${qsW2<;{%Nd1Z0c0=;-kW6P<+^%M8qIA23znGgIS{isLaQf1*(q_ihi` zH=_!XaV2ie25?55?TXr1bZPN8N8P&RC`H-UbL%-ZBh@TRqOZ?9@fk#Ht&09)2qB4Ukcn~$Ya7? z(VJ@QEKCc6>JVLP%So`1K%jFcS~g0i&j3&Mo9Py@e_X?x#bjmOcg+vZ73JKl3d$$T znqLT??-pOE1En!**(Qv>J$6|fCJ{8BhzVNGYZ)N1dC8s}pcgdru5Xr0T`kg?CNVI> zB;RmT6^1H}!iEmeq_EulSPHZcUFmw~X-bvf4EGI&Gf!tpziKlKSy8pI-|lKdwS^oo z)7ES<8H9LA40d%pgT-ikysnPEnbFe~dy z>1)?}nPg=d`Q=sWT&#s0CuxxNT*9_l<6CWsc@j&M3CNdZ$P`~r9)}z->ApM9HeiSv zq)+G4h_(V5VQk;-Pmu`+BQ^TOXwygBRWoT{9XWza?IW4%i4KV~;Nhj>n|306qs3-} z7Q3W6REJvW<%~dGD-{pLzzH}V95&>OLnbhkh}B9_(Oc(PbE1$#>U=jvG6P06>%P2EK7AmrCBtMh+%-uj88%>J$Bqdl zlX}|}4O(yQMeaDorg(-X54i+5><0F`)r5V?_lsJFd-C@iSF084`JrKPp2_S=8lr%H zT2uU|?)}ICBNh#tDXZ`mFz@8dl2Bgy3dMP@vA!D7TZ#Borno&W?Tac-_*OP<4^8pN zp^b5H2DdPjwb!G-M$JojHc_c(Rs4PVkzxWuBe%<$l~WypUfc!_i4A4wqk5XayJT^j zkwTlH^B+gj_>;kYt~UA3Qp~6{@5YshrYf*zw*%BF(Pywc?4G7;fEW2(-gOpL_mFfO zbABY!CO#kZ92{2AHhW7Eo+x^2*9Ay6)8koPlvK^%=icxI_msyhT_q`gw^=y;aRMqU zL181hXi~#-L=V!jG7U0nYxVX5`v4Pl0|N%Rgys}{xRkspfrR74eCjooXcZO@uJ~L7 zbSceP7xHt1ht@y~3eJsjoygE(tJL`8<{~(qi$pRo4POamC~@q@jf}O0>grZv3>>K= zfYwVgX`ejkW(~hFt1a|qa$!1O4OvSM+;QS>bYia<`aXbl;c4YhOoVX;3wpTSn5}p` z_;4b-*`70}nl=s!(VB?qGw3-PL09|AE$ z+Pf^zCuqX^&j25*Cfd-}@wdu1y&WAn_|L)Aj-*?eHC_#Y)uU*~edz3A&WhHqz{9q- zGeA|-5MBV?UDYL_qT#WK9ADH-KS^$`tBkm>S3Dgiq~xg%H?9!PV>blHt~emvJTOb+ zmK~iI!*y8BQX0bDhqcaHW&=IvUezRUg=E|}QN7Wb#rJTz2|7@!#chQFweyA<(6b2a zTty9d4=-8PhzN)~{Zwm`pRlm>>xY7m1e_K+aM0{@CoOh%3J8w8yHfi-(JNVOWt4;J zD_r;DVXxRRm4HHAE1-XcO3@NxM8QsvaaULdyKdB3O}!Lh{*db;+-GV%)+W@zZrp8` zEq)Ey{J=@bDqp>1tI>rgM7@+;lYfV|d4q^#h*>*U)9<=kk3s@g*;uUI-ed#QDd2RV z?-imORc1F|uEWm29WCn8FyX;edmeR;Wnf)hbq1)@`u7y@=!{lxBJ|{T#P0 zkhA!%lwppxtrV?sHn&<3gmzOu^_F$Z^jB z{fS~G`9E1L^+h%gyXp_1ueuE?zu+Z%elhtc!c1kxn}4$a5a3_51%M~`y`XQY3J2(Z zS?Hs4zuEo9?k}N%`u|6Ya!03=u0KXap2U$2!rljFk$QbhrVq||v>IS~%?5}V56_^z ziNC>C*P>gGJa$6ds@$19s_|d4I1I!OtX7G|_Tgj%#}T_#YGMvRnrswuW4x+G9G+k) zID#CO!15Qq%7R)@W`zam_o#@rdh=V0tk>5{5yNAtmg4O9O6F+XyAly#VaUd$<<7(+ zqOaIPR!4xSO|7k0QLDsoIAfQV#FNdm=~+cJ5s=tRDdVG$v3NolcNT>iwz^1*>1xk0 zcQyHdeRV1inKQm1sa@MXNgWfrh4c)w9KO3#@{qq9szU z=+fkNptNbVGig047-LoB6Ik5`#2Px-dxgu{trNLYvIbQ2&j0}a%$6qzQs9#u8%em} zP=z75H*z~tg_XZ0Gf64Ws4~WCKTP}abB4@_bYr?(S?bmkIy_cPM+j*R7#*Tp!^6Ec zyALkXVWn67dakqK$+w8G$Mg^#9yYPKN@`Tea4lfUJ%zI%bMr$9WFQMOjvZ9QNKr(J5~@SGoyf#&yK|X6H*MEz6*Z*qFVG1Q@pcrobB(4U0G; zBa8pmBuN^QJEj{s^}48>N@OM1cKF*XUEI|&*&1P+- zUuks9tSL(+XXS$nvu5x><5S)QzOPqpqBb>T9v)BDh%B>JbtM6dsCN}Md}bl20`C#E zO=Ob%`cZtzI#O}6*s?7Sdefmt(b<7G!q<9{+^Mdu{(?bzo@onLKE*?3(eqJPr<{3+ ztDMP}4DimhC}h_NuEAVCPxmhEwZxETNd79EQLfbvpR$`2pQ4`Jvf^E$(uP&-&tJJu znvoB<0FZI5C->+xo?PxoeAl+f^XJWw^SVDtG3{wmWiC?y^K)!T<`>s{kS`=y@t08@ zde5)EVROXS(TBt8E?BF7TyVvHJkLpF#O-p01ycz4$q?|*j3mWE%5v5JjJvL)O;pS# zyH7aLFCw7Knqbi8yaYpb74CF2nfYx~hFNojCVoMF>;J`^?g!^{>7zPO%3iWFz@AE4 zTzrnS)*j|Hzsq};0|f){+|miNocsO1NTbDLF88ZU^k-$oUsC)Mft}(%+}m-O9U1y5EvGW|C69~IB0Pu4-ocfdiupey>d#no zk&W`=U$Ov7=Xibw*`IL`Kz9GHQTyUU@`@kP`rOY@eePc{qTt#Tb80tlCCYcbiY_M` zLt&KP&h$N9|Bs>k!e<*?SmQD`U!HDmC)rOBi=*8XvO-k>I2sUQ<=Q+57$5 zY>XEHlGgZP58!UhHz)5F`>=)&+FExEf>HhFDqJZt)TQaTa1mk=|9Ev_(0_q&@?zo)FsU%LD}LB;dRuO9B;(@=lWuEV2*b4?%B5kp?19dU zX&RQyA~H)>N>veMMhS;9^OeQdmNS$esH)4s*Qof==1@1ZXw#-+U{Z^ct8D*uc}c~H zv@i}RLM_`NTj-ny7c|leRM(AXH9GLm_N2Yi@iwr9Jwhwn{8L(s^j&@XG0Lhfh!iR1 zs~YE$PNZ1-wGKEC&#}nc^$ghcRn|vnZZXblVJiY*vC0Nc!!+H;_8EJSCk$7!@H=Ti zL=Bq93ax13hP2$3Lg9sdG!YV4z74$9^s@RI9kn!xGJEKZD2=*mAM_rri7k$Eq~=B(DC~Du)HX|QXxfz?BQCu z&mzr)ZyTJYM-$2ges+xo%Ek?*u@;eXmQz6uFIdpqZ`_zee&uK9_N3s0W>n^fmv`DF zd*AD>P0br0GC+1ByirbY!u~YM`+l-|Fcim3F*vPlvo|mfdAM~q#z`V?-^p7of_vR! zRA;dMeD0eQsh6W_uRmBs+{UrX8zPhRxbl zgrzvrUJrr*24oq&m5#Wy9K}A=FC)YNr3;3r%Yx&b8_-gIQit$?fKB`5@eR`B> z5TC-SMi!7|E~#`Y$kg;EPB}MqSUs}6*Sq5-EjGc?fLw(&^F!sd4NJeQmiszGdiR~- zq78N&1eO5{A2^E!(~YdevxYQV5D!_*Efi#yy zF_^5|9$JB8md>=Y(VNy25F8Bl@X5>B&~<{iZ9)=-7Tca3=)^lql+$7|?j&_}bu~Tk zxc^`Jf4G0DbPgL!*(m&dS)0ykDBw0+V?j@#;YpKh=V_Ms>A5pN*K-#^(`#;IgPzG+ z6jZm)PkF@fry)K~IVOstVOcj5$s}Kjh{jHVM8`V9#4iq8VtnS{MKcfTX^lu3VhB4L z?cnMt8ZLH_qK)ZGVR9Bw1hULmIjdaj4{|GR%xE&)VWEA&qpInp`T^s9>^Hsxq<$~- z7B+CDyDLoeD}q6_6S-7O1WQ3!8PpPQXGeIY>sVw?7~oZ%E`sGv4Pi=4%+Qbu@gqZ* z+&fFWhHH2B%Vxf=oq)LGW>)Oq=K04JQ+?6utgyRq`q@XDaL<@T=A-Z4rz-p}-ba*i zN0@m^d4k^ua0aNI#>!2Hi`Lv6;C)7EFBukMEpPGwd3g>?b6L@$YXWUjo9}TWW!L5K zZS5IA(tpp$_buV@7!P49epc_aW03Z54(vJxhD#Oh*PN(nR<(-LHeLurNF_352}K!4 zlv!rlU8mQz&|!Ok%hdMq-2@?87J*i4*&vV9LY|XBh}Ub?O$M8n+l8sc!SVPZ!JREj zo~yU$TrcrU!@?T_nD`S>C37St@?q>a2-*+U)#OOGjd?HO7aC&kVJxRrsKwC}B__&k z$dtsPJtv$#<)UpEkbbaaF}h1tAp25OnpYuODwWr2eOVQ*A zzC_mo$uG%P+LMWblLX`8_jmB1(gwfT1x$htS!OUW1(7JSm;9;Nn+R zH(wgsis=#iJ702bFDg^4S)6v#Q#97M|fs=2Kz@ zsaK^I`Ckgf+cl#`S%z33sxTiq&`LRjDzh9P?I3GTi*7NEe&7{99evS!PWh&&FHQ4~ z**jdrL>&=C6daO=*d#<*C03oo&iHJ21dtAJ7`{sjYi2=M$X4#HldKI=Jm_&G>vz=Kg1CvoQt-J#>oecR{ z^ZcLe@xPQojC2eW7jlb8lUz8u2q_~ChT13wGQ*iV6e56YEmj@6FQ%iRQBnR6)LoWt zu724ayc`@Tm@gI@WRj(tIz*F`fBIS#?ie!y=~?qh6PZGTZ~3y;UJ3Bqn{bHBd}=BH z_53DkF_So0QYeiGBg%E)00J(~WlJF5OO9oWG4h@XQRH@!nKiTJTp&s-*=`H7XxLs47a#RbF%{kWK zmV*7wTiJsGVt;z850C07msm2LBs1B^if+y46?;%b$j)1h=b^C@uf~FhXyWr~y~x7I zK8H%35)oWl-~iC>Yp62D$4y6qjQs&#-FqbSt=em4qYxF~4C1rB|G>)h0pc`al#|$A~9U$DF$RgO{gDk5P*Kl^UFMN-j zGc{Hg4aqK;$JYB>X_s_$8zG>7z+%=>3#9u=Qj zG~1b*%{gcSc4ONKXIeie5bj~{k=U_Y)|aCl{xWhoUOlUwJynN|Pj~`I9y}mV2aKAk z8;>aRPWD$dGq4B*7FD9v(oF=98fI@^DYNa9ihFL`!{RevD8Gg zt9ZOn_PB$N+OS?Q2VUeaQrX09!x$b#eNbLV7yg~|-w};xWh-SkDRQ)xJxp7VjqDKR zaP*I=5ZV4}!&vrGgSRQm$|b6DbQDn<;SZW^;KB{NBDAOfK|w?=uk`R~`U&Q(pG39woSp z7sKPGKZsCl735TWh1gv+`Jup)KjhkT-TB*pWwCle54lKxNI>&D=f5EuW56G(od(2n z^PrI@EwUbuzux+`_yj5QA2h;-SnMiieqIbxogD4OA_B#p0aD`*5pWN=e z*Mqf-;j40NOd~`LLw*nicG^0Z-Le^7xi0$e2acw04u6()P0#(=294ALN2fZ|@v zmp@-TpK2$b?NKol%v0kd49I$xU1UOIrUz&UTCzV2j--g7luAU4B z%k#4zahv7l?&$L95rxC>4Z1j=$uqzok=I;?v!^Qv=T@yQwqD#Osi1hn$k`-_e{~4r z7_!O=quFLf4&ll>j*$n(f$s~`uVHO3_CKy|8nEB3H1Q~Bx~TeibUg0l@M*4po#i}W z?$xZCeDDqYM$)lEm}sU7CX2?vK*>^=Wrv}_B%m$;YiFJD3gRtfj96|e{a@6*cU+U( zwl2(atILK;RS-}D0YXy}I)VxzkU#=~&_Yol1QMEbLD98TAaoLHLQ_Zrp(&kE#3da9 zNN7@3s(|1U5EPa5<(%(s*ZG}$_TA;)fA;%d-ud!QW-`YZbBytfXUI*5RQVE-yJGZ2 zsL6kRb7!L+NUm%PIY{YUU0d8#g(i|kcs8$2&Q0j+52~kkN+10@3;qX(joV)vn|%to zOYBVWSJN7@`tE$4R#|v+81Bosf#dhEL>Ko4oxSm-{wDb3hM7x9+aj#qL>DghX_LN z8}l`^ z-)-+x*F?l?jzz4b$KBaWs4M81=#f7?Z~pA9=2RTI@Zx~_G>HfQPk?6^tcvoLtp<1y zST|+cH9GEQmpx;H#SvUOEl7aaKP&^T+}PR>XYYBJOUfl5NXuXyI-qPT0?c?BC}n+2 z<553{9v+}92AWdeHZR-BKxh+zu%rDaih?X%Qt;t5j_^;cibYQ7$>2^d}XXdb2o zFOL4cL;~$uR8(jRm89J&YkQc^)`=NGWUYCW!EldyK=MaDLc+^^rq;7hdASMuXxWvx z=@zQ=BqN=6Rua55x()GKk|>r#pjf1|hs?9>+$g<+E4u7o#3M_v1*{?*~j+AJk=!NRcW#cqbp=SE-}2SzP8sVr_K#l-CIu<Uw( za_hc3i8!u?xY1g2TRwmM-Hj{Zb6(uq;~@i{HVDr^=p02$(eu$J`U{TzWz2i`e50=N z1zVp@@OW*k3mVS(`kYU&;UC=U|NSw*oPPmhud!9b&GLtKh#P(3o>uZ>-yitvuK!8x zx62O#qJEFME^ZMjA}&}2C#0J?dVyuk2w!?%IQsw_4A0q^VRoBGb}{>Oh)FzD#tk-gwHGiw)qdqn}*P2 z6>(k_mvX7{j2GeN(x|7+?S;M7O0W8Xf$t?nY}{@oH+S7re#*?Ah3qB=&R;REaXvqm z?S00Ef7Ry|_A{7A@FDCcXXJ&oeSjRsd0X6j)ciF{wbGd0xFeGdFS&$y7ldq3ql?Eu zGlXjeg(>w^*;JeLNdq+(&0_b1zxlZboJ~G--0$)&bV{2q1EHZ13%UrWk}N+8zfxC> zl4d-5Y~ko<@V}&B!kIA{`QThS8WJaiud&AXV>ZSzwxm6|A*v#$&W{t)J}-((fc#8+ z#S%?$#l1_O%X-It^HZzqxD`9?NbGOh&4z0Y2-m;O zUI)b>WB3o(4K80;pEPk}A1S!X_a8mM{;#h;*Om6CRMp_YYq+ zziDxS@90(Kh7ZSwZ!!#pgnPGac5p^St2~cXUi2=#r&!54!NTD;*Y{I_Jp5)r>CxCE)2uwcpPJ}5N@gN*ST8{vJ)}(0p~iUowCKdqGdqUJ z>#xkAqcuWm=lV?fw9fkfJf;>z5iq^KuxKKCjy}^&;Sr5%wKBZn_W~TU5*I~mggc2j z>Tkdt(kBDQkGKnykx{Jr(~&H+WI_vF?Z8zb$AbQdL_k@zaLJvpsf4wCTtiK{sl~3` z*uAgN3jnuUdj`O z7!;yHl}&1~^>*G$*dg85`2!Dt{HIA-xo?F>MPP)SU-*DG{>fke|Kh~(PtNqW9{+QT z{bP!ow@BWrj$%s68fACz&r=$zCLo%#KJV$%2}!SCag5LT$Q#1s+ApmnA&EJ$hYNHp z?zHom&v!EmW}XEQgCJ)Y9ok`Q&*HaP){jR@63yC^x!KvK6C93%ikAoSQR;a$X+>KM zSsc-hw|g&&m2^8OdG2}1K=+1pDDhoNE?DV`h(B-~=U)|nF=K`kzw&Ip_NT;isvd+a z0iuc-5KXoV852Z|3Oq$+<8!7)Qo-=4aDP2NwbWzp3ZBGzaZ5I^hg3+tDY2@rw#Yoi zotl-98gge1yXZP$Z0A1F86G%}WbafbNw$d-lumGiSr?c#uA_2B`F4KFbEG*e6G%k3 z*AyZk3Mq8<;)Qgd2?`#sy=1@*u|mn^HQG2t&t1mN7a`0NpRV<~Tdh4r$)*vlkWhx0 zs5f=$R($+6cJVO#WV%@?tUYkCFI9lvRy*RW>&v*Vy{kGAzp))>^u7Wzz%zj-H46bL& z&przN8n^n{#=j!fGU7nKtPr!eJSU~5A^Q(LW1#$ZQ-@MrRb#zlS4*K4#wF%i4JrlH zv!vO6=_04vSXkJ#I#d0bQq{rB*ME-}Sr4(+bY7B9jciX{UnIzu#pF6vJ=zlExg247 zr?i|!V4L;jwNCzONq_K_^dY+Vn+idf?A!Y-S1WqbzB|Ost9X|JU!clj35Fz2vW^3u zqC7zgdHvCZ->um_hR6F}@PY|*9K7aVU|hVj&;+pg{q2|!pYL6NMJ7(^JD;?s zF)!DwNnYM-1)kw}yk^&AeB0gGMQPrpTLiA+j!*CMXYXQp1d`=cDmJIhV=JjmCDVW09I|L75y0W`I;GN#Jm@I;&P zC9qy{Y$LEDxVIPN%d9hx?W>oh=ZoFWv(^Siy5%Z3)E|W@U34Hy!ZHsJu_1#lLrf?{pL2_evU71|bWSKWUjkImu{-y5N z{XXCJF-IM?3EQFmp3$ruU{OfdEzDToxTJJQsP#PX65rvZU;dU({h#h1bV6=pTJ7wX z%Dg(agd#;Qj*fmQ6<14is!93@|5tl%jC1(mLX*`4<9MfW;-mlRZU4%>13!Fq;Gai~ zawj<*#9ybs3i{!{3rPrd^Bwrlrg>AY8dgFi*W6pVHgc=uspkzQP-FW$LITtmasgr% z&$TP$PL}BzAaz1SB*N?s1^0_n%M4QrugHF2!;}v(?0sEX!kxu<>aij{xEq2&O%2G{ zZ>Y$5X4SomXFD~&@Dm@Zlj0so2jpX&PYS~b>v#<$LEg zPj4n_#6{XFQ_+av&>W!7*=cnlUT1|&HUEpNhUzhbYa1#@Mjs;}h>Ld^ksbH6*Q>S< zncrDaU-i4-`{hU~#@M!?PIyvWp^>8g_!t_$nNc9q=%4i@%?tlFN8tVp6;X}~EVuMs zmcTpxW6{gqszqR>BCtm8P5TZn+}^p4womz8@xoGX=kv!F%pCC<5n9GA zAD;L--oCe8oALF%wx6|mCo!QkVn)Oo;;gfK`wu?g5`)=$`;~9Zo^o8YT)-sbb*759 z_PaE=@fbdT%O+LxYsUWTt6V$vkJwzW)1-rHtYt(|4OvlXIk)iL!f%g~W}>q{e0>jY zA5sCgUJI=}&@z;h!QL1qB(+;5cFKekIUC+Uhm#AodOQZBOs|~eRC>qQ+|?^SsIy-4RQFx$?bT0Lj&(9~K|-EgIkE5iXmifyHq2|y z5f2wQv)(*kx(r9036lKFfp4_mziusy*p}JQ{1H(iLaxmjjf&@unBD;(jhPqN(-WF7 z9KK5LRZ!;d8E1>$kTkR=vjPj;kUR`R9#C^l7J<$-1;|{KjSr_zZvf=_tx3s1w+hOl zweWE6{1>0>eK1!*PL`DR^CKN|=)`FuZpaSx!my_(-Wd0&T1>!cBklW=`YS!e%8PB& zk5crsFE?FM0Vh&ZyyV8dLMOMFT{&e?kLLP4Q({1uO@8RHn}vb9C8%b)z;qw|BAVAk z@FcIrO=O4lQ-5TmoOUSMZ4`4??DMk0m9e{im1j`PCzGSzrk`hCF%I~dyKE}&tQnhL zQ+LkA(Au|DC(o%@mS*j3PbAXdk4NQ(W8cfgtOT!`rFB1jO?yidWt0={j8SAX1T#GS zejB`MQBt5qa?$lh>yY*aU&j}5YnH*(!UHe#^i{Lb45Q?WP6RXGZZxP(v%8sLKbA(# zo5R*0J9*Aor}4XfNN{;@O>-(Gqq`sBw~rRxoW*H8zlanb&M{H(sx@X)3)FHK^KO^5 z=$esfBfQj{wXe$;L3}7LEvVAQ$5;J7^z8iGitpc9!CryVJfljLWDJv+Z>T zUdpN;1&r>Q1L~An39iWNT6zP}j}lS?-;4H3p~9rxWmy=y0JLqjh=ER4HP#TGGKz`p zWO!7Pzl^Uu9sJ7)OOU<8gH)9I_ynWX+HnI8RyW|3Jshf^aED8N+y8YODYDY9;oF-3 zI-XX-8c-~XOpo0obbQi%s6!$8YHwRd!T}FoSXSR6Yla> zWS4f&C5inY9A|<*6+Z;*kj>V>_qo4s&6_1B_A))itNFc{07#J_S&^;lE61<4y!G3| zqBD|ZEam7X&spQ3XIAT1F5TDd!1Dtbg?Em;chVDk;20wwiH@!%V+d32%mg1IMVWJebo#4*WjqPn!-t|#xr z2e%mKRVZc$e>AwX%pMxXN0zwX85~T{J4{paPz>&|l$2&Bgv2hD1*xEkTw*EkosGLj-){EOgXfqwkk+^sdFI8T`_wbY0Di9C{Q1Z}#m z`oi|y7Z=-nAAXd1WpWx?+DWLV8>7o>nzrD!V43~Su>Cg7Tz?0PILk}BBtI9|g zx8?Y6jr<5JCZ3&j`(MFEcbHmf2Kl-2$m>#ci|-$N&%4XwHMCYo{2lN84wg$o+wnTH zWB%3)|LOZbob~p{Xa0JE6DfVz1;YH8{?K11Kj3~poR1H|n?rErKVl~F|9i{?D#)^N z2y5zAnFD4KA^lqmR!|1@=S5Ov@eMg5ICR7*NLTxKo-{bAh z$$i`x2|6$$%?4$qtv_O`d0D<(xx6YOn}K`=n`J?f0%YYJwtd`G7Y18U%&|#w+6pYr zAq0dG0_UyWMr?b@C(V-7`(`~@Vo2QeVcp2WIY|R!BNrbThhl<-PIFwh>hSCDCcfNt zOif9L>Pd-Gjo8^3-9qK;WDzt%)&w)~xDd!V6ihKM%O+#T!A~pRc(qt0#<9*Ou}_^$ zN6?r8C*3WY%5Lt~Elv<#04&m=G}%dhFQBVo*eNK?~&EY7Q5#@`N1kG`rpvtmU!jq-`dzZ?4RfYrvbkd7U8kucP$()Zk2yc5M$zh?e&0C*QEX_rlicusE&6QNl? zRWTDXZY!ro+6sSjaB^CEWN+m2(?#KT38n!|55d5-lyos*=#~>H>GiFL`X&nh^q&9E zKlsygPD@wofL-P zORX^+>rbH7-a@WTBy-)m1_?u z%UYnf9Ye(2k3Ukv-n(3#!JV)*^8{GgxPv+Qa=Wue=7|#H3#LZqoqp&Fhu;ierA(2m z+h?mm3Te2z@Y&t^>>4LEi{1l;vEDVuXsjMXmJr>-$iFva)1jr5Ga;Vb?Nb|yu=W;6 z^b_SyX`_q85@WJLb>)4J_%;FC-fd*daqBY&Wn@~CpLRzrWs9|&&krt6&6XkG z)M^?boF*if>Vgxal?Ng&es3?yOU*0xS~3uPXXjd!eT#0IQlD4|S6t||VHeomE>3ND zZ&(RsLEy#0F>k8TJ}EWC^BRJFbgE#z7>`wdaW|#6)lMJ|YhB@~ap5F6LETI=UH9^3 z9T#^Yc*yclsk@@jl)3r}`%YKGR>Spu$o_-u#M$E=$A4=`(y-xaJsR+_k9HwkJL=KP z0=B*HS(OMu0zHcB9&hqaA+qC9wKu#hQwgGaC{9UN2CXl+mMZHhUI zDW4ZNyt|GMxidsj->S~<q>+kx^z?KsO95at0>wj#HUsVM zFkQ(v|0l8fTVwyO#`c^K2#_jt+9lOvKkPH7)lwYjq9EhWo#Hr2N;TlBgF*HHF8$fm3zC@U&Y`3*ne|hwc^I7#^AU# znp?i+Sc_qz&Zd&?iSL^F3$pdel>jd=$k;li(Y?gBvX-pcS=~rV!{I4tGLZHfHwC0Y0f!f};o@a@hx8zov4-XCbu~9R;`W#7WqtkA zRyAO*sJXZmohl}nk~gTZ>o3FJI2(Y3#=6 zC_b{Olk7}NSmAu%we@O&B-EoUpQ;>)|8;fC#-7HC8yj&G;%C&KjzOw2j>(&L_l}|F z*#4JW9>Cr^T_mm6G>pt;n!28L(n%^$H}Ha?n&O4SQDfAvVGJ6YQV zrudIB;eiwaM#gHxhh|Dj<2mC9#BxxTY15Hg&ettQom=sX@mb8AC9R$6guC}Hcb&~Q z?C--kR%E9wd7jO`sCD&abmBXE-dSeuR(o4NreHY5`nuzx+z8J41&W>4xBI;az%>Vl zg!+?kgS>66yn(jznwYc!kD>sD@GR?Or^#ZYNbYYCg@#z+s@5){aEJ;lYXoB$jYU%2%uwP`P_9_h}iADL;2XdbrB zf#Cy4uk#>R47!^FM{VB~kY*v&txdvnzKEoM$sqqY`2O>_mcON7{>l6QT9%5xLZsc| zt>QOC4Sp*8b7vt!Qi;BiisBKSj~*RC$WEJJ+;UN#bn`o$Y_Bvp2M6(CfVC4KPh! zZ@JYp?T@vX@z?k89P5O^%ydOFe%kD;X-kC}%EP7Wl@2VGu-$uCEvsKVUy*u{GLZ&H zATlNs4-zi|y(?XIWYAR6`B^2P*!y)JCP(if?0#<;Iy|8TFqz<(xXlYN8CE*7hAiRG zym)aeC0_SoL%M^!Hw}}zy$2l)q|FPVWCpHe-Uk(w$mD?H;2Ti2hiznqYQs_%E0u{Cam(Xmh(xP zb6JQxbh22T?-_dHU5bnZ5vMpSRs37AsZqHZCCwt~%LKl8-^wm>7qVXYVLSPOTYX~5 zCPN%Jx_WU<_Sp)#q4rgx89IL&idWAb%G%MI`tSuLT68|%6T@_Ml8VsH*Ypsy{#2{# zs{e8Zg(becxAQzfQCsYpRGg;ZA++;Zhq1sooZ~WydI^7XCJpJWGDr5 zagvzICuHf5 zYqYpsi|A2)7cf*A@r`jRR{%VBtc-nUwZ zE0DpU?PD0@a+Y~{&0}u_mtYnPlpXj=>fRNL?35dSI%9HTB>h0)+4(**K2E$4R)ZJq< zLS%hv8LNRAvFMRG!A<@{A%E~?cxJtK+!fe3f6Am#SGz=!eV3Z3c6LfU1lp;U0~;35 zU%spM!NTVDS>|--*7AV<>+=ul=MP`XbwBa8jyalX^1`w=vlww+-kw5?E2QB12wJD- zoMeC%op^7(FHuqU(HUiTa;a#-s70ZbL}1}nj~alI@02~4@})Mt=t!SNJz195!&`c3 zIhYXZ7>^=XO^2{H>e_<{gdj*f3U{GL4xg${rV5rfB)^ocEx2sE?uw~mdgPY+j?}RE zh__=>z`<(UE6U>Fvj(;x&$OsnxlB#ci~QOdn)+VZ$K}K#|LD-J?3W8W$2`rm zst9u>fD#+gF)p(ENj4H(4D%jUps5S;aCt4gJsjg8n;2#PbK_G(Hh{R%fFACuh~^M~ z)MeX5DUH}FxYCkf4qD9RHPpp*5cFB9$)`J~#(^P9Ya!ff~J zwv!8=*K+CCSd#i4qJi9Le~`|sh8ROG?YbJ7D&{iAJ{fNizv6>bbN*c6rqEe_rAesh zY$s&!#hu06NSnzyJWcI$!(c+^y`qkpk}L{6!TXo#DZ%0(r-v)HPN^F8z-)fqdR}`X z9|Y&&m!sfTSO00ZA{e*D{^<@`i9#Fz(z27(PNtzmjmRLFcaZ#JeqgA<3-lwa<4|oj zueM9qa9CQ+M!nx(({zOK!q;qo*vBTy=6xk^2oM@I+BHZ)9!3vi`3=X`HsRjjqg9QA zs@_xqkqu*4(Y;e99nChOv81j{ab{W2<$bAJ_bUpEX?0BZ{42_lI=g)ic5T+hH$hg5 zkB{J)zx5=0kc(d;)TjIUo0DsZo#8=?79-nK)$WnH4D49hDEZKqRrZc-bGu{oPdle1 z{y_`-r(-Ry*8C@a)!j}-=9mAHjCA-f09K?#K?NV5c=10t!{2}Ghqv*M;)(hA(s*x$ zJTFEt`us2;)pp8E|EWvWhQp0r?kbB7oEzuv$n&ZY15W7PVRtjT?u?kFEmqazs2|vw zIpyCwSg}-66y8k+-14qkl3SpqtEtH9^VQw+A#EZVaIl|DH10Q%4T`#A&z7j8-?^^f z+?eaX)gGZN!&98~C)8MI%QeugblDv6ooZqZyx=RRn!Kp`LIfcfgP%*dhI{}^8+qq% z^2_@k_RC2?1zh%%2^EUKnvXy!dU;0E(mgLXQ{h^%;w`HI zj`5%(C0j%o?Y57?q$#tHTLH-@6{F-L^%pMnz_X>Z1{&*L`5w2*w%V|>GVic5NK}f# z#-OrKyww2|EP@9bCT%KwxF~uo0suj|ZIQ)tEBN2dR_oe$JvISC89f*~93s4U1xPOG zZcKxEgW-7?YTo>@4X38F75V48nem~!%qOS%N1eDM_OGnS=0zhOm^Cz&(GhPNo~?G$ z-1Edta0am#SJikqkBfdCaQaI*K{WMO_2Lre!wk*TXjh}ugEPOZlySFKu!$yQC`!mr zJB`e%wtOp)nH3njr_r9qQ62;EO00up1SfmGyPfD!`Vwb#WDBTRHxCBr&yp+JZebbm z_$JY;7cK!AiMyEjVnSWE3_t_q4MreV0X)1RIsAqH%%s}0S6@GT5x~!G<>tDjG7wM| z$-%;0(@aYZB)5}GjuF@4IZHsfJkV0nek{!g&kUCeK+3R`K+7R z6PweVTLW@g8Ka=hoKA+=hm=^(7mTNSr2ut9O%8vE+3|cTKx0QDwfH)ef~|;n+`rYPAX>>@&PHvl*DvB<2UXs1Tsr zf70)KM%M6zoQt*TEs7bUIZ70l+s&yb$D__ZS8v>qn6wHIj<^$VZa{h~>c8n=M*4#f zedm)Hy|pOkPPxm26#})Qq=eH+&21RCQ#YrT5ODT&7~?v=NEgXBvEeAumM2$Q(+ z{*=&>`U6FBk40k3`^$|nKm9_1LB+6eUCK4%5QUKXiZ^V3Ag(>vvR zYUMS!P>1fc0s#10R#txMm~?2NQS=ytNEKs2Bv($Ps=<4XdmKc0cE2qqXT{0~vB{!u zugpZsj<1zg;90Q=oUWvxc9Vyk+m%uRN%uZPxbZ+*DDJjr)?R z7Ad1vP{&$eQ3Vyui zo2gl`#~r9t8fqb1_DSP{A=_@qMm5#2qR&MxDQKnm&M+SrT5mf&($%w70rP?cRX=TQ zSZX6i3UNmROGnJx`>ij3=0GiUHaR9@>(yp=$tCOJ?m_~jc?s0*@Xd`8XBAgvNMfZB zi|CBVw#$|yuAUI{6@^~ofM_9ppjX&{w%y}b1+G*ZrW2{VCDEor_9;c zZG#`WE*g)i51CR)(ty<1RFk6i=xtx`8pD)6^4M2DIaOA8lOXrRn8)Hpwb$X)Eo#40y}Q z>zALK-~6NLtv^vX|0ICf^|7(rYFMo#D<+SBf_zphe zO?*cAlmKn?XJPAwG&xHSfHpF5q6nf2982|el^uf?po>6G6$LZPirG);YGSb`!Eu57vvLYwZ#QlnvZH~e7o9VOY2*uYsS|Mm-x`1WsB!KeAvvOlS^jm&I<+SA1jioK8cs~U5zvh9~JB| za{$H4r3%{Dt{WIXis-N0i8rf@5izHNW#kmP&z&m!vDjNM>X~vt)H7 z7>dk?YA_C$0%bh|-?w_j{CwK=n=p&#Cib=0?9~_>6~l5*KcdR$`CWKPZ(L5N9*m5d zSbny8_UNZt)Yc$P-$t$GX3cOwwfZCqNM};GD2E(_H*BuY zrLziXS59bZtQLxd7vI&_r+E`R__LK+2sq6OO598sSh_v9mw1z}zp%J{cm^S}u1&+) z2wEczDc&|2B=Q;I)Ll=bILH;XoulZQZ4SQRIZ8Ak*gnzN>~xYNm9h|)6JF0B$;A6B zr`hrl2lXdS{~}fm{j4L;sJ_zl?VC{PsLgn3x_EXXqe!kN5Rq-+h9qi;otbIA#&-_t z?umgy-T3$p{=(aU|M2xAZsZQr%KA|*kU(6d-#q>!QLF^`QPLM%m}c{w?=Lq0@C1MF z!9T@H;YSp$gZNgh*XFO8;-7wqTGpGqt9*jL@Y#QCH`h9ONA@i>aIqus9O@bCA;sFi zxT3DNqxGW4x1FCv$(E(6>6UbB+L%cSB^0e8sTln7fz0e;wcwHNr19GBXz@H5sx8Bc zHOK-A(xM7#uN*w8RIon^B%In*QlE53KSDJi2m}f zK;q3FaqE})Mnkg!G2|^L0xbQ^HdyHFz`LAzk65f`d-M*A=Exnx?3BbQbd>c;whO*2 ztk2;V%uMb2iA&}yjG4Y0^i-$C>Q=MKevthr_nqUR$!eRwPw!DNiW)FC6tg1F|C()O zXPAIy0V3l*7+GeVRR#+^gOF1F)pRIbKTy&reSBGw%D>ojUS;^`((#p)xE=i+9u$Rc6jwHn|FoL5qhm^rA)@IRacv9jn-bPmwp@NM0vsaK z7$4v-Gppup*pK<=POOiyB}{(w?-sS4_-lCzI+em65)Qp4re7lf=1q%d;l!2I@cXBqSCHi zGb7qkRZ|VATc0IAs{0z=^~m9iA(wUXDqbRP`e7H(Ohh0(Z0sDue2mfq$hbQsxjko$5`!cTMxx`=$071@9HqcQdwRtHX5pLEef;1dzG` zpOA0pa&^fr_G;f=;U8HOoR{%Bw?(`}sjm$*PsoyG8e-sZfiHvrIT#*iyZ)_^POI>1FxW5{xtlAu$niDPS-rS2Is5tR*Dq{8 z;1J{XQS|)CDtd}2kq9d{4OfJWU$UrgNFIn1_&#&LOw$*Gx0Qv)=+gHJSe-8;r5DA| z0RY#ewkkbPbK3&;cjrhoue9R|#mT@RP{K3jeD}?`4SLc$h|hd7m+&Dl79W;(7oj$@R z3svSrv33DxLy@2oWm!-+Y8ad59e{#}_-;*wjwU8$D#4z1xgH(UwQPlfQl@Fy&)Vnf$^O72pyPAJk}egM4qZ2 z0HTQ?x=lg96HFc$bJSBD5u~};$}QMRNtEW^HL9QpPN=}jNJ>C0gBM?;Ma<2YWcXKN zN$mr6jTy;ay=|DTceM*P9}kY-0MpE1sV<(AAt({jhXob>!aw-B?apJqA9jnV4cWs8 zG5haA#J`|Ai>v0<;tk9zR20ELPcX81cc$qU)6(1O>5ShY+haZKlzeD3#v>3&@9te( zR!V6a4t|b7MA`KENyVamwZ+kLkEyec$P1%VW3jeooC$`pn`~|w9tP7P#*;sX1&p70 zHyJzFx?yl+Gx&V`h2bJZx}dtJG#kix5$b3RL?my2IoBT|cw__bSl(O#T)Ai{lE80o zeW|`RfM(h^ z5Jt^rPfAA=u|~B?o$ibC^Sht!y6K-7Q8@87Yb8}Y#HCv0-9wJfkx1Us3{`Rud)(;- zgSR}kPx!yP``9wm-uVDDA{{K8SqMwnT7SCm37j){8nGl>_v_38)mks_mFesXK=m-Wv*ch zHx&(qK}*R3WQC+oI{~SB$M)rlNZhXolCJn zk2{$A2!7!0eAm!dH+VHJN!v_OB0?F4x2=sET38_nDym7Xwuo6i z=H}2lf0ZtbWKtL)EO!7O@j`=2X#u$TE#I2($}7T{cTVj`e($!t1k?>p#LeNx5|%oO z)lM2;DWn4FdS$)UHwQZJEmB{_KmBTCY7hH0`lz0efQD1^#0jY~ZYV)4#Lv&5W67>j zhO0Ie-2Ag`n_@u+B`&@@g}`YP(g9C9pL(qmYE1S+(T_iOeLLi z9|DmjM;w28L;Rnk@cQ$}UwDr5XVH&FAXod)59S9E@{gh)=uofX8@``Pe)(^f4kEJ2N3u8H2-MnU|@VBCh;iNndKY01!)_0+m zCn{^s3w&-lv6{@RtCPx@tOX7oty>HZLZshmFVrionu%JLSUR?r*0F8xoiAXK8l<5N z@)|IearArD6iB8~o@j8oJ(S%^`AjxKan!gQEIFns4|jOnL94(Mo^5IPe;vH%wGy{J zKUoxZdB`P_Ru`(%D9}bhWuszs&7p1S_DI-cjT&%$oZO?b`x+jA#x$I#w_wulQ`Si8 zuQ&C$EY*(7s1~<;JiRZ<&9^(+)MvA#lYY4XO?66Eoqz3$Et}`jm_0s*w5@f9b`t~C zax+2G?@Jakj~*_Zz6%#DpYok+vMC*?7!37=xo3IYG6gGk|`ldfPfjd zb8vrkvI3_sV2TQV^tQw=`SB#IBl)?cvGJCg;4skf`V6fs1G(rJK%ehfF`Eerx-Q|s@v zG<`j2?YDr!KLIMNeCV*Yu~|+Q+nlNCs4l*h;jEvaVtDs26AMC#0<@8xu(3MRxaBRZ zIxi06pI?JXNR-2QxT|y;c|?Ca(X8ZVJ*FsbZe{{cD78< zR8H)%YDT6a>gjLNN0Lk3r5g%1H_}9LA1ZTsuS-KP4kSLHF?6KvhiHPVWGjeAi*UkA zi}%vfnp5@2kD3HS(UQ9x68oXaYbnbx(ulm`sqUgmD}=N(islefg+ zto_B{~V#dz{pxh8s|2e_XWivC}CD{3!Xvf zY5$^;n@si2&pXLdQX+Kgd6jlchGuj@&Ae%`I=-Bcn^t%u2Mp0);q~EklbAZ@l_}tU z#FQ!ub~g?*zg4cUoHi-x*rzVb4L469al^JF=N+A&*JA%tvy|rxmdqDkQYVc&to9&e z*p4+-3V-lD+AJE%;vECJAm_zmKYzKM8!*~Fkay3tjcqqOw5G1?HY$~RjU_#qi%I;1 zOll)f$=eKxNMtzliv`l)sg)mqB4yf|(l0)|?XC&SkIWRYB2h_%>dXC)VK|CSUrqOu z?cW$-b zfXwT+QZ8q)iyo|yd?U)%1 zz_268aF~l>?CsqR^`d~po|O!;;;$gqNIkHBWi9uxj(Wx<$vXu_gSQtade!y;C>}v< zF?%mogp&W6e(a@BF4AqWh1nJAK{TzoolzrR0%C`=94+p6*H*JSfkyQLMrmZ}8HXsw zugm2dI=!L*0t-C*Qb##^|tJyd&51#do8+d8YJ6AR-rW+teq@$apLeM*s({yy%0PTC|!~N zkQKNp+z_nWCMfz1*iBieU41zmJAj{ApCrH?xkTyoK?e+Ue0Mh^W81n`F?J{E0lMt% z9TUWF>cOoBas&F%3BiD?p=kB0pwUqhT)?#hD8rMtr&=Wh>x;fI2d?=HAdSaz2ZK9Da`?hNGPU>cQ z3EJ^#y?-s|(df;*vqd+GJbXLy-x>x@NS^qbN%GL&ejiCWja5)H4KLc3x)xg&RaW z4fXQX4drkdlTX&g?K}o=9$^-DfyLEKOJ$1@$FegSij5WnMmtg|p0Gl;MWF2e*WQ^0 zHMwPb+|%vxs7KI%pg}=p2qa8~1dzcAA&?M|gg}@Pgg^oTgAAfaJqHCL%pnBAD1ijR zq|7s%76bxeN(eG@l}ToqRm8q@^{u{D_uhx@`*y1Ob=9u@uxi!b-?!Iq{r_N3VK1k9 zO@|d=_^b$=^aXp*eMvrro#dULy%dsY1AF9sz|$(+%!*1lOMgLeMzBi^M#g| zyOH4AB{k<25I*)O1DBmT#RlD<(IqF{BJbgE2Eme`UmJYe(m4Go>3x>uZ>6hWxY!bU z^Zs7Vq)H2Jv2POC6YLIu&jS(Vd^1ki*%w^?aMQZPaIeG%H{I<^N5YiU1ld_3o%E@o zH8)m{E&fIUy?q+NV3Em-?5bk_E@WQsB(16QTf6byoQ8A9-WMDEy3}!#sV6EP&$6sX zxm%V9m0orV-RpwSIX=KD!x z+#Kh3b|$CoPIY=BgMIV!3@a$}3_o?RQ8sYAZ`6SC+b5|@Gw)>H1`>K5wY@82ordIs z$hA#=Wf_rLI&{L6plEKks`Rc6_9eDZ|6-aISY24Sby%_rjLiW;kQxpNndq>4JX@t| zdy5|fP{m$ut#Zi=E89|boT$-4F!R$+E^(J4Iq9a;1e7k=uKb{F+-vwavjwl;UK^nS zDh;fK&n-|+wW4)p%Qf0A(ny#@fJ{s$zjugL!@X~V%*?sBI^oP5lfc4` zIju>A!pYqGhYnr**H4*$bPNAr%>9Wn_a^Nvm@K<_gas3b5k``7-$|T?@rxYYKs|g9u%^Kc1#>D0IlQL z6?TvLfTzK{ByAA-Xf<eWaA^-FFfoUSz5SGg zyCnze5Ea|FCgGEzzPwODh@vN0tlA@ttcThweophhZy>!19raW_UKZz_2*KQ=56KH> z7U!&GBgPK~3&8NCsGDh4qqlj8TI&4$tL+|69cGn3k%sGi)5K-3e4?B2MPL&RedkX5 zjS?38m!&LRCe6!z+~}Q3Y1&ii5L@a(;j7lzc2#@WlPBNQi+-+30onUvJ^%xfbaYUtEUFU3}Tc zD9^^^^BE4jsy{HEhsE?@EU!#I`GxgMzFgi`@Is8pHC_nZix(O~y8<~mHR_Zs zWBf_T1#5yC=Ib%%h(|FVq-d+h)1CzqPJ!vl7Dqi1#V;C@eS#lP_h0F1`gO4qZJ_^h z!!k(TICh&e4(5`Sy`oKb#-rZ$8u(vMs0p)`h=!BLZN)Q2J343S=Mut|bs zyw&ps$1a-0l9bLQ&sJv65as0!PUH(iwn%YV511J%fT-Atc6ZSIM$5Zr`_9BgOj4E< z)~-KUnRJ2pR^7stQ`g&2<=_q94Zv41=adWO3rQCxO+gClJOO{Cek5P-A!@eqp^Uge z>&ELW~~ zJSni7(slw_^nwZCY61;rtzXe=Y;wOYc*h^ucTyw?tW&mNV8*)>g>Lpz>2t#?cbmE< z6Bn=o@ju72`PSOnBg&xCaGhCeRyjv3D!h`OPrF+yA^fQa_>f}V*-kxXX zWA%F2%6t~|JrpoKoqX!`tlcaGjGfD%=j$^+F7+a}m<~I89q-*nxz$VI=u~n!Aw_E7 zoyS3OX4W{a$+lNS%I8bnk%3!wq z;s4}S`v?Ar*Qv#eH$|(igQ1fo1A&Ec$_1Drh^OtZ_5B&{x>eOB={9oSKb%HyMtIO$~2 zd^^FOzpaYhfomACnn&S!KlMIWI?yarZc~5Y7oDU1rUDMx%3bxytEEdw!ZW(jSyXHq0-+CED*`a^*T-RtIqK zAgVVT!L1PYcs}SrKob)k?GsDhXe%8q`enakb?)bzR{RZ(Vt=>vDqd=|_ zj9~V2*MxPz$8*7Fk_0pExh8pn?K09RHOO#L%j0QTHAc2KB_X3OS}U@_oZ=e1z8$kw zWa@=l>(0CE(+XvE{@QKDAk(5|>Pje$Zy)){+H+=yk;{^B`+3_jdDVvY%<-Np`t`Ne z1W=+j#!cOV_aN04flDfnG9|aWJiRe&4fl6SzjlIXHNghm7w?SwHa9rtmm`+`g1*u` zW8%MPG=>&x5g$lB2!{4h8B}ZE+K61WN%Hhx552{XX)7)V8%E$YO}#}6Cy}ShlEtHC zYhM)>9W6J&(HQ-ku}MTD2N+o?gN7Wha<(mV^5P64?lWC&Ml#%T+ET^YFNy-d&yfWU za_6iw1AsDu2*&97y44Bydy#zt)nzTNW_6d=JjM9=97eI!i#+!z`fKWFzt0J45f)dT zy3qN&b|r&&WPrvO-gW)%VHdZsxw<80q&08(Xr_5Dc=*0e>|Bb8Ap*bA&-PxoKCP8) z?vRnsDX3d9vrcrlvrEusgAPE&q#21)lB&xGw{O`{n1*PWzJKj>*P}HA8b9e0YECR6 zZ6oM1%~T&o3bdyziQyCMas;T777(@Ger@5-zo*kUETW@Pvc zCn9%`9qrd92bm6!;#m3G$GG$O-t~5COBF%1V%pH0wvtH-{;48=SE_vqKx8FF-Rrp) zFQ1Jiz#w5B-B>`;vw;zvL5jI1%?~(d>wmq{_v{xVgx{^@l6t{(gY-EK9Mv85Xen-E z99i37Cm`ChCaO^(nKh&S4}C;)Dm%^R3A%CXzz#!%C?GPICHh?bd3XQ1<>?3dmx=~o z3l`To)|0l}5p`>x=yXadc>+6mQzl?m$(2%&><;U8m-PIoRU=a-ku`xx23t1C8%CWl zd|!2J2#~pDNC-2?(S^Y!B3ImD(3<%CptjZrjB{v1ruJRNn3#tLGh+P3{o;hiw6WkX zz$o4Fl7Mpu_&@mC3mmJVe==K6i>(I@u#X#i#oY-)6zPm&*~$SG8jBdlrgYsSAw}Eb zv~fpOd`iXp`I^v`Hfz&cP?^H)lk+XYH3&aDX;Lv?1hSs%<`~h1o$*p94O_n6d|Opw zWM6)=>WJy=Oc_&gxuo^B-GCA)I{bi+*wVeui&y&k$Wmpd-E(j8JVh^H)@8{P!z5UA zmTFR(F%uU6*Rg{K)_+i70Y(la$LE{{VVC06E3nd!dQd)KCNTNiH2$aCn_xRI)f}CP z@GFPb7DlUa^Qv3x2X#D`Qa!T@2MwF%e8IViR>{`%l82QvdPh}NjDDQE0t8f+u)}-s`ux~ zvLEmH#J0VxO!Ij7ocsK}Du<^EG4QZpPHD-?V;I=(Cg+r|%$G7WBCP0Wwv5`5$p<6G z^oG>w>h(%L86NOxXJ?;=Z#xnuFJ&l}m)0JiqD-KhrX@^ksz;RxHa(V5+VBOy4j9C? zJ23W)A!M>;s<4sUI)M*=X)B%(@g72Od&ek*Dt1+9v{p=aW!L=OOYfxY(;gR0g}{X& zw!#XJ?~x#@b#D3rw;c#dfzqFk}CW1%YYjyg~Y)uuITd$E53 zH%eV7F@R6poBE}KsY4@ITu+Nm`&%z}0pPh{+kh>#TC5Psps!Ax$ zZB>fg-AMu-n)%SFNWY$Y^-qcN+Q<*|Ez_55U(QX5Xs74dJE>W!_q@jGB07X_#i*J?{PmcN&AOY^Y=4?#0}6*vLLFeRw7W27CizpT11z$z?b z&40Tcb01{MFxMIJrPBc;$FOt)J1;UaX7}sScK%k}ic9kGBTlE1VVJ?2%23hkCl54^>p^kU1UO>=<^&j|V*kdMJiU;gl*QBwo1pLo< z?@#NjT!61=CJ-Cc?xBU&D;l!nwF`XIYRXvrEt*;wL&DJrcnb<7EDU^-v`wf{-;5D{tcnk{ zLt8N8NxJ(_Srup8A7?kU6dB4MM;749P6RJuuy29YjHRw9HAcm~xHj}+Rk&|H6G4-o zXbBa=jk<{W91e_t2%Os5gg^E7R7r;Ryo>tKY;KppKsT0(F8I4y+_f0~Ee5e4m@7Pk zu|}7-7DXg|j3NThftsW>E!Ny&P2oTI=t{FyR@t)r@9PeQHGpN)?2lFOapulEuk6)8 z(t!^4Lbe18@5Wd8^AN{F+4F)|8Y*|Kqtj7VqGuI%xS zxL7kIcXy=sf~gZvT9g4j#$2MOMh;_G-mRRhXGKH$XcEmer4LtITnm;DmqekLrCTNpmKeDytED*lj-j$N zx8-ag`zhMM%)SR>3bQ{%4d4Ta73LH+RQCCe;Ny5%mK&lPN6+Nb!@&p?47L#yHxqn* z^GsP~Eh)b!b@cA)<4M<|otE&|vNFubyO{(x_p?_o6%3pXm$BUdB@vMYiR5K3=T(z{ zl}&MPB^%Q1AyN`V0-X$U?0zgn+QpJE1qn8_7(wUW>+*QAMV*AOt=YJbU4#O`ZVs<~Q;C z>lq|P{=V$&8QR<}d7G9T<|E^-Yoi6fXIkW|Z?|>^urH5p)Fex9ylWm(sPWHwqqaCc zN>>3WHv1vMM$_XavGQb4E@nr16Lw8FwJh=c;-OOs|5AqkkH!Bz+V#KnrfbD(gfZ(tTw9@q7z*AIyK*$@O{iUU53D|A#f+Th6{IUp(( zIR^q;iA(@ccF&x5`!#9|-n-~pC13x86#8sJ{i! z_8wM8yAc_|F(c!;&|iIw!<4FL@|sEbOnjH^_psC-3N0=-3n;VliAF_6e(6d9i|R?o zQ}d%cee`XKiVp9zFB!Ba{e5%l$0K#{H*c$nnS(8)TmOi0{~bH>?;LzQ$U&={9T&t} fQXCblwnvm4K4AMw352KPe4pQc^a{%U>&SlsV01o? literal 0 HcmV?d00001 diff --git a/docs/images/web-ui-light.png b/docs/images/web-ui-light.png new file mode 100644 index 0000000000000000000000000000000000000000..44ce7dadfa691c4fa6a995c8feae846b4411b8b7 GIT binary patch literal 53630 zcmeFZby!@>(l0y&P4M7O(BSSCg1h?w!5Lt12(H212AAOO0|ZNOcXxM5&;SW=*~!`O zKIeS*e9!y-^WFPB&+eJ2DOT62s{VCVvu1VodYpe;2Vlrb%18oWU;qG^rx)OH6J}mU zOw3SORY_7tUgCE}Kj5jru>t^KTW3dAskh|XI=bYD>%Y(Vqt3|0$^MV;|4^RvUeEra z9RQeO`VTVyZ-<|onmL&~34D9{P&qyse{vT4iO071&A zR96*y;!U6U*B1Z88~+n;V(<8eeB_giAlSy`4_kkfKRiY;v(-?0`bK*C5Cfb5ssJg# z+dta>^!HP-%LM>z^$;$O$8asUAI4*)>J*k8x~!o=Rl(dd^t zxF`C|+#CQnF9HBibpQaYaRA_j-mkhR@*jL7f2tyW^2_e&WdX1Om;uNEG5}kE34r;D zV+XJT*Z|y*O8_wd?6YToyq^l((;FTM9v%)3{skf;0uss#6cpqa$jGQ@FELQjFwu~a zF>o<3v9NJ)a8S_k@Nu#6Ut;56|Dgm1_URlr_~-EO&#_UFQL+EW)=pA#N;o<>=honIy!FSUGREi8a7pZ- z<`&a@ZW0h!*ZEESNiFe{nqNl$vI_G{Eh5rWtuW?OQat$p2mgfFGkEwX&tRTm!oGY3 zhs7qU631@j@C}}V!~bJV#{>fQ2Ibo`94XG4 zAOS*>*S=hRZ~MBTy;@asT6+mzv@v1);7Sm8uNxgiV9#ekM(S0~_v(vRsNN?PNHcO$ zz%DHK@{)~hMniSyKz#NkyOZxsag^|9)p9Kb6%X@+G^;|ey3W`13=%bggkL5vgeCZZ zHRnVA$2S4U5|S^=n#C=Opuk}j&6Lkm6oIIPQ8m=pnq7sM#2jgAyWTe{m1i1(^!yqe0TJv`ZF!4 z&y3{-xCFIl+ooBPJpg)ug&iutx=FHpTW~H81qXdLb$f`58m9*57`|upAHZ$@YG1o{_0Lab%&bPsDvsN| zI~Lnz7|W?P4Vwp*D#CAXsn~iL>;2R6!bS-Yt%Zb;msnaWdP2V95lLv2nz%&vHL0=7 zf4^?sMn(g&3kmTtIy7W3Wu=timWe+C#(uhN5H@^SICD)a%y`|}_t~3wsO2wAA?l}b z-y{$6FlBX-=jW_Y`5XY-96ua&DpS%wotRgQqLus^&*Ea5fBD;xi>mimbS;K*{fcRY zKg5Tu$Y=gSkf}KE@6-N<((MYM2Zk?z`=J0AfQWuz~65Q?xh zmx(+&u+h!TB2YAB8obztfp1EU)+s=t+tNf}%IP`yOT!_a#GyvYYN@a@7wq@^g9G`w zU9K;*gtZT80GQ?VC@CDE_hQ*!V2;QbG#%N_KWq!2t9pI>%IJM9H*4G7WNt1L-z6?5 zZ>)))wj2T&N8#fMQ8dJ>J5E=hsh_FyEs!w4Pk98q=dT!~Em})BcFn9Z3wO10&AzfO z>R}T(*-^M1_KmhXpe1k3l%N)H$Xs;=R?c(}AVU$6q{<(@mmL!0vN=V`udVT$9=a_gnp9m0vr@jMwPVym>R4EXx?uTBns@zP zvw^9@kxf6gd{mS*-g(-R7eJ@@u3Sz(dUJj!pY0ZBPRj3}UrCP;^CoWAhj`(62C$X% zs?74u9)K&0<}I*K@5vY63^+PD63V$8P{v68U~#of*+NI75A*sI{vi9aYEsoP!r$J2 zw)3(zZL1|yqPMhg5AO8S61-epX*6!*r6VHoBE28B_9lEU-`ZIKt8>g+~M6kN; z8O7xob7drIX&a<%7kjaIZ(`W-?A)y7XO50vNe!w?qf7l1@St+kB+HPlxX4Cj0BHhJ z`03-GiXCPbSMRylIa9Z`8s36kO8dRtXZ7igqk_hl(>+w_R*R(rMCtRuj&wK$YbRGJ zzx8(irt_jEmDJlhP|{%KT9Mn(&y@TG!;wdT<``p}&R*&OsF%1#WqlagxH~Daf?}WC zzK{zhD9V#N=2f?cLqa)bS|xrnw!jJ7H1CQHCuzs>qQ9 z)fv7sX*3x`7bMG3lW>hfYWYE1E(1$-_&53tri-C6`$lk<#NO`A-gzc@R)w#-Hwe%6 zh8poNW+v)RT#lg%ZeA9O#Gm@sKHOSf@uCzW4Ud?ZPjWS|%Zb%)#gUtH+(E4BkXKj2 zSa)g<4`nR%^%Mt2IM;-Q6cA;;YFZc0PK-WhMJ&FZo(Xw%f+$O{(8G*uB*(VX3(s_6xqSjUuew%z)i zsl4lOCA8j|y}&7q7l6*$wuS@CfNBZAP3ZgR9;% zCboU7#j`T$+N5rkbBjy60-_Hz;BC)Fd&n~x=hmnxuHPEx#)uib>3=DlQ`_a0vEfDL z+PuODAw<^iJ-jafD=?y(?75n)#*yh|_)IFvh+5mVPA(r>9~>-ymlIvh}{Ev!VF*GSF#CexmJ8;vu`a9|D&H0%^pi!f4 zna$UrDRn}fd~Y*sJ;4PPz9IA8cKP}Fv3y5nL~_TNp%_MdYF%;A%`F1X~)dJ3hbVI=;%8)+8eY6Q0f4jYHf`tyq0$Of!K{+qm@h(HC4= z6gMxMba*1EEz?sGG*6r>1d6B05_s(i{ap14BJY%4EkgqbAC!rU*W6j5Mny(PE?k2f zZY|u41ZpT#2%KGvK^?Jowj#N(uTBg=gLZ?vUkAW&*_^N;Qt@1-In6aKa!5=DO;B_aFzk^u zgFpn;J%Qrh>3Iusa-lS-qo%Zd?{hqBp0+RFj{a$C<&KzG%XG! zFx>&j(uz7*b};ILnk4ehrS9Z{m{Jv6hb!?1$7H7+4wPjp7WK=-_nt0J`=y`*qbw|< zK>TlH*dypBwQd`!aHgVLvByOn4fLhfBb?W1G9_Qdo42sz5V^}C2qZazB>T{ctwR{= zjvK;`f&1bm`<-0K$lC*y%7A#*FMApO4%Zoe1ljLI^DyRWhu-0oe+;iJl_9`_iyGq* z+Q`WwxSKI!y0cm}^5R~yPIsWLilMAXlUd~T5aBfC_cn!}R**a>A(7!?;?m~`jvvVE z=sL2E$J@sCtjlFx+TUd3Fe5OjWwdB!w}AO#f0sO9e5|M8wopHzJvzi;bRoIeWeP60CXd5k6>rrHzG=SnUW6>! zSa0>4~9{gVvmn7Plx)uTA0Q0nR3wPF!7e{XoMG6C@(WL8BfWKqzI=I7}7Cc zjlSe3kRfVgNLh{u4!N@>FyBR~V^}lWegvQnk1sGLs&Z<`=@onn;68^A$IG|vah<~5 zb%mEUJJR}9+0W-T88Il>xYBSlSX&fY_b?!cv!y-)@EUBuU(6d!NoS;ey=3r#^zo4>l#H*V=K|{=o6jVCzEA48Ez}%QJ^8emUtR!dk zF|_}Li}R%*yKdgmC=a(}EblXu@5$pXH|S_9^j7o?jP)8E)9O>Ra#YnJcq1?f1Zcj8 z=3+8ernxich9Am~GWFC#z*CxhUt>pa2n~SW`zWJ*^){o{te+9KRz@U8YH3Bd%LS$u z>lt<0RM>FXUh(h66S@wLANURuB%A7@xzpRqKB#MlKxhnJgSiE~vmOC9UFupM;nsNt zjM0S_LnR*?!yw)c--Y)4bU_()w>R+nsAE&l>o_50-JmKVW}6pQtv2;$g)uCOfUANu z=UG~qWmPd}A{SOYBLC~kzgt_4St+p8^NWF zij6BcQVW-zJxo15qq>cQ@@dW{gF2_cj6x2fDJ4O(o(fMGQ$^4uELHz!!449HhL+@3 z@CVCJS}n%N8Udv<0fgH9;CRJ>Lo;WU0bE-jur+%uB5{+c^m?0XUVJN=R`>xM=e+F- z(?e3ZDG%P8DF#?kl>Q%2KwbK|F_;9|Z0mPbBvygf4iMVOcV|4FiA=(FtoosD9g42w z*(Lh0ch1TiioLI&FY0k691^6^(<`OTfe3s^(-wQPm|Q1UXYIs%iFCWbsDGZ-lNTS! z6Gc}Y#Wa(wdzj8!ln0SKp&t&Wr_(8aHg6jDiC56d{Nq%d!AQt0d55-U-|%cC8@O@t zd(%-ABL+hC7*X1;w09-Q#8J3{a=tw8OOp>FjQEfc}rn zuRkn0XdX!r*$R-{4o9ko+gwY^2UjoO9E=IpZN&$9WHt;%72=;H)=tfg)j%vvk z)00VKN`TXn2b2T(h|h>Q_SZF2^*DQiWo1FgBo#rESouGsK7Oep19x=yWG5&-T^pBs z-v}ur;6{p&w)!dv@Rc+9hCc$_D)Jx;GFX&G5L!vt%zW9KbGM#=^p3#)YASsl&O~?l1Cf7>KW<<8 zX!GLoC8%-h-Ij*e)2LhUbx5*D=)(M?TnNd%8S@GZJ+ zbM1A_w-jiEvle6%E?CqXf~UXhncm6QL*=LYwnYhIiv6^j&dG#Ks*;kH0FDx#ZCZ;q zr#-VRmnmMVQrh>urIrg&r@UCdb?$fHC|Nh+^vw(zQ*zH@K5-XyVQSM?M|0$PcfKgC z<1LNG&kL8~<(Zh)V^+Av?D5b@NB}YfmsDV1my6gnids5H=R~I=)YOm0no*`8irUk1 zOgiaRxS^x#=$V7zv*P0#EO)|}DI$4XOjE%`WX&Y8!|2B7jN5WMY!ZXt>9sGAYWaDC zq7_^ZK)Wp7`T}NNFWa_qa0fdkCKvF%t$rl=0MiG8?xGiM3U?Zda1c~9YA2C1mTSk4 zAMEOxCnx;ucLL;qkRvV^-Rn#g(Ly9sC*U>bU0{T+^mXL)4+wGns(G|^P-S?t zWiLcVO>uyDBFp`m=zvL-BDK2Si!!;LJuy4y5&sj_IJmGA7p<%Oi)>L}D~Q3~$1WR;wiAQ4l{Td*?ZoaTKW-i93VGDk;}j4&kc!0T8{23fzg&aqXJl%+~`$ zHD=|QTo$uk;x_y*CwliJ7@p7MpX3cZgz*XDvifJa_%aAem~YdcM4Y-3xo{mcz6Ljh z$hE4CFY8m;_>4bKTY%Neh!P@C8Gs8qy^fasHj>uoR4-)<)_@;~39sbuOC6qQ!q{Kl zi{G3|U6;A-z8h>V>2hsuTwD`^d)YjDUx4Yvv9gj=rzR94m$7{RA(zYR5fCP&oZN-{J*@d;1t=Weq$jAyR&l$uE6k4j2CSvKE7Llm z*4h@^KVV2;NgH+>{>4!xFpUn-rMX-}sH2D~ARS7OF04TM5o%(1U612yQK!7|!`T^k zQM&~G5{6l9Djd@$vM(BBQV#zkuwY6e>C8P zVN9Q_g)5*OtwTa&i1i_c1}iZ;cW45w|7>KnGICB!P|uAj^wTgp$hMF;gM)2o6SvKEH;YvI3APa|mlQrf@8ZzXWR@6Po(O$7jzzO@j^g^7 z@l;cYSZq`jF#v8al{R4Cl1wm>bF9?FxYQZUUK7GPw{rkN;&id8o>NKNJEy*VJ{iR z3>K3gjofl@fITF9gG>~Z7JUTDTF?Px1-lKicWyd*BJ~F*LxC40O4boyL^AoJi=aL0 zWTUBhB^Erm7aWyGjwZt6bo2$`5!jJ_y2@Ne3IHqW;#xPp9 zgSd{5Ioa0$-&*LOE<620DTkEmsA?IEwzX{?(4w(cwxn)WZl$2RPSiE>@^EVZa7eJt zTKs3KkwAA3Z?;NzkNtbjh zmdQlYpuEXBY5w1Jr~Vvr=L@Zt2q)xE(_DJRdBqv0tUz>OACJ`a!69QzOl&22v3}gq zJEWq1B!I}&oO{?xM0QVlPg+~2q^CRC1FkXJi&;^8JReBx@G{|pptiKN^!3Y{(AEWx zycUUziY~ORql)ZL5o73%VM3ogVVa7&F0t!+Kc{EA6qSdeX0$iAM21u8(MVW}zh`HQ z2uiW`k2EU_vyQ2X+>S0D+5Wx_456;)k@LZ0TOrVR&ZX9#_Ts>`u1C>8-o~?zFLteb z=ZkssRmK6so6zu=6co=W$bXTXbh3>!&jS4hpeQ(cONOYRxWGjXuDYgTdXMkZF2L@k zQVF=Kx5;Nlj!VJpbWKhPnF1nXR$`*tE0Zh$9SZcK_}uh`5Gys zgF*_zp(uPU6MPxHvYl1&5p@nIp+(hF8=Cn%k1-E z*!atI#ph)?y$vlxyZ+Oc5K=2oLd80oNggX=_NfH)Dv=Tzx+hNrIK_1;|LVj4GhA*@ zl2aE>b6S>#TH0WPTC?`~^la>=LFIcqA85!U;NtZo0CtXhibD}c4J|5*!U5Fs z{U6z=QbrJWcGf^yzuguQ~!H_wF-^BK?RI=i-fE`EM;Xn)m|5`KFt)o%Ck5zwjX zyOnH6@Ht83zc_dJAz~A5NA6=exiHuF_*S{rBNEN29mjDK9EvJ!UrY@Y-FKb({n{oc z6ttwkMZwLD8CLVl`K1d;4IxYU_GItWB=B8Ea%o$i=7Nk)W;RE1nevrhxR)YeyDD7Y8IVXygW`onS8uKA4ReKZUgI^yYU+X9Gv$HiS zqXAf@`BOp77}}vng4+2)mH@`7`%KV74FnpwH9bySrGj63*D8CgA4tbsizGfJc}5Ak zvP1_lkt6zTbUS0F?CawTfO)Taur-8thikY!st-ogJvWMXT* zLMxLXMS7VE#4N#9g<>29w5)R&LKs3`-accxZ3T}2LGK_>w-gQuEKQL86i|L~1j^*B z{OJUuyfJZ*ZPls{{aiZm2>3Bu330J=}O)yRp^0F8Oa2<+STFLDJ}dT&*^jOt&bs#!D&)%113m+sht@S;C4r zjVy%Ux{FqIygV<`QsJCS^W++gaV;oG}v8Zq_fp2tG+&r?@$9xPi3V+cm ztiM7?cJmBBR*kBFz)2I=HlYvRBeTs`o{nc$~;1YFS{?_I4Rb|9q2m15+O_tX8b%LOHu6HlXcPIR=N08Ahld=|lG>;1lS4lKhU+&y2PzG@d`Inz zVctVk84IpX$Pd?%=;^Gi6osX-H1(vIZR8`I1U>>lLm~Js8PKhCSA?t+oq>zuqxGh6 zP~cAH<#FKx7*#0`Cb6FEjX#+Z>4zs1b^l_5=KNMmBNU_~0cxBzT4}3|&)vZ3>D7|c z$1;ujCRGb_2DtW6WMUrPM#zYAks7qpwr>M3q>{0bL^U(^8PvV%vYSB3A3<{Nx$fvvw@QE8*tGWdG4sE9RyyQRHIT0sm! zG!-S|_{P*&kI$-`Crg>RAq@pnMaL+oENk^BQ7!hqUgc=GzM7S7^b)Zs%apiQkYX~u zYo-yw^ZX`==NGkKjy#WZ+#wv$XF8pO55AHTFfOg{qZ)-IHgmUf>*uT78N_Xl>#oBf zM!yCBNF1~hv=a@iP>#r=Okpo9O-W{}cNUL53~7-eFh|x!lnW*1jh&vD{b#7+!pNuwL9%Am9EB;zSD^&=pLpn`pgkso)C zDatb*z~=6q?igSauqiWWyzeqDID}#+h@6JL+-|%xl-Mc-?wfHvM9#m&P8>1OArYwG zl@q1aekH}^g^CRGt{t!Gm4evZG)dw0D_N|pzw))Jzq|n%ytB~unob`8T z64{v&p6_=Y-$=Cwy3MZ-n^kAw)y3O`^j?Rkr?h$|;UMZ#u)u{$Zd}c$kD0WSo{qwu zB{f%&WOU>3(ig&y>>Uc9%a&j7u!T}iuPFQQsQd`>q+V@yGFpNQkZDg9$5!4Dq? zgPc~w?TSZ0f1}9Hfwd>htQYYv`!0LAX+%02Y~*zdOAE6&%FmM5MW*qc-~H4gjpVJD z0FnbwneVO99|5~64~UgvV$HfGU$I+W_?^7!IB_D@-EDHlkP z!cl_jkwQS|N}L3mhId$peJ9t`-BsyDRTiR9Bux=9u-3X^C;KUT@CYb#^bLIV2P{Cp$7v93h;nQW&$1b*X4zfuoO61*T|3lU{Zv{&ivH#mbRGQv`LWA?Eq zUo#Yp{dGR=UrNO{`(8Y0qC|g|Nm12zYXp7->EptjWtbkM_xT{LK)CW*OOb`;H;S5JoYDeTGC`D-BD_PK1MYBJvDp9>WnT!exh@N zB$x79G;2vtLq|@F5hcDbS+i3MWrg%(LalIlA3UKvk9E>{+a(6y`80dQDdXlrYOM9x zEN5iQbj5ACYgkKPyp#3`*83Rh$m8TK6K@LvVfe0@x1vm0ahuXRVYl5vG}0%IoIk`e zyJM`9mTp8@wfP-u@VX{jAXOzIU@1ryTxEYn-vpW@w&I5SjWdI>xvzr(RX(#9`^=azbTNyt6+i=wtc2J3md} ztbq8+)&Spc-=G3CG9wDPGQDZJQ!aY@S>L$WD*Jaiw&JcUs^47860ZY>7K<)^HGpcj zW|8JAsa$Qvi3-FVUs5~$Ieox5}40=j9R^o#-12$kXBIEe3Q zdfpH9wfFHWX{ERRtk+a6OQ($jLe${FRndYn2&-uXEh2zq3Q`zi>Shk3Tlq87DB{Z7 z1>D&qrlX}VYiU&o!O#~Z(YxR13-%^0aA_8SDtvdR*?*YfS=r8Z7*Oahge$I>uugcf zWM~_%HM(damX5p%aDQ5uq**~JcrnJzS9Vzb%B5nt4|dquxf!%J5|J-_FtI)_VOP9Af0wK zG)^t&c(HPS>SQGi|XNMQ1c=Hj$^Y zl|6jvGfIM7zCyNG_@g!9x35Y~dGBeOH0BnG=5BmenG@OA39TSs#`jach`~B;?1%93 z%s(GuoYobVuGVjtD?6y}X+T`j-Y<(FhjlZ_GT3cdL=NL~Hdlf=Fa7Qw+n5tI?^T)a zINEj3jE-HD;P3;+WL(1$@w(|v(8i?)7D(e#)}_jwi!aVWL8W#Vt2@;b!UqC!)Fo`F zs?SCcmG`L{Cx*|40^0t~&x+0znjZiC-Gb`HgA;oNnpw>+%MCI8JUpcFjsS-%0M3`N z04-Vk2}(bZ4^Wz5o8#I+Xb1E!N<^u#!N2>4N9wwy{VSEM?CXDVTbe32>R$pQ;BSFn z3Gz1%zf3FE^44n%omu5KzjLfrCihwkIib%SL~G_=@hG+v?dX+t_td zUPP3Rfv!c~ifWUH6D~&ev*iLC2SMphM`kz??aR{L``&Ty%28#3JK#}0TuT>+W{$xf;s z0n_MIkAOO6^y|4tz#(FMf$#X|Y2HNJqwYe`7N`Gu!$VYQ}OaYZ_C-?u1bUq1st3qpVZH*Or}L>D5yJ3sehelwCdjkf#pY{ zMg{ONfGbinap^`+SI#0kWZ~cEj5(~>9|7MEL#BWqba`kzQ~>a_w`tL;4l^m&H2Tcu zvt#9PUS$4-JF>|MUQS?B{LT$d<)v(_BieS$YkpvE4vTE^BRHrQCRntG&`K^%<^lqp=@lh?bwf}AhkY@|(hMeNw(yYiOo zu-B%n-%(m;qpD7KDBCu#w7v+2NiZkNgSF+vAXchizfH{s=ia^@dSD}?8Vq3w1V*(B1-CekSqj#Z#fz1l4P!0MwWtt| z^Bzulsq#6W>p+m&V*ZWJcDiiV3~lEa^?JRUNd$?$K9JL8z4=9vRLOy^4aDIYTLM zPO;utjjc*Jj$`ni|8CLFruZfa2c&@`e&=%X_4ulyK*=g$!y+C`@2Q@RESMap%T~zt z4r^{wqaC3+^(qQ?E>M0?_Ie2W9S@)GY%s|itfS$*uIq%CTj6(}N#^0D+9m5j6K{{~ z3Qr2eM?3?iM@CKMP3qC&CA|fmvOgG4ad;fm>+)V?H)enBaJz{nUYwq(*b7nm{8_8= zA2t*I0YEFH5yu4IcGmK>o|>L*;xns5rmCPRlJ@ukLVRa4GK{Zc>`wax49n==pI7MF zNQ74D6I!xw-?u0BV2(_pvc=DSS^x}pATr+Y?sYLL1sfX~jWW(C2x5<-{d!tX7nr+3Y*UaM<-w zB#~<#4t)^vzNlMnND?Yl3d)kHFF8^5Vmvpn`*4QKT-k%I-e_gf1@@*igSe`Es^Ajf z#uG~=fClpL@?ItsiAY7t6`WqlIkcwf9Ik^}_@5urm7tm?o^hvEhH{gmBl1R$8q`f> znWPC57@XT*sCgQeJ2Way(iY*at*Imk>p)MY);@Xs8Km65eUR&C)=t3Q*k?|{n4Ft# zcGcwPAZeF*UW`4S!fuhTJ9%G((m&=;4f<@1Vx~1V?QoGOk=SBMmG^PI6U9QB+AlfQ z@C)8v@||Pv5z_ z#99;UZXNa$&*J>#Zl=#oD=WPEHaB>8kf-Z<$Pj)QZguPRSwX+>ANlxaQ+rLjQxH?!zpFE_P>K2hM{WelwP`Skr>rwjGV`$EZspx3YTxq?% zZdRp^6rZaTWvdxx;qzOKhBJ#hC|aLS64!f~enjkHaChJSkoIYB(^>q6zOhKp@kd+V zzXjL8yQ73up~WmIB|)06f}CF`_kyEdjl!?ykd&j`cqHq#+St%_R57;6GfMXqaT5I= z1E?0&uStj#o8N8g+m-c+tV_2(w4%kshK@)>y%u9O9|6ZW z5=l8*t+GFZ+k%K(JkAHjk{42ij`%j~?Uib_kkM%3HFdta9@TBaOmYWT@;hfZF3zn5S7hAR5IF!znlVR$$g&gJrFLxYf#rzQB~)U=ALdyx9MN1EoNav zgU>m{4DhKrd5-C5J|-uzF=1k3AqTES?$HOsB|is|F@9U*8p558mN5&8+vnSl^K*dj z3T2Scq}zEGJVI^FbY-ulIfhl_2_mEE56ACEjgjlOE`Z~O`LfG_7}_o)Y0*k?<~ehb zXg;Z>r8cC3Qq!Tw@Y<*$jGz)9|0ZQpulUH_(>veZR@}U{vS{@0miLnGJTmeL)5F)M1`Hl8CT04=V{nc1w{*p}v7)$}+*~hf zwNcPxxw3hy`z6H@ZO%!k2)zu$*;cxqX?=koMcoY8oTq<%;wYmg_^}+Ldz}&#!+M}t zJ-e&RPRaZ_*CLHWI6z`Aqu7{O!7MATfwvS{fkb?GUWG7ov!YNaO7H`0ok@p}-NwX4 zFwnA!>t@tyR`R>1y7G)>KR27o{z@vU3u|OZy}4Mf^M^w!j7iBiIG74k@2g)!gGRjt zMSCjZwt4Hf9Z{cp!>oTD`Q-e&dwYkY(|bMj7C-w)9=8;sF?RcXBAz$wWQTKC%*|z2 zr6QXG-}odd=-Sp={%M}0DNDzp{6-9wo1aImL&vZ_C`rQ!>7#!|WZPF}X1juX5~gVm z;hH$zTdb~RB2s*Bh3-D&N;K0m)i;K@G?oC~kWbx0x7PO4ZrO$}&8Mt$?-rIPlDV!h z@$k5L{3f?j`|HW>rweeCuS&-@dA@PUY9xISS4Il;3l04T2^{iKbz?t?ac3;6TcCU2 zd~5a2$z+=7i{MKq;V&%}s@I@)%-u>%*BR(jbV!b{5rEPP`B%%IX0f->bX`3_eO08i zy15j-*Q;ygC0B9_g*Q@ZR>^e=-(tAzBa%6C2fcr*NGmv=@}e98QkXLq&9IoKZ;*mY z4Muo61!p>GjQ_KcwI2Dx2-WaMPqPH_TOxckAAN#s1D&#N`3nRM;Sx{IHKYrLKYirD zRXhA;ne(>+s|_qRv;U`%N(aJmXTPN(7IH*{4!-4Z#=yoAReZyrPKR*~A5p3OZ_fK~ zDgRsOzt;(W=0*pktzhL96osep2uD6Ps5NPQt-cB8%=C; z@(fQ5%ZU(ojaQe28UG$IDXHT(&haBLUp#K;z}HYDTutuo_NQtsFqxjWwg|z9uM#`b z~e0jqx`R=GS%<(Y2D66vy!haZVEU*S7rAwpawP{2=v9n}~=&-MMETZhPB-=KmDUNqtSFMX16(I2?rf4owo$djiprrpW%gbA938S>d>G zg720BT~`y~!u`Ca?X2Z*KuUrSl}s{Nvt_*eBO~a3<(l^Igh=?Eh|L+t|FJGm=vT^u z{ulu?iGF1))$c?kANw^Rr2UbHNx{GE|4u|{j$dh6_{(#n-&v{fI}uU-HuN-x{SDo( zQThM2U|?<9qkKM-vy=J*Mh~0H0DSKM2xvJFNsalDbigput}OE1oA!e35#ZSFbeHfj z0(}JB9Ntr(dLcg?)cJm&y6c*h={NVle$CRbm?mTOu}O7E0q-_}-TYJJ4HBG>7TbRf}Li{NN!71qO=AJ34vu#!W!d?>WpbF&8Zy1}GB=JbzWe+RB$|#dk@aSK{uCBkI$jZ|3Z*MJPK!$c3vmIu|RH z4?A90*s82KGa{#?uOK8(OJ@|W`ROeCE)C7(elFROr2h($W^UOOMzr$6rPyUre_EWbl#(fI*oi&! z91(PBO6_M63(o|D@-Q!{MhyY98etOQE zUUJZdQUMnDEY$#diI}{*AcS&bUg@r}&3qBYDvW8C4L>X6)SxmassyjD*#W02yNj_H zE?F;5ctUwu-6ZtMnRsqem%mkDOlmgc>l<5yK<}cpK(Q$1nHFVq(WxwVO6E&;prM@^ zSfFfvB=11Hf*sm^X6x>MwcTz*MpO2{yfavav%1@;`x>MWUCBpREIz|ACWpBwg({Xm zgQ9zG?Qb2iD24IS=v1Nxhm1~hfb2tVVYABSV#|sq50*q}Wq=r+DKXk~{9H}Y2au)t zyUW-0cv&$eluv_e?SvZgb$94xKUyun-J20ed`E#U$lJ? zSW{- z@tKEgXz52Pe<~Jq5M@!Q-W*~-gv=Fx`yqbyhy1k`yABX!1uCIi<#6DGsQP1!9d4a$ zw)9Bk{7)YD_1Ck(MDGx+nzJ!=ODkP)_ifc{=cb}mr`XL?DM=@nFJAOJv+#Y|5a=cE z{vK9ZY+P96f+K;`TuPUos3&Q9KswHa$LoI$b5)6A1C*tiZUxtY`Z`ipB))P(KY5&A zWqEH^*)rA&&rpvvhSTchxrWSy2dAVRpZB*2)@jBLkjOJa=!h7VES*TZ(t+rrh_iTM zOYXFvC)Wq)3W9>m=Q@-Rxu<#P@cTd54lI~1-vfC8Le|sO)X{mU?~a5jOHSeoA*nU} zyBWPXPkuNv+BZa6?aoNlJJ{&?EW`lSVnQJ7s}Jutmh>EgwsfFruLsD5Hu9r0l3W>j znoJO8rY3>(hV7#;W}J%DcZ%g1PUHY*0md;BTIL`N^rOVJ9^|xEL)MdsM9=x|nTA6` zt1|u1Mx!w%1PrN61{M4_FIN=Cn4`oN+k_0|i1Fq%PmFr68#NaWGdUI9!ye+$!nUSG zuP(`qWI-s?XVMQJjkfsDYgb?Y*Kvg8f8Y4Gy&jC~b5J>Up1Z2&cLQ#B{oS3Wm16KmyvPQQ2IfL|-)}6~PWIyFJHPcJuJ%H!|rTiNj=2*x*pbuxWkB6P$uKTNd z7M%wvVEb$xop{f2>jyVl(==Te2S-RXw>v(E-O)CwtRp3OmlV)TPGnj@1O=e1+{z89 zR9ctm@&nTJ&Sh`QC|g$5cW=+Jn3;@_BZ($E3Ywe@?KU%1ApTmi(0>pn|LdaG4=tC1 zhby&5KwCl9Ds1I%aur(q&RVSb@5TDxCw~xCTl;T3_r7B7h5SJ@Bhu{1q44q8%RD0I zX%EA;e{t=+$CurWSrcsMkFB@Dr!^HKR~&h}+XY+X)4x==y`R4QrP8$5oUc6;jQ{OY zUOQw|Hs9ko=*>~uV{!ctB9A(*LnRwOzPWBBgi}MZEuwQ|Em%cL8eZ zhyVJ;_>0V&i;GGj{wyo{MAT$bS9Hqz-tb2~(96@(Q(M+u@b3R1Am)O_18>GuL)F#U zpigtBt{im=8b+c-jE%K;9j*O5jl!fl`?IHsnETx8eci}n6K7p_hi)C0x%437$X{`n zH)0wpCLc?*AhhE*Nq$}9=0=SyXwBj}g7gOcjCj*EkNvEpJkO3N2c&&b%O?AG+h@^^ z0&gGxxVRMrmE`6;tJM8A6WTYza(r6%tTOHi++D#pklKIfwTDRHsW^0z2e)_H{0^J( zIaN!8IpCDw7BI6_mnsP)H<(WQss9+7=^9n^Bd`Fr$WC!r8)wEWCDv5eX7;ZuTZ)&+?!=oGy7ur4yp88MUGBM$Oi>fF#S#%Ck4YH{;g#r z5de1qeOS`h=967UcP&05rIa?bJ3k; zg4CbH%$r_hd}hAJVU)5yv7(0QcVeLTanyyM_)aTor~p_9ePa_dmg4o{^R%qc8UOaE zY?<=I6X{OwnzRJFwQ&_~4x1$)1rR7yp>EZ!@0V^ZF3vL2t!~ovXFvLHo$3G1s}k=| zx~<=Ze;Jt%MtwOg`xG(OeHJR02mXVo(d+q@MthGD+I(-m;nULdbMi`yzND(BS>To8 zWpR6+^2nBgFpFhalB!F|Q4wXm<1blDhqjKk`P~;ZVr*}&-@Jd3Wbe-5neOEqpoUbv z;d1k=^7@-JS1s$n?N$9 zaj2W~6x3o`Y@SzkgT(iV&WX@92&Q;u`<5Z~dK!~kU3!9?L@oUF9eciHF9$~4`%gD& zy5sgk`7Ji_g|r6yrt)Pz!VRJG&ZDb9Krb>iu0>atVSJ3cH%j{OX#(|b0?~m&bXjrS zd)2{2^mY<^lzVO^(yN#Cm5`_gMzc}J(sHJ+5j2VpuKOA>l0+5pacDre})V?G?HPs{J zL(~&QLvGC;nTu50?vUuiBW3|J=yM};*RFcmP@O$S@`WfS0NyJIk0IK2Q;z8;*eg9W zReI+SAmeRhO@xVHpxfp7MfqVl`u(w5f?4g>|lg+%uNttas5lwMAUMMN3R+-{j*?p0{E z6e0OK*Y;-VDiau86bvK$Iq>5m&q*u;&R*zvlAOySXFGS@FG{i|IO zgpIDOTy>3G{}R~r7kJ8V(zbj-B{LL}XZ)PUGQQr4ulPY8H4;PwQ`%hMd zbQjf56J_TPJI!z%@mIeXu`?~GW~&O6LqQz5$<@bI)Mn3K?FwaXyrnT+8#VM~6kIGT z<1I)ql1jkx1-ntDv`;l{sh&l&z!GV_r6fTLmUf;M0EvgkeT{p*J3`ioF`el0Q<)Z~ zb1Bou5~!Oe{CX_oQwd{6M0Cq~+(-|u2ipJQs{H%YZvVM1pZ;yJ=Ew2c{tTM_Irh5) zK9q9V3cK9CO0q4R3BkMH2I_5Yho4YWTPK(JE=e^yltu0)y*Bl#pjRw3n`0Eu)2|&U z_;tX{!BKq2qaCtV97m?Tv+m@bGPeX7Cx4Hy%yI9h+T>2!lsN&ZQKl~I0l?e`Png_u z%nc=|Yafe{{6VxM!bVnCIZpB7cJ1BOIeh~kFJAjA>&)`^sj8fgGv{n`E34zGw+BW& z^+f_+K_)T--aI^impQ>U%hi*Lft~`ZhF)R=2An={aZL*!sUfhMS{XbZzHDT=lriy) z!15u`s{nb5F&))ZVT<$r@vSEL0+*Ze5txS>v0;#{x~A&~FN|~tu2DODYmi|Cc2uzG z`1Rjl=K5^F{4DuA-S0GDy{q_VB=WBYE&u)0|1W3wf6~hRZ`jU1ydqJ9Ux1f8T-QR| zO=WEht$#5*<1d@&p{e@Y{q6tT7OYnZ9=0)8MWXy8CZ@7qU7f@_X3umc|BkgVzU7-@ zqHtZn-eTb#kG&&CIX^|PN40&a)ORy!J*YAyDJ}w~Te>un>FMbnkYv+NgvNW;W<@xB z!^ICDZSzf7h$$V-6tq@n)zgQoxv^~zZ;5}cxqwWi%iUbZ7hDhEXpcmH3-2~%I;5Nh z)Wd7%{3yhR=rv58-(qjOdX!F0*U5P~K6Q+_arYph^PogtwRTbXn@}3}R!MPVtNKV1 zjg!c1!^5e@!tVP0{yUZfo*xbDy3*Z5>8m@~u_b+~?3yoJ0&KYDWj#INxwOXWHUdi$hEPCR(&-1(EGKNHRKN4RR{|2+h9mNIcg?^OJ(K=gxaaCigBS ztLJH0?wzpskG(wbWXqC#wn-VnJyQ5JvJ9CxeC^L|_dQHKX^tCH&l0_X*Z0 zvOXr4iysw1WH;yaNKbcOYsyH!L7KV#K8&+H{9+xzG0Vi(M<$if^>UaVMKwmRZUEkj z4@Y$OWMpZ`yB=@lp-PV5D)EJ7<}oz1J=}$sygD!Npbgy|dg)plhxxQRsINW9H{~Uf zk9LNJ$vP7nm1-}V(rycfyJX#M=$~EkrYcQM)~c2F;*P~Mx&D0PZXSinmN92ur;OR; zoRV;z-@8($67+kFluxH=8C!>W>Ww0*GGLTAqp|?x-FS8CH)7{@mS&(Cqw8%C62XyE%C1C z@hJ4&EvXTvfMcvQ#bS=8&C;s{G@+6q+ga60?;ZSIr;Y$xV3VDIJ>u;J6Vd<67rbOpySYv{nyQcsu()|4QJg*%L7y%MYrTM-b+mFow- zkzMRiPm7?+melFHB_9eA^=W)==uGZB_je3#1C>-F%vb%C0~eG+5DcN&JN$X_m}vM^ z*cwF6?P}GZ8QJ!j#NtFF~*zAy?5y4diC*>_DMAuHr2wJ#1l_EkvwnCW2 zsmVy0P5_frG`GfL2ErDVxpUE#UCSM320_o$G+_ z{3IjQe5pwSkvQkSCA zD22F?498Sv2wPuWLOk@&^_%in{C=xgZ|R@}d3a^+2l!|UBGrs z6dNMZzNYU(c?^@T7)2J%8@CyODq&&ng#iUuro-4fH#kVzbjBuIW||F<^ABA=&6IiJ z44`v@3XtIUO7%RQJR`Z+zRbza?g$f_UAyRO=PiwlK}zrmobFr{NU4YFtM&`sy^mx{ z5kxA7sVkM)6gnTlRzuh;NmEN{HiT<}atMN3)hs{bMa-knTk|D>W-GnI%Pt z8<}BoQ_hkfK}eX@6EPGCprgfN$43nG*o=zuM8wq99s*n{6|~BvyPo&`y!SmW?_G~l zPz(TT9`HK3&1*rBnb?Zl|MGr7_CxL|GAj9sX+v`u>;YFuD^b<**!K_$jE1{WCZHZO=yn{UdokZ;D=MAL8ReWy zaruH|ef(I_{|};TR(t-l`!!&z%>uaTX}tn_=qy>ZvKG?`EHu8>OXlreg2ftZp;yH_zPN>-v8dAIL8iS1@$8f2uS%q9AHA%p z6^33h-i|vfTU=sR;gJ>a^OTaZc*f!pTwZ6a;fpQ_>|HprRT`ZcsJ%8yIW)l%xNG;L ztiIk~13<+Wx79^|BXuZH8XhPzJE=Xpm3TxM;^IFZ8Vc0KzDc_fgoNocMMPANgrIYa zE6eg{S~MTW+BjaSVX_YxNKVJT&8PtWCVF!TSBP+bDmMFY=BQiTMsbm~f0YvBN zvLb1bQudmS{u7b4y^WU@WvJe^Ot4v(CtOYr&Ej74wBgI8S;@vUc|Pn_{7n{}t2sWd zBJzT*j6Bm}4BTB{{h2Xi4K+P2-&P|bXX)z?$Zt7$C$!7%%13ZqW8Tgb?4tEQ^QoV6 zD5F-89gAD|{TBmel)0^-18=UJJOzD;_7bgLJIGU>=shMVh z{NVSlq)6P161%m+ODv&vH<(_9U;r^};hP77uWF6M<%5;#bY8h)G85>$mX4~bHQ40? z=Jo}1z|&L-%OLz1Nj?sc{+LWMV-4K+;8()r5@&8+4fb(+6uDGGsIfUGtfDGlT^Jod zp@1R=S}KYyDe3N4a|nK1GaJ6L6tKGH3{7-K)rkD7zqj=~aLX>1hq}BThYM z!1kN*^S|1BXpaqo+Z=?A041vKaffQ)8}-M7vjtBvkGK=}2E}l zig{%9H3pxWmuy7A^i#)883x4Nix8+sYnLpBn5~Ve3pK;yukw*QXQxs#p|k!?bNgZn z?FyD`{e)b%r`;Z5j;ks1A4lcGphi08+EoU0I7#u53MMIINmIWxGkSE3xqYj%#sN}L zv8`?|9ISK$p~1=AoG%f2hbqk@rgG+==|rmb{k6u5)wmex`jKAh;j5gc9KRl}`%$AM zn!w^yzx=vF2!01EwG8`o%gTsUU?GS6(p&ZG}2@y3dqj{Egi z3tSRJ0jKhriedrGN~g|!yxmqm$Z8=u59eTo_;-Q(1vFS@E^)j<=H}NHwc5#>{7Dhx z{>(|_nnGng7UZeJw(zRTB!Z;@?e2#_P=+-dAo68L)od&OE^I;4og;Zfw_B+My7zr6 zZ;T`l8RpErKU`XtS~`-h(9DzA!cB3XAUwRa`ni&2x8o}Dn!JCWb$XmMigcvm-gpnZ zas#tHhgbLWC508v6=elVnbu+3Y1!Grx?J57Jev?7Ujag!eB~>@+_ZPAjx6?zdSd#D zyCASKf+>LicZNl8(%!UeRE0$!WmX0J_(U)0<-2>iFFv_U4bQrU1Y|>qA&!B7F??=L zV@1~!fhrktI9yF&9aTiCdu}qyA44O_nM!qsqf^1GNzPQ=wI~}iM$=NfiLCtPmE1_9 ze0Vi_q_U81VadsRPa>!y*E{>{q85*^DRgPdg8#g0>R%dGr#;8*T=*fs#BNT}V=;gC znlFo7ssmAkKM_TXZlvQT%aLz>BUA`L7dZ7ZvCHq3v)T6GLP1L80jZeW&JCh)50#cK zl@%8Lnv`P9sqPm|Im0A`ugj z8_n(sMrIB<@s4o)>PD^n6!}NrQnfj%Y+#dD%&$qjDM$@OQ7?57G>&;_%kUu!ey!W( z+K_S@lU#>D#?cYCgv2l@`h z?NbMO6O#1viK(PxzTJN6=+kUnT`?CoW;RG(s3Eylgbum?=o`hW?|!SO=X=GFl4bAu z39ODWuT%1){`bbRWAEy78C$=|yF9}SFf?MXfW&{0w*2>&?Z5M`PBhHXF?*Y|K3`(Z zpGY_@h^q$Vkf0J!YxZT~KnjC3stro_-1x5&TFKO4KhH6#Tr`N)P^3{gYFme7G`0^H zVO;Tg^UFPZNU5(^Y8>z`gplvE)546y_ys<{<;OjXT&Xc*mb;GEpiHtF0b*KqXGLn~ zx!@Z5ezzTZ5z+|(FGP~=`nwZ^P_?#4ZBKsD{Ol5?x5Cp)!A+%3vA8{6k!Q_YzL67( zGCPx<=L~oK$)vl?q@|`kcBYq?b9M;{@<<;82(YtAFtoq0AX~!BfED@OHf6Hw^A<4s zY6}F9q@?FXMxc@q4+sxdU=DG7L{sAVFWm0=A1UivJ+In?LaS1i67@Xccg>VnHNThI zl}IOWJ>all+1hdA=303;rkpnK-($%ujT*fO_6AE}_H_i}=2ZbUehn_ny%ef(M|ZQ`L}2m}<hkC2SpT18_Xk_2{?CMpY^Hvp#gkEr^@*yf>^Ct%AfQ7?{?Fut8B2eO0l> z(PkH=F?oQHScAX=LM*Z#?(><+Z|{RW#+Y>C`kWmnk-D@;zw<7>Pb6V7UYQ{mV_n54 z=%N_jsypCO7*;DHYzKn?6N%WOr^3;r*Y(9yp@u1$zWt}6oj-=&Qpi4UJSGITEhnyi<*r<8C;D*E8&i zRaHQv$&k6su**Jm^~c#emi_b&)d)T#+VzygRN07W@h-8IP*slVJRdK)B0xB_r|jJV zFraRFVWa9QTGbTYw@RC|XSiY6y-J~m@`2jR->h6W`6)mSie7Pgn?%hEcG7g!hZLil z*M~9d*!_Gxt&1op*ObTdIvs}H=QppMmgz92JtlJ*L%TUzwZZP!H9w|&!ZIh36i|1V z86Ss-E-lhz11+4PZ`Gev_EglVNXwUQV4yKM+J7uaELI{ucu5c`$?1}1M_i$oH=@R^-EKS9#A&X;U@+~2YXj8_uw z%+`nOX2jHKeF_)eF@9_>Shf#+qO~lrS~%G5Vl2VgjU#@`cEBIopJRSqj^tSjdj!{m ze^`|Nt^Ge6obik7oh_Tfl6QaUwiFW+Ks)WSlVy{C@*c2%0ylME9d@Xx?f%tH7KlG$q>t!F?4+COI#3GCS@!hjB(WQ zm0~L}atU+n4IE!xHE9wPr?<7UOf4(rh zS-kYAbMnAJRQdF`+2pUn$%UHt+jk}`JY494c0+fB&T5@y=Di9Swr;wMZQRir-XeXN z?Ry~EJ#HT#IZbchT*_BiT%1-H)IXw*Z62?|NteU2p;p|eiS*L;_B6Q8OScE&bh1|# zC4^l|4f-1?7~6?4I*l!{^OWwo{$DXe+d{&s&TptKJ@zq^rdTbL5h`R7h;H~|Zgt$; zjGcaopQbW^;BB2@4wk7GL-oNNuQ=ri$J|_usdl5*ygkqouzk7}moq84DYrbzTz(jV zGN4L&3?VHhvLV*NN^PG+oHaG6mpzIKCVRpgC6aOzm)JkRgOPHMsQ8Ss{K@Rtc~`zW!jND(@JIIiqNyiznm%wA!ZO ziHvH8JXL|!O5nBJVA&QopZs{kbD=I>?soR;KnZ+Q?7RTdyqCo119Y@{2KX&M71O(9 z0RHa6ZHPMi)`d~m*lPJ#b^-t1c)=B1(2hBbs+^SB?ecB{n;4J)?U*xo0&Y6x{7zN9 zaw~ADH=XR#FaT(%mq(!Zn0XN9r1go!5^F|8MC+MgG?#+|h}OMLY3lfw^T0U+8i^=U z((o;*w1=U&0<-F_^F<@NIl4GUl7f;~!X@{tW)sRp&a$(i0%(FDfU&0Z;AN`jcE7t* zvYgA|@#Q__ieU)bcah$fh^|C8TLViYpZ1Bq`*^xxXLYY<4--0uiQm5bd1tDAY9&F@ zzqGKltQxY57Jy8FMx@z%o&wxQKD=&}c@avq1Fem;{;h*EeD=f#mGyL@>U&7VSXu(e zy{M;A1_beLunOG!kXsTZ&naQrZqIy2B;|7-M=slHvFvqHOPbatBT@7D#UveZ`WsS= z4_u#$c-|n@oI)#T$fx)&_{wj22owd-S3`tb=zhlS9pxL;h&T*np`HjCA>JesZdhk2ZyH zjS5nP$376h+>H>}#|QnW%AUSK`$hV$_O8s}v~Q4=nCeKgO921l9k98wg}CN}jgz~J zd&7A(I&O4zcnQ4+{ZE#+^;)dr<*K?a1b zVda#e^&b7N`gW~^m z`8h0Cw>fQee6puA=q*<3$N~kbxiv1j7UmUKH5)FhdJZF8``&RLUtG(R(2IReGm$(d z{ll+&=E_CMPm@wQu*s#eGO1wJy+RTBm|;Ou!$A9*;U)8%7!3! zN|_%G^n|lHf&9i!9YxjNa4-vJxpaMZ$!kBK6Y@g4Lu@U5XSK+)mr|YHa%P+z3F2PG z%8uCNG=5T%cBF|}HEh59O$Wv;egz|oLJlUSCGa*@nAB~~B)JuY*-Ki(r#9C(^QZi+ zF|W_9s;XOL8xX5>lA#8^o)u2z@<(j`0fx2~f*uD&TmmuCQcEt!U-gQ(+aX_jMf2WJ zPeBjvu0bHTLvn=u^tW^chVo!@<1;TsgQ)S}m7ziPB<9^_U$KhbzKMH& zmsv^0T~GsFi|K}yV}j;qNoMvKj`8O>9P&ctuzD>cPVDUCq1&cG1tHu;L8)s0OXd$W zc4{5?+&sBs&}(TVu?jpbsQ7*~8!F^=D)SR=GjSlMS_dP!@8Z-X3k;1N>3VTPFk3Of z&zq;Kk#P!d6JIJ$oH$Z9p%CHb{$AgPD-stKDxBP?bP3>=#D1JZzM^WSHJt+C=BYS6 z?ca{Eaxc9Cs&C7 zA?I(5e(JPz#BGJkY?p^i@)EMAo4C*SJS;0Lg5n4PrS&FO_nZ3vAo@XYTTjF^ zFRBy*)^l`D5ou4gT+zrpUvAsR`Cn)4DKZ)5o=r94o<`x}-!^`9ejEHPkh|g6i7LKp zRViO|l8Ed+v5n-gsA-ddbXQsy7});pNl~F!yWYns=3?Qf zo6yB<>Wl>-nf%;x%9@PGNGR)SZTo~s$&NKFJCkQv(w;M*Rz!s${}%NO^T}x|3c6MN z)}N7O=0z&M+uRsy0P$l&fTlNLm}0CxV9jd=y!<56{l~@gmL=oW%|WTF0T5$QE9oa+ ze=Gl55?77ktCxI-w%R;Cp>Mp?V_-|#yT*qO^mZzsmV~H`h$rN)sSdp1^uq+EjMy}>hzR|j7ZK;8Sm1@d>s1dzq#4}_fFKg%bs-^sRO=s z)4k3gs)|z)9}@lC1AW|KQI0VyMt6$^_q4)`I=_b!LdvI`=S!W-vRovCVrFdiqRTgK zSC|dSH}Q#v%QcnZU;XCj^T?qZHy_a9#n&$6=HZpzxEwf;>By&KIgE*3VWZuv>q+)) zc95(DS>(2knh||CMV^I~9$#Z7UtoozY<9d_#?kMTf+L$kw@r}_c!Sx(J!|%sxYQ4I z*fHNQJG-!qzB-rnbZYMBi{918k@npTUwBQ;SwdZx>}e-V@cRARnV(Lpvqx>sU{Stb zzo7Y$`s zClIy%))fh4((Lh%ID!0BN|S}4(ZN1=%DBR>^1om8hfJyty;KVJTl;wHdlHUa2~O2w zEOUz!uEr}(K^bT;1nL;$nka2Xz05dA>kc(gx6G8(Q0_qN^WG;?gRS)y9`X>}!eZHi zH?EzP-o`Q@!<3fdW}lR7@~ulZ*<|YYw|QAx5|6I(5|_+P11rf4 zKiWAx3$kW+CG20TmqFiqqu)2gnCf?+Io1C>21&BA1Yhwv9`I_m`M4 zZyw_s<2d-|D}$alJnK14IYNJ36V-P&1%HcasA8pc>?-0zqw64xTZjC8Gd8OUM}`8< z`BZp|G665y+j{UoQ$-QKG8DT=s_x5V3TDze+DtzY9{1bDH&%o;W%<4jZq^t^rL%f{ORwrq76-3bx>A=xNb z6p9-=#LKcgsL9$au`OjD2N;ZSBWzZ{)ozd+Izq>1CHsG^D1-(J6TXj_u4>Y$Ljd2i zuH=0ZnX|q{A2+7UmrpN0Y-Z%VwYn^3Sg|NS&nTcWh!!_kx)Lcl1pB_@g0xavdxI@w`)(u=tdz^i!z4vFI+P%~D&&z)Iw`#r+bhe~v3 zAk5=I-}hb-U_h)?x4|LdcoTP|TtmvyrO7Vu5O@jy^a)J=hC%h&C)0r)`9*q zX43mVDv1($wM1(S>RLqB`Ks;Jy;|=U)p= zfp26x{~+S`_@!uW7jDtG#Hy#|U7Wdv2@Np3FlY2gtZ=81+RlK*`^#@<2rV1?O=DKq z%uyxy2}9{X5Q4+`b%;n+C*y)%AdT^&%!t&v2Qz9Xzo_VGB~p87rOz3yb%6|LngQyf zrw5+#G|Y&>c#3MKrtPODK?fky{#{7SrX8z+Cfm&U=4UtG{wCL+FdF{zNp%SD%kw$P zGpOq_{~L_~FgTtKzh-$g58fitqFD@w9~@W>exZd)qNr2J-O%eJMnLJO_?CZYH)?1Z zI8-!TSsSYQI{KtYzr*v%zQXu9qBNf^@(b7YZ>F9Gf>?p#wEBi`yO)NC^^cpRBI2mr4VoMD0(#I#RDVO z`+QGUS^myrc_AsYuFv^YKDY6)U_bZAt5(wB?8R>-JKRfU8zu3+3AG@0gr@$5(`t7T z`|ULkh0y5ep&R~f6t7U9wV7X~2a{b!EX3!*9bHq_Q0lJTrqdQ{)|yazew zu{d!5xKN8(T{rL+2muX&jH`a*9A#i-5j;BE>-4YfXm zT?$7BqQiCGP&cXm|KZ607jDU`q`$VrX#T40S_u~nXY9R53yuFPp#@^Ld#}K~efk+q z1B$}>I+rlx|3ta)59j`khM4vzH}TX@z3dO7zsc+TRsK}s)VyK0`5{x*Vbt!xC4`}7 z1V)Ji&F(iXyQ78iW=&V5mGXc|`NDdeqzccWOL>OVivf;8E{#8kC^cd{Don=Al^&0q z#(gkiNTdaRlC%Wy^JR}3aDN%m%I`ER?voYP0(81JBIVpZtHVnpxMX`oy=$tqT7rn`MX|-}fMnd`6JN;120e-(Q+ZZ^2P3o{_maE2aXCvfV7B9u8PM&`;T zNDlRah$p91`|%+I((0_JW!CyGDz1SHXGG0I)_aa5at0s`ziU-RmjX6_tOt6p@$uaos>z3b_w{)^z2%RD z&$i5YE%2)&R}Zo~K$WPYXam1c*9BlHc&Wx9hccsQilE~yq4~o?(8V(}V?<#=5=d+n zpj@Fg*X~yhsafLe!l#)r+6c@`15M#+^x!a6%ll2Tng_W10Km&y*}@$8{HtLQ!>j|& zfD>|zusNkO)?yjNc73CZBDqT-pWoIa&sb%&-l~<9MCzri}q6gP-N|EMv%Fn@5zF*m(Ft>THW)mC0>Di>TxS6r3 zm>#A2ojXnm++tfPpI_~pm}fx6-c1P`+2t2BEO>~eQGR?^7uYcPp0e;g=8oZG8|>B& z_S!lk-FK~t!qTl5VHG6bf?x2i?jH<$^&yawGV-YTM@NxC&A^D8x25JnQb>*u(4tl! zrk7fghvtU(xLyq@#hFZkKqE?iMkZ_hj$tnXUrRMby|H;ndrra`{K}X9$`%>O>YCRw zG54Xxbj*m}z#Dv5-A#|w2R6_@Y@JL6RPLEsC6|%g(pLlw-38%>=UA*SqF}zM)+Mp6 zW|`{EF4ko+?7NfGrel$z;%Ky&lu;|Zw%z!E@iq)hhfjOkr>94*w}CV#tx06(c{|Sd zdRDAKCWyVc!_3E2nySI156oTUrHA&W%p65nWY)XS$~Rvp&d|P35%c&6McvP!NX8}e)*Hid_c0YME6H;Y4!l!IX|(|&>HB=QseyAx6-re(KSR>A`(rI;x?NH~anIU@ku3W> zTaa78K9LB_rq=BR@pj@i`=4+FX|_heC)oDTBKdts4(zRK1%B%t{!hGhk0{q^8n$^y z@oaE7!$r&YNZ};kaGs<9brI2(>FdhA@^`hzl-a=eH~MoKpD4qATqw9F2u!&wt^cb0 zYAeJ51sPi#7#IQC1zE(ch10H;C)Q*ZCuDc5ro7y^R2Lat^eb!~2Te_wYME<2?%)A+ zu54*zC8=%%M%1)m2drS_#gP*j_YY4!1IzE&`MDD{7jILHQGYT1+S8CX7VT9h?XLhyB6a~Q@o5e7h>ZFcZ`Cp5?FVDi0TG)@x!sX zGI|FizQ8p{yaMiUsj~I%T9z`+2QTLXf{uGZK(~X(Ko%`IhF^Gq&`*1Qym7dMx>h51>gEv{@1d)#=_)$LUC3=Cv!l_V!c>$--7(1S zlbEJmLK5`m*;ZLOG}&x*sQ#62a}P=Tyq1xcv9N>Lq`Aa{AbSjDm}Fl}kYxgf1Mgl& z^NSIAlvk#qpir(d2#lw9fF&X(tVw!3ZU=9pJS?qvJVl-+jB6{gQ8=ZXMJB2U%y{U* z8ybrC^}Hgsh1Nev*UE5%3+LdPw@#4(H|{xR?UTR69E-*Xn_Udb*gRNfn~D<#(oI&k zFgq4R=|~T*muw5=r*%a=_b3J&wl$o#J z8q4)Fu8vZvbu9JH9j_Eg`p_ zI5K{`H}vYxJ+rFPD>!{h$~Gi13lccJd`}DH*BdxBZ0=d3r(@aBF}|JG5Ml!nO@aUdLtp+V)JRcwK2`a%a zrh1d^=~Z)k>C2Z&Kz?pfqkL`~6Y+pwz%j>L=PNDDZRtxNBQxX6g z#;O1yuR0*#lhO%L_STiJr)NBqwTvIZcqOtsfWnR6&>n+}bAE+I9huQxnO8K;{x*JW zvb0%R(m0|QrBQe`c{0daSN80TjT*sjDP3&5ve%-zV@Bhj9(z=eWKFu!fHRJLIjF*R^j!afH;**UM4g981AQuOKrSM)m*)26X&#V~6t0Z;18*Pqp;ojFXTbc5vdX0TdaqH(nDz_-+?A@k$P{S2Y%?5AsV+&P6^sdgy zILIy&Wjzmnkk9XVi5gaXe8~|SFm`F_x;tW7^$5PQmeFRp<>y~x8U3O0u>(xK^MoCP zXgQRodcTxBB$Rj7luA5vK&;GWI#dNPQxpapp_2+L3z9I9jJa`Za`&Z~fhYIQS~N+2 z!oxLu+WjrnV*NJKe6=5JU8c>;uk9#rNOe0yJ{X)W6QRP_#T2v~dMpTGytApYeMevoWL(Q6^;sJG{ zPq-e(%xcJuuWmjB{~eyq9I8mT-v(yjNrS3}HE(aZs(eXQk;f1Hqo(TWsDZM_Bn1gC z&#pWxzh2pGj375@1xvSTJ6es^NT3N(4=`>3>S*`-QFUy6?40VL_^{zqvj=mMHXelE z&x5kBS;c>0R{35Tmy{3}`b4WGbd&R^T{!pWyTk1`Y|EKZg76jT8vw5ZO)Jj=;F5$M zC$Gt!dW!fL!+!nQO_2)IK5-MC1s@{E0;Q@kqzdMYO7#^)G)6l8ft4}w8kKuR*)_05 z0cyI+f1aTG@BM&54*lltdIB>%0WkbQqyrE+xi+W`uWqz@R)ccErzoxXE|u+lw2s`}7#U8s|C(={4zL+bg37>9M`mzqK;{Su@Ah zs3x=`oqFDn4m99Zo>Y;n&6PGhHsJ@exi`5g{Soqu0uwh#1j@x=bkAfsCE=C4ZjS~`dN`q zo+e$%pa*^sC)?i-S-UlI=nK=j<9=TR$(5kskLzRtOM}6ipK<2+3IAFDyozq02t?7M z9)J>K&uS%qr-VjEsn@BIkGA+t!Ig3v-QcLWUrRY(1337pKM%Jad-6UNB*9c_N2@)e zseiKmHh@2R=A+D)@LbGIO1PfD>qGIrDixiM$`Cdc0_@Gt2Te~HEo;IRx9ZG$d?OQM z4+29rSh;T`C}~wxx?gDqdYUq_Yho*F*+NDxzIeaq#kIBBxZ#X?-^;hz`FF*_%F26% zA~B14AciHfX~d)XSZV)WNB1W*R;zhK>>Et=@c%)>X1rVBw#-Un~>AS_O%j zDTTx92raQYkLvET)e>!vmx!I=D8aU(lR=P{TL;zp10pph{nG<%N!|#rhf24oldpX< z*Bq){Tg919n@)G_4~@O~XzA!M0qq9qgMPN$P`4KT7qO;)XN2jt^ys`^NCSTUi=DFp zJ=7>7*onD8dx0E^JG-lG0(Rm5|JwV`s3yB@UEC$BSl(*pi%@Q@Li7ge0SV??m1`dbAH@A_89xm z^J}g3&avJfbFOF3`OMa*;os(Gwwgh3f;kA%d`BVCmRV+Wp=|XHZJ^wOja|vh*p8-} z8T>3=plwlo?9C?o{9qAK@Dx$I1g^yC~1T+wHeOeB)V z=2ZG;l@yIp*@!iDxSi;kb}pyIW9cEU;UJbvl0Vv9afJEYlA10SxcFy}?|>bX1A~6L z*qC!4f37&4`H7vvn+~+T;I~0mU66DtZ8le{$u=+_aFk+@s`bz2+0voae16M(L@RE` z`K&cuB2R*?>w4j~YXO2i@cuRhf8m~cYV%+LocqP*GO~fUjX4e9H(CEIanxEfY+O^v zZ|dX0HE}CGKZ7gb@Xd{iagx?u8-KnV{4v2D6Yy*g5$A4iX#HHJLy)BUN@wdX$mRJy zhvE=6$=!MkhUiU=MUON2sVIky{gLo+RhxCvMtnQ2LNR&Y(g!LF(L0>G5n1kAaig6d zBRDrQ*`-(%qvn<=iHZ)bB*kCqfIxoCiB@I+waR z`NkEV(7i5wls{RYQ z=QQ=kpmnj*shl9{HOgec@%{3ul8&y5@nLFu_R*n2cjn!a328RgH3mw!td1KCy^zn~ z>xPMz&zEMmIc2QmQa+*BH@>8dE5^jts2J$xoGJE=lX4?d(BTLL5&p>nxn%>TVL*MC zY-q0c)ezj6)}}4k_93pGNbImMlMV$vicse12FBS_NAA(y78(#6i<-3e_20{BmuVa! z8j9RAU=I%)wp-f|Xf2SJXlT@?Q>r^|icft*)F0cGbNND__n`2o8f1CxYi7Q~kTSog ziXmmtokhac@zYjuyem9O2M``){~+v=#68GDZo}9t)x89Z3(vmw5}?LdbJxX0lvO~g zKezFhA!657Ww~XU$d00ZNno=n{;wnk{_1@D2j+g*PRSoGphIa@4R=P6Vv?uW!?c^D z{y}Z!Hpo0A(YM>qqj>ciqopH?-c`a~yaeenoKiDs-j-W_oh?IGG;-K$BrNQGQzdp~ zdr8+m4E63kCTf<28Ba~$zS`>o)femTTh^V;`{TYF>)x}WwTorNtAfo*0X8z)sTYIP znqK2CZpcq}PIU0qwVcWJ^h%2_!L_|zWz+ZSelxRC#--Lb^d%ftd?O^*(JB3V^+~iL zDM=~Ou)jc11A5LnLkl&jTx!xlvi7qukZ!Yeh~r&hMS)MgdNn?f@p1OURS=Whn0>g{ zQYvSRgbSWD((wi;l@H3$3un)P`g*>yErGz*Q$>jvX}8d}S^GnEgc_L5vXkdAPY&_T z`6)klVU1(9947Y)bDY#ZfdC;6s+W`Ne0`HWr1*d)+`|1Q9{`J4_9~l*)2ghupn7~o z6z&#tM!l5EYsA*CfWg!9lOH0jiN0(}3vc$<6#5-4J?bnJhrn&eXxfKT!^|LDWc)1l z8>PG@WddG3%(AWCs&UnqsFY|iX4WQw>x(crJ2K0unSXtWCcE^8w}wCH$i}7gR2}A5 zC`&Lp#gA3NCmg`!{)`v2|lmb1OBE006TyJAht}Q#rM%Q;!M%{Qi zDQn{y(+p#I(3JY=Thl<)@>|hut&_3c@7}I?6CC%c`3ctsV+Dh}B~8NZPg9ymf~JcM~dzGt%6gG z+zoVX151J^+L!dVDe+j3Z6~kRlb1TfL+&iB{vl_6yeauMDSn81&$cu(+q_iRd4LI$ zI}NXdkuQQG-Co9fjt`cHxfLs>I=3SO%4OTQ5KB+JjeClYkPoq6m5;!4L_1biDH5B? z33{FKxX?iozN+yUXfJ7_zFL{S7ZbyrTQnj*V@R*?X6U#vC}rp9EdS2+mG@BkvHv6C z_wNgn{9j8L1^()^7yZ{3oRW5$CGB?XzT`gVU)jjI^1oC_(Hh*Rv5>XQfBpUOAME(= z3V?R&L7o2P$g=JU`|o0W&9KMmt_?IJx5sI$=KAHYnr8Q7cCT5RsYJAhsZz<2vRV0D zB#VxK+^8iMjpl%9@gXG|V(wSw(h0R9KJkkZ8nYlRKwq45IzsomC#j#?*Bj}GYWKRt zGPGK%m9&LGs)RQr8grSM=|+AoRDzygNv)u0$Te0+U`YHj8G8=v$n)f`=+;1KrMaTn zo`pnO)Eo$G;F*9oLQe{_D6SZRZ#aE)xG^O2#F&08x4(Twl9@-nq3 zYEA2I-DGKb>ki1Z^2JY4;j=1y#SAvo1!+C~#TS#@KVpA2GS@X0IJdvzySSs|TC=pP zNkpAAar1BY50R5-Wd9@xx*vatz<*gi6Jj( zZz+ka8Pne>-qD9*)D-PrO?{Hl&v}FJ03k^$eKoNV>?7$ECAsNA9O!rCaV{Y~>s(4_ zG-VYmG*-ihAV3x-_#6}M0aOf3yoHQCv;&5f%h{D|6D_z)7mJ*Qo#TKisu}5y{Ac<* znzB;wuNMEZY(5Tu%|4CWf{LF5pR-W*(L=yX+J-)GEZ0qSZh;2K+rv5$%d_N9u`2Ry z4E-Yac$J%jcxW)#kLTOIVco@#`B5>|uf!QAdCm>mDZiX+`6ASs{w2XLK$Lpp` zPt&7)*_w_}eOeAAU+V*QinP z1Jh0u%XG*P*!^!IG~@@}j?L=<#G86Dk2Pe0ZBw()&IoW0?adP!~B&GtoIP7gFf$Z@&#MZ7%J~@UmqQ2IV~}JqZ{CoSk|T^Mprc~1zopLYdYXB z3L-Es<+)*)SzI?5HLufZhaZ=cVoO~yPu$nxyV)VZyWZPgdA>!8J7x~XHyN%*t=!0l zMapoHpu-}qY6Sp_U^^XMXw-hl2m9!9kItzRvReLsI})SI#r8{2PT2vNTb4l7eI2ZN|Q;@sNG3@2o>@blG& zj`Ib|Kt`o!dvpxW!b==(L7%N7cQf{)_s3{@G~r*=r+fQHexb(Et4xp)c5}$0$)gG- zRm>7cW|xs@&zDl{GsC5O_QnA%Y8r#tz`vdM*E`#8jb;B3BPU$;XfUK1q+?t3JcYqV z0=W=oO`BQ?aC&rVDEHWD*nLu1XnzhTfpff~xb=w!%>0us#c}!SP`7hd=)q2?UGz%x z{sA{>N7TXys1woP4tf=g+fF3wxj&1_7ti;eaiMSt=(lJa+~HBZZABO*+6LMcWGh?2 zbL(gAAGaD(OXy(~nBxmBrBi7xhN0cJga!BY?n67On0tkomM3Qp3t_YHtLra6l*x3C zAr^a0yW#fgW?!2}7j#y&ZYRrJk}tw*tJ$x(0q8;)R??^e)G&1S*HaY$GxRg82_=~d zqV{tDZO%bcu|s!UMNK|CSOiXX@~gc>)TIR_?Gow;5xpUg5_0vQvSL}w>L=xXtiDwo z5j2x~+CwrSD;c=E9sQgE_^cf0L9FJ$p3Qcic%02p%0w+UE?(zv3c{fD?wGjyg0I|L zfbaeTH}JotkN+x>`$wj$?o~pgj5U#!O_PIFxw+WHqC8uXjo4Tj?>=t;UC>o>9zKdG zg+pJ|QmVMHIF<-v4pVN8;{g-|b)0?09_-d5hoV+gJ;<<<3NQRYeQqJ3k;kLp;Atv_ zYF}2R-ToKW1XYhj^Uh{8F@)ZV>LHlty|KYn&DUh@n9XI_Xx? z_Pzf@ZeIx3uuBV?hY|$d3kukiG0*D=54?kcr3;-_P8Ni+XYr49^RDsF&0!WVv5&R9 znCt_eyvU|Hb3oqmJhe_mz5D~S(P7mO;_vMhWJ;SQH=3d7$*=y)NO8sp;1vhgp|;8o&LLw=vL|l;a+U4iTe2*0x0pLR%nO+$;EI?j2|Z z+`4y;O1&n)k#)ccz!bZQ2xSs9kdqo*iC+kt=L}AoXT&GrLBQR-$G*FzU>VxgHWjzw zVL%R0UiCPtf$f1h@=6WjA(vV>>E383h3d>ABjpIZa%U)IMYS@KFZD*xL~~khNdaCT zXnL0OSE#S-u18tc*Wl;AoYpus1Mc-qlF-)j<1$r4H~s8y6-!#r6HDy^SSJqPx7XBvhoJ zuEDqr0B8w%B-!(5s*)LK;o_{>HezID?;T!a?UdX;|A$rM&f2H9%=ONj!a_|cvs?|s zJtN9(aV9w_8aHhpG}=jgwcNLA4mF^dnK9W4`?tlv8$Bb>UjB~3CH*?{xY|cp6$BqO z3(?$BrEJa|wCi2Tl5z|aq|kYKD^+-*VxH#~tUS6E)~%84$akF2HAXT6BC~P(rhf0T zdGUar>WDNLLuT4hzG%VP8R_9i(D=U-t7QOxJ}n0Vo+U*ty^wqs|yJ9qxA|YEfShhs7h6%rY>{w1@;Xr z+A#Ck+K1*;G$`WwGrn|2tydjpJE%xBq6i$3_b#f)a1*zwTv0(f`@Nqv+@SBg5I}+D zqe^TK1lc|Y1ebSak758az0Y10yRpSZsN){_o1}eG;>-DO}cXvm>!84Rt5Nd`@!;He# zn82zocgf9jAaGOgum$R~pT@_+O_bYL6{wO~Wh_Imtnk48IcZI82WyJ(+g?(@sGNf-kvD@O;U_u;F%8nw}q0P8r z)Q_=057Yu%k)^3+Ji4fS!blLCIa$rBstJSkn7%9~uV7Fdc7ZqZ+vr@c6S8c1mHiSp z^5Zq~wlN`_;|1!dA;&i`CB%u~mJ93k`-YID<`T>-DOIjB z?ju6F1;mZaaA*DCYhBAXWu#6=^Tm9S;TJv$=*d<5yakyY^^q*ZNy`lrbs@np>m3(OLzKfSd&JN z*^RTG`C@c5&LFHYTbBM*fB>Xseu2e+I8uzX-({9&xq;Ql4!O)C4AqfaiMaLY}H@}FGj}ks$thytUSgK=zzm#pPe5P)anUo^S3KFA91Rr zeEsk6;s40)8$!TrYDTlnds^1X&rw||qQz0+bjB%{9GNos?wnm)rsJXS-n%7YCa1vp z@&gx>=|HBURb%PxAGlu<3w%JZY15!0S)_CNf)g5vJ(JPV$B*~CS2ZF-c=Qw9wKIN~ zrZ(8BscF!WaHk*vYDW!a@bLYHgo`S8QV&|0ygsnvLxz##^G+CXjgfNr0m62;x z`P(FOgmiFQR{}yaeq{^Ym68gJQjZ%QC5@55ZKECcC_Ml*{z*V%_cE(q!_;}Ym`N6k zIub%(?ZbQRC!Uzc3Z}ya%`h#qFDh(w1*eJ&HpOcdPO=t;KmE-#40hkC$ogg7Xha$U z=o9YUUxkg%NjtVc(1R6QGKB^2iZD1g`LoT&Xk-m9gHviuYv>IJhZQ{YZNDBakZrH4 zCs!kVx)c#_K&%6dNX23c3wI26b50Ye_aOe;K=&<9gtn0hA z_i%(UWK?HShn}3KJY45{5U@)L)URs#wM8cC5BLjaTmd>dBZ``U5n-{4c>*QKQ9UQ= zF%crg^`=Ja-C4HfyUY?Eexbe44|Kr~P!A%<`i18np}2crtg9x{(On_r92!V-<4f7$ z>)|yuHYyDyh`DYB>^V0QT};9$XFk8qnz_@*pZqHe^Cw-L+d0vRI4L!nO@3K^MSdw7 zl&;RtmZX({GVj*6(g4jI)VGLW73Pl=O)5=G;ip4Ecft z^?E{eznICZFN{)o!jS^P&o4j+@O%x>xsqE{ob<>$ET#fDK^$g&7{!mTjNNvOA;#yOyc7s5IEQBboSIINI)m;)hh7!bDZCWmW#kTc&*+np)xnyPw-O z$db4w)z6qXuJEY0j2arLN#bsFit5iEGPk6a}i>Ah{ zYe22jZOocTV{Mc7B%PCt{K2mcY82}~Xw>v^lsOK*OiNGQ_(l%iu(#n*_Y_mXYi3Zg zw#D>Ip!a*27|tEp{ngN1c-Mq-!$869|2s2(Z_? zwBbg}w#1Mrc#+j=NefUgq1($ct$`O&wY8iY7td-nzl6#0pkk1O8Wr?Xv`#-ZE*)`_ z9WlS3@Yt!|5*F+K>9b~6KuO5=t#&?!%$nH7rv=Vk+U~Wse)@-?#9~YyQTeT!+Y6i_WBc*)dj|V)W|WZV$^zpO4IiCCR!bAK>n1NrYN!sc3@+ zmg~*3@_pAHyjBt8^Ki3?2qcd-1&F??`!?1)3Yy}}#0uAwQtzvVHsUs2gc*o#;k=-u zJ@VcGyVr{%Uf0>Htg>k!o(sddg)cK(Kj(~Bx7`FPlH)@q;+`DVbk3DeJ}83U#CDRK zU-?=p$k$_XI5E%V0$GU(Y+uq#56eencxZPEJJOI+Jg=m!#BV0z_(IhsrWL1A0j`4z zZ<)zsV-YyvwJf-UzPIs1v7J)|VTZqy`1?J6^B*m5wCob%> zahU%dZty=}@}D`$0SRUfHe%->j=0F~k`3;g!O zCBy;n8=*qZVUTz&!J)4)H-Dq#igA^D^?KKI*7ujc@f9L6mF3@@BHw}gkaG$7xR?Dm zay$~VRss~C7k=Z#M)rT2^8e#j z!ps1rIN#L_jj0KS^&C2*Kk4T0M?DZyJx`W1mXx60A9a42$a@loSr~boofl7QnJ}y= zy@` +- `inecs/vmware-api-simulator:latest` (unless `PUSH_LATEST=0`) + +## Quick start with the published compose file + +[`docker-compose.release.yml`](../docker-compose.release.yml) pulls the Hub +runtime image and starts PostgreSQL + migrate + simulator + the HTTPS +gateway: + +```bash +docker compose -f docker-compose.release.yml up -d +docker compose -f docker-compose.release.yml run --rm --entrypoint python \ + simulator -m app.simulation.seed_cli + +curl -sk https://localhost/health/ready +open https://localhost/ +``` + +Helpers from a git checkout: + +```bash +make release-up +make release-seed PROFILE=small +make release-down +``` + +Useful overrides: + +| Variable | Default | Meaning | +|---|---|---| +| `DOCKER_IMAGE` | `inecs/vmware-api-simulator` | Image repository | +| `IMAGE_TAG` | `latest` | Tag to pull | +| `HTTP_PORT` | `80` | Host HTTP port | +| `HTTPS_PORT` | `443` | Host HTTPS port | +| `POSTGRES_PORT` | `127.0.0.1:5434` | Host Postgres bind | +| `TICKET_SIGNING_KEY` | lab default | Change outside toy labs | +| `POSTGRES_PASSWORD` | `vmware` | DB password | + +For Kubernetes with public TLS (cert-manager / Let's Encrypt), use the Helm +chart — see [Kubernetes / Helm](kubernetes.md). + +## Upgrades + +1. Pull / rebuild images (`make install` / `make docker-build` as appropriate). +2. Run migrations (`make db-migrate`). +3. Confirm `/health/ready`. +4. Re-check `/ui/api/compatibility?major=9` and `/api/appliance/system/version`. +5. Re-run `make test-vsphere` / `make vsphere-matrix` if you validate the + surface after upgrading. + +## Resetting a lab + +```bash +make seed PROFILE=small +# or via UI: unload demo → small, then seed again +``` + +For a hard database reset use `make db-reset` (destructive — see Makefile +help). diff --git a/docs/ports.md b/docs/ports.md new file mode 100644 index 0000000..30e3078 --- /dev/null +++ b/docs/ports.md @@ -0,0 +1,49 @@ +**Language / Язык:** [English](ports.md) | [Русский](ru/ports.md) + +# vCenter ports in this simulator + +Reference: [vSphere Networking Ports](https://ports.esp.vmware.com/) (vCenter Server). + +The `api-gateway` (nginx) publishes the **primary vCenter HTTPS listener** +plus an HTTP lab face. Every published port proxies to the same FastAPI +process, which already path-routes REST (`/api`, `/rest`) and SOAP (`/sdk`) +internally — there is no separate port per protocol. The gateway also sets +`X-VMware-Service` / `X-Forwarded-Port` so clients and future routers can tell +which port was used. + +## Published by Compose (`api-gateway`) + +| Service | Container port | Host port (dev compose) | +|---|---:|---:| +| HTTP lab face | 80 | 80 | +| vCenter HTTPS (primary UI/API entry) | 443 | 443 | + +Host ports match real vCenter defaults so remote clients can use +`https:///` and `http:///` without a non-standard port. +Override on release compose with `HTTP_PORT` / `HTTPS_PORT` if needed. + +Also published by Compose (not via the gateway): + +| Service | Host port (dev compose) | +|---|---:| +| PostgreSQL | `5434` (localhost only) | + +Internal simulator process (not published to the host): `8080`. + +## Path layout on HTTPS + +| Surface | Path prefix | Status | +|---|---|---| +| vSphere REST | `/api/…`, `/rest/…` | implemented (core inventory + session) | +| SOAP / VIM SDK | `/sdk` | implemented (RetrieveServiceContent / Login / RetrieveProperties subset) | +| HttpNfcLease / NFC | `/nfc/…` | lab transfer handshake on the same HTTPS listener | +| Lab console | `/` | yes | +| Health | `/health/live`, `/health/ready` | yes | + +## Documented but not published yet + +| Service | Ports | +|---|---| +| VAMI / appliance management | 5480 | +| ESXi host management (if simulated later) | 443 (separate host) | +| Syslog / etc. | various | diff --git a/docs/ru/README.md b/docs/ru/README.md new file mode 100644 index 0000000..9069e96 --- /dev/null +++ b/docs/ru/README.md @@ -0,0 +1,32 @@ +**Language / Язык:** [English](../README.md) | [Русский](README.md) + +# Документация + +Руководства по симулятору VMware vSphere API. Переключайте язык с помощью заголовка на +каждой странице. Русские версии находятся в каталоге [`ru/`](README.md). + +| Руководство | Описание | +|---|---| +| [Быстрый старт](getting-started.md) | Первая успешная лабораторная сессия | +| [Конфигурация](configuration.md) | Переменные окружения и Compose | +| [Аутентификация](authentication.md) | Сессии, `vmware-api-session-id`, привилегии | +| [Версии API](api-versions.md) | Catalog majors 6–9 и hot-swap | +| [Поверхность API](api-surface.md) | Маршрутизация REST/SOAP, coverage registry, stubs | +| [Покрытие API](api-coverage.md) | Broadcom universe vs реализованная поверхность | +| [Клиенты и примеры](clients.md) | Python, Go, Java, Perl, Ansible, Terraform, Pulumi | +| [Профили seed](seed-profiles.md) | Детерминированные фикстуры инвентаря | +| [Домены](domains/README.md) | Session, inventory, VM, storage, networking, tagging, SOAP, tasks, … | +| [Web UI](web-ui.md) | Интерактивная консоль и каталоги | +| [Эксплуатация](operations.md) | Reseed, migrate, release, upgrade | +| [Kubernetes / Helm](kubernetes.md) | Образ Hub + Ingress + Let's Encrypt | +| [Безопасность](security.md) | Модель угроз лаборатории и учётные данные | +| [Наблюдаемость](observability.md) | Эндпоинты health и логирование | +| [Порты](ports.md) | Опубликованные порты хоста и внутренние сервисы | +| [Устранение неполадок](troubleshooting.md) | Типичные сбои | +| [FAQ](faq.md) | Краткие ответы | +| [Архитектура](architecture.md) | Границы компонентов | +| [Совместимость](compatibility.md) | Модель evidence и матрица релизов | + +Исполняемые cookbook'и: [`examples/`](../../examples/README.ru.md). +Интеграционные наборы: [`pulumi-tests/`](../../pulumi-tests/README.ru.md) +(`make pulumi-tests`). diff --git a/docs/ru/api-coverage.md b/docs/ru/api-coverage.md new file mode 100644 index 0000000..82ebc4e --- /dev/null +++ b/docs/ru/api-coverage.md @@ -0,0 +1,167 @@ +**Language / Язык:** [English](../api-coverage.md) | [Русский](api-coverage.md) + +# Матрица покрытия vSphere API + +Реестр, ориентированный на автоматизацию: [`app/vsphere/rest/coverage.py`](../../app/vsphere/rest/coverage.py). +Стабы universe от Broadcom: [`app/vsphere/rest/universe.json`](../../app/vsphere/rest/universe.json) (из публичного индекса операций). +Уровни по мажорам + бандлы стаб-OpenAPI: [`app/vsphere/contracts/matrix.py`](../../app/vsphere/contracts/matrix.py) → `contracts/vsphere//manifest.json`. + +## Broadcom в сравнении с этим симулятором + +Публичный источник (собран скрапингом): [Индекс операций vSphere Automation API (9.1 Latest)](https://developer.broadcom.com/xapis/vsphere-automation-api/latest/operation-index/) + +| Поверхность | Количество | Примечания | +|---|---:|---| +| Индекс операций Broadcom | **1348** | GET 628 / POST 422 / DELETE 114 / PUT 93 / PATCH 91 | +| Сгенерированные уникальные маршруты `verb + path` | **~1037** | Один и тот же HTTP-путь может обслуживать несколько именованных операций (`?action=…`, `$Task`) | +| Реестр симулятора (core + стабы + `/rest`) | **1077** | Глубокие core-обработчики перезаписывают записи стабов на том же пути | +| Глубокие core-обработчики | **104** | Поведение seeded-инвентаря / жизненного цикла / authz | +| Строки поверхности, поддерживаемые БД (`vsphere_api_state`) | **~540+** | Загружаются seed для каждого GET-маршрута `/api` + лабораторные дополнения | + +Регенерируйте universe после обновления дампа индекса: + +```bash +python scripts/generate_vsphere_universe.py +make vsphere-bundles +``` + +Обновление живой статистики / регенерация артефактов: + +```bash +curl -sk https://localhost/ui/api/compatibility?major=9 +make vsphere-surface +python scripts/write_vsphere_bundles.py +python scripts/write_vsphere_evidence.py +``` + +| Мажор | Метка | Реализовано / universe | Покрытие | Примечания | +|---|---|---:|---:|---| +| 6 | vSphere 7.0 | 31 / 1077 | 2.9% | Только floor каталога/evidence | +| 7 | vSphere 7.0 U3 | 77 / 1077 | 7.2% | Только floor каталога/evidence | +| 8 | vSphere 8.0 | 103 / 1077 | 9.6% | Только floor каталога/evidence | +| 9 | vSphere 8.0 U2 / поверхность Automation 9.1 | **1077 / 1077** | **100%** | Глубокие обработчики + DB-backed поверхность Broadcom | + +Числа берутся из `GET /ui/api/compatibility?major=N` и +`evidence/vsphere-*.json` (`make vsphere-bundles`). + +Hot-swap (`POST /ui/api/contract/apply?major=N`) меняет **catalog** major для +Web UI / evidence-отчётов. **Runtime всегда обслуживает полную +зарегистрированную поверхность** — известные пути не получают HTTP 501 из-за +version floor. + +## Плоскости + +| Плоскость | По умолчанию | Примечания | +|---|---|---| +| Native REST `/api`, `/rest` | включена | Основная лабораторная поверхность | +| Native SOAP `/sdk` | включена | Подмножество PropertyCollector + задачи ВМ | +| Стаб Proxmox `/api2/*` | **выключена** (`ENABLE_PVE_STUB=false`) | Опциональный legacy | + +## Auth и синтетические данные + +| Пункт | Детали | +|---|---| +| Пользователи | `administrator`, `readonly`, `operator`, `vmadmin` `@vsphere.local` / `VMware1!` | +| AuthZ | Проверка привилегий по роли на мутирующих эндпоинтах (403 `unauthorized`) | +| Seed `large` | 10 хостов, **1000 ВМ**, 4 datastore, DVS, папки, права | +| Seed `demo-cluster` | 20 хостов, 1000 ВМ (загрузка demo в UI) | +| Seed `small` | 3 хоста, 5 именованных ВМ (тесты) | + +## Домены REST + +### Глубокие (core) на мажоре 9 + +- Сессия / задачи CIS / роли+права AuthZ / провайдеры идентичности / стаб TLS-сертификата +- Список/получение/создание/удаление/power ВМ, оборудование, снапшоты, + клонирование, relocate, tools, идентичность/сети/питание/customization + гостя, консольные тикеты, template/unregister +- Список/получение хостов + maintenance + storage-device + сети +- Список/получение datastore + метаданные файлов +- Список сетей + создание DVS/DVPG +- CRUD для datacenter / cluster / folder (+ дети) / resource-pool +- Тегирование, content library + OVF, политики хранения (+ привязки к ВМ), привилегии +- Версия/health/сети/timesync appliance +- Стаб списка сервисов метамодели `vapi` + +### DB-backed поверхность Automation (catch-all universe Broadcom) + +Оставшиеся маршруты Automation API из индекса операций 9.1 зарегистрированы +и обслуживаются [`app/vsphere/rest/stub_surface.py`](../../app/vsphere/rest/stub_surface.py) против PostgreSQL: + +- таблица `vsphere_api_state` (миграция `011_vsphere_api_state.sql`) +- seed через `seed_api_surface()` при каждом профиле, включая + **`demo-cluster`** / UI `POST /ui/api/demo/load` +- overlay инвентаря для оборудования ВМ (cdrom/scsi/boot/…), сетей/хранения + хоста, тегирования, content library +- PUT/PATCH сохраняются в `vsphere_api_state`; POST добавляет строки + коллекции; DELETE их удаляет + +Нет маркеров `"stub": true` — зондам нужны реальные seeded-payload'ы на +мажоре 9. + +## Домены SOAP (govmomi / Terraform / Pulumi / pyvmomi) + +- RetrieveServiceContent (+ TaskManager / SearchIndex / GuestOperationsManager / FileManager / OvfManager) +- RetrieveProperties / RetrievePropertiesEx / **ContinueRetrievePropertiesEx** (токены пагинации; `` во множественном числе) +- PropertyCollector: цепочка предков Ancestors, однохоповый `childEntity` + ListFolder, обход ContainerView `view` +- `Folder.childType` как `ArrayOfString`; строковые свойства несут + `xsi:type="xsd:string"` (декодирование govmomi) +- `Datastore.host` как `ArrayOfDatastoreHostMount`; **environmentBrowser** у + Cluster/Host +- **QueryConfigOption** / QueryConfigOptionEx / QueryConfigOptionDescriptor / QueryConfigTarget +- CreateFilter / WaitForUpdatesEx (токены версий; пустые опросы) +- FindByInventoryPath (пути govmomi не включают корневую `Datacenters`), + FindByUuid/Dns/Ip, FindChild +- **CreateVM_Task** / CreateChildVM_Task, CreateFolder, + Power/Clone/Snapshot/Rename/Reconfig/Relocate/Destroy/Unregister/MarkAsTemplate/CustomizeVM_Task + CancelTask +- Файловые операции гостя: ListFilesInGuest, + InitiateFileTransferTo/FromGuest, DeleteFileInGuest, MakeDirectoryInGuest +- Реальные ID задач из `vsphere_tasks` (включая MoRef в `info.result` при + create/clone) +- `/sdk/vimService.wsdl`, `/sdk/about.do`, стаб `/pbm` +- Строгий по типам поиск MOR: `VirtualApp:resgroup-*` не резолвится как + обычный ResourcePool (путь CreateVM в Terraform) + +## Дополнения REST для Ansible / Python-приложений + +- Power ВМ возвращает `{ "task": "task-…" }` для опроса задач CIS +- Виртуальная файловая система гостя: + `/api/vcenter/vm/{vm}/guest/filesystem` (+ листинг локальной файловой + системы) +- Сессии обновления/загрузки content library для лабораторных потоков + push/pull OVF + +## Legacy `/rest` + +Обёртки `{ "value": … }` для +vm/host/datastore/network/datacenter/cluster/power/appliance. + +## Мажоры контракта (browse в сравнении с runtime) + +Hot-swap (`POST /ui/api/contract/apply?major=N`) всё ещё переключает мажор +**каталога** для просмотра/evidence в UI. **Runtime всегда обслуживает +полную зарегистрированную поверхность** глубокими обработчиками или +DB-backed стабами — известные пути никогда не получают HTTP 501 из-за +уровня версии. Уровни каталога остаются историческими только для +документации. + +## Поверхности платформы (доступны в лаборатории) + +Исторически они считались «отложенными»; теперь они возвращают +**непустые seeded лабораторные данные** и принимают базовые мутации: + +| Область | REST | SOAP | +|---|---|---| +| NSX (tier0 / проекты / edges / VPC / подсети) | Seeded-пути Automation под `namespace-management` / `namespaces` | — | +| Supervisor / WCP | namespace, классы ВМ, сводка/идентичность supervisor, политики инфраструктуры | — | +| vSAN | Политики хранения с `policy_type: VSAN` (+ лабораторная политика RAID1) | — | +| SAML / OIDC | `GET/POST/PATCH/DELETE /api/vcenter/identity/providers` (LocalOS + OIDC + SAML) | — | +| VECS / сертификаты | TLS, CSR TLS, доверенные цепочки корней, сертификаты/запросы подписи supervisor | — | +| HttpNfcLease | `PUT/GET /nfc/{lease}/files/...` | `ImportVApp_Task`, `CreateImportSpec`, ход/завершение lease | +| Customization гостя | GET+POST `/api/vcenter/vm/{vm}/guest/customization` | `CustomizeVM_Task` | + +Это всё ещё **лабораторный** заменитель (не бинарно совместимый с NSX +Manager / не настоящее хранилище VECS / не полная матрица XML устройств +Broadcom). Perf/Event/Alarm по-прежнему отвечают, но не симулируются +глубоко. diff --git a/docs/ru/api-surface.md b/docs/ru/api-surface.md new file mode 100644 index 0000000..55477c0 --- /dev/null +++ b/docs/ru/api-surface.md @@ -0,0 +1,91 @@ +**Language / Язык:** [English](../api-surface.md) | [Русский](api-surface.md) + +# Поверхность API + +## Путь запроса + +1. Middleware назначает или пересылает ID запроса (`REQUEST_ID_HEADER`). +2. FastAPI направляет запрос в роутер vSphere REST (`/api`, `/rest`), роутер + SOAP (`/sdk`) или (если `ENABLE_PVE_STUB=true`) в опциональный legacy-стаб. +3. `/api/session` (либо `/rest/com/vmware/cis/session`, либо SOAP `Login`) + определяет принципала и выдаёт `vmware-api-session-id`. +4. Зависимости `require_read` / `require_privilege(...)` проверяют роли + сессии перед раскрытием или мутацией ресурсов. +5. Глубокий обработчик (базовая логика инвентаря/жизненного цикла/тегов/ + контента/appliance) или DB-backed поверхность стабов выполняется против + состояния, хранимого в PostgreSQL. +6. Долгие операции (power, clone, relocate, snapshot, деплой OVF) создают + долговечную CIS-задачу и возвращают `{ "task": "task-…" }`. + +## Две REST-поверхности в одном реестре + +- **Core (глубокие) обработчики** — ~104 комбинации verb+path в + [`app/vsphere/rest/router.py`](../../app/vsphere/rest/router.py), + `vm_ext.py`, `inventory_ext.py`, `platform_rest.py`, `tagging_rest.py`, + `content_rest.py`, `appliance_ext.py`, `nfc_rest.py`, `tasks.py`. Они + читают и мутируют напрямую seeded-таблицы инвентаря/тегов/контента/ + appliance. +- **DB-backed поверхность стабов** — + [`app/vsphere/rest/stub_surface.py`](../../app/vsphere/rest/stub_surface.py) + отвечает на оставшиеся маршруты индекса операций Broadcom Automation API + (зарегистрированные из `universe.json`) против `vsphere_api_state`. GET + возвращает живые payload'ы, производные от инвентаря, когда это возможно, + иначе — seeded-строки; PUT/PATCH сохраняются в `vsphere_api_state`; POST + добавляет строки коллекции; DELETE их удаляет. Маркер `"stub": true` не + возвращается — зонды видят реальные seeded-payload'ы. + +Обе поверхности используют одну таблицу маршрутов; core-обработчики имеют +приоритет над записями стабов, зарегистрированными для того же verb+path. + +## Legacy `/rest` + +[`app/vsphere/rest/legacy.py`](../../app/vsphere/rest/legacy.py) оборачивает +чтения vm/host/datastore/network/datacenter/cluster/power/appliance (и +power ВМ) в конверты `{ "value": … }` для более старых клиентов +`com.vmware.vcenter.*`. + +## Ошибки ([`app/vsphere/errors.py`](../../app/vsphere/errors.py)) + +| Статус | `error_type` | Типичная причина | +|---|---|---| +| 400 | `invalid_argument` / `already_exists` | Некорректное тело, дублирующееся имя | +| 401 | `unauthenticated` | Отсутствующая/недействительная/истёкшая сессия | +| 403 | `unauthorized` | У сессии нет требуемой привилегии | +| 404 | `not_found` | Неизвестный параметр MOID/path | +| 409 | (зависит от обработчика) | Недопустимый переход состояния питания, конфликт блокировки | +| 501 | `error` | Достижимо только через fallback опционального legacy-стаба для необъявленных методов | + +Все тела ошибок следуют форме vSphere Automation: +`{ "error_type": "...", "messages": [{ "default_message": "...", "id": "...", "args": [] }] }`. + +## Задачи + +Асинхронная работа (power, clone, snapshot, relocate, деплой OVF, guest +customize) возвращает id задачи. Опрашивайте: + +```text +GET /api/cis/tasks/{task} +``` + +Строки задач фиксируются в `vsphere_tasks`; `progress` равен `100`, как +только `status` становится `SUCCEEDED`/`FAILED`. HTTP 200/201 на запросе +мутации означает «принято», а не «ВМ уже в конечном состоянии». См. +[Задачи](domains/tasks.md). + +## Исследование + +- Интерактивная документация FastAPI: `/docs` +- Инспектор методов в Web UI: `/` → каталог → метод +- Вспомогательные API UI: `/ui/api/catalog`, `/ui/api/method`, + `/ui/api/compatibility` +- Реестр покрытия: [`app/vsphere/rest/coverage.py`](../../app/vsphere/rest/coverage.py) +- Матрица уровней пути / каталога: [`app/vsphere/contracts/matrix.py`](../../app/vsphere/contracts/matrix.py) + +## Эндпоинты совместимости + +| Path | Формат | +|---|---| +| `/ui/api/compatibility?major=N` | JSON | + +См. [Совместимость](compatibility.md) и [Покрытие API](api-coverage.md) для +полной разбивки Broadcom-universe в сравнении с реализованным. diff --git a/docs/ru/api-versions.md b/docs/ru/api-versions.md new file mode 100644 index 0000000..33543e6 --- /dev/null +++ b/docs/ru/api-versions.md @@ -0,0 +1,77 @@ +**Language / Язык:** [English](../api-versions.md) | [Русский](api-versions.md) + +# Версии API (vSphere catalog majors 6–9) + +Web UI и evidence/compatibility отчёты просматривают четыре целочисленных **catalog +majors**, которые сопоставляются с label floors vSphere Automation API: + +| Major | Метка vSphere | Строка версии contract | +|---|---|---| +| 6 | 7.0 | `7.0.0` | +| 7 | 7.0 U3 | `7.0.3` | +| 8 | 8.0 | `8.0.0` | +| 9 | 8.0 U2 (Automation 9.1 surface) | `8.0.2` | + +Определения находятся в [`app/vsphere/contracts/matrix.py`](../../app/vsphere/contracts/matrix.py) +(`VERSIONS`, `PATH_FLOOR`). Каждый зарегистрированный REST path имеет **floor** — +наименьший major, при котором он появляется в catalog — из того же +модуля. Undated paths по умолчанию получают наивысший major (9), пока не catalogued. + +## Runtime vs catalog + +Это самое важное различие в проекте: + +- **Catalog major** — управляет тем, что показывает Web UI endpoint tree, `/ui/api/catalog`, + и compatibility/evidence отчёты для данного major. +- **Runtime surface** — симулятор всегда обслуживает **полную зарегистрированную + route table** с deep handlers или DB-backed stubs, независимо от + активного catalog major. Известный path никогда не возвращается как HTTP 501 из-за + version floor. + +Hot-swap catalog major — это **documentation/browse** +переключатель, а не compatibility gate для live traffic. См. +[`available_for_request()`](../../app/vsphere/contracts/matrix.py) для точной +политики. + +## Cold start + +`GET /api/appliance/system/version` сообщает version string текущего +выбранного runtime source (по умолчанию `8.0.2` / major 9, если процесс не +переопределяет `app.state.runtime_source_version`). + +## Hot-swap (catalog browse) + +Просматривайте любой major в Web UI catalog или вызывайте: + +```http +POST /ui/api/contract/apply?major=7 +``` + +Эффекты: + +- Web UI catalog, `/ui/api/compatibility` и evidence отчёты переключаются на + floor major 7 и ledger (`evidence/vsphere-7.0.3.json`). +- Изменение **process-local** и **не сохраняется**; restart возвращает + default (major 9). +- Зарегистрированные REST/SOAP routes продолжают отвечать своими реальными + handlers независимо от применённого major. + +### Рекомендации для клиентов + +- Большинству клиентов (pyvmomi, govmomi, Terraform, Pulumi, Ansible `uri`) не + нужно pin'ить catalog major — runtime surface не меняет форму + на его основе. +- Используйте catalog majors, когда нужно, чтобы Web UI / evidence view + отражали более старую метку vSphere для документации или скриншотов. +- После apply перепроверьте `/ui/api/compatibility?major=N` для активного + catalog state. + +## Регенерация catalog artifacts + +```bash +make vsphere-bundles # stub OpenAPI matrices + evidence ledgers +make vsphere-universe # regenerate universe.json from the Broadcom operations index +make evidence # regenerate per-major verified surface evidence ledgers +``` + +См. [Поверхность API](api-surface.md) и [Совместимость](compatibility.md). diff --git a/docs/ru/architecture.md b/docs/ru/architecture.md new file mode 100644 index 0000000..7d34731 --- /dev/null +++ b/docs/ru/architecture.md @@ -0,0 +1,77 @@ +**Language / Язык:** [English](../architecture.md) | [Русский](architecture.md) + +# Архитектура + +## Цели + +`vmware-api-simulator` — stateful лабораторный эмулятор vSphere (Automation REST + +VIM SOAP). Главная цель дизайна — **практическая совместимость клиентов**: +сессии, inventory, жизненный цикл VM, обходы PropertyCollector, задачи, +stubs tagging/content library и роли AuthZ реализованы поверх большого +синтетического datastore, чтобы инструменты вроде curl, govc-подобных +потоков, pyvmomi и Terraform могли прогонять типовые пути без реального +vCenter. + +Catalog majors **6–9** соответствуют floors vSphere 7.0 / 7.0U3 / 8.0 / 8.0U2. +Hot-swap меняет каталог только для browse/evidence в Web UI — он **не** +гейтит живые маршруты. Опциональный stub Proxmox `/api2/*` остаётся за +`ENABLE_PVE_STUB` (по умолчанию выключен). + +## Контекст системы + +```mermaid +flowchart LR + Client["API clients
pyvmomi / Terraform / govc / REST SDKs"] + Admin["Lab operator"] + UI["Web lab UI"] + API["FastAPI application"] + Gateway["HTTPS gateway :443"] + Contract["vSphere contract matrix"] + Domain["vsphere domain + inventory"] + DB[(PostgreSQL)] + Obs["Logs / Prometheus / OpenTelemetry"] + + Client -->|"/api /rest /sdk"| Gateway + Gateway --> API + UI --> Gateway + Admin -->|"seed / migrate"| API + API --> Contract + API --> Domain + Domain --> DB + API --> Obs +``` + +## Плоскости + +| Плоскость | Путь | Заметки | +|---|---|---| +| Automation REST | `/api`, `/rest` | Заголовок сессии `vmware-api-session-id` | +| VIM SOAP | `/sdk` | Подмножество PropertyCollector + VM tasks | +| Lab UI helpers | `/ui/api/*` | Каталог, demo seed, совместимость | +| Опциональный PVE stub | `/api2/*` | Выкл., пока `ENABLE_PVE_STUB=true` | + +## Модель данных + +Inventory живёт в `vsphere_objects` (MOID, типы, props JSON, parent-ссылки). +Sessions, credentials, tasks, tags, libraries, snapshots и permissions — +соседние таблицы (миграции `009_vsphere.sql`, `010_vsphere_platform.sql`). +DB-backed Automation stubs используют `vsphere_api_state` (`011`); сессии +transfer content library и строки HttpNfcLease — в `vsphere_transfer_sessions` / +`vsphere_nfc_leases` (`012`); views/tokens PropertyCollector и console tickets — +в `vsphere_pc_state` / `vsphere_console_tickets` (`013`). + +Профили seed (`small` / `large` / `demo-cluster`) строят детерминированный +кластер — по умолчанию **large** это ~10 hosts / **1000 VMs**. + +## AuthZ + +Credentials отображаются в roles → privilege sets. Мутирующие обработчики +используют `require_privilege(...)`; пути чтения — `require_read`. SOAP Login +выдаёт cookie, совместимый с VIM-сессиями. + +## Связанные документы + +- [Покрытие API](api-coverage.md) +- [Аутентификация](authentication.md) +- [Web UI](web-ui.md) +- [Клиенты](clients.md) diff --git a/docs/ru/authentication.md b/docs/ru/authentication.md new file mode 100644 index 0000000..da3536b --- /dev/null +++ b/docs/ru/authentication.md @@ -0,0 +1,101 @@ +**Language / Язык:** [English](../authentication.md) | [Русский](authentication.md) + +# Аутентификация + +Основная плоскость: **vSphere Automation REST** sessions (`vmware-api-session-id`). +SOAP `/sdk` использует собственные `Login`/`Logout` на VIM `SessionManager`. Опциональная +legacy Proxmox stub-плоскость (`ENABLE_PVE_STUB=true`) сохраняет историческое поведение +`/api2/json/access/ticket` из общей platform lineage — это не default lab path и далее +не рассматривается. + +## Session login (REST) + +```http +POST /api/session +Authorization: Basic base64(user:password) +``` + +Успешный ответ: + +- Body: JSON string session id (например, `"a1b2c3…"`) +- Header: `vmware-api-session-id: ` +- Cookie: `vmware-api-session-id=` (`SameSite=Strict`, TTL 2 часа) + +Legacy wrapper (те же credentials, форма `{ "value": "" }`): + +```http +POST /rest/com/vmware/cis/session +Authorization: Basic base64(user:password) +``` + +### Вызов API + +```bash +SID=$(curl -sk -u 'administrator@vsphere.local:VMware1!' \ + -X POST 'https://localhost/api/session' | tr -d '"') + +curl -sk -H "vmware-api-session-id: $SID" \ + 'https://localhost/api/vcenter/vm' +``` + +Cookie-only клиенты также работают после login (`credentials: include` в +браузерном Web UI). + +### Inspect / logout сессии + +| Метод | Путь | Заметки | +|---|---|---| +| GET | `/api/session` | HTTP 200 с заголовками `x-vmware-session-user` / `x-vmware-session-roles` | +| DELETE | `/api/session` | Инвалидирует сессию и очищает cookie | +| GET / DELETE | `/rest/com/vmware/cis/session` | Legacy эквиваленты `{ "value": … }` | + +Сессии хранятся в PostgreSQL (`vsphere_sessions`) с 2-часовым sliding +expiry — каждый аутентифицированный запрос продлевает `expires_at`. Истёкшие сессии +возвращают HTTP 401 при следующем lookup и лениво удаляются. + +## Засеянные lab principals + +Пароль для всех: `VMware1!` + +| Principal | Роль | +|---|---| +| `administrator@vsphere.local` | Administrator | +| `readonly@vsphere.local` | ReadOnly | +| `operator@vsphere.local` | VirtualMachinePowerUser | +| `vmadmin@vsphere.local` | VirtualMachineAdministrator | + +Credentials хранятся в `vsphere_credentials` (scrypt-hashed passwords, +массив `roles`) и идемпотентно re-insert'ятся при первом вызове `/api/session` +и каждым seed profile. См. [Authorization](domains/authz.md) для модели +привилегий и [Профили seed](seed-profiles.md) для соответствия четырёх +principals inventory-scoped permissions. + +Mutating endpoints проверяют привилегии через `require_privilege(...)`; вызов +mutate path как `readonly@vsphere.local` возвращает **403**. + +## SOAP `/sdk` + +```xml + + + + SessionManager + administrator@vsphere.local + VMware1! + + + +``` + +`Login` выдаёт тот же underlying session id, возвращаемый как +`vmware-api-session-id` и как cookie `vmware_soap_session`; последующие SOAP +вызовы (pyvmomi, govmomi, Terraform provider `hashicorp/vsphere`, Pulumi) +передают этот cookie автоматически. `Logout` удаляет сессию. См. +[SOAP / VIM](domains/soap.md). + +## Опциональная legacy Proxmox stub + +Только при `ENABLE_PVE_STUB=true`: ticket login на `/api2/json/access/ticket` +с `PVEAuthCookie` + CSRF, унаследованный от общей simulator platform, от которой +этот проект fork'нулся. По умолчанию выключен (`ENABLE_PVE_STUB=false`) и +не используется vSphere docs, examples или test suites в этом репозитории. diff --git a/docs/ru/clients.md b/docs/ru/clients.md new file mode 100644 index 0000000..3df14ad --- /dev/null +++ b/docs/ru/clients.md @@ -0,0 +1,88 @@ +**Language / Язык:** [English](../clients.md) | [Русский](clients.md) + +# Клиенты + +Используйте симулятор из распространённых стеков автоматизации VMware: +Python, Ansible, Terraform, Pulumi. + +## Матрица подключений + +| Стек | Транспорт | Примечания | Код | +|---|---|---|---| +| REST (curl / SDK) | HTTPS `:443` | `vmware-api-session-id` после Basic-сессии | `examples/python/vsphere_rest_smoke.py`, `vsphere_lifecycle.py` | +| SOAP / VIM | HTTPS `:443/sdk` | провайдеры pyvmomi / govmomi / Terraform / Pulumi | `examples/python/vsphere_soap_smoke.py` | +| Legacy `/rest` | HTTPS `:443` | обёртки `{ "value": … }` | `/rest/vcenter/vm` | +| Terraform | HTTPS `:443` | источники данных `hashicorp/vsphere` + опциональный ресурс ВМ | `examples/terraform/vsphere/` | +| Ansible | HTTPS `:443` | playbook жизненного цикла REST (модуль `uri`) | `examples/ansible/vsphere_playbook.yml` | +| Pulumi | HTTPS `:443` | кулинарная книга REST ComponentResource | `examples/pulumi/` | +| govc | HTTPS `:443` | `GOVC_URL=https://…` insecure | см. ниже | +| Go / Java / Perl | HTTPS `:443` | минимальные кулинарные книги REST (сессия по Basic-auth) | `examples/go/`, `examples/java/`, `examples/perl/` | + +## Учётные данные (seed) + +| Пользователь | Пароль | Роль | +|---|---|---| +| `administrator@vsphere.local` | `VMware1!` | Administrator | +| `readonly@vsphere.local` | `VMware1!` | ReadOnly | +| `operator@vsphere.local` | `VMware1!` | VirtualMachinePowerUser | +| `vmadmin@vsphere.local` | `VMware1!` | VirtualMachineAdministrator | + +## Seed инвентаря + +```bash +make seed # large: 10 хостов / 1000 ВМ +VSPHERE_PROFILE=demo-cluster make seed +VSPHERE_PROFILE=small make seed +``` + +## Быстрые кулинарные книги + +```bash +# Все четыре стека (в стиле Python/Ansible/Terraform/Pulumi) внутри Compose +make client-cookbooks + +# Python REST + SOAP CreateVM / NFC +VSPHERE_BASE=https://localhost python examples/python/vsphere_lifecycle.py + +# Ansible +ansible-playbook -i examples/ansible/inventory.ini examples/ansible/vsphere_playbook.yml + +# Terraform — источники данных hashicorp/vsphere (plan) + опциональный ресурс CreateVM +cd examples/terraform/vsphere +terraform init +TF_VAR_vsphere_server=localhost TF_VAR_create_lab_vm=false terraform plan +TF_VAR_vsphere_server=localhost TF_VAR_create_lab_vm=true terraform apply + +# Pulumi REST +cd examples/pulumi && pulumi up +``` + +Проверено против gateway (`:443`): жизненный цикл Python, playbook Ansible, +REST в стиле Pulumi и `terraform plan` (источники данных +datacenter/cluster/datastore/network/VM) — всё зелёное. SOAP +`CreateVM_Task` доступен для пути ресурса; используйте свежий seed, если +имена папок были переименованы зондами (`make seed`). + +## govc (опциональный инструмент на хосте) + +```bash +export GOVC_URL=https://localhost +export GOVC_USERNAME=administrator@vsphere.local +export GOVC_PASSWORD='VMware1!' +export GOVC_INSECURE=1 +govc about +govc ls / +govc find / -type m | head +govc vm.info web-01 +``` + +## Smoke-тест pyvmomi + +```bash +docker compose run --rm --no-deps -e VSPHERE_BASE=http://simulator:8080 \ + -e TEST_DATABASE_URL=postgresql://vmware:vmware@postgres:5432/vmware_simulator \ + dev pytest tests/compatibility/test_vsphere_pyvmomi.py -q +``` + +Руководства по языкам: [examples/overview.md](examples/overview.md). Покрытие: +[api-coverage.md](api-coverage.md). diff --git a/docs/ru/compatibility-0.1.0.md b/docs/ru/compatibility-0.1.0.md new file mode 100644 index 0000000..1b33fd9 --- /dev/null +++ b/docs/ru/compatibility-0.1.0.md @@ -0,0 +1,87 @@ +**Language / Язык:** [English](../compatibility-0.1.0.md) | [Русский](compatibility-0.1.0.md) + +# Отчёт совместимости — 0.1.0 + +Этот отчёт фиксирует evidence для релиза симулятора 0.1.0 относительно реестра +маршрутов vSphere Automation API (catalog majors 6–9, основной contract major 9 / +8.0 U2). Это матрица ограничений по измерениям *качества / внешней интеграции*, +а не утверждение общей аппаратной совместимости с vCenter/ESXi. + +Пользовательский обзор — [compatibility.md](compatibility.md). Живые +машиночитаемые счётчики всегда доступны из +`/ui/api/compatibility?major=N`, когда симулятор запущен. + +## Сводка (major 9 / основной контракт vSphere 8.0 U2) + +| Уровень | Methods | Доля universe | Evidence | +|---|---:|---:|---| +| Declared in universe (Broadcom operations index → route table) | 1077 | 100% | `app/vsphere/rest/universe.json` | +| Implemented at major 9 (catalog floor) | **1077** | **100%** | `app/vsphere/contracts/matrix.py` | +| Core deep handlers (inventory/lifecycle/tagging/content/appliance) | 104 | 9.7% | `app/vsphere/rest/coverage.py` (`CORE_IMPLEMENTED`) | +| DB-backed stub surface (остальной реестр) | ~973 | 90.3% | `app/vsphere/rest/stub_surface.py` против `vsphere_api_state` | +| Verified / observed surface ledger | **1077** | **100%** | `evidence/vsphere-8.0.2.json` | + +## Покрытие по catalog major + +| Major | Метка vSphere | Implemented | Universe | Coverage | +|---|---|---:|---:|---:| +| 6 | 7.0 | 31 | 1077 | 2.88% | +| 7 | 7.0 U3 | 77 | 1077 | 7.15% | +| 8 | 8.0 | 103 | 1077 | 9.56% | +| 9 | 8.0 U2 | 1077 | 1077 | 100.00% | + +**Implemented** здесь — оценка catalog-floor для browse в Web UI и +evidence-отчётов, перегенерируется через `make evidence` / `make vsphere-bundles` +и защищена `tests/compatibility/test_verified_surface.py`. Она **не** +гейтит живой трафик — почему runtime всегда обслуживает зарегистрированный +маршрут независимо от применённого major, см. [Поверхность API](api-surface.md). + +## Реализованная поверхность (верхний уровень) + +- **Session**: `/api/session`, `/rest/com/vmware/cis/session`, SOAP + `Login`/`Logout` — всё устойчиво в PostgreSQL (`vsphere_sessions`, + `vsphere_credentials`). +- **Inventory**: list+get для VM/host/datastore/network/datacenter/cluster/folder/resource-pool, + плюс create/delete для datacenter/cluster/folder/resource-pool. +- **VM lifecycle**: create, delete, power, hardware (CPU/memory/disk/NIC/boot), + snapshots, clone, relocate, guest identity/networking/power/customization, + console tickets, tools. +- **Tasks**: `/api/cis/tasks`, реальные ids из `vsphere_tasks`, SOAP task MoRefs. +- **Tagging / content library**: categories, tags, associations, libraries, + library items, update/download sessions, OVF deploy. +- **Authorization**: privileges, roles, permissions CRUD, identity providers. +- **Appliance**: version, health, networking (hostname/DNS), timesync. +- **SOAP / VIM**: RetrieveServiceContent, PropertyCollector + (RetrieveProperties/Ex, ContinueRetrievePropertiesEx, CreateFilter, + WaitForUpdatesEx), FindBy* / FindChild, CreateVM_Task и связанные, guest + file operations, HttpNfcLease import flow, WSDL stub. +- **Platform lab surfaces**: seeded (не бинарно совместимые) stand-in'ы + NSX/Supervisor/vSAN/SAML-OIDC/VECS-cert — точный список и оговорки в + [Покрытие API](api-coverage.md). + +## Принцип персистентности + +Каждый путь create/update/delete пишет в PostgreSQL (таблицы и/или catch-all +`vsphere_api_state`). Секреты могут храниться, но не должны отдаваться на GET. +Пользовательские ошибки «not supported in the emulator» для зарегистрированных +путей запрещены — см. `.cursor/rules/durable-simulator.mdc`. + +## Известные ограничения + +| Область | Текущее поведение | +|---|---| +| Внешние системы | NSX/LDAP/SAML/OIDC/ACME не обращаются к реальным remotes; состояние симулируется локально | +| TLS | Локальный nginx gateway только с закоммиченным self-signed development key | +| Сертификация клиентов | SOAP smoke в стиле pyvmomi/govmomi + cookbook'и Ansible/Terraform/Pulumi; не формальный certification suite для каждой версии провайдера | +| Smoke провайдера | Набор `pulumi-vsphere` в `pulumi-tests/` (`make pulumi-tests`) гоняет SOAP inventory/VM/tag с проверкой непустых export'ов; семантическая глубина по-прежнему разная (deep handlers vs DB-backed stubs) | + +Полное покрытие реестра на major 9 означает, что HTTP 501 «handler pending» +не должен появляться ни для одного маршрута в реестре симулятора. *Качество* +совместимости (точный паритет крайних случаев vSphere) по-прежнему углубляется +тестами и observation. + +При импорте обновлённого дампа Broadcom operations index: перегенерируйте +`universe.json` (`make vsphere-universe`), bundles/evidence +(`make vsphere-bundles`, `make evidence`), запустите +`pytest tests/compatibility/test_verified_surface.py` и закоммитьте обновлённые +ledgers `evidence/vsphere-*.json`. diff --git a/docs/ru/compatibility.md b/docs/ru/compatibility.md new file mode 100644 index 0000000..f680e0e --- /dev/null +++ b/docs/ru/compatibility.md @@ -0,0 +1,79 @@ +**Language / Язык:** [English](../compatibility.md) | [Русский](compatibility.md) + +# Совместимость + +Этот документ объясняет, как симулятор заявляет совместимость с vSphere +Automation API по мажорам каталога **6–9**. Когда процесс запущен, +предпочитайте живые отчёты. + +## Живые отчёты + +| URL | Формат | +|---|---| +| `/ui/api/compatibility?major=N` | JSON | + +Web UI также предоставляет панель совместимости, управляемую этим +endpoint'ом. + +## Покрытие реестра в сравнении с проверенной поверхностью + +| Мажор | Метка vSphere | Реализовано / universe | Покрытие | +|---|---|---:|---:| +| 6 | 7.0 | 31 / 1077 | 2.9% | +| 7 | 7.0 U3 | 77 / 1077 | 7.2% | +| 8 | 8.0 | 103 / 1077 | 9.6% | +| 9 | 8.0 U2 (поверхность Automation 9.1) | **1077 / 1077** | **100%** | + +- **Universe** — уникальные маршруты verb+path, полученные из публичного + [индекса операций vSphere Automation API](https://developer.broadcom.com/xapis/vsphere-automation-api/latest/operation-index/) + (1348 документированных операций → ~1037 уникальных маршрутов → 1077 + зарегистрированных в таблице маршрутов этого симулятора, поскольку + некоторые пути обслуживают несколько именованных операций). +- **Реализовано (по мажору)** — маршруты, чей уровень каталога + (`app/vsphere/contracts/matrix.py`) равен этому мажору или ниже. Это + оценка **каталога/документации**, а не ограничение живого трафика. +- **Runtime** — независимо от применённого мажора каталога, каждый + зарегистрированный маршрут всегда обслуживается своим реальным + обработчиком (104 глубоких обработчика) или DB-backed поверхностью + стабов. См. [Поверхность API](api-surface.md). + +После **Apply as runtime** (`POST /ui/api/contract/apply?major=N`) живой +отчёт загружает журнал этого мажора (`evidence/vsphere-{version}.json`), так +что панель совместимости Web UI отражает выбранный мажор. + +## Измерения evidence + +Журналы по мажорам в `evidence/vsphere-{version}.json` записывают счётчики +`declared`, `implemented`, `observed` и `verified`, а также разбивки по +HTTP-методам и доменам (`auth_session`, `inventory`, …). Регенерируйте с +помощью: + +```bash +make evidence # app/evidence_gen.py +make vsphere-bundles # стаб-бандлы OpenAPI + журналы evidence вместе +``` + +Исполняемое подтверждение этих заявлений: + +| Набор тестов | Роль | +|---|---| +| `tests/compatibility/test_verified_surface.py` | hot-swap + дрейф журнала + пороги оценки | +| `tests/compatibility/test_group_smoke.py` | представительные мутации групп REST с PostgreSQL | +| `tests/compatibility/test_vsphere_pyvmomi.py` | внешний smoke-тест SOAP через pyvmomi | +| `tests/integration/test_vsphere_full_api.py` | широкое интеграционное покрытие REST/SOAP | + +Дополнительные cookbook'и под [`examples/`](../../examples/README.ru.md) +и lab-набор `pulumi-vsphere` под +[`pulumi-tests/`](../../pulumi-tests/README.ru.md) (`make pulumi-tests`) +выполняются вручную или опционально в CI. + +## Известные поведенческие ограничения + +| Область | Поведение | +|---|---| +| Внешние системы | NSX Manager, живые LDAP/SAML/OIDC IdP и ACME-директории не обращаются к реальным удалённым сервисам; только seeded/локальное состояние | +| TLS | Только локальный self-signed development-gateway (Compose); используйте свои сертификаты / cert-manager для реальных развёртываний | +| Гипервизор | Нет реального выполнения ESXi/KVM; нет бинарных загрузок NFC | +| Корпус наблюдений | Санированные данные наблюдений реального vCenter остаются ограниченными; глубокий семантический паритет проверяется путь-за-путём указанными выше наборами тестов, а не исчерпывающим сравнением с production | + +Исторические заметки о релизах: [compatibility-0.1.0.md](compatibility-0.1.0.md). diff --git a/docs/ru/configuration.md b/docs/ru/configuration.md new file mode 100644 index 0000000..6e6eabe --- /dev/null +++ b/docs/ru/configuration.md @@ -0,0 +1,96 @@ +**Language / Язык:** [English](../configuration.md) | [Русский](configuration.md) + +# Конфигурация + +Настройки приложения загружаются из окружения (см. `.env.example`). +Docker Compose инжектирует многие из них для сервиса `simulator`; значения, +объявленные в `environment:` в `docker-compose.yml`, переопределяют `.env` для этого +сервиса. Типизированная модель настроек находится в [`app/config.py`](../../app/config.py). + +## Основное + +| Переменная | По умолчанию / пример | Значение | +|---|---|---| +| `APP_HOST` | `0.0.0.0` | Адрес bind | +| `APP_PORT` | `8080` | Внутренний порт uvicorn (не публикуется; gateway публикует vCenter HTTPS) | +| `DATABASE_URL` | `postgresql://vmware:vmware@postgres:5432/vmware_simulator` | asyncpg DSN | +| `DB_POOL_MIN_SIZE` | `1` | Минимум пула | +| `DB_POOL_MAX_SIZE` | `10` | Максимум пула | +| `DB_CONNECT_TIMEOUT_SECONDS` | `10` | Таймаут подключения | +| `DB_COMMAND_TIMEOUT_SECONDS` | `30` | Таймаут команды | +| `LOG_LEVEL` | `INFO` | Уровень логирования | +| `REQUEST_ID_HEADER` | `X-Request-ID` | Заголовок корреляции запросов | + +## vSphere seed inventory + +| Переменная | По умолчанию | Значение | +|---|---|---| +| `SEED_VSPHERE_PROFILE` | `large` | `small` \| `large` \| `demo-cluster` — см. [Профили seed](seed-profiles.md) | +| `SEED_VSPHERE_LARGE_HOSTS` | `10` | Число хостов для профиля `large` | +| `SEED_VSPHERE_LARGE_VMS` | `1000` | Число VM для профиля `large` | + +## Опциональная legacy-плоскость + +| Переменная | По умолчанию | Значение | +|---|---|---| +| `ENABLE_PVE_STUB` | `false` | Включает legacy Proxmox VE `/api2/*` stub-плоскость, унаследованную из общей platform lineage. Нативная vSphere `/api` + `/rest` + `/sdk` — основная плоскость по умолчанию независимо от этого флага. | + +## Contract и catalog + +| Переменная | Значение | +|---|---| +| `CONTRACT_SNAPSHOT` | Опциональный путь к нормализованному PVE-style snapshot (актуально только при `ENABLE_PVE_STUB=true`) | +| `CONTRACT_FALLBACK` | `error` (default), `schema-default`, или `fixture` — fallback-поведение для опциональной stub-плоскости | +| `COMPATIBILITY_EVIDENCE` | Опциональный путь к evidence JSON для отчётов совместимости | +| `CATALOG_ARTIFACT_URL_6` … `_9` | Метки catalog majors vSphere (6→7.0, 7→7.0 U3, 8→8.0, 9→8.0 U2); stub URLs, не live downloads | + +Runtime hot-swap (Web UI / `POST /ui/api/contract/apply?major=N`) переключает +активный **catalog** major, используемый Web UI и compatibility/evidence +отчётами. Он не ограничивает зарегистрированную REST/SOAP поверхность — каждый +известный маршрут всегда обслуживается реальным обработчиком или DB-backed stub. +См. [Версии API](api-versions.md). + +## Безопасность и задачи + +| Переменная | Значение | +|---|---| +| `TICKET_SIGNING_KEY` | HMAC signing key для сессий (**меняйте вне toy labs**) | +| `TASK_WORKER_CONCURRENCY` | Число leased asyncio workers (1–32) | +| `TASK_LEASE_SECONDS` | Длительность lease PostgreSQL-задачи | +| `SIMULATION_TIME_SCALE` | Ускоряет симулированные длительности задач (выше = быстрее) | + +## Client test hooks + +| Переменная | Значение | +|---|---| +| `TEST_DATABASE_URL` | DSN для integration-тестов | +| `VSPHERE_BASE` | Базовый URL для cookbooks/probes (`https://localhost` с хоста, `http://simulator:8080` изнутри Compose) | + +## Порты и TLS + +| Endpoint | Назначение | +|---|---| +| `https://localhost` | Основная vCenter HTTPS точка входа (curl, browsers, pyvmomi, govmomi, Terraform, большинство examples) | +| `http://localhost` | HTTP-грань для лабораторных нужд | +| `localhost:5434` | PostgreSQL (только localhost) | +| Internal `simulator:8080` | Прямой процесс FastAPI; доступен только внутри Compose network | + +Вшитый сертификат в `docker/tls/` — одноразовый development material. +Никогда не используйте его вне локальных labs. См. [Безопасность](security.md) и +[Порты](ports.md). + +## Заметки по Compose + +- `migrate` выполняется один раз; `simulator` ждёт успешного migrate. +- Development Compose bind-mount'ит репозиторий и включает Uvicorn reload. +- Сервис `api-gateway` (nginx) публикует `443`/`80` и проксирует на + внутренний процесс `simulator:8080`; устанавливает `X-VMware-Service` / + `X-Forwarded-Port`, чтобы будущие routers могли определить использованный listener. + +## Открытые и неиспользуемые example keys + +`.env.example` всё ещё перечисляет несколько ключей из общей platform lineage, которые +**не** потребляются текущей vSphere-first моделью настроек, в частности +`SIMULATION_SEED`, `SIMULATOR_ADMIN_ENABLED` и `SIMULATOR_ADMIN_TOKEN`. Не +предполагайте, что аутентифицированный admin API `/_simulator` существует сегодня — см. +[Безопасность](security.md). diff --git a/docs/ru/domains/README.md b/docs/ru/domains/README.md new file mode 100644 index 0000000..2930566 --- /dev/null +++ b/docs/ru/domains/README.md @@ -0,0 +1,43 @@ +**Language / Язык:** [English](../../domains/README.md) | [Русский](README.md) + +# Руководства по доменам + +Эти страницы описывают устойчивую семантику по областям API. Для исчерпывающих +списков методов используйте каталог Web UI или OpenAPI (`/docs`), либо +непосредственно +[`app/vsphere/rest/coverage.py`](../../../app/vsphere/rest/coverage.py) — +runtime всегда обслуживает полную зарегистрированную поверхность независимо от +активного catalog major. + +| Руководство | Темы | +|---|---| +| [Session](session.md) | `/api/session`, legacy `/rest` session, SOAP `Login`/`Logout` | +| [Inventory](inventory.md) | Datacenter, cluster, folder, resource pool, host, datastore, network CRUD | +| [Виртуальные машины](vm.md) | Create/delete, power, hardware, snapshots, clone, relocate, guest ops | +| [Storage](storage.md) | Datastores, files, host storage devices, storage policies | +| [Networking](networking.md) | Standard/distributed portgroups, DVS, host networking | +| [Tagging](tagging.md) | Categories, tags, associations | +| [Content library](content-library.md) | Libraries, items, update/download sessions, OVF deploy | +| [SOAP / VIM](soap.md) | RetrieveServiceContent, PropertyCollector, task-returning operations | +| [Tasks](tasks.md) | CIS task ids, polling, workers | +| [Appliance](appliance.md) | Version, health, networking, timesync | +| [Авторизация](authz.md) | Roles, privileges, permissions | + +## Карта персистентности + +- Объекты inventory (hosts, VMs, datastores, networks, folders, …) → + `vsphere_objects` (MOID, type, name, parent, `props` JSONB). +- Sessions / credentials → `vsphere_sessions`, `vsphere_credentials`. +- Tasks → `vsphere_tasks`. +- Tags / categories / associations → `vsphere_tag_categories`, + `vsphere_tags`, `vsphere_tag_associations`. +- Content libraries / items → `vsphere_libraries`, `vsphere_library_items`. +- Метаданные файлов datastore → `vsphere_datastore_files`. +- Оставшиеся маршруты Broadcom Automation API (DB-backed stub surface) → + `vsphere_api_state` (миграция `011`). +- Update/download sessions content library → `vsphere_transfer_sessions` + (миграция `012`). +- Состояние transfer HttpNfcLease → `vsphere_nfc_leases` (миграция `012`). +- Views PropertyCollector / токены WaitForUpdates → `vsphere_pc_state` + (миграция `013`). +- Console tickets → `vsphere_console_tickets` (миграция `013`). diff --git a/docs/ru/domains/appliance.md b/docs/ru/domains/appliance.md new file mode 100644 index 0000000..15f36c5 --- /dev/null +++ b/docs/ru/domains/appliance.md @@ -0,0 +1,35 @@ +**Language / Язык:** [English](../../domains/appliance.md) | [Русский](appliance.md) + +# Appliance + +Поверхности vCenter Server Appliance (VCSA) — version, health, networking, +timesync: +[`app/vsphere/rest/appliance_ext.py`](../../../app/vsphere/rest/appliance_ext.py), +[`app/vsphere/domain/appliance.py`](../../../app/vsphere/domain/appliance.py). + +## Эндпоинты + +| Метод | Путь | Заметки | +|---|---|---| +| GET | `/api/appliance/system/version` | Читается без сессии; отражает метку активного catalog major | +| GET | `/api/appliance/health/system` | Сводка общего health | +| GET/PUT/POST | `/api/appliance/networking` | Hostname, DNS, default gateway, interfaces, proxy | +| GET/PUT/POST | `/api/appliance/networking/dns/hostname` \| `/dns/servers` \| `/dns/domains` | Сфокусированные зеркала, синхронизированные с `/networking` | +| GET | `/api/appliance/timesync` | Режим NTP + servers | +| GET | `/api/vcenter/certificate-management/vcenter/tls[-csr]` \| `/trusted-root-chains` | Stand-in'ы machine-cert / CSR / trust-chain | + +## Основные моменты + +- Defaults моделируют реалистичный single-nic VCSA (`vcenter.lab.local`, + `192.168.1.50/24`, gateway `192.168.1.1`, DNS `8.8.8.8`/`1.1.1.1`). +- `save_networking` держит сфокусированные DNS-зеркала + (`/dns/hostname`, `/dns/servers`, `/dns/domains`) согласованными с полным + документом `/networking`, чтобы работали оба стиля клиентов Automation API. +- Состояние идемпотентно засевается один раз на свежую БД + (`seed_appliance_state`) и хранится в `vsphere_api_state`. +- Эндпоинты TLS/certificate-management — seeded stand-in'ы, не настоящее + хранилище сертификатов VECS — см. [Покрытие API](../api-coverage.md). + +`/api/appliance/system/version` намеренно не требует сессию в этой lab-сборке +(поведение реального vCenter зависит от версии), чтобы smoke-скрипты могли +проверить доступность до аутентификации. diff --git a/docs/ru/domains/authz.md b/docs/ru/domains/authz.md new file mode 100644 index 0000000..bbf5bb1 --- /dev/null +++ b/docs/ru/domains/authz.md @@ -0,0 +1,51 @@ +**Language / Язык:** [English](../../domains/authz.md) | [Русский](authz.md) + +# Авторизация + +Gate роль → privilege для мутирующих REST-эндпоинтов (и decorator-style hook +для SOAP): [`app/vsphere/security/authz.py`](../../../app/vsphere/security/authz.py), +[`platform_rest.py`](../../../app/vsphere/rest/platform_rest.py). + +## Эндпоинты + +| Метод | Путь | Заметки | +|---|---|---| +| GET | `/api/vcenter/privilege` | Каталог привилегий | +| GET | `/api/vcenter/authorization/roles` | Role → набор privilege | +| GET/POST/DELETE | `/api/vcenter/authorization/permissions[/{permission_id}]` | Привязки principal ↔ role ↔ entity | +| GET/POST/PATCH/DELETE | `/api/vcenter/identity/providers[/{provider}]` | Stand-in'ы identity-provider LocalOS + OIDC + SAML | + +## Роли (seed) + +| Роль | Область | +|---|---| +| `Administrator` | Каждая привилегия в каталоге | +| `ReadOnly` | `System.Anonymous`, `System.Read`, `System.View`, `Datastore.Browse` | +| `VirtualMachinePowerUser` | Read + взаимодействия power/snapshot/clone | +| `VirtualMachineAdministrator` | Набор power-user + привилегии create/delete/reconfigure/tag/content-library | + +`ROLE_PRIVILEGES` в `authz.py` задаёт точные наборы привилегий; неполный +пример gated-привилегий: `VirtualMachine.Inventory.Create`, +`VirtualMachine.Inventory.Delete`, `VirtualMachine.Interact.PowerOn`, +`VirtualMachine.Config.CPUCount`, `VirtualMachine.Provisioning.Clone`, +`Datastore.FileManagement`, `Network.Assign`, +`InventoryService.Tagging.CreateTag`, `ContentLibrary.AddLibraryItem`, +`Authorization.ModifyPermissions`. + +## Как работает gating + +- `require_privilege(*needed)` — фабрика зависимостей FastAPI: резолвит + сессию, загружает роли (из сессии или `vsphere_credentials`, если нет), + и поднимает HTTP 403 (`unauthorized`), если отсутствует любая из + перечисленных привилегий. +- `require_read` — сокращение для `require_privilege("System.Read")`. +- Permissions также могут ограничить роль конкретным entity MOID + (`PermissionSpec(principal, role, entity_moid, propagate)`); seed + ограничивает `readonly@vsphere.local` datacenter'ом, а двух VM-admin + принципалов — папкой VM. + +## Seeded-принципалы + +Четыре принципала `@vsphere.local` и их роли — в +[Аутентификация](../authentication.md); как permissions скоупятся по +профилю — в [Профили seed](../seed-profiles.md). diff --git a/docs/ru/domains/content-library.md b/docs/ru/domains/content-library.md new file mode 100644 index 0000000..9b480ce --- /dev/null +++ b/docs/ru/domains/content-library.md @@ -0,0 +1,38 @@ +**Language / Язык:** [English](../../domains/content-library.md) | [Русский](content-library.md) + +# Content library + +Локальные content libraries, library items, upload/download sessions и OVF +deploy: +[`app/vsphere/rest/content_rest.py`](../../../app/vsphere/rest/content_rest.py), +[`nfc_rest.py`](../../../app/vsphere/rest/nfc_rest.py), +[`app/vsphere/domain/content.py`](../../../app/vsphere/domain/content.py). + +## Эндпоинты + +| Метод | Путь | Заметки | +|---|---|---| +| GET | `/api/content/library` | Список library ids | +| POST | `/api/content/local-library` | Создать local library | +| GET/POST | `/api/content/library/item` | Список / create items (`?library_id=`) | +| POST | `/api/vcenter/ovf/library-item/{item_id}` | Deploy OVF item → новая `VirtualMachine` + task | +| POST | `/api/content/library/item/update-session[/{session_id}[/file]]` | Поток push-upload (стиль Ansible/Terraform) | +| GET/POST | `/api/content/library/item/download-session[/{session_id}[/file]]` | Поток pull-download | +| GET/PUT/POST | `/nfc/{lease}` \| `/nfc/{lease}/files/{filename}` \| `/nfc/{lease}/complete` | Эндпоинты transfer в стиле HttpNfcLease для SOAP import path | + +## Основные моменты + +- Libraries/items живут в `vsphere_libraries` / `vsphere_library_items`; + seed создаёт две libraries («Local Content», «Published Templates») с + OVF-typed items (`ubuntu-22.04`, `centos-stream-9`, `golden-image`). +- Update/download sessions живут в PostgreSQL (`vsphere_transfer_sessions`, + миграция `012`) и моделируют handshake передачи файлов — не реальное + byte-for-byte хранилище OVF/VMDK. Строки HttpNfcLease — в `vsphere_nfc_leases`. +- `deploy_ovf_from_library` создаёт реальную строку `VirtualMachine` и + возвращает task id, зеркаля SOAP-поток `ImportVApp_Task` / + `CreateImportSpec` + `HttpNfcLease*`, используемый govc-style `ovf.import`. +- Для create нужны `ContentLibrary.CreateLocalLibrary` / `.AddLibraryItem`, + для deploy — `VirtualMachine.Provisioning.DeployTemplate`. + +Операции HttpNfcLease progress/complete/abort для upload-heavy клиентов — +[SOAP / VIM](soap.md). diff --git a/docs/ru/domains/inventory.md b/docs/ru/domains/inventory.md new file mode 100644 index 0000000..cb9e806 --- /dev/null +++ b/docs/ru/domains/inventory.md @@ -0,0 +1,46 @@ +**Language / Язык:** [English](../../domains/inventory.md) | [Русский](inventory.md) + +# Inventory + +Listing + CRUD для datacenter, cluster, folder, resource pool, host и +datastore/network: +[`app/vsphere/rest/router.py`](../../../app/vsphere/rest/router.py), +[`app/vsphere/domain/inventory_ops.py`](../../../app/vsphere/domain/inventory_ops.py). + +## Эндпоинты + +| Метод | Путь | Заметки | +|---|---|---| +| GET | `/api/vcenter/datacenter` | Список | +| POST/DELETE | `/api/vcenter/datacenter[/{datacenter}]` | Create засевает подпапки host/vm/datastore/network | +| GET | `/api/vcenter/cluster` | Список | +| POST/DELETE | `/api/vcenter/cluster[/{cluster}]` | Create засевает `ResourcePool` | +| GET | `/api/vcenter/folder` | Список; `GET /api/vcenter/folder/{folder}/children` | +| POST/DELETE | `/api/vcenter/folder[/{folder}]` | | +| GET | `/api/vcenter/resource-pool` | Список | +| POST/DELETE | `/api/vcenter/resource-pool[/{resource_pool}]` | | +| GET | `/api/vcenter/host[/{host}]` | Connection state, CPU/memory, IP, storage devices, networking | +| POST | `/api/vcenter/host/{host}/maintenance` | Переключение maintenance mode | +| GET | `/api/vcenter/datastore[/{datastore}]` | Type, capacity, free space, accessibility | +| GET | `/api/vcenter/network` | Standard networks + distributed portgroups | + +Legacy `/rest/vcenter/*` зеркалит большинство GET-путей с конвертом +`{ "value": … }` — см. [Поверхность API](../api-surface.md). + +## Основные моменты + +- Каждый объект inventory — строка в `vsphere_objects` (MOID, type, name, + `parent_moid`, `props` JSONB) — см. + [`app/vsphere/inventory.py`](../../../app/vsphere/inventory.py). +- Конвенции MOID следуют формам реального vCenter: `datacenter-NN`, + `domain-cNN` (cluster), `resgroup-NN` (resource pool), `group-vNN`/`group-hNN`/ + `group-sNN`/`group-nNN` (папки VM/host/datastore/network), `host-NN`, + `datastore-NN`, `network-NN` / `dvportgroup-NN`. +- `list_hosts`/`list_clusters`/и т.п. фильтруют живое состояние PostgreSQL; + отдельного кэша для инвалидации после мутации нет. +- Список VM (`GET /api/vcenter/vm`) поддерживает фильтры: `names`, + `power_states`, `hosts`, `folders`, `datacenters`, `clusters`, + `resource_pools`, плюс пагинацию `limit`/`cursor`. + +Форма топологии по умолчанию — [Профили seed](../seed-profiles.md); +операции по VM — [Виртуальные машины](vm.md). diff --git a/docs/ru/domains/networking.md b/docs/ru/domains/networking.md new file mode 100644 index 0000000..568358b --- /dev/null +++ b/docs/ru/domains/networking.md @@ -0,0 +1,35 @@ +**Language / Язык:** [English](../../domains/networking.md) | [Русский](networking.md) + +# Networking + +Standard networks, distributed portgroups/switches и host networking: +[`app/vsphere/rest/router.py`](../../../app/vsphere/rest/router.py), +[`platform_rest.py`](../../../app/vsphere/rest/platform_rest.py). + +## Эндпоинты + +| Метод | Путь | Заметки | +|---|---|---| +| GET | `/api/vcenter/network` | Объекты standard `Network` + `DistributedVirtualPortgroup` | +| GET/POST | `/api/vcenter/network/dvs` | Distributed virtual switches | +| POST | `/api/vcenter/network/dvpg` | Создать distributed portgroup | +| GET | `/api/vcenter/host/{host}/networking` | DNS, default gateway, интерфейс `vmk0`, routing | +| GET/PUT/POST | `/api/appliance/networking` \| `/networking/dns/{hostname,servers,domains}` | Networking на уровне appliance vCenter (см. [Appliance](appliance.md)) | + +Legacy `GET /rest/vcenter/network` зеркалит список. + +## Основные моменты + +- `nics[].value.backing` каждой VM указывает либо на `STANDARD_PORTGROUP` + (`network-41`, «VM Network»), либо на `DISTRIBUTED_PORTGROUP` + (`dvportgroup-4N`, с `vlan_id`). +- Топология по умолчанию засевает один `VmwareDistributedVirtualSwitch` + (`dvs-51`, `mtu: 9000`) и 1–3 дополнительных distributed portgroup в + зависимости от размера профиля. +- Host networking (`GET /api/vcenter/host/{host}/networking`) возвращает DNS + servers/domains, default gateway и один management-интерфейс `vmk0` с + детерминированным IPv4 по индексу host. +- Пути Automation API с меткой NSX (tier-0 gateway, projects, edges, + VPC/subnets) — seeded lab stand-in'ы под `namespace-management` — см. + таблицу «Platform surfaces» в [Покрытие API](../api-coverage.md); это не + реальный NSX Manager. diff --git a/docs/ru/domains/session.md b/docs/ru/domains/session.md new file mode 100644 index 0000000..80f9add --- /dev/null +++ b/docs/ru/domains/session.md @@ -0,0 +1,32 @@ +**Language / Язык:** [English](../../domains/session.md) | [Русский](session.md) + +# Session + +Устойчивая идентичность сессии, общая для REST и SOAP: +[`app/vsphere/security/session.py`](../../../app/vsphere/security/session.py). + +## Эндпоинты + +| Метод | Путь | Заметки | +|---|---|---| +| POST | `/api/session` | Basic auth → JSON-строка session id + заголовок/cookie `vmware-api-session-id` | +| GET | `/api/session` | HTTP 200; заголовки `x-vmware-session-user` / `x-vmware-session-roles` | +| DELETE | `/api/session` | Инвалидирует сессию, очищает cookie | +| POST/GET/DELETE | `/rest/com/vmware/cis/session` | Legacy-эквиваленты `{ "value": … }` | +| POST | SOAP `SessionManager.Login` | Возвращает тот же session id; ставит cookie `vmware_soap_session` | +| POST | SOAP `SessionManager.Logout` | Удаляет сессию | + +## Основные моменты + +- Сессии — непрозрачные 32-символьные hex-токены в `vsphere_sessions` со + **скользящим TTL 2 часа** — каждый аутентифицированный вызов продлевает + `expires_at`. +- Четыре лабораторные учётки (`vsphere_credentials`, scrypt-хеш) идемпотентно + обеспечиваются при первом login и каждым профилем seed + (`ensure_default_credentials`). +- `require_session` резолвит сессию из заголовка или cookie + `vmware-api-session-id`; отсутствует/истекла → HTTP 401. +- Роли привязываются к сессии при lookup (`vsphere_credentials.roles`) и + управляют [Авторизацией](authz.md). + +Полные примеры запросов — [Аутентификация](../authentication.md). diff --git a/docs/ru/domains/soap.md b/docs/ru/domains/soap.md new file mode 100644 index 0000000..a8768c8 --- /dev/null +++ b/docs/ru/domains/soap.md @@ -0,0 +1,68 @@ +**Language / Язык:** [English](../../domains/soap.md) | [Русский](soap.md) + +# SOAP / VIM + +Минимальный VIM SDK для клиентов в стиле pyvmomi / govmomi (провайдер +Terraform `hashicorp/vsphere`, Pulumi, govc): +[`app/vsphere/soap/router.py`](../../../app/vsphere/soap/router.py), +[`property_collector.py`](../../../app/vsphere/soap/property_collector.py), +[`pbm.py`](../../../app/vsphere/soap/pbm.py). + +## Эндпоинт + +Все операции POST'ят SOAP-конверт на `/sdk` (также `/sdk/`). Вспомогательные +маршруты: + +| Метод | Путь | Заметки | +|---|---|---| +| GET | `/sdk/vimService.wsdl` (alias `/sdk/vim.wsdl`) | WSDL stub со списком реализованных операций | +| GET | `/sdk/about.do` (alias `/about.do`) | Человекочитаемая страница «VMware vCenter Server» | +| POST | `/sdk/vim25/{version}/SessionManager/SessionManager/Login` | Login-вариант с JSON-телом, используемый некоторыми SDK | + +## Реализованные операции + +- `RetrieveServiceContent`, `Login`, `Logout` +- `RetrieveProperties`, `RetrievePropertiesEx`, **ContinueRetrievePropertiesEx** + (токены пагинации; plural ``), `CreateFilter`, + `WaitForUpdatesEx` (version tokens; пустые polls), `CreateContainerView`, + `DestroyPropertyFilter` +- `FindByInventoryPath` (пути без корневой папки `Datacenters`, как в + конвенциях govmomi), `FindByUuid`, `FindByDnsName`, `FindByIp`, `FindChild` +- `CreateVM_Task`, `CreateChildVM_Task`, `CreateFolder`, `PowerOnVM_Task`, + `PowerOffVM_Task`, `CloneVM_Task`, `CreateSnapshot_Task`, `Rename_Task`, + `ReconfigVM_Task`, `RelocateVM_Task`, `Destroy_Task`, `CustomizeVM_Task`, + `CancelTask`, `CurrentTime` +- Guest file ops: `InitiateFileTransferToGuest`, + `InitiateFileTransferFromGuest`, `ListFilesInGuest`, `DeleteFileInGuest`, + `MakeDirectoryInGuest` +- Import/upload: `ImportVApp_Task`, `CreateImportSpec`, + `HttpNfcLeaseComplete`, `HttpNfcLeaseProgress`, `HttpNfcLeaseAbort`, + `HttpNfcLeaseGetManifest` (в паре с REST `/nfc/{lease}` — + см. [Content library](content-library.md)) +- `QueryConfigOption`, `QueryConfigOptionEx`, `QueryConfigOptionDescriptor`, + `QueryConfigTarget` +- Stub PBM (`/pbm`) для клиентов, учитывающих storage policy + +## Основные моменты + +- `Login` выдаёт ту же underlying-сессию, что и REST (`vmware-api-session-id` + cookie/header плюс cookie `vmware_soap_session`) — см. + [Session](session.md). +- `VIM_VERSION` зафиксирован как `8.0.2` с ≤3 компонентами через точку, так + как `hashicorp/vsphere` строго парсит `AboutInfo.version`. +- Type-strict MOR lookup отклоняет ссылку `VirtualApp:resgroup-*`, + резолвящуюся как plain `ResourcePool` — важно для Terraform resource path + `CreateVM_Task`. +- Операции, возвращающие задачу, создают реальную строку в `vsphere_tasks` + (общую с REST — см. [Tasks](tasks.md)), включая MoRefs `info.result` при + create/clone. +- Filters PropertyCollector, ContainerViews и version tokens WaitForUpdatesEx + живут в `vsphere_pc_state` (миграция `013`) между перезапусками процесса + в рамках лаборатории. +- `Folder.childType` отдаётся как `ArrayOfString`; строковые свойства несут + `xsi:type="xsd:string"`, чтобы их принимал decoder govmomi; `Datastore.host` + — `ArrayOfDatastoreHostMount`; у `Cluster`/`Host` есть `environmentBrowser`. + +Примеры подключений pyvmomi/govmomi/Terraform/Pulumi — [Клиенты](../clients.md); +минимальный raw-XML smoke — +[examples/python/vsphere_soap_smoke.py](../../../examples/python/vsphere_soap_smoke.py). diff --git a/docs/ru/domains/storage.md b/docs/ru/domains/storage.md new file mode 100644 index 0000000..93fe9ec --- /dev/null +++ b/docs/ru/domains/storage.md @@ -0,0 +1,37 @@ +**Language / Язык:** [English](../../domains/storage.md) | [Русский](storage.md) + +# Storage + +Datastores, метаданные файлов datastore, устройства хранения host и storage +policies: +[`app/vsphere/rest/router.py`](../../../app/vsphere/rest/router.py), +[`content_rest.py`](../../../app/vsphere/rest/content_rest.py), +[`platform_rest.py`](../../../app/vsphere/rest/platform_rest.py), +[`app/vsphere/domain/content.py`](../../../app/vsphere/domain/content.py). + +## Эндпоинты + +| Метод | Путь | Заметки | +|---|---|---| +| GET | `/api/vcenter/datastore[/{datastore}]` | Type (`VMFS`/`NFS`), capacity, free space, `multiple_host_access` | +| GET/POST | `/api/vcenter/datastore/{datastore}/files` | Список / регистрация метаданных файлов (пути ISO, VMX, VMDK) | +| GET | `/api/vcenter/host/{host}/storage/storage-device` | Seeded local disk devices (`naa.*`, capacity, флаг SSD) | +| GET | `/api/vcenter/storage/policies[/{policy}/vm]` | Storage-based policy management, в т.ч. lab-политики `policy_type: VSAN` | + +Legacy `GET /rest/vcenter/datastore` зеркалит список в конверте +`{ "value": … }`. + +## Основные моменты + +- Строки datastore засеваются реалистичными парами capacity/free-space + (`type`, `capacity`, `free_space`, `accessible`, + `multiple_host_access`) — см. + [`app/vsphere/profiles.py`](../../../app/vsphere/profiles.py). +- Метаданные файлов живут в `vsphere_datastore_files` (`path`, `size`, `type`); + seed заранее заполняет ISO и записи `.vmx`/`.vmdk` VM + (`seed_platform_extras`). +- Среди storage policies есть lab-политика с меткой vSAN `RAID1` — оговорку + по vSAN (seeded lab data, не реальный кластер vSAN) см. в таблице + «Platform surfaces» в [Покрытие API](../api-coverage.md). +- Устройства хранения host — синтетические диски на host, не реальные extents + ESXi VMFS; флаги capacity/SSD детерминированно зависят от индекса host. diff --git a/docs/ru/domains/tagging.md b/docs/ru/domains/tagging.md new file mode 100644 index 0000000..5246170 --- /dev/null +++ b/docs/ru/domains/tagging.md @@ -0,0 +1,33 @@ +**Language / Язык:** [English](../../domains/tagging.md) | [Русский](tagging.md) + +# Tagging + +Сервис CIS tagging (categories, tags, object associations): +[`app/vsphere/rest/tagging_rest.py`](../../../app/vsphere/rest/tagging_rest.py), +[`app/vsphere/domain/tagging.py`](../../../app/vsphere/domain/tagging.py). + +## Эндпоинты + +| Метод | Путь | Заметки | +|---|---|---| +| GET/POST | `/api/cis/tagging/category` | Список / create (`cardinality`, `associable_types`) | +| GET/DELETE | `/api/cis/tagging/category/{category_id}` | | +| GET/POST | `/api/cis/tagging/tag` | Список / create под category | +| GET/DELETE | `/api/cis/tagging/tag/{tag_id}` | | +| POST | `/api/cis/tagging/tag-association` | Attach/detach тега к/от объекта | + +## Основные моменты + +- Id category и tag следуют реальной форме + `urn:vmomi:InventoryServiceCategory:…` / + `urn:vmomi:InventoryServiceTag:…:GLOBAL`. +- Строки живут в `vsphere_tag_categories`, `vsphere_tags`, + `vsphere_tag_associations` — устойчивы между перезапусками, заменяются + при reseed. +- Seed создаёт две categories (`Environment`, `Owner`) с тегами `prod`/ + `staging`/`platform` и прикрепляет `prod` к двум seeded VM + (`seed_platform_extras` в + [`app/vsphere/domain/content.py`](../../../app/vsphere/domain/content.py)). +- Attach/create тега требует привилегии + `InventoryService.Tagging.CreateCategory` / `.CreateTag` / `.AttachTag` — + см. [Авторизация](authz.md). diff --git a/docs/ru/domains/tasks.md b/docs/ru/domains/tasks.md new file mode 100644 index 0000000..ac66453 --- /dev/null +++ b/docs/ru/domains/tasks.md @@ -0,0 +1,38 @@ +**Language / Язык:** [English](../../domains/tasks.md) | [Русский](tasks.md) + +# Tasks + +Длительные операции (power, clone, relocate, snapshot, OVF deploy, guest +customize) возвращают CIS-style task id: +[`app/vsphere/domain/tasks.py`](../../../app/vsphere/domain/tasks.py), +[`app/vsphere/rest/tasks.py`](../../../app/vsphere/rest/tasks.py). + +## Эндпоинты + +| Метод | Путь | Заметки | +|---|---|---| +| GET | `/api/cis/tasks` | Список недавних задач (до 200 последних) | +| GET | `/api/cis/tasks/{task}` | Status, progress, `service`/`operation`, `result`/`error` | + +## Паттерн клиента + +1. Мутация `POST`/`DELETE` → прочитайте task id из `{ "task": "task-…" }` + (REST) или SOAP MoRef `*_Task`. +2. Опрашивайте `GET /api/cis/tasks/{task}`, пока `status` не станет + `SUCCEEDED` или `FAILED`. +3. В `result` — результат операции (например `{"vm": "vm-104"}` при + create/clone/deploy). + +## Основные моменты + +- Строки задач коммитятся в `vsphere_tasks` (`id`, `description`, `status`, + `service`, `operation`, `result`, `error`, `completed_at`). +- `progress` синтезируется как `50` во время выполнения и `100` в терминальном + состоянии — дробный progress этот симулятор не моделирует. +- Одно и то же хранилище задач обслуживает и REST `/api/cis/tasks`, и SOAP + task MoRefs, поэтому Terraform apply (SOAP `CreateVM_Task`) и REST-опрос + того же id видят согласованное состояние. +- Длительности симуляции учитывают `SIMULATION_TIME_SCALE` + (больше = быстрее завершение). + +См. [Поверхность API](../api-surface.md) и [Эксплуатация](../operations.md). diff --git a/docs/ru/domains/vm.md b/docs/ru/domains/vm.md new file mode 100644 index 0000000..aa797ed --- /dev/null +++ b/docs/ru/domains/vm.md @@ -0,0 +1,50 @@ +**Language / Язык:** [English](../../domains/vm.md) | [Русский](vm.md) + +# Виртуальные машины + +Полный REST lifecycle для объектов `VirtualMachine`: +[`app/vsphere/rest/router.py`](../../../app/vsphere/rest/router.py), +[`vm_ext.py`](../../../app/vsphere/rest/vm_ext.py), +[`app/vsphere/domain/vm_ops.py`](../../../app/vsphere/domain/vm_ops.py). + +## Эндпоинты + +| Метод | Путь | Заметки | +|---|---|---| +| GET | `/api/vcenter/vm` | Список с фильтрами `names`/`power_states`/`hosts`/`folders`/`datacenters`/`clusters`/`resource_pools`/`limit`/`cursor` | +| GET/DELETE | `/api/vcenter/vm/{vm}` | Get / delete (должна быть powered off) | +| POST | `/api/vcenter/vm` | Create — `placement.{folder,host,datastore,resource_pool}`, `cpu.count`, `memory.size_MiB`, `disks`, `nics` | +| GET/POST | `/api/vcenter/vm/{vm}/power` | Get power state / `?action=start\|stop\|suspend\|reset` — возвращает `{ "task": "task-…" }` | +| GET | `/api/vcenter/vm/{vm}/hardware` | Сводка | +| GET/PATCH | `/api/vcenter/vm/{vm}/hardware/cpu` \| `/memory` | Смена CPU count / memory (privilege-gated) | +| GET/POST | `/api/vcenter/vm/{vm}/hardware/disk` \| `/ethernet` | Добавить disk / NIC | +| GET | `/api/vcenter/vm/{vm}/hardware/boot` | Boot type/order | +| GET/POST/DELETE | `/api/vcenter/vm/{vm}/snapshots[/{snapshot}]` | Create, revert (`?action=revert`), delete | +| POST | `/api/vcenter/vm/{vm}/clone` \| `/relocate` | Возвращают задачу | +| GET/POST | `/api/vcenter/vm/{vm}/tools` | Статус guest tools / upgrade | +| GET | `/api/vcenter/vm/{vm}/guest/identity` \| `/networking` | Имя guest OS, синтетический IP | +| GET/POST | `/api/vcenter/vm/{vm}/guest/power` | Guest-level power ops | +| POST | `/api/vcenter/vm/{vm}/guest/customization` | Спека customization в стиле sysprep/cloud-init | +| POST | `/api/vcenter/vm/{vm}/console/tickets` | Console-тикет (стиль VNC/WebMKS) | +| GET/PUT/DELETE | `/api/vcenter/vm/{vm}/guest/filesystem` | Lab virtual guest filesystem (потоки write-a-file Ansible/Terraform) | +| GET | `/api/vcenter/vm/{vm}/guest/filesystem/files` \| `/guest/local-filesystem` | Listing | + +## Основные моменты + +- У каждой строки VM реалистичная форма устройств: `nics`, `disks`, `cdroms`, + `floppies`, `serials`, `scsi_adapters`, `boot`/`boot_devices`, `identity` + (`instance_uuid`, `bios_uuid`) и синтетическая карта `guest_ip` / + `guest_filesystems` — те же поля питают и REST hardware-эндпоинты, и SOAP + `VirtualMachineConfigInfo`. +- Create требует `VirtualMachine.Inventory.Create`; delete требует + `VirtualMachine.Inventory.Delete` **и** VM должна быть `POWERED_OFF`. +- Power/clone/snapshot/relocate/customize создают устойчивую CIS-задачу (см. + [Tasks](tasks.md)), а не мутируют синхронно в теле ответа. +- Console tickets из `/api/vcenter/vm/{vm}/console/tickets` живут в + `vsphere_console_tickets` (миграция `013`). +- MOID следуют конвенции `vm-{100+n}`, засеваемой + [`app/vsphere/profiles.py`](../../../app/vsphere/profiles.py). + +Семантика datastore/disk-file — [Storage](storage.md); эквивалентные +операции `CreateVM_Task`/`PowerOnVM_Task`/… для pyvmomi, govmomi, Terraform и +Pulumi — [SOAP / VIM](soap.md). diff --git a/docs/ru/examples/ansible.md b/docs/ru/examples/ansible.md new file mode 100644 index 0000000..8c3beb2 --- /dev/null +++ b/docs/ru/examples/ansible.md @@ -0,0 +1,23 @@ +**Language / Язык:** [English](../../examples/ansible.md) | [Русский](ansible.md) + +# Ansible + +Playbook использует модуль `uri` против HTTPS-шлюза +(`https://localhost`): вход по Basic-auth сессии, затем вызовы с +заголовком `vmware-api-session-id` для остального жизненного цикла. + +```bash +cd examples/ansible +ansible-playbook -i inventory.ini vsphere_playbook.yml +``` + +[`vsphere_playbook.yml`](../../../examples/ansible/vsphere_playbook.yml) охватывает: +вход в сессию, список ВМ, создание, power on, опрос CIS-задачи +(`/api/cis/tasks/{task}`), запись файла в лабораторную гостевую виртуальную ФС, +power off, удаление и выход из сессии. + +Перед опорой на фиксированные имена ВМ/MOID из предыдущего запуска выполните +повторный seed симулятора (`make seed`). + +Для lab-набора на официальном `pulumi-vsphere` (непустые export'ы, HTML-отчёт) +см. [`pulumi-tests/`](../../../pulumi-tests/README.ru.md) или `make pulumi-tests`. diff --git a/docs/ru/examples/go.md b/docs/ru/examples/go.md new file mode 100644 index 0000000..ac002a2 --- /dev/null +++ b/docs/ru/examples/go.md @@ -0,0 +1,21 @@ +**Language / Язык:** [English](../../examples/go.md) | [Русский](go.md) + +# Go + +Использует стандартную библиотеку Go (`net/http`) против +`https://localhost` с Basic-auth сессией +(`vmware-api-session-id`). + +```bash +cd examples/go +go run . +``` + +Переопределите значения по умолчанию через `VSPHERE_BASE`, `VSPHERE_USER`, +`VSPHERE_PASSWORD`, `VSPHERE_VM_NAME`. См. [`main.go`](../../../examples/go/main.go) +для потока session → list → create → power → wait-task → delete и вспомогательной +функции `waitTask`, которая опрашивает `GET /api/cis/tasks/{task}`. + +Проверка TLS отключена в HTTP-клиенте только для локального самоподписанного +сертификата разработческого шлюза — не переиспользуйте такой transport против +реального vCenter. diff --git a/docs/ru/examples/java.md b/docs/ru/examples/java.md new file mode 100644 index 0000000..76d7727 --- /dev/null +++ b/docs/ru/examples/java.md @@ -0,0 +1,22 @@ +**Language / Язык:** [English](../../examples/java.md) | [Русский](java.md) + +# Java + +Cookbook на Java 11+ `HttpClient` с Basic-auth сессией +(`vmware-api-session-id`) против `https://localhost`. Без сторонних +JSON-библиотек — ответы разбираются простым строковым извлечением полей, +достаточным для лабораторного smoke. + +```bash +cd examples/java +javac Cookbook.java && java Cookbook +``` + +Переопределите значения по умолчанию переменными окружения `VSPHERE_BASE`, +`VSPHERE_USER`, `VSPHERE_PASSWORD`, `VSPHERE_VM_NAME`. См. +[`Cookbook.java`](../../../examples/java/Cookbook.java) для потока session → +create → power → wait-task → delete. + +Клиент устанавливает trust-all `SSLContext` только для локального +самоподписанного сертификата разработческого шлюза — не переиспользуйте его +против реального vCenter. diff --git a/docs/ru/examples/overview.md b/docs/ru/examples/overview.md new file mode 100644 index 0000000..155b4ec --- /dev/null +++ b/docs/ru/examples/overview.md @@ -0,0 +1,53 @@ +**Language / Язык:** [English](../../examples/overview.md) | [Русский](overview.md) + +# Обзор примеров клиентов + +## Чеклист запуска + +```bash +make up +curl -skf https://localhost/health/ready +make seed +curl -sk https://localhost/api/appliance/system/version +``` + +## Конечные точки + +| URL | Когда использовать | +|---|---| +| `https://localhost` | curl, pyvmomi, govmomi, Terraform, Pulumi, Ansible, Go, Java, Perl — всё из `examples/` | +| `http://localhost` | Лабораторный HTTP без TLS (без рукопожатия TLS) | + +## Краткая справка по аутентификации + +**Сессия (REST)** + +```bash +SID=$(curl -sk -u 'administrator@vsphere.local:VMware1!' \ + -X POST https://localhost/api/session | tr -d '"') +curl -sk -H "vmware-api-session-id: $SID" https://localhost/api/vcenter/vm +``` + +**SOAP Login** + +```bash +python examples/python/vsphere_soap_smoke.py https://localhost +``` + +## Ожидание задач + +Не считайте HTTP-ответ мутации достаточным признаком «ВМ запущена». Вызовы +power, clone, relocate, snapshot и OVF-deploy возвращают `{ "task": "task-…" }`; +опрашивайте `GET /api/cis/tasks/{task}`, пока `status` не станет `SUCCEEDED` или +`FAILED`. См. [Задачи](../domains/tasks.md). + +## Предупреждение о повторном seed + +`make seed` заменяет инвентарь PostgreSQL. После этого обновите состояние +Terraform/Pulumi/Ansible — см. [Профили seed](../seed-profiles.md). + +## Дерево исполняемых примеров + +См. [`examples/README.ru.md`](../../../examples/README.ru.md). Lab-набор на +официальном `pulumi-vsphere` — в +[`pulumi-tests/`](../../../pulumi-tests/README.ru.md) (`make pulumi-tests`). diff --git a/docs/ru/examples/perl.md b/docs/ru/examples/perl.md new file mode 100644 index 0000000..4e70438 --- /dev/null +++ b/docs/ru/examples/perl.md @@ -0,0 +1,20 @@ +**Language / Язык:** [English](../../examples/perl.md) | [Русский](perl.md) + +# Perl + +Cookbook на `HTTP::Tiny` + `JSON` с Basic-auth сессией +(`vmware-api-session-id`) против `https://localhost`. + +```bash +cd examples/perl +cpanm --installdeps . # или установите HTTP::Tiny, JSON, IO::Socket::SSL вручную +perl cookbook.pl +``` + +Переопределите значения по умолчанию переменными окружения `VSPHERE_BASE`, +`VSPHERE_USER`, `VSPHERE_PASSWORD`, `VSPHERE_VM_NAME`. См. +[`cookbook.pl`](../../../examples/perl/cookbook.pl) для потока session → list → +create → power → wait-task → delete. + +`HTTP::Tiny` создаётся с `verify_SSL => 0` только для локального самоподписанного +сертификата разработческого шлюза. diff --git a/docs/ru/examples/pulumi.md b/docs/ru/examples/pulumi.md new file mode 100644 index 0000000..12c069f --- /dev/null +++ b/docs/ru/examples/pulumi.md @@ -0,0 +1,32 @@ +**Language / Язык:** [English](../../examples/pulumi.md) | [Русский](pulumi.md) + +# Pulumi + +[`examples/pulumi/`](../../../examples/pulumi/) — Python-программа Pulumi на +официальном [`pulumi-vsphere`](https://www.pulumi.com/registry/packages/vsphere/) +(SOAP/VIM) против симулятора — тот же путь провайдера, что у Terraform +`hashicorp/vsphere`. + +```bash +cd examples/pulumi +pip install -r requirements.txt +pulumi plugin install resource vsphere 4.17.0 +pulumi stack init dev # один раз +pulumi config set server localhost +pulumi config set --secret password 'VMware1!' +pulumi up +``` + +Конфигурация (`pulumi config set`): `server` (по умолчанию `localhost`), `user` +(по умолчанию `administrator@vsphere.local`), `password` (secret), `datacenter`, +`datastore`, `cluster`, `network`, `vm_name` (по умолчанию `pulumi-lab-01`). + +Та же осторожность при reseed, что и для Terraform: состояние PostgreSQL +симулятора и state Pulumi независимы. Закрепите major каталога для +воспроизводимого CI, если ваш workflow зависит от вывода Web UI/evidence (см. +[Версии API](../api-versions.md)) — сами runtime-маршруты доступны всегда +независимо от major. + +Для lab-набора (inventory + folder + VM + tags, проверки непустых export'ов, +HTML-отчёт) см. [`pulumi-tests/`](../../../pulumi-tests/README.ru.md) или +`make pulumi-tests` из корня репозитория. diff --git a/docs/ru/examples/python-requests.md b/docs/ru/examples/python-requests.md new file mode 100644 index 0000000..c75c557 --- /dev/null +++ b/docs/ru/examples/python-requests.md @@ -0,0 +1,33 @@ +**Language / Язык:** [English](../../examples/python-requests.md) | [Русский](python-requests.md) + +# Python — REST (requests / stdlib) + +Сырой HTTP к REST-шлюзу vSphere без vendor SDK. + +```bash +pip install -r examples/python/requirements.txt +python examples/python/requests_cookbook.py +``` + +[`requests_cookbook.py`](../../../examples/python/requests_cookbook.py) +демонстрирует общий поток session → create → wait-for-task → power on → wait → +power off → delete с помощью `requests`; идентификатор сессии передаётся в +заголовке `vmware-api-session-id`. + +Для варианта без внешних зависимостей, только на стандартной библиотеке +(`urllib`), см. [`vsphere_rest_smoke.py`](../../../examples/python/vsphere_rest_smoke.py): + +```bash +python examples/python/vsphere_rest_smoke.py https://localhost +``` + +Для комбинированного smoke REST-create + SOAP-`CreateVM_Task` + guest-filesystem +см. [`vsphere_lifecycle.py`](../../../examples/python/vsphere_lifecycle.py): + +```bash +VSPHERE_BASE=https://localhost python examples/python/vsphere_lifecycle.py +``` + +Все три скрипта по умолчанию используют `administrator@vsphere.local` / `VMware1!` +и отключают проверку TLS только для локального самоподписанного сертификата +разработческого шлюза. diff --git a/docs/ru/examples/terraform.md b/docs/ru/examples/terraform.md new file mode 100644 index 0000000..1aa049c --- /dev/null +++ b/docs/ru/examples/terraform.md @@ -0,0 +1,32 @@ +**Language / Язык:** [English](../../examples/terraform.md) | [Русский](terraform.md) + +# Terraform + +[`examples/terraform/vsphere/`](../../../examples/terraform/vsphere/) использует +официальный провайдер `hashicorp/vsphere` (SOAP `/sdk` под капотом), направленный +на локальный HTTPS-шлюз (`https://localhost`) с +`allow_unverified_ssl = true` для разработческого сертификата. + +```bash +cd examples/terraform/vsphere +terraform init +TF_VAR_create_lab_vm=false terraform plan # только data sources (datacenter/cluster/datastore/network/VM) +TF_VAR_create_lab_vm=true terraform apply # также создаёт лабораторную ВМ (SOAP CreateVM_Task) +``` + +Значения по умолчанию (`variables.tf`): `vsphere_server = "localhost"`, +`vsphere_user = "administrator@vsphere.local"`, +`vsphere_password = "VMware1!"`, `datacenter = "Datacenter"`, +`cluster = "Cluster"`, `datastore = "datastore1"`, +`network = "VM Network"`, `vm_name = "web-01"` (ВМ из seed `small`/`large`). + +Версии плагинов провайдера меняются быстро — закрепите версии в блоке +`required_providers` под то, что вы протестировали. После `make seed` обновите +или пересоздайте state, чтобы допущения об именах ВМ/MOID оставались согласованными. + +Этот cookbook — отправная точка для лабораторного CI, а не сертификация каждого +resource/data source `hashicorp/vsphere` против полного реестра маршрутов. См. +[SOAP / VIM](../domains/soap.md) для точных операций, лежащих в основе create/read +путей провайдера, и +[`pulumi-tests/`](../../../pulumi-tests/README.ru.md) для lab-набора +`pulumi-vsphere` (`make pulumi-tests`). diff --git a/docs/ru/examples/troubleshooting-clients.md b/docs/ru/examples/troubleshooting-clients.md new file mode 100644 index 0000000..618ad53 --- /dev/null +++ b/docs/ru/examples/troubleshooting-clients.md @@ -0,0 +1,15 @@ +**Language / Язык:** [English](../../examples/troubleshooting-clients.md) | [Русский](troubleshooting-clients.md) + +# Устранение неполадок клиентов + +| Симптом | Решение | +|---|---| +| Ошибки TLS-сертификата | Используйте `:443` с `verify=False` / `insecure`/`allow_unverified_ssl=true` **только** локально или plain HTTP `:80` | +| 401 на первом вызове | Отправляйте `Authorization: Basic …` только на `/api/session` (или SOAP `Login`); все остальные вызовы требуют `vmware-api-session-id` | +| 403 на power/create | Возможно, вы используете `readonly@vsphere.local` — переключитесь на `administrator@vsphere.local` или `operator@vsphere.local` | +| ВМ не найдена | Имена ВМ seed `small`: `web-01`, `web-02`, `db-01`, `app-01`, `jumpbox` — не числовые VMID в стиле Proxmox | +| Create возвращает MOID, а не task | REST `POST /api/vcenter/vm` синхронно возвращает MOID новой ВМ; только **power/clone/relocate/snapshot/OVF-deploy** возвращают `{ "task": "…" }` | +| Create провайдера vs task | Опрашивайте `/api/cis/tasks/{task}`; многие провайдеры (Terraform, Pulumi) уже ждут внутри — сырые HTTP/Go/Java/Perl клиенты часто забывают | +| Drift после reseed | Обновите/пересоздайте state Terraform/Pulumi/Ansible после `make seed` | +| Сессия истекла во время выполнения | Сессии имеют скользящий TTL 2 часа; выполните повторный login, если длинный скрипт простаивал дольше | +| SOAP `Login` не проходит | Убедитесь, что envelope направлен на `/sdk` с `SOAPAction` (пустая строка допустима) и `Content-Type: text/xml` | diff --git a/docs/ru/faq.md b/docs/ru/faq.md new file mode 100644 index 0000000..8fa7417 --- /dev/null +++ b/docs/ru/faq.md @@ -0,0 +1,57 @@ +**Language / Язык:** [English](../faq.md) | [Русский](faq.md) + +# FAQ + +## Это настоящий vCenter / ESXi? + +Нет. Это симулятор API и состояния. Хосты, VM, datastores и сети — +устойчивые модели PostgreSQL, а не ESXi-хосты или процессы KVM/vmkernel. + +## Вы действительно покрываете vSphere Automation API? + +**Runtime** всегда обслуживает полную зарегистрированную route table (1077 маршрутов: +104 deep handlers + DB-backed stub surface для остальных) — см. +[Поверхность API](api-surface.md). **Catalog** majors 6–8 — намеренно +низкопокрытые исторические floors (2.9%–9.6%); только major 9 (8.0 U2 / Automation +9.1 surface) объявлен как 100% в catalog. См. +[Версии API](api-versions.md) и [Совместимость](compatibility.md). + +## Можно ли использовать это в CI для Terraform / Ansible / pyvmomi / custom clients? + +Да. Это основной сценарий использования. Засейте профиль и направьте клиентов на +HTTPS gateway `:443` (REST `/api`/`/rest` или SOAP `/sdk`). См. +[Клиенты](clients.md). + +## Почему некоторые NSX / Supervisor / vSAN / SAML calls «успешны» без remotes? + +Эти области сохраняют **локальное, засеянное** состояние симулятора (см. таблицу +«Platform surfaces» в [Покрытие API](api-coverage.md)). Они намеренно не +обращаются к реальному NSX Manager, Tanzu Supervisor или IdP. + +## Означает ли registry coverage perfect vSphere parity? + +Это означает, что каждый зарегистрированный маршрут имеет устойчивый обработчик +или DB-backed stub и проходит verification suites проекта. Точное совпадение +краевых случаев с физическим ESXi-кластером может отличаться; используйте +`/ui/api/compatibility` и собственные client tests для certification claims. + +## Где Web UI? + +[https://localhost/](https://localhost/) после `make up` (gateway). + +## Можно ли развернуть в Kubernetes? + +Да. Используйте Helm chart в `helm/vmware-api-simulator` с опубликованным +образом Hub. Поддерживаются Ingress + cert-manager Let's Encrypt — см. +[Kubernetes / Helm](kubernetes.md). + +## Что такое `ENABLE_PVE_STUB`? + +Опциональная, выключенная по умолчанию legacy Proxmox VE `/api2/*` stub-плоскость, +унаследованная из общей platform lineage. Нативная vSphere REST/SOAP всегда +включена и является основной поверхностью проекта независимо от этого флага. + +## Какие VM использует seed `small`? + +`web-01`, `web-02`, `db-01`, `app-01`, `jumpbox` — см. +[Профили seed](seed-profiles.md). diff --git a/docs/ru/getting-started.md b/docs/ru/getting-started.md new file mode 100644 index 0000000..d748852 --- /dev/null +++ b/docs/ru/getting-started.md @@ -0,0 +1,176 @@ +**Language / Язык:** [English](../getting-started.md) | [Русский](getting-started.md) + +# Быстрый старт + +Поднимите локальную лабораторию vSphere, пройдите аутентификацию и выполните первый +цикл чтения/мутации против симулятора. + +## Требования + +- Docker и Docker Compose +- `make` (необязательно, но используется в документированных командах) + +Python, линтеры и тесты запускаются **внутри** контейнеров. Для повседневной работы +локальный Python-инструментарий не нужен. + +## Выберите путь + +| Путь | Когда использовать | +|---|---| +| [Опубликованный образ](#1a-опубликованный-образ-docker-hub) | Самая быстрая лаборатория на `inecs/vmware-api-simulator` | +| [Helm / Kubernetes](kubernetes.md) | Установка в кластер с Ingress + Let's Encrypt | +| [Development checkout](#1b-development-checkout) | Вклад в код / bind-mount исходников | + +## 1a. Опубликованный образ (Docker Hub) + +Использует [`docker-compose.release.yml`](../../docker-compose.release.yml) — PostgreSQL + +runtime-симулятор + HTTPS gateway с Hub. Сборка исходников не нужна, но Compose +нужно запускать из **checkout этого репозитория**, чтобы смонтировались +`docker/gateway/` и `docker/tls/`. Seed выполняется автоматически после готовности +симулятора. + +```bash +# из git checkout этого репозитория (нужны docker/gateway и docker/tls) +docker compose -f docker-compose.release.yml pull +docker compose -f docker-compose.release.yml up -d --wait +``` + +Закрепить версию: + +```bash +IMAGE_TAG=0.1.0 docker compose -f docker-compose.release.yml up -d --wait +``` + +Make-хелперы (git checkout): + +```bash +make release-up +# опциональный повторный seed: make release-seed PROFILE=small +``` + +| Порт хоста | Сервис | +|---|---| +| `443` | HTTPS gateway (основная точка входа vCenter) | +| `80` | HTTP lab face | +| `5434` | PostgreSQL (только localhost) | + +Миграции выполняются автоматически через one-shot сервис `migrate`. + +Далее — с [Дождитесь готовности](#2-дождитесь-готовности). + +## 1b. Development checkout + +```bash +make install +make up +``` + +Сервисы (полная картина — [Порты](ports.md)): + +| Порт хоста | Сервис | +|---|---| +| `443` | HTTPS gateway (nginx) → simulator | +| `80` | HTTP lab face | +| `5434` | PostgreSQL (только localhost) | + +Миграции применяются автоматически до готовности симулятора. Внутренний +процесс FastAPI слушает `8080` и на хост не публикуется. + +## 2. Дождитесь готовности + +```bash +curl -sk https://localhost/health/live +curl -sk https://localhost/health/ready +``` + +`/health/ready` возвращает HTTP 503, пока PostgreSQL недоступен **и** пока +не применена последняя упакованная миграция. + +## 3. Засейте профиль + +```bash +make seed # default: large — 10 hosts / 1000 VMs +VSPHERE_PROFILE=small make seed +``` + +`small` создаёт 3-хостовый кластер с пятью именованными VM (`web-01`, `web-02`, +`db-01`, `app-01`, `jumpbox`), datastores, standard portgroup и четырьмя +лабораторными принципалами. Другие размеры — [Профили seed](seed-profiles.md). + +## 4. Проверьте версию API + +```bash +curl -sk https://localhost/api/appliance/system/version | jq . +``` + +Catalog major при холодном старте по умолчанию — **9** (vSphere 8.0 U2 / +поверхность Automation 9.1) в Docker Compose. Просмотр и hot-swap majors 6–9 — +из Web UI или [Версии API](api-versions.md). + +## 5. Аутентификация + +```bash +SID=$(curl -sk -u 'administrator@vsphere.local:VMware1!' \ + -X POST https://localhost/api/session | tr -d '"') +echo "$SID" +``` + +`SID` — это `vmware-api-session-id`. Передавайте его в каждом последующем +вызове как заголовок (или опирайтесь на cookie, которую также выставляет +ответ login): + +```bash +curl -sk -H "vmware-api-session-id: $SID" https://localhost/api/vcenter/vm +``` + +Подробности: [Аутентификация](authentication.md). + +## 6. Список VM и включение одной + +```bash +curl -sk -H "vmware-api-session-id: $SID" \ + https://localhost/api/vcenter/vm | jq . + +curl -sk -X POST -H "vmware-api-session-id: $SID" \ + "https://localhost/api/vcenter/vm/vm-104/power?action=start" | jq . +``` + +Power-действия и другие длительные операции возвращают CIS task id. +Опрашивайте задачу до завершения: + +```bash +curl -sk -H "vmware-api-session-id: $SID" \ + "https://localhost/api/cis/tasks/${TASK_ID}" | jq . +``` + +## 7. Откройте Web UI + +Откройте [https://localhost/](https://localhost/) — интерактивная +консоль, каталог эндпоинтов (vSphere majors 6–9), вид совместимости, apply +runtime-контракта и управление demo-cluster. Скриншоты светлой/тёмной темы и +полный список возможностей — [Web UI](web-ui.md). + +## 8. Попробуйте клиентскую библиотеку + +```bash +# from the repository root after make up + seed +python examples/python/vsphere_rest_smoke.py https://localhost +python examples/python/vsphere_soap_smoke.py https://localhost +``` + +Другие стеки: [Клиенты](clients.md) и [`examples/`](../../examples/README.ru.md). + +## Готово, когда… + +- `/health/ready` возвращает `{"status": "ok"}` (или эквивалентное OK-тело) +- `/api/appliance/system/version` сообщает версию активного catalog major +- Session login успешен для `administrator@vsphere.local` +- `/api/vcenter/vm` перечисляет seeded VM +- Power-действие возвращает task id, который доходит до `SUCCEEDED` + +## Дальше + +- [Конфигурация](configuration.md) — env vars, workers, размер seed +- [Версии API](api-versions.md) — hot-swap catalog majors 6–9 +- [Клиенты](clients.md) — Python, Ansible, Terraform, Pulumi +- [Эксплуатация](operations.md) — reseed, migrate, upgrades diff --git a/docs/ru/kubernetes.md b/docs/ru/kubernetes.md new file mode 100644 index 0000000..1b2807d --- /dev/null +++ b/docs/ru/kubernetes.md @@ -0,0 +1,166 @@ +**Language / Язык:** [English](../kubernetes.md) | [Русский](kubernetes.md) + +# Kubernetes / Helm + +Разверните опубликованный образ runtime из Docker Hub с помощью чарта +[`helm/vmware-api-simulator`](../../helm/vmware-api-simulator). + +Образ: [`inecs/vmware-api-simulator`](https://hub.docker.com/r/inecs/vmware-api-simulator) + +## Требования + +- Kubernetes 1.27+ (или сопоставимая версия) +- Helm 3.14+ +- [Ingress NGINX](https://kubernetes.github.io/ingress-nginx/) (или другой + IngressClass с поддержкой HTTP-01) +- [cert-manager](https://cert-manager.io/), установленный на весь кластер + +Пример установки cert-manager: + +```bash +kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.2/cert-manager.yaml +``` + +## Быстрая установка (Hub-релиз + Ingress + Let's Encrypt) + +Из git checkout этого репозитория: + +```bash +helm upgrade --install vmware-sim ./helm/vmware-api-simulator \ + -n vmware-sim --create-namespace \ + -f ./helm/vmware-api-simulator/values-ingress-example.yaml \ + --set certManager.email=you@example.com \ + --set ingress.hosts[0].host=vmware-sim.example.com \ + --set ingress.tls[0].hosts[0]=vmware-sim.example.com \ + --set secret.ticketSigningKey="$(openssl rand -hex 32)" \ + --set postgresql.auth.password="$(openssl rand -hex 16)" +``` + +Что это делает: + +1. Скачивает `inecs/vmware-api-simulator:0.1.0` (см. `image.tag` в примерном файле). +2. Устанавливает встроенный PostgreSQL 17 (`postgres:17.5-bookworm`, как и в Compose). +3. Выполняет миграции схемы в init-контейнере (идемпотентно). +4. Загружает лабораторный профиль `small` (`seed.enabled=true`). +5. Создаёт ресурсы `ClusterIssuer`: + - `letsencrypt-prod` + - `letsencrypt-staging` +6. Создаёт Ingress с + `cert-manager.io/cluster-issuer: letsencrypt-prod` и TLS-секретом + `vmware-api-simulator-tls`. + +DNS для `vmware-sim.example.com` должен указывать на ваш Ingress-контроллер. +Затем: + +```bash +kubectl -n vmware-sim get certificate,ingress,pods +# дождитесь Certificate READY=True +curl -sS https://vmware-sim.example.com/health/ready +open https://vmware-sim.example.com/ +``` + +Seeded-логин по умолчанию: `administrator@vsphere.local` / `VMware1!`. + +### Сначала staging (рекомендуется) + +Проверьте HTTP-01, не расходуя лимиты запросов production: + +```bash +helm upgrade --install vmware-sim ./helm/vmware-api-simulator \ + -n vmware-sim --create-namespace \ + -f ./helm/vmware-api-simulator/values-ingress-example.yaml \ + --set certManager.email=you@example.com \ + --set certManager.useStaging=true \ + --set ingress.hosts[0].host=vmware-sim.example.com \ + --set ingress.tls[0].hosts[0]=vmware-sim.example.com \ + --set secret.ticketSigningKey="$(openssl rand -hex 32)" +``` + +Браузеры не будут доверять staging CA — используйте `curl -k` во время +тестирования. Переключите `certManager.useStaging=false` и пересоздайте +Certificate/TLS-секрет для production. + +## Минимальная установка (ClusterIP + port-forward) + +```bash +helm upgrade --install vmware-sim ./helm/vmware-api-simulator \ + -n vmware-sim --create-namespace \ + --set secret.ticketSigningKey="$(openssl rand -hex 32)" \ + --set seed.enabled=true + +kubectl -n vmware-sim port-forward svc/vmware-sim-vmware-api-simulator 8080:8080 +``` + +Откройте http://127.0.0.1:8080/. Service выставляет внутренний порт +приложения (`8080`, см. [Порты](ports.md)) — чарт не запускает TLS-gateway +nginx, используемый Compose; в production выставляйте TLS перед сервисом +через Ingress, либо обращайтесь к обычному HTTP-сервису для локального +тестирования. + +## Внешний PostgreSQL + +```bash +helm upgrade --install vmware-sim ./helm/vmware-api-simulator \ + -n vmware-sim --create-namespace \ + --set postgresql.enabled=false \ + --set secret.ticketSigningKey="$(openssl rand -hex 32)" \ + --set secret.databaseUrl='postgresql://user:pass@pg.example.com:5432/vmware_simulator' +``` + +Либо используйте `secret.existingSecret` с ключами `DATABASE_URL` и +`TICKET_SIGNING_KEY`. + +## Как работает выпуск TLS + +Когда `certManager.enabled=true` и `certManager.createClusterIssuer=true`, +чарт создаёт объекты ACME `ClusterIssuer`, которые решают HTTP-01 через ваш +Ingress-класс. Шаблон Ingress добавляет: + +```yaml +metadata: + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod +spec: + tls: + - secretName: vmware-api-simulator-tls + hosts: [vmware-sim.example.com] +``` + +Затем cert-manager создаёт `Certificate`, проходит HTTP-01 и сохраняет пару +ключей Let's Encrypt в этом TLS-секрете. Чарт **не** устанавливает +cert-manager или Ingress-контроллер — только issuer'ы и связку с Ingress. + +Если ClusterIssuer'ы уже существуют на уровне кластера, задайте: + +```yaml +certManager: + enabled: true + createClusterIssuer: false + issuerName: your-existing-issuer +``` + +## Эксплуатация + +```bash +# логи +kubectl -n vmware-sim logs -l app.kubernetes.io/instance=vmware-sim -c simulator -f + +# reseed +kubectl -n vmware-sim exec deploy/vmware-sim-vmware-api-simulator -- \ + python -m app.simulation.seed_cli +# SEED_VSPHERE_PROFILE через: kubectl set env ... либо --set seed.profile=demo-cluster и upgrade + +# удаление +helm -n vmware-sim uninstall vmware-sim +``` + +## Справочник по values + +См. [`helm/vmware-api-simulator/values.yaml`](../../helm/vmware-api-simulator/values.yaml) +и [README чарта](../../helm/vmware-api-simulator/README.ru.md). Связанная +документация: + +- [Быстрый старт](getting-started.md) — пути через Compose +- [Эксплуатация](operations.md) — публикация в Docker Hub / release compose +- [Безопасность](security.md) — лабораторные учётные данные и граница доверия +- [Порты](ports.md) — внутренний `8080` в сравнении с опубликованными портами gateway diff --git a/docs/ru/observability.md b/docs/ru/observability.md new file mode 100644 index 0000000..0676592 --- /dev/null +++ b/docs/ru/observability.md @@ -0,0 +1,47 @@ +**Language / Язык:** [English](../observability.md) | [Русский](observability.md) + +# Наблюдаемость + +## Health + +| Path | Значение | +|---|---| +| `GET /health/live` | Liveness процесса — без проверки зависимостей | +| `GET /health/ready` | База данных доступна через `database.is_ready()`; HTTP 503, если нет | + +Пример: + +```bash +curl -sk https://localhost/health/live +curl -sk https://localhost/health/ready +``` + +Реализация: [`app/observability/health.py`](../../app/observability/health.py). + +## Корреляция запросов + +Входящие запросы принимают или генерируют ID через `REQUEST_ID_HEADER` +(по умолчанию `X-Request-ID`). Структурированные логи содержат поля +корреляции и маскируют известные шаблоны секретов (session id, пароли, +токены в стиле ticket). + +## Метрики / трейсинг + +В текущем приложении **нет** endpoint для scrape `/metrics` Prometheus и +**нет** встроенного экспортера OpenTelemetry. Заметки в архитектурной +документации, где они упоминаются, описывают целевой дизайн, а не +реально поставляемую телеметрию. + +Не путайте пути vSphere REST под `/api/vcenter/activity-history` или +seeded-эндпоинты health/timesync appliance с телеметрией самого процесса +симулятора — эти обработчики симулируют состояние appliance vCenter внутри +PostgreSQL, а не собственные метрики этого процесса. + +## Evidence совместимости + +Отчёты о совместимости в эксплуатации: + +- `/ui/api/compatibility?major=N` + +Также доступны через панель совместимости Web UI. См. +[Совместимость](compatibility.md). diff --git a/docs/ru/operations.md b/docs/ru/operations.md new file mode 100644 index 0000000..8b2b5d6 --- /dev/null +++ b/docs/ru/operations.md @@ -0,0 +1,151 @@ +**Language / Язык:** [English](../operations.md) | [Русский](operations.md) + +# Эксплуатация + +## Команды day-2 + +```bash +make up # запуск стека +make down # остановка стека +make restart +make logs +make dev # foreground-workflow, ориентированный на reload +make db-migrate # идемпотентные миграции +make seed # атомарный reseed (SEED_VSPHERE_PROFILE=large по умолчанию) +make shell # интерактивный контейнер с инструментами +``` + +## Миграции + +Упорядоченные SQL-файлы применяются транзакционно и записывают контрольные +суммы SHA-256. Повторный запуск `make db-migrate` безопасен. Изменение уже +применённой миграции отклоняется. `/health/ready` остаётся недоступным, пока +не появится последняя упакованная миграция. + +## Reseed + +```bash +make seed # large (по умолчанию) +VSPHERE_PROFILE=small make seed +VSPHERE_PROFILE=demo-cluster make seed +``` + +Reseed атомарно заменяет инвентарь в PostgreSQL. Состояние внешней +автоматизации (файлы состояния Terraform, стеки Pulumi, инвентари Ansible, +кодирующие MOID/имена ВМ) может после этого разойтись — обновите или +пересоздайте эти внешние каналы. См. [Профили seed](seed-profiles.md). + +## Восстановление workers + +CIS task workers используют аренды PostgreSQL (`FOR UPDATE SKIP LOCKED`). +После сбоя или перезапуска просроченные аренды переиспользуются, и +незавершённая работа безопасно возобновляется. Настраиваемые параметры: +`TASK_WORKER_CONCURRENCY`, `TASK_LEASE_SECONDS`, `SIMULATION_TIME_SCALE`. + +## Изменение мажора каталога по умолчанию + +1. Мажор каталога по умолчанию — **9** (поверхность 8.0 U2 / Automation 9.1) + при холодном старте; это не ограничивает таблицу маршрутов runtime (см. + [Версии API](api-versions.md)). +2. Используйте «Apply as runtime» в Web UI или + `POST /ui/api/contract/apply?major=N`, чтобы переключить мажор каталога + локально для процесса, для целей просмотра/evidence. + +## Резервное копирование состояния лаборатории + +PostgreSQL — это система записи (system of record). Используйте обычные +backup/restore для Postgres (`pg_dump` / снимки томов), если нужно сохранить +seeded-лабораторию. Контейнеры приложения одноразовые, пока сохраняется том +базы данных. + +## Публикация в Docker Hub + +`make release` собирает образ **runtime** (build target `runtime`, а не +локальный bind-mounted образ `dev`) и публикует его в Docker Hub: + +```bash +docker login # один раз; учётная запись должна владеть или иметь права push в DOCKERHUB_USER +make release +``` + +Значения по умолчанию: + +| Переменная | По умолчанию | Значение | +|---|---|---| +| `DOCKERHUB_USER` | `inecs` | Namespace/организация Docker Hub | +| `IMAGE_NAME` | `vmware-api-simulator` | Имя репозитория | +| `VERSION` | из `pyproject.toml` | Тег образа | +| `PUSH_LATEST` | `1` | Также помечать/публиковать `:latest` | + +Примеры: + +```bash +make release +make release VERSION=0.2.0 +make release DOCKERHUB_USER=myorg PUSH_LATEST=0 +make release-build # локальная сборка/тегирование без публикации +``` + +Опубликованные теги: + +- `inecs/vmware-api-simulator:` +- `inecs/vmware-api-simulator:latest` (если не задано `PUSH_LATEST=0`) + +## Быстрый старт с опубликованным compose-файлом + +[`docker-compose.release.yml`](../../docker-compose.release.yml) скачивает +runtime-образ из Hub и запускает PostgreSQL + migrate + симулятор + HTTPS +gateway: + +```bash +docker compose -f docker-compose.release.yml up -d +docker compose -f docker-compose.release.yml run --rm --entrypoint python \ + simulator -m app.simulation.seed_cli + +curl -sk https://localhost/health/ready +open https://localhost/ +``` + +Вспомогательные команды из git checkout: + +```bash +make release-up +make release-seed PROFILE=small +make release-down +``` + +Полезные переопределения: + +| Переменная | По умолчанию | Значение | +|---|---|---| +| `DOCKER_IMAGE` | `inecs/vmware-api-simulator` | Репозиторий образа | +| `IMAGE_TAG` | `latest` | Тег для скачивания | +| `HTTP_PORT` | `80` | Порт хоста для HTTP | +| `HTTPS_PORT` | `443` | Порт хоста для HTTPS | +| `POSTGRES_PORT` | `127.0.0.1:5434` | Bind хоста для Postgres | +| `TICKET_SIGNING_KEY` | лабораторное значение по умолчанию | Меняйте вне игрушечных лабораторий | +| `POSTGRES_PASSWORD` | `vmware` | Пароль БД | + +Для Kubernetes с публичным TLS (cert-manager / Let's Encrypt) используйте +Helm-чарт — см. [Kubernetes / Helm](kubernetes.md). + +## Обновления + +1. Скачайте / пересоберите образы (`make install` / `make docker-build` по + ситуации). +2. Выполните миграции (`make db-migrate`). +3. Убедитесь, что `/health/ready` отвечает нормально. +4. Перепроверьте `/ui/api/compatibility?major=9` и + `/api/appliance/system/version`. +5. При необходимости заново запустите `make test-vsphere` / + `make vsphere-matrix`, если проверяете поверхность после обновления. + +## Сброс лаборатории + +```bash +make seed PROFILE=small +# или через UI: unload demo → small, затем снова seed +``` + +Для жёсткого сброса базы данных используйте `make db-reset` (деструктивно — +см. справку Makefile). diff --git a/docs/ru/ports.md b/docs/ru/ports.md new file mode 100644 index 0000000..cdb8386 --- /dev/null +++ b/docs/ru/ports.md @@ -0,0 +1,50 @@ +**Language / Язык:** [English](../ports.md) | [Русский](ports.md) + +# Порты vCenter в этом симуляторе + +Справочник: [vSphere Networking Ports](https://ports.esp.vmware.com/) (vCenter Server). + +`api-gateway` (nginx) публикует **основной HTTPS-listener vCenter** плюс +HTTP-грань для лабораторных нужд. Каждый опубликованный порт проксирует к +одному и тому же процессу FastAPI, который сам маршрутизирует по path REST +(`/api`, `/rest`) и SOAP (`/sdk`) — отдельного порта на протокол нет. Gateway +также выставляет `X-VMware-Service` / `X-Forwarded-Port`, чтобы клиенты и +будущие роутеры могли определить, какой порт был использован. + +## Опубликовано через Compose (`api-gateway`) + +| Сервис | Порт контейнера | Порт хоста (dev compose) | +|---|---:|---:| +| HTTP-грань для лабораторных нужд | 80 | 80 | +| vCenter HTTPS (основная точка входа UI/API) | 443 | 443 | + +Порты хоста совпадают с реальными defaults vCenter, чтобы удалённые клиенты +ходили на `https:///` и `http:///` без нестандартного порта. +При необходимости переопределяйте в release compose через `HTTP_PORT` / +`HTTPS_PORT`. + +Также публикуется Compose (не через gateway): + +| Сервис | Порт хоста (dev compose) | +|---|---:| +| PostgreSQL | `5434` (только localhost) | + +Внутренний процесс симулятора (не публикуется на хост): `8080`. + +## Раскладка путей на HTTPS + +| Поверхность | Префикс пути | Статус | +|---|---|---| +| vSphere REST | `/api/…`, `/rest/…` | реализовано (базовый инвентарь + сессия) | +| SOAP / VIM SDK | `/sdk` | реализовано (подмножество RetrieveServiceContent / Login / RetrieveProperties) | +| HttpNfcLease / NFC | `/nfc/…` | lab transfer handshake на том же HTTPS-слушателе | +| Лабораторная консоль | `/` | да | +| Health | `/health/live`, `/health/ready` | да | + +## Задокументировано, но пока не опубликовано + +| Сервис | Порты | +|---|---| +| VAMI / управление appliance | 5480 | +| Управление хостом ESXi (если будет симулировано позже) | 443 (отдельный хост) | +| Syslog / прочее | разное | diff --git a/docs/ru/security.md b/docs/ru/security.md new file mode 100644 index 0000000..65c1b2e --- /dev/null +++ b/docs/ru/security.md @@ -0,0 +1,57 @@ +**Language / Язык:** [English](../security.md) | [Русский](security.md) + +# Безопасность + +## Модель угроз лаборатории + +Этот проект — **локальный / CI лабораторный симулятор**. Он не защищён как +multi-tenant публичный сервис vCenter. Учётные данные по умолчанию, демо- +элементы управления в UI и endpoint'ы совместимости удобны для разработки и +намеренно открыты в стандартном стеке Compose. + +Не публикуйте порты `443` / `80` в недоверенные сети без дополнительных +средств защиты, которые вы предоставляете самостоятельно. + +## Учётные данные и секреты + +- Пароли хранятся как хэши scrypt (`vsphere_credentials.password_hash`). +- Session id — это непрозрачные токены (`vmware-api-session-id`) со + скользящим сроком действия 2 часа, отслеживаемые в PostgreSQL + (`vsphere_sessions`). +- Логи маскируют распознанные представления session id и паролей. +- Ответы сессий обновления/загрузки content library раскрывают только + endpoint'ы загрузки/скачивания, а не сырые секреты. + +Меняйте `TICKET_SIGNING_KEY` для любой общей лаборатории. Заменяйте seeded- +пароли перед демонстрацией другим людям. + +## Материалы TLS + +`docker/tls/` содержит закоммиченный self-signed сертификат для локального +сервиса nginx `api-gateway`. Он существует, чтобы немодифицированные +TLS-клиенты (pyvmomi, govmomi, провайдер Terraform `hashicorp/vsphere`) могли +подключаться с установленным `insecure`/`verify=False`. **Никогда** не +используйте эти файлы повторно в production. + +## Администрирование симулятора + +На данный момент **нет** отдельно аутентифицируемой административной +control plane. Вспомогательные маршруты Web UI под `/ui/api/*` доступны, +когда процесс достижим по сети, — включая действия reseed и hot-swap. +Считайте сетевую доступность границей доверия. + +## Авторизация + +Мутирующие REST-эндпоинты проверяют привилегии, производные от роли +(`app/vsphere/security/authz.py`), прежде чем обращаться к инвентарю. +Seeded-принципал `readonly@vsphere.local` не может включать/создавать/ +удалять ВМ (HTTP 403). См. [Авторизация](domains/authz.md). + +## Симулированные внешние системы + +Заменители NSX/Supervisor/vSAN/SAML-OIDC/VECS-сертификатов (см. +[Покрытие API](api-coverage.md)) сохраняют только локальное состояние +симулятора. Они не открывают реальных соединений с внешними IdP, NSX +Manager или живым кластером vSAN. Не полагайтесь на симулятор для +тестирования защиты от эксфильтрации живых учётных данных против реальных +провайдеров. diff --git a/docs/ru/seed-profiles.md b/docs/ru/seed-profiles.md new file mode 100644 index 0000000..950d413 --- /dev/null +++ b/docs/ru/seed-profiles.md @@ -0,0 +1,76 @@ +**Language / Язык:** [English](../seed-profiles.md) | [Русский](seed-profiles.md) + +# Профили seed + +Seed **атомарно** заменяет инвентарь vSphere, используя детерминированные +MOID, чтобы лаборатории были воспроизводимыми. Определения находятся в +[`app/vsphere/profiles.py`](../../app/vsphere/profiles.py). + +```bash +make seed # по умолчанию: large (10 хостов / 1000 ВМ) +VSPHERE_PROFILE=small make seed +``` + +## Профили + +| Профиль | Содержимое | +|---|---| +| `small` | 3 хоста ESXi, 2 datastore, 2 сети, один datacenter/cluster/resource-pool и пять именованных ВМ: `web-01`, `web-02`, `db-01`, `app-01`, `jumpbox` (смешанные состояния питания). Используется unit/integration-тестами. | +| `large` (по умолчанию) | Настраиваемое число хостов/ВМ (`SEED_VSPHERE_LARGE_HOSTS` по умолчанию 10, `SEED_VSPHERE_LARGE_VMS` по умолчанию 1000), 4 datastore, 4 сети/portgroup, `VmwareDistributedVirtualSwitch`, папки ВМ production/staging/templates. Первые пять ВМ совпадают по именам с `small` для стабильности кулинарных книг; остальные генерируются (префиксы ролей `web-`, `app-`, `db-`, `cache-`, `batch-`, `jump-`, `ci-`, `mon-`, `log-`, `ml-`). | +| `demo-cluster` | `large` с 20 хостами / 1000 ВМ — набор данных в форме предприятия для демо UI. | + +Каждый профиль также загружает четыре лабораторные учётные записи, права, +привязанные к ролям (см. [Авторизация](domains/authz.md)), и — там, где +существуют таблицы платформы — стартовую content library, категории/теги +тегирования и метаданные файлов datastore (`seed_platform_extras`). + +## Примеры + +```bash +make seed # large, 10 хостов / 1000 ВМ +VSPHERE_PROFILE=small make seed +VSPHERE_PROFILE=demo-cluster make seed +VSPHERE_PROFILE=large VSPHERE_HOSTS=20 VSPHERE_VMS=5000 make seed +``` + +Либо запустите CLI seed напрямую с базовыми переменными окружения (например, +из скрипта без `make` или на шаге CI): + +```bash +SEED_VSPHERE_PROFILE=small \ + docker compose run --rm --entrypoint python simulator -m app.simulation.seed_cli +``` + +## Форма топологии + +Каждый профиль строит один и тот же скелет (папка `Datacenters` → +`Datacenter` → подпапки host/vm/datastore/network → один +`ClusterComputeResource` + `ResourcePool`), затем масштабирует хосты, +datastore, portgroup и ВМ. MOID ВМ имеют вид `vm-{100+n}`; MOID хостов — +`host-{10+n}`; каждая ВМ несёт одинаковую форму оборудования, используемую +как REST (`hardware/*`), так и SOAP (`VirtualMachineConfigInfo`) ответами — +NIC, диски, CD-ROM, порядок загрузки и синтетический guest IP/файловая +система. + +## Демо-кластер через UI + +Интерактивная консоль может загружать демо-набор данных и делать reseed по +запросу: + +- `POST /ui/api/demo/load` — загружает `demo-cluster` +- `POST /ui/api/demo/unload` — очищает состояние, созданное через API, затем + загружает `small` +- `GET /ui/api/demo/state` +- `POST /ui/api/vsphere/seed?profile=small|large|demo-cluster` — reseed + любого профиля + +Эти вспомогательные эндпоинты UI ориентированы на разработку и сегодня не +имеют отдельной аутентификации. Считайте их только лабораторными органами +управления. + +## Reseed в сравнении с состоянием клиентов + +Terraform, Pulumi и Ansible могут по-прежнему хранить состояние ресурсов +после reseed (MOID и имена ВМ могут измениться). Выполните refresh или +destroy/recreate внешнего состояния после замены инвентаря PostgreSQL. См. +[Эксплуатация](operations.md) и [Клиенты](clients.md). diff --git a/docs/ru/troubleshooting.md b/docs/ru/troubleshooting.md new file mode 100644 index 0000000..6f13e4f --- /dev/null +++ b/docs/ru/troubleshooting.md @@ -0,0 +1,75 @@ +**Language / Язык:** [English](../troubleshooting.md) | [Русский](troubleshooting.md) + +# Устранение неполадок + +## Ready остаётся недоступным + +1. Проверьте Postgres: `make logs` / health в Compose. +2. Выполните `make db-migrate`. +3. Снова вызовите `/health/ready`. + +Task workers могут повторять попытки, пока миграции не догонят после позднего migrate. + +## Неожиданный HTTP 501 + +У каждого зарегистрированного маршрута должен быть реальный обработчик или +DB-backed стаб — 501 не должен появляться для известного пути. Если вы его видите: + +- Убедитесь, что вызываете точный зарегистрированный path/verb (проверьте + `app/vsphere/rest/coverage.py` или `/docs`). +- 501 от опционального legacy-стаба (`ENABLE_PVE_STUB=true`) ожидается для + необъявленных методов в стиле PVE, когда `CONTRACT_FALLBACK=error`; это + не относится к native vSphere-поверхности. +- Сообщите о регрессии — на native vSphere-плоскости ожидается полное + покрытие реестра. + +## 401 / 403 + +- Сессия истекла (скользящий TTL 2 часа) или заголовок/cookie + `vmware-api-session-id` не отправлен. +- Некорректный Basic auth на `/api/session` (отсутствует заголовок, неверный + base64 от `user:password`). +- Отказ по правам — попробуйте сравнить `administrator@vsphere.local` и + `readonly@vsphere.local` (см. [Авторизация](domains/authz.md)). + +## Задача никогда не завершается + +- Изучите `/api/cis/tasks/{task}`. +- Проверьте логи worker/симулятора (`make logs`). +- Убедитесь, что `TASK_WORKER_CONCURRENCY` > 0 и аренды в базе данных можно + забрать (claim). +- Очень высокий `SIMULATION_TIME_SCALE` даёт необычные замедления (больше = + быстрее симуляция); чаще виноваты неверно заданные worker-аренды. + +## Сбои TLS / gateway + +- Используйте порт хоста **443** (gateway) для TLS-клиентов — pyvmomi, + govmomi, провайдер Terraform `hashicorp/vsphere`, Pulumi. +- Устанавливайте `verify_ssl=False` / `allow_unverified_ssl=true` **только** + для локального self-signed development-сертификата. +- Внутри Compose обращайтесь напрямую к `simulator:8080` (обычный HTTP, без + gateway). +- Seeded-имена ВМ для `small` — `web-01`, `web-02`, `db-01`, `app-01`, + `jumpbox`, а не Proxmox-style `pve01`/VMID. + +## Drift Terraform / Pulumi / Ansible после reseed + +Reseed заменяет инвентарь в PostgreSQL (MOID-ы и имена ВМ могут измениться); +состояние внешних инструментов автоматически не обновляется. Выполните +refresh, import или пересоберите стеки после `make seed`. + +## Hot-swap «ничего не сделал» + +- Просмотр каталога ≠ apply. Используйте **Apply as runtime** или + `POST /ui/api/contract/apply?major=N`. +- Применение мажора меняет **каталог Web UI / представление evidence**, а не + живую таблицу маршрутов — runtime всегда обслуживает полную + зарегистрированную поверхность. См. [Версии API](api-versions.md). +- Apply локален для процесса; перезапуск Compose возвращает к значению по + умолчанию (мажор 9). + +## Demo unload удивил + +`POST /ui/api/demo/unload` очищает состояние, созданное через API, и +загружает `small`. Повторите `make seed` (или снова загрузите +`demo-cluster`), чтобы восстановить более богатую фикстуру. diff --git a/docs/ru/web-ui.md b/docs/ru/web-ui.md new file mode 100644 index 0000000..4507552 --- /dev/null +++ b/docs/ru/web-ui.md @@ -0,0 +1,68 @@ +**Language / Язык:** [English](../web-ui.md) | [Русский](web-ui.md) + +# Web UI + +Откройте [https://localhost/](https://localhost/) после `make up` +(gateway). +Внутренний порт симулятора — `8080`; лабораторный UI также доступен на этом хосте. + +UI — это лабораторная консоль для симулятора **vSphere**, а не замена +vSphere Client. Она поддерживает светлую и тёмную темы, мажоры каталога +**6–9** (уровни vSphere 7–8.0U2), редактирование запроса/ответа, историю и +применение runtime-контракта. + +## Возможности + +- Дерево endpoint'ов и селектор метода, управляемые выбранным мажором каталога +- Параметры и примеры payload, производные от контракта +- Редактор запроса, просмотрщик ответа и история +- Вход в сессию через `POST /api/session` (Basic) → заголовок/cookie + `vmware-api-session-id` +- Сводка окружения (версия runtime, хосты, ВМ, кластеры, datastore, сети) +- Предпросмотр запросов в виде curl +- Индикатор покрытия для реализованного реестра REST +- Hot-swap **Apply as runtime** для активного уровня мажора +- Загрузка demo / seed (профили large / demo-cluster) +- Компактная консоль на `/console.html` +- Ссылка на OpenAPI по адресу `/docs` + +## Аутентификация (лаборатория) + +| Пользователь | Пароль | Роль | +|---|---|---| +| `administrator@vsphere.local` | `VMware1!` | Administrator | +| `readonly@vsphere.local` | `VMware1!` | ReadOnly | +| `operator@vsphere.local` | `VMware1!` | VirtualMachinePowerUser | +| `vmadmin@vsphere.local` | `VMware1!` | VirtualMachineAdministrator | + +После входа кнопка Send автоматически прикладывает `vmware-api-session-id`. + +## Вспомогательные методы backend + +| Метод | Path | Назначение | +|---|---|---| +| GET | `/ui/api/versions` | Мажоры каталога в сравнении с runtime | +| GET | `/ui/api/catalog?major=N` | Каталог для мажора 6–9 | +| GET | `/ui/api/method?...` | Метаданные одного метода | +| GET | `/ui/api/compatibility?major=N` | Payload покрытия | +| POST | `/ui/api/contract/apply?major=N` | Hot-swap runtime-контракта | +| GET | `/ui/api/demo/state` | Состояние демо-набора данных | +| POST | `/ui/api/demo/load` | Загрузить `demo-cluster` | +| POST | `/ui/api/vsphere/seed?profile=…` | Reseed `small` / `large` / `demo-cluster` | + +## Workflow работы с версиями + +1. Выберите мажор **6 / 7 / 8 / 9** в каталоге. +2. Изучите методы и покрытие. +3. Используйте **Apply as runtime**, когда нужно, чтобы живые маршруты были + ограничены уровнем этого мажора. +4. Подтвердите через `/api/appliance/system/version` и `/ui/api/compatibility`. + +Hot-swap хранится только в памяти; перезапуск восстанавливает настройки по +умолчанию. Подробности: [Версии API](api-versions.md). + +## Замечание о безопасности + +Эндпоинты UI и demo предназначены для локальной разработки. В текущей +сборке они не защищены отдельным admin-токеном. Не выставляйте порт +симулятора в недоверенные сети. diff --git a/docs/security.md b/docs/security.md new file mode 100644 index 0000000..85be1c7 --- /dev/null +++ b/docs/security.md @@ -0,0 +1,54 @@ +**Language / Язык:** [English](security.md) | [Русский](ru/security.md) + +# Security + +## Lab threat model + +This project is a **local / CI laboratory simulator**. It is not hardened as +a multi-tenant public vCenter service. Default credentials, UI demo controls, +and compatibility endpoints are convenient for development and intentionally +open in the default Compose stack. + +Do not expose ports `443` / `80` to untrusted networks without additional +controls you supply yourself. + +## Credentials and secrets + +- Passwords are stored as scrypt hashes (`vsphere_credentials.password_hash`). +- Session ids are opaque tokens (`vmware-api-session-id`) with a 2-hour + sliding expiry, tracked in PostgreSQL (`vsphere_sessions`). +- Logs redact recognized session-id and password representations. +- Content library update/download session responses expose upload/download + endpoints, not raw secrets. + +Change `TICKET_SIGNING_KEY` for any shared lab. Replace seeded passwords +before demoing to others. + +## TLS materials + +`docker/tls/` contains a checked-in self-signed certificate for the local +`api-gateway` nginx service. It exists so unmodified TLS clients (pyvmomi, +govmomi, Terraform's `hashicorp/vsphere` provider) can connect with +`insecure`/`verify=False` set. **Never** reuse these files in production. + +## Simulator administration + +There is currently **no** separately authenticated admin control plane. Web +UI helper routes under `/ui/api/*` are available whenever the process is +reachable — including reseed and hot-swap actions. Treat network exposure as +the trust boundary. + +## Authorization + +Mutating REST endpoints check role-derived privileges +(`app/vsphere/security/authz.py`) before touching inventory. The seeded +`readonly@vsphere.local` principal cannot power on/create/delete VMs (HTTP +403). See [Authorization](domains/authz.md). + +## Simulated remotes + +NSX/Supervisor/vSAN/SAML-OIDC/VECS-certificate stand-ins (see +[API coverage](api-coverage.md)) persist local simulator state only. They do +not open real connections to external IdPs, NSX Manager, or a live vSAN +cluster. Do not rely on the simulator for testing live credential +exfiltration defenses against real providers. diff --git a/docs/seed-profiles.md b/docs/seed-profiles.md new file mode 100644 index 0000000..dae5176 --- /dev/null +++ b/docs/seed-profiles.md @@ -0,0 +1,70 @@ +**Language / Язык:** [English](seed-profiles.md) | [Русский](ru/seed-profiles.md) + +# Seed profiles + +Seeds replace the vSphere inventory **atomically** using deterministic MOIDs +so labs are reproducible. Definitions live in +[`app/vsphere/profiles.py`](../app/vsphere/profiles.py). + +```bash +make seed # default: large (10 hosts / 1000 VMs) +VSPHERE_PROFILE=small make seed +``` + +## Profiles + +| Profile | Contents | +|---|---| +| `small` | 3 ESXi hosts, 2 datastores, 2 networks, one datacenter/cluster/resource-pool, and five named VMs: `web-01`, `web-02`, `db-01`, `app-01`, `jumpbox` (mixed power states). Used by unit/integration tests. | +| `large` (default) | Configurable hosts/VMs (`SEED_VSPHERE_LARGE_HOSTS` default 10, `SEED_VSPHERE_LARGE_VMS` default 1000), 4 datastores, 4 networks/portgroups, a `VmwareDistributedVirtualSwitch`, production/staging/templates VM folders. The first five VMs match the `small` names for cookbook stability; the rest are generated (`web-`, `app-`, `db-`, `cache-`, `batch-`, `jump-`, `ci-`, `mon-`, `log-`, `ml-` role prefixes). | +| `demo-cluster` | `large` with 20 hosts / 1000 VMs — an enterprise-shaped dataset for UI demos. | + +Every profile also seeds the four lab credentials, role-scoped permissions +(see [Authorization](domains/authz.md)), and — where the platform tables +exist — a starter content library, tag categories/tags, and datastore file +metadata (`seed_platform_extras`). + +## Examples + +```bash +make seed # large, 10 hosts / 1000 VMs +VSPHERE_PROFILE=small make seed +VSPHERE_PROFILE=demo-cluster make seed +VSPHERE_PROFILE=large VSPHERE_HOSTS=20 VSPHERE_VMS=5000 make seed +``` + +Or run the seed CLI directly with the underlying environment variables (for +example from a non-`make` script or CI step): + +```bash +SEED_VSPHERE_PROFILE=small \ + docker compose run --rm --entrypoint python simulator -m app.simulation.seed_cli +``` + +## Topology shape + +Every profile builds the same skeleton (`Datacenters` folder → `Datacenter` → +host/vm/datastore/network sub-folders → one `ClusterComputeResource` + +`ResourcePool`), then scales hosts, datastores, portgroups, and VMs. VM MOIDs +are `vm-{100+n}`; host MOIDs are `host-{10+n}`; each VM carries the same +hardware shape used by both REST (`hardware/*`) and SOAP (`VirtualMachineConfigInfo`) +responses — NICs, disks, CD-ROM, boot order, and a synthetic guest IP/filesystem. + +## Demo cluster via UI + +The interactive console can load the demo dataset and reseed on demand: + +- `POST /ui/api/demo/load` — loads `demo-cluster` +- `POST /ui/api/demo/unload` — wipes API-created state, then loads `small` +- `GET /ui/api/demo/state` +- `POST /ui/api/vsphere/seed?profile=small|large|demo-cluster` — reseed any profile + +These UI helper endpoints are development-oriented and are not separately +authenticated today. Treat them as lab controls only. + +## Reseed vs client state + +Terraform, Pulumi, and Ansible may still hold resource state after a reseed +(VM MOIDs and names can change). Refresh or destroy/recreate external state +after replacing the PostgreSQL inventory. See [Operations](operations.md) and +[Clients](clients.md). diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md new file mode 100644 index 0000000..a0d1837 --- /dev/null +++ b/docs/troubleshooting.md @@ -0,0 +1,71 @@ +**Language / Язык:** [English](troubleshooting.md) | [Русский](ru/troubleshooting.md) + +# Troubleshooting + +## Ready stays unavailable + +1. Confirm Postgres: `make logs` / Compose health. +2. Run `make db-migrate`. +3. Hit `/health/ready` again. + +Task workers may retry until migrations catch up after a late migrate. + +## Unexpected HTTP 501 + +Every registered route should have a real handler or DB-backed stub — 501 +should not appear for a known path. If you see it: + +- Confirm you are calling the exact registered path/verb (check + `app/vsphere/rest/coverage.py` or `/docs`). +- 501 from the optional legacy stub (`ENABLE_PVE_STUB=true`) is expected for + undeclared PVE-style methods when `CONTRACT_FALLBACK=error`; it is + unrelated to the vSphere surface. +- Report a regression — full registry coverage is expected on the native + vSphere plane. + +## 401 / 403 + +- Session expired (2-hour sliding TTL) or `vmware-api-session-id` header/cookie + not sent. +- Basic auth malformed on `/api/session` (missing header, wrong + `user:password` base64). +- Privilege denial — try `administrator@vsphere.local` vs + `readonly@vsphere.local` to compare (see [Authorization](domains/authz.md)). + +## Task never finishes + +- Inspect `/api/cis/tasks/{task}`. +- Check worker/simulator logs (`make logs`). +- Verify `TASK_WORKER_CONCURRENCY` > 0 and database leases can be claimed. +- Extremely high `SIMULATION_TIME_SCALE` slowdowns are unusual (higher = + faster simulation); mis-set worker leases are more common culprits. + +## TLS / gateway failures + +- Use host port **443** (gateway) for TLS clients — pyvmomi, govmomi, + Terraform's `hashicorp/vsphere` provider, Pulumi. +- Set `verify_ssl=False` / `allow_unverified_ssl=true` **only** for the local + self-signed development certificate. +- Inside Compose, target `simulator:8080` directly (plain HTTP, no gateway). +- Seeded VM names for `small` are `web-01`, `web-02`, `db-01`, `app-01`, + `jumpbox` — not Proxmox-style `pve01`/VMIDs. + +## Terraform / Pulumi / Ansible drift after reseed + +Reseed replaces PostgreSQL inventory (MOIDs and VM names can change); +external tool state does not update automatically. Refresh, import, or +rebuild stacks after `make seed`. + +## Hot-swap "did nothing" + +- Catalog browse ≠ apply. Use **Apply as runtime** or + `POST /ui/api/contract/apply?major=N`. +- Applying a major changes the **Web UI catalog / evidence view**, not the + live route table — the runtime always serves the full registered surface. + See [API versions](api-versions.md). +- Apply is process-local; a Compose restart returns to the default (major 9). + +## Demo unload surprised you + +`POST /ui/api/demo/unload` clears API-created state and loads `small`. Re-run +`make seed` (or load `demo-cluster` again) to restore a richer fixture. diff --git a/docs/web-ui.md b/docs/web-ui.md new file mode 100644 index 0000000..6e3dab4 --- /dev/null +++ b/docs/web-ui.md @@ -0,0 +1,64 @@ +**Language / Язык:** [English](web-ui.md) | [Русский](ru/web-ui.md) + +# Web UI + +Open [https://localhost/](https://localhost/) after `make up` (gateway). +Internal simulator port is `8080`; the lab UI is also on that host. + +The UI is a laboratory console for the **vSphere** simulator — not a vSphere Client +replacement. It supports light and dark themes, catalog majors **6–9** (vSphere 7–8.0U2 +floors), request/response editing, history, and runtime contract apply. + +## Features + +- Endpoint tree and method selector driven by the selected catalog major +- Contract-derived parameters and example payloads +- Request editor, response viewer, and history +- Session login via `POST /api/session` (Basic) → `vmware-api-session-id` header/cookie +- Environment summary (runtime version, hosts, VMs, clusters, datastores, networks) +- Curl / request previews +- Coverage meter for the implemented REST registry +- **Apply as runtime** hot-swap for the active major floor +- Demo / seed load (large / demo-cluster profiles) +- Compact console at `/console.html` +- Link to OpenAPI at `/docs` + +## Auth (lab) + +| User | Password | Role | +|---|---|---| +| `administrator@vsphere.local` | `VMware1!` | Administrator | +| `readonly@vsphere.local` | `VMware1!` | ReadOnly | +| `operator@vsphere.local` | `VMware1!` | VirtualMachinePowerUser | +| `vmadmin@vsphere.local` | `VMware1!` | VirtualMachineAdministrator | + +After sign-in, Send attaches `vmware-api-session-id` automatically. + +## Backend helpers + +| Method | Path | Purpose | +|---|---|---| +| GET | `/ui/api/versions` | Catalog majors vs runtime | +| GET | `/ui/api/catalog?major=N` | Catalog for major 6–9 | +| GET | `/ui/api/method?...` | Single method metadata | +| GET | `/ui/api/compatibility?major=N` | Coverage payload | +| POST | `/ui/api/contract/apply?major=N` | Hot-swap runtime contract | +| GET | `/ui/api/demo/state` | Demo dataset state | +| POST | `/ui/api/demo/load` | Load `demo-cluster` | +| POST | `/ui/api/vsphere/seed?profile=…` | Reseed `small` / `large` / `demo-cluster` | + +## Version workflow + +1. Pick major **6 / 7 / 8 / 9** in the catalog. +2. Inspect methods and coverage. +3. **Apply as runtime** when you want live routes gated to that major’s floor. +4. Confirm with `/api/appliance/system/version` and `/ui/api/compatibility`. + +Hot-swap is memory-only; restart restores the default settings. Details: +[API versions](api-versions.md). + +## Security note + +UI and demo endpoints are intended for local development. They are not gated by +a separate admin token in the current build. Do not expose the simulator port to +untrusted networks. diff --git a/evidence/pve-6.4-15.json b/evidence/pve-6.4-15.json new file mode 100644 index 0000000..64a1b19 --- /dev/null +++ b/evidence/pve-6.4-15.json @@ -0,0 +1,12607 @@ +{ + "format_version": 1, + "profile": "pve-6.4", + "records": [ + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/acl", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/acl", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains/{realm}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains/{realm}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains/{realm}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains/{realm}/sync", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups/{groupid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups/{groupid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups/{groupid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/password", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/permissions", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles/{roleid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles/{roleid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles/{roleid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/ticket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/ticket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/tfa", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token/{tokenid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token/{tokenid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token/{tokenid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token/{tokenid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/challenge-schema", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/directories", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/tos", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup/{id}/included_volumes", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backupinfo", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backupinfo/not_backed_up", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/flags", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/flags", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/flags/{flag}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/flags/{flag}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/metadata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/apiversion", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/join", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/join", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/nodes", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/nodes/{node}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/nodes/{node}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/qdevice", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/totem", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/macros", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/refs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}/migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}/relocate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/status/current", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/status/manager_status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/nextid", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/resources", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers/{controller}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers/{controller}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers/{controller}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns/{dns}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns/{dns}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns/{dns}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams/{ipam}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams/{ipam}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams/{ipam}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones/{zone}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones/{zone}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones/{zone}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/tasks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/aplinfo", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/aplinfo", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/changelog", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/update", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/update", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/versions", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities/qemu", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities/qemu/machines", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/configdb", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/crush", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/disks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/flags", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/flags/{flag}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/flags/{flag}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/fs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/fs/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/init", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mds", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mds/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mds/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mgr", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mgr/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mgr/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mon", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mon/{monid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mon/{monid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/in", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/out", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/scrub", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pools", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pools", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pools/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pools/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pools/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/restart", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/start", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/stop", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/acme", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/acme/certificate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/acme/certificate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/acme/certificate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/custom", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/custom", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/cpu", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/directory", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/directory", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/initgpt", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/list", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvm", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvm", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvmthin", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvmthin", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/smart", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/zfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/zfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/zfs/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/dns", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/dns", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/execute", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware/pci", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware/pci/{pciid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware/pci/{pciid}/mdev", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware/usb", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hosts", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hosts", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/journal", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/clone", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/feature", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/refs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/move_volume", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/pending", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/resize", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/rrd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/rrddata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/spiceproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/current", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/reboot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/resume", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/shutdown", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/start", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/stop", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/suspend", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/template", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/termproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/vncproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/vncwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/migrateall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/netstat", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network/{iface}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network/{iface}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network/{iface}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/exec", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/exec-status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/file-read", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/file-write", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/fstrim", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-fsinfo", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-host-name", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-osinfo", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-time", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-timezone", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-users", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-vcpus", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/ping", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/set-user-password", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/shutdown", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-disk", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-ram", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/clone", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/cloudinit/dump", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/feature", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/refs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/monitor", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/move_disk", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/pending", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/resize", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/rrd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/rrddata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/sendkey", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/spiceproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/current", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/reboot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/reset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/resume", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/shutdown", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/start", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/stop", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/suspend", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/template", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/termproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/unlink", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/vncproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/vncwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication/{id}/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication/{id}/schedule_now", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication/{id}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/report", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/rrd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/rrddata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/cifs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/glusterfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/iscsi", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/lvm", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/lvmthin", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/nfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/pbs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/usb", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/zfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/zones", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/zones/{zone}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/zones/{zone}/content", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/reload", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/restart", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/start", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/state", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/stop", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/spiceshell", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/startall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/stopall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/file-restore/download", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/file-restore/list", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/prunebackups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/prunebackups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/rrd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/rrddata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/upload", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/subscription", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/subscription", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/subscription", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/subscription", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/syslog", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks/{upid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks/{upid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks/{upid}/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks/{upid}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/termproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/time", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/time", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/version", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vncshell", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vncwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vzdump", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vzdump/defaults", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vzdump/extractconfig", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/wakeonlan", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools/{poolid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools/{poolid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools/{poolid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage/{storage}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage/{storage}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage/{storage}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/version", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + } + ], + "source_version": "6.4-15" +} diff --git a/evidence/pve-7.4-16.json b/evidence/pve-7.4-16.json new file mode 100644 index 0000000..f8f03ee --- /dev/null +++ b/evidence/pve-7.4-16.json @@ -0,0 +1,13507 @@ +{ + "format_version": 1, + "profile": "pve-7.4", + "records": [ + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/acl", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/acl", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains/{realm}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains/{realm}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains/{realm}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains/{realm}/sync", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups/{groupid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups/{groupid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups/{groupid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/openid", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/openid/auth-url", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/openid/login", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/password", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/permissions", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles/{roleid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles/{roleid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles/{roleid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa/{userid}/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa/{userid}/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa/{userid}/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/ticket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/ticket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/tfa", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token/{tokenid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token/{tokenid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token/{tokenid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token/{tokenid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/challenge-schema", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/directories", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/tos", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup-info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup-info/not-backed-up", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup/{id}/included_volumes", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/flags", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/flags", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/flags/{flag}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/flags/{flag}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/metadata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/apiversion", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/join", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/join", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/nodes", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/nodes/{node}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/nodes/{node}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/qdevice", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/totem", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/macros", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/refs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}/migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}/relocate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/status/current", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/status/manager_status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/jobs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/jobs/schedule-analyze", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/nextid", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/resources", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers/{controller}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers/{controller}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers/{controller}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns/{dns}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns/{dns}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns/{dns}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams/{ipam}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams/{ipam}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams/{ipam}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones/{zone}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones/{zone}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones/{zone}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/tasks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/aplinfo", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/aplinfo", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/changelog", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/repositories", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/repositories", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/repositories", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/update", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/update", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/versions", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities/qemu", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities/qemu/cpu", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities/qemu/machines", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/cfg", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/cfg/db", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/cfg/raw", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/cmd-safety", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/configdb", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/crush", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/fs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/fs/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/init", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mds", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mds/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mds/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mgr", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mgr/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mgr/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mon", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mon/{monid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mon/{monid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/in", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/lv-info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/metadata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/out", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/scrub", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool/{name}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pools", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pools", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pools/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pools/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pools/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/restart", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/start", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/stop", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/acme", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/acme/certificate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/acme/certificate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/acme/certificate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/custom", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/custom", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/directory", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/directory", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/directory/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/initgpt", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/list", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvm", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvm", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvm/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvmthin", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvmthin", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvmthin/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/smart", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/wipedisk", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/zfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/zfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/zfs/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/zfs/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/dns", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/dns", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/execute", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware/pci", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware/pci/{pciid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware/pci/{pciid}/mdev", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware/usb", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hosts", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hosts", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/journal", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/clone", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/feature", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/refs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/move_volume", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/mtunnel", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/mtunnelwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/pending", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/remote_migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/resize", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/rrd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/rrddata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/spiceproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/current", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/reboot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/resume", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/shutdown", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/start", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/stop", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/suspend", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/template", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/termproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/vncproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/vncwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/migrateall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/netstat", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network/{iface}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network/{iface}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network/{iface}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/exec", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/exec-status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/file-read", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/file-write", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/fstrim", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-fsinfo", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-host-name", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-osinfo", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-time", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-timezone", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-users", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-vcpus", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/ping", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/set-user-password", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/shutdown", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-disk", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-ram", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/clone", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/cloudinit", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/cloudinit", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/cloudinit/dump", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/feature", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/refs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/monitor", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/move_disk", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/mtunnel", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/mtunnelwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/pending", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/remote_migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/resize", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/rrd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/rrddata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/sendkey", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/spiceproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/current", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/reboot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/reset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/resume", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/shutdown", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/start", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/stop", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/suspend", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/template", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/termproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/unlink", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/vncproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/vncwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/query-url-metadata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication/{id}/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication/{id}/schedule_now", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication/{id}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/report", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/rrd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/rrddata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/cifs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/glusterfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/iscsi", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/lvm", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/lvmthin", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/nfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/pbs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/zfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/zones", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/zones/{zone}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/zones/{zone}/content", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/reload", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/restart", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/start", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/state", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/stop", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/spiceshell", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/startall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/stopall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/download-url", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/file-restore/download", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/file-restore/list", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/prunebackups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/prunebackups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/rrd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/rrddata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/upload", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/subscription", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/subscription", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/subscription", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/subscription", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/syslog", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks/{upid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks/{upid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks/{upid}/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks/{upid}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/termproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/time", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/time", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/version", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vncshell", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vncwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vzdump", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vzdump/defaults", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vzdump/extractconfig", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/wakeonlan", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools/{poolid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools/{poolid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools/{poolid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage/{storage}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage/{storage}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage/{storage}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/version", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + } + ], + "source_version": "7.4-16" +} diff --git a/evidence/pve-8.4.5.json b/evidence/pve-8.4.5.json new file mode 100644 index 0000000..8d042eb --- /dev/null +++ b/evidence/pve-8.4.5.json @@ -0,0 +1,15132 @@ +{ + "format_version": 1, + "profile": "pve-8.4.5", + "records": [ + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/acl", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/acl", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains/{realm}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains/{realm}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains/{realm}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains/{realm}/sync", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups/{groupid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups/{groupid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups/{groupid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/openid", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/openid/auth-url", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/openid/login", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/password", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/permissions", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles/{roleid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles/{roleid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles/{roleid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa/{userid}/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa/{userid}/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa/{userid}/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/ticket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/ticket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/tfa", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token/{tokenid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token/{tokenid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token/{tokenid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token/{tokenid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/unlock-tfa", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/challenge-schema", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/directories", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/meta", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/tos", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup-info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup-info/not-backed-up", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup/{id}/included_volumes", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/flags", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/flags", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/flags/{flag}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/flags/{flag}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/metadata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/apiversion", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/join", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/join", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/nodes", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/nodes/{node}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/nodes/{node}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/qdevice", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/totem", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/macros", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/refs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}/migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}/relocate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/status/current", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/status/manager_status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/jobs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/jobs/realm-sync", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/jobs/realm-sync/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/jobs/realm-sync/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/jobs/realm-sync/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/jobs/realm-sync/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/jobs/schedule-analyze", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/dir", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/dir", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/dir/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/dir/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/dir/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/pci", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/pci", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/pci/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/pci/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/pci/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/usb", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/usb", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/usb/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/usb/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/usb/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/export", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/nextid", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/gotify", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/gotify", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/gotify/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/gotify/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/gotify/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/sendmail", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/sendmail", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/sendmail/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/sendmail/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/sendmail/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/smtp", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/smtp", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/smtp/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/smtp/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/smtp/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/webhook", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/webhook", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/webhook/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/webhook/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/webhook/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/matcher-field-values", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/matcher-fields", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/matchers", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/matchers", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/matchers/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/matchers/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/matchers/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/targets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/targets/{name}/test", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/resources", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers/{controller}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers/{controller}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers/{controller}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns/{dns}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns/{dns}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns/{dns}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams/{ipam}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams/{ipam}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams/{ipam}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams/{ipam}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/ips", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/ips", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/ips", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones/{zone}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones/{zone}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones/{zone}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/tasks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/aplinfo", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/aplinfo", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/changelog", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/repositories", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/repositories", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/repositories", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/update", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/update", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/versions", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities/qemu", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities/qemu/cpu", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities/qemu/machines", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/cfg", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/cfg/db", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/cfg/raw", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/cfg/value", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/cmd-safety", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/crush", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/fs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/fs/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/init", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mds", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mds/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mds/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mgr", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mgr/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mgr/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mon", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mon/{monid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mon/{monid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/in", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/lv-info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/metadata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/out", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/scrub", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool/{name}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/restart", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/start", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/stop", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/acme", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/acme/certificate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/acme/certificate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/acme/certificate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/custom", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/custom", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/directory", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/directory", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/directory/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/initgpt", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/list", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvm", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvm", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvm/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvmthin", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvmthin", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvmthin/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/smart", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/wipedisk", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/zfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/zfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/zfs/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/zfs/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/dns", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/dns", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/execute", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware/pci", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware/pci/{pci-id-or-mapping}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware/usb", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hosts", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hosts", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/journal", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/clone", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/feature", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/refs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/interfaces", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/move_volume", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/mtunnel", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/mtunnelwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/pending", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/remote_migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/resize", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/rrd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/rrddata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/spiceproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/current", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/reboot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/resume", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/shutdown", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/start", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/stop", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/suspend", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/template", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/termproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/vncproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/vncwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/migrateall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/netstat", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network/{iface}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network/{iface}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network/{iface}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/exec", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/exec-status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/file-read", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/file-write", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/fstrim", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-fsinfo", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-host-name", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-osinfo", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-time", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-timezone", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-users", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-vcpus", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/ping", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/set-user-password", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/shutdown", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-disk", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-ram", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/clone", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/cloudinit", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/cloudinit", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/cloudinit/dump", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/feature", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/refs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/monitor", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/move_disk", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/mtunnel", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/mtunnelwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/pending", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/remote_migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/resize", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/rrd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/rrddata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/sendkey", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/spiceproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/current", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/reboot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/reset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/resume", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/shutdown", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/start", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/stop", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/suspend", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/template", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/termproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/unlink", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/vncproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/vncwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/query-url-metadata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication/{id}/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication/{id}/schedule_now", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication/{id}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/report", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/rrd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/rrddata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/cifs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/glusterfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/iscsi", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/lvm", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/lvmthin", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/nfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/pbs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/zfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/zones", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/zones/{zone}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/zones/{zone}/content", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/reload", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/restart", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/start", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/state", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/stop", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/spiceshell", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/startall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/stopall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/download-url", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/file-restore/download", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/file-restore/list", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/import-metadata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/prunebackups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/prunebackups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/rrd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/rrddata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/upload", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/subscription", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/subscription", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/subscription", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/subscription", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/suspendall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/syslog", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks/{upid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks/{upid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks/{upid}/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks/{upid}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/termproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/time", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/time", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/version", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vncshell", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vncwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vzdump", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vzdump/defaults", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vzdump/extractconfig", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/wakeonlan", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools/{poolid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools/{poolid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools/{poolid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage/{storage}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage/{storage}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage/{storage}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/version", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + } + ], + "source_version": "8.4.5" +} diff --git a/evidence/pve-9.2.3-0.1.0.json b/evidence/pve-9.2.3-0.1.0.json new file mode 100644 index 0000000..c5730bf --- /dev/null +++ b/evidence/pve-9.2.3-0.1.0.json @@ -0,0 +1,223 @@ +{ + "format_version": 1, + "profile": "pve-9.2", + "source_version": "9.2.3", + "records": [ + { + "path": "/version", + "verb": "GET", + "dimensions": ["http_status", "json_structure", "response_field_types", "response_required_fields"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_core_handlers.py"] + }, + { + "path": "/access/ticket", + "verb": "POST", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "response_field_types", "response_required_fields", "headers_cookies", "errors_prohibitions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_auth.py", "tests/unit/test_dynamic_routes.py"] + }, + { + "path": "/nodes", + "verb": "GET", + "dimensions": ["http_status", "json_structure", "response_field_types", "response_required_fields", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_core_handlers.py", "tests/unit/test_acl.py"] + }, + { + "path": "/nodes/{node}/qemu", + "verb": "GET", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "response_field_types", "response_required_fields", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_core_handlers.py", "tests/unit/test_acl.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/status/current", + "verb": "GET", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "response_field_types", "response_required_fields", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_core_handlers.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/status/start", + "verb": "POST", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "headers_cookies", "state_semantics", "long_task_behavior", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_task.py", "tests/unit/test_transitions.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/status/stop", + "verb": "POST", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "headers_cookies", "state_semantics", "long_task_behavior", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_task.py", "tests/unit/test_transitions.py"] + }, + { + "path": "/nodes/{node}/tasks/{upid}/status", + "verb": "GET", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "response_field_types", "response_required_fields", "long_task_behavior", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_task_worker.py", "tests/unit/test_upid.py"] + }, + { + "path": "/nodes/{node}/qemu", + "verb": "POST", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "long_task_behavior", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_handlers.py", "tests/unit/test_qemu_task.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}", + "verb": "DELETE", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "long_task_behavior", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_handlers.py", "tests/unit/test_qemu_task.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/config", + "verb": "POST", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "long_task_behavior", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_handlers.py", "tests/unit/test_qemu_task.py", "tests/unit/test_acl.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/config", + "verb": "PUT", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_handlers.py", "tests/unit/test_acl.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/status/shutdown", + "verb": "POST", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "long_task_behavior", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_transitions.py", "tests/unit/test_qemu_task.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/status/reboot", + "verb": "POST", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "long_task_behavior", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_transitions.py", "tests/unit/test_qemu_task.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/status/reset", + "verb": "POST", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "long_task_behavior", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_transitions.py", "tests/unit/test_qemu_task.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/status/suspend", + "verb": "POST", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "long_task_behavior", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_transitions.py", "tests/unit/test_qemu_task.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/status/resume", + "verb": "POST", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "long_task_behavior", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_transitions.py", "tests/unit/test_qemu_task.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/snapshot", + "verb": "GET", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_task.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/snapshot", + "verb": "POST", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "long_task_behavior", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_task.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "verb": "GET", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "verb": "DELETE", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "long_task_behavior", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_task.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "verb": "GET", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "verb": "PUT", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback", + "verb": "POST", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "long_task_behavior", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_task.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/clone", + "verb": "POST", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "long_task_behavior", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_handlers.py", "tests/unit/test_qemu_task.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/migrate", + "verb": "GET", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_handlers.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/migrate", + "verb": "POST", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "long_task_behavior", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_handlers.py", "tests/unit/test_qemu_task.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/resize", + "verb": "PUT", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_compatible_io.py", "tests/unit/test_qemu_handlers.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/move_disk", + "verb": "POST", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "long_task_behavior", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_handlers.py", "tests/unit/test_qemu_task.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/pending", + "verb": "GET", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_handlers.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/agent/info", + "verb": "GET", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_handlers.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/agent/get-osinfo", + "verb": "GET", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_handlers.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/agent/get-host-name", + "verb": "GET", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_handlers.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces", + "verb": "GET", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_handlers.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/agent/get-time", + "verb": "GET", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_handlers.py"] + }, + { + "path": "/nodes/{node}/qemu/{vmid}/agent/ping", + "verb": "POST", + "dimensions": ["input_parameters", "parameter_requiredness", "types_constraints", "http_status", "json_structure", "state_semantics", "errors_prohibitions", "permissions"], + "sources": ["tests/compatibility/test_proxmoxer.py", "tests/unit/test_qemu_handlers.py"] + } + ] +} diff --git a/evidence/pve-9.2.3.json b/evidence/pve-9.2.3.json new file mode 100644 index 0000000..fbbab0f --- /dev/null +++ b/evidence/pve-9.2.3.json @@ -0,0 +1,16971 @@ +{ + "format_version": 1, + "profile": "pve-9.2.3", + "records": [ + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/acl", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/acl", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains/{realm}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains/{realm}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains/{realm}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/domains/{realm}/sync", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups/{groupid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups/{groupid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/groups/{groupid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/openid", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/openid/auth-url", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/openid/login", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/password", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/permissions", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles/{roleid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles/{roleid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/roles/{roleid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa/{userid}/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa/{userid}/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/tfa/{userid}/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/ticket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/ticket", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_auth.py", + "tests/unit/test_dynamic_routes.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/tfa", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token/{tokenid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token/{tokenid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token/{tokenid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/token/{tokenid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/users/{userid}/unlock-tfa", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/access/vncticket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/account/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/challenge-schema", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/directories", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/meta", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/plugins/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/acme/tos", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup-info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup-info/not-backed-up", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/backup/{id}/included_volumes", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/bulk-action", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/bulk-action/guest", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/bulk-action/guest/migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/bulk-action/guest/shutdown", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/bulk-action/guest/start", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/bulk-action/guest/suspend", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/flags", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/flags", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/flags/{flag}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/flags/{flag}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/metadata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ceph/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/apiversion", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/join", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/join", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/nodes", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/nodes/{node}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/nodes/{node}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/qdevice", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/config/totem", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/groups/{group}/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/macros", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/refs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/groups/{group}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}/migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/resources/{sid}/relocate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/rules/{rule}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/rules/{rule}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/rules/{rule}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/status/arm-ha", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/status/current", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/status/disarm-ha", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/ha/status/manager_status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/jobs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/jobs/realm-sync", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/jobs/realm-sync/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/jobs/realm-sync/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/jobs/realm-sync/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/jobs/realm-sync/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/jobs/schedule-analyze", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/dir", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/dir", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/dir/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/dir/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/dir/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/pci", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/pci", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/pci/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/pci/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/pci/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/usb", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/usb", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/usb/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/usb/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/mapping/usb/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/export", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/metrics/server/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/nextid", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/gotify", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/gotify", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/gotify/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/gotify/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/gotify/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/sendmail", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/sendmail", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/sendmail/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/sendmail/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/sendmail/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/smtp", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/smtp", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/smtp/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/smtp/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/smtp/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/webhook", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/webhook", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/webhook/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/webhook/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/endpoints/webhook/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/matcher-field-values", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/matcher-fields", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/matchers", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/matchers", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/matchers/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/matchers/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/matchers/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/targets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/notifications/targets/{name}/test", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/qemu", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/qemu/cpu-flags", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/qemu/custom-cpu-models", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/qemu/custom-cpu-models", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/qemu/custom-cpu-models/{cputype}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/qemu/custom-cpu-models/{cputype}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/qemu/custom-cpu-models/{cputype}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/replication/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/resources", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers/{controller}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers/{controller}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/controllers/{controller}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns/{dns}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns/{dns}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dns/{dns}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/dry-run", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/fabrics", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/fabrics/all", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/fabrics/fabric", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/fabrics/fabric", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/fabrics/fabric/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/fabrics/fabric/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/fabrics/fabric/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/fabrics/node", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/fabrics/node/{fabric_id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/fabrics/node/{fabric_id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams/{ipam}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams/{ipam}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams/{ipam}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/ipams/{ipam}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/lock", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/lock", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/prefix-lists", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/prefix-lists", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/prefix-lists/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/prefix-lists/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/prefix-lists/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/prefix-lists/{id}/entries", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/prefix-lists/{id}/entries", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/rollback", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/route-maps", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/route-maps/entries", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/route-maps/entries", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/route-maps/entries/{route-map-id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/ips", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/ips", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/ips", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones/{zone}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones/{zone}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/sdn/zones/{zone}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/cluster/tasks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_acl.py", + "tests/unit/test_core_handlers.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/aplinfo", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/aplinfo", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/changelog", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/repositories", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/repositories", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/repositories", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/update", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/update", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/apt/versions", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities/qemu", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities/qemu/cpu", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities/qemu/cpu-flags", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities/qemu/machines", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/capabilities/qemu/migration", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/cfg", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/cfg/db", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/cfg/raw", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/cfg/value", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/cmd-safety", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/crush", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/fs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/fs/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/fs/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/init", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mds", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mds/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mds/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mgr", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mgr/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mgr/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mon", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mon/{monid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/mon/{monid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/in", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/lv-info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/metadata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/out", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/osd/{osdid}/scrub", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/pool/{name}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/restart", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/start", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/ceph/stop", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/acme", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/acme/certificate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/acme/certificate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/acme/certificate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/custom", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/custom", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/certificates/info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/directory", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/directory", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/directory/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/initgpt", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/list", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvm", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvm", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvm/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvmthin", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvmthin", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/lvmthin/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/smart", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/wipedisk", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/zfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/zfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/zfs/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/disks/zfs/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/dns", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/dns", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/execute", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware/pci", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware/pci/{pci-id-or-mapping}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hardware/usb", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hosts", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/hosts", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/journal", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/clone", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/feature", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/refs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/interfaces", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/move_volume", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/mtunnel", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/mtunnelwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/pending", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/remote_migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/resize", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/rrd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/rrddata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/spiceproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/current", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/reboot", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/resume", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/shutdown", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/start", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/stop", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/status/suspend", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/template", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/termproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/vncproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/lxc/{vmid}/vncwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/migrateall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/netstat", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network/{iface}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network/{iface}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/network/{iface}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_acl.py", + "tests/unit/test_core_handlers.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_handlers.py", + "tests/unit/test_qemu_task.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_handlers.py", + "tests/unit/test_qemu_task.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/exec", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/exec-status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/file-read", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/file-write", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/fstrim", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-fsinfo", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-host-name", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_handlers.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-osinfo", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_handlers.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-time", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_handlers.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-timezone", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-users", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/get-vcpus", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/info", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_handlers.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_handlers.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/ping", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_handlers.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/set-user-password", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/shutdown", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-disk", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-ram", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/clone", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_handlers.py", + "tests/unit/test_qemu_task.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/cloudinit", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/cloudinit", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/cloudinit/dump", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/config", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/config", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_acl.py", + "tests/unit/test_qemu_handlers.py", + "tests/unit/test_qemu_task.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/config", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_acl.py", + "tests/unit/test_qemu_handlers.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/dbus-vmstate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/feature", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/options", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/refs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/migrate", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_handlers.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/migrate", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_handlers.py", + "tests/unit/test_qemu_task.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/monitor", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/move_disk", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_handlers.py", + "tests/unit/test_qemu_task.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/mtunnel", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/mtunnelwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/pending", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_handlers.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/remote_migrate", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/resize", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_compatible_io.py", + "tests/unit/test_qemu_handlers.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/rrd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/rrddata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/sendkey", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_task.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_task.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_task.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_task.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/spiceproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/current", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_core_handlers.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/reboot", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_task.py", + "tests/unit/test_transitions.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/reset", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_task.py", + "tests/unit/test_transitions.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/resume", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_task.py", + "tests/unit/test_transitions.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/shutdown", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_task.py", + "tests/unit/test_transitions.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/start", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_task.py", + "tests/unit/test_transitions.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/stop", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_task.py", + "tests/unit/test_transitions.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/status/suspend", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_qemu_task.py", + "tests/unit/test_transitions.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/template", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/termproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/unlink", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/vncproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/qemu/{vmid}/vncwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/query-oci-repo-tags", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/query-url-metadata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication/{id}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication/{id}/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication/{id}/schedule_now", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/replication/{id}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/report", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/rrd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/rrddata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/cifs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/iscsi", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/lvm", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/lvmthin", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/nfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/pbs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/scan/zfs", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/fabrics/{fabric}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/fabrics/{fabric}/interfaces", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/fabrics/{fabric}/neighbors", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/fabrics/{fabric}/routes", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/vnets/{vnet}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/vnets/{vnet}/mac-vrf", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/zones", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/zones/{zone}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/zones/{zone}/bridges", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/zones/{zone}/content", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/sdn/zones/{zone}/ip-vrf", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/reload", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/restart", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/start", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/state", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/services/{service}/stop", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/spiceshell", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/startall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/stopall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/download-url", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/file-restore/download", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/file-restore/list", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/identity", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/import-metadata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/oci-registry-pull", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/prunebackups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/prunebackups", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/rrd", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/rrddata", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/status", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/storage/{storage}/upload", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/subscription", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/subscription", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/subscription", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/subscription", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/suspendall", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/syslog", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks/{upid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks/{upid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks/{upid}/log", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/tasks/{upid}/status", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_task_worker.py", + "tests/unit/test_upid.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/termproxy", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/time", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/time", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/version", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vncshell", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vncwebsocket", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vzdump", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vzdump/defaults", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/vzdump/extractconfig", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/nodes/{node}/wakeonlan", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools/{poolid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools/{poolid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/pools/{poolid}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "POST", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage/{storage}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "DELETE", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage/{storage}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "GET", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/storage/{storage}", + "sources": [ + "tests/compatibility/test_verified_surface.py", + "tests/compatibility/test_group_smoke.py" + ], + "verb": "PUT", + "verified": true + }, + { + "dimensions": [ + "route_method", + "input_parameters", + "parameter_requiredness", + "types_constraints", + "http_status", + "json_structure", + "response_field_types", + "response_required_fields", + "headers_cookies", + "state_semantics", + "long_task_behavior", + "errors_prohibitions", + "permissions" + ], + "observed": true, + "path": "/version", + "sources": [ + "tests/compatibility/test_group_smoke.py", + "tests/compatibility/test_proxmoxer.py", + "tests/compatibility/test_verified_surface.py", + "tests/unit/test_core_handlers.py" + ], + "verb": "GET", + "verified": true + } + ], + "source_version": "9.2.3" +} diff --git a/evidence/vsphere-7.0.0.json b/evidence/vsphere-7.0.0.json new file mode 100644 index 0000000..0e42287 --- /dev/null +++ b/evidence/vsphere-7.0.0.json @@ -0,0 +1,81 @@ +{ + "product": "vmware-api-simulator", + "api_version": "7.0.0", + "major": 6, + "series": "vSphere 7.0", + "plane": "vsphere-rest", + "generated_at": "2026-07-15T23:58:55Z", + "notes": "Ledger derived from app/vsphere/rest/coverage.py + PATH_FLOOR. implemented_methods = available at this major; universe_methods = full simulator registry.", + "summary": { + "implemented_methods": 31, + "universe_methods": 1077, + "unsupported_in_version": 1046, + "coverage": 0.0288, + "by_verb": { + "DELETE": 3, + "GET": 23, + "POST": 5 + }, + "status": "partial-clone" + }, + "levels": { + "declared": { + "count": 1077, + "score": 1.0 + }, + "gated": { + "count": 1046, + "score": 0.9712 + }, + "schema_only": { + "count": 1046, + "score": 0.9712 + }, + "implemented": { + "count": 31, + "score": 0.0288 + }, + "observed": { + "count": 31, + "score": 0.0288 + }, + "verified": { + "count": 31, + "score": 0.0288 + } + }, + "dimensions": { + "route_method": { + "count": 31, + "score": 0.0288 + }, + "get": { + "count": 23, + "score": 0.042 + }, + "post": { + "count": 5, + "score": 0.0214 + }, + "patch": { + "count": 0, + "score": 0.0 + }, + "delete": { + "count": 3, + "score": 0.0261 + }, + "auth_session": { + "count": 6, + "score": 1.0 + }, + "inventory": { + "count": 15, + "score": 0.026 + }, + "legacy_rest": { + "count": 12, + "score": 1.0 + } + } +} diff --git a/evidence/vsphere-7.0.3.json b/evidence/vsphere-7.0.3.json new file mode 100644 index 0000000..320abe9 --- /dev/null +++ b/evidence/vsphere-7.0.3.json @@ -0,0 +1,82 @@ +{ + "product": "vmware-api-simulator", + "api_version": "7.0.3", + "major": 7, + "series": "vSphere 7.0 U3", + "plane": "vsphere-rest", + "generated_at": "2026-07-15T23:58:55Z", + "notes": "Ledger derived from app/vsphere/rest/coverage.py + PATH_FLOOR. implemented_methods = available at this major; universe_methods = full simulator registry.", + "summary": { + "implemented_methods": 77, + "universe_methods": 1077, + "unsupported_in_version": 1000, + "coverage": 0.0715, + "by_verb": { + "DELETE": 10, + "GET": 41, + "PATCH": 2, + "POST": 24 + }, + "status": "partial-clone" + }, + "levels": { + "declared": { + "count": 1077, + "score": 1.0 + }, + "gated": { + "count": 1000, + "score": 0.9285 + }, + "schema_only": { + "count": 1000, + "score": 0.9285 + }, + "implemented": { + "count": 77, + "score": 0.0715 + }, + "observed": { + "count": 77, + "score": 0.0715 + }, + "verified": { + "count": 77, + "score": 0.0715 + } + }, + "dimensions": { + "route_method": { + "count": 77, + "score": 0.0715 + }, + "get": { + "count": 41, + "score": 0.0748 + }, + "post": { + "count": 24, + "score": 0.1026 + }, + "patch": { + "count": 2, + "score": 0.023 + }, + "delete": { + "count": 10, + "score": 0.087 + }, + "auth_session": { + "count": 6, + "score": 1.0 + }, + "inventory": { + "count": 50, + "score": 0.0865 + }, + "legacy_rest": { + "count": 12, + "score": 1.0 + } + } +} diff --git a/evidence/vsphere-8.0.0.json b/evidence/vsphere-8.0.0.json new file mode 100644 index 0000000..7dbde0b --- /dev/null +++ b/evidence/vsphere-8.0.0.json @@ -0,0 +1,82 @@ +{ + "product": "vmware-api-simulator", + "api_version": "8.0.0", + "major": 8, + "series": "vSphere 8.0", + "plane": "vsphere-rest", + "generated_at": "2026-07-15T23:58:55Z", + "notes": "Ledger derived from app/vsphere/rest/coverage.py + PATH_FLOOR. implemented_methods = available at this major; universe_methods = full simulator registry.", + "summary": { + "implemented_methods": 103, + "universe_methods": 1077, + "unsupported_in_version": 974, + "coverage": 0.0956, + "by_verb": { + "DELETE": 11, + "GET": 58, + "PATCH": 2, + "POST": 32 + }, + "status": "partial-clone" + }, + "levels": { + "declared": { + "count": 1077, + "score": 1.0 + }, + "gated": { + "count": 974, + "score": 0.9044 + }, + "schema_only": { + "count": 974, + "score": 0.9044 + }, + "implemented": { + "count": 103, + "score": 0.0956 + }, + "observed": { + "count": 103, + "score": 0.0956 + }, + "verified": { + "count": 103, + "score": 0.0956 + } + }, + "dimensions": { + "route_method": { + "count": 103, + "score": 0.0956 + }, + "get": { + "count": 58, + "score": 0.1058 + }, + "post": { + "count": 32, + "score": 0.1368 + }, + "patch": { + "count": 2, + "score": 0.023 + }, + "delete": { + "count": 11, + "score": 0.0957 + }, + "auth_session": { + "count": 6, + "score": 1.0 + }, + "inventory": { + "count": 67, + "score": 0.1159 + }, + "legacy_rest": { + "count": 12, + "score": 1.0 + } + } +} diff --git a/evidence/vsphere-8.0.2.json b/evidence/vsphere-8.0.2.json new file mode 100644 index 0000000..4b0504e --- /dev/null +++ b/evidence/vsphere-8.0.2.json @@ -0,0 +1,83 @@ +{ + "product": "vmware-api-simulator", + "api_version": "8.0.2", + "major": 9, + "series": "vSphere 8.0 U2", + "plane": "vsphere-rest", + "generated_at": "2026-07-15T23:58:55Z", + "notes": "Ledger derived from app/vsphere/rest/coverage.py + PATH_FLOOR. implemented_methods = available at this major; universe_methods = full simulator registry.", + "summary": { + "implemented_methods": 1077, + "universe_methods": 1077, + "unsupported_in_version": 0, + "coverage": 1.0, + "by_verb": { + "DELETE": 115, + "GET": 548, + "PATCH": 87, + "POST": 234, + "PUT": 93 + }, + "status": "registry-complete" + }, + "levels": { + "declared": { + "count": 1077, + "score": 1.0 + }, + "gated": { + "count": 0, + "score": 0.0 + }, + "schema_only": { + "count": 0, + "score": 0.0 + }, + "implemented": { + "count": 1077, + "score": 1.0 + }, + "observed": { + "count": 1077, + "score": 1.0 + }, + "verified": { + "count": 1077, + "score": 1.0 + } + }, + "dimensions": { + "route_method": { + "count": 1077, + "score": 1.0 + }, + "get": { + "count": 548, + "score": 1.0 + }, + "post": { + "count": 234, + "score": 1.0 + }, + "patch": { + "count": 87, + "score": 1.0 + }, + "delete": { + "count": 115, + "score": 1.0 + }, + "auth_session": { + "count": 6, + "score": 1.0 + }, + "inventory": { + "count": 578, + "score": 1.0 + }, + "legacy_rest": { + "count": 12, + "score": 1.0 + } + } +} diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..f82bf9b --- /dev/null +++ b/examples/README.md @@ -0,0 +1,49 @@ +**Language / Язык:** [English](README.md) | [Русский](README.ru.md) + +# Runnable client cookbooks + +Companion code for [docs/clients.md](../docs/clients.md) and +[docs/examples/](../docs/examples/overview.md). + +## Prerequisites + +```bash +make up +VSPHERE_PROFILE=demo-cluster make seed # or small / large +``` + +Default lab credentials: `administrator@vsphere.local` / `VMware1!`. + +## Native vSphere smokes + +```bash +python examples/python/vsphere_rest_smoke.py https://localhost +python examples/python/vsphere_soap_smoke.py https://localhost +python examples/python/vsphere_lifecycle.py # REST create/power/guest FS + SOAP CreateVM +python examples/python/requests_cookbook.py # raw requests, no SDK +ansible-playbook -i examples/ansible/inventory.ini examples/ansible/vsphere_playbook.yml +cd examples/terraform/vsphere && terraform init && terraform apply +cd examples/pulumi && pulumi up +cd examples/go && go run . +cd examples/java && javac Cookbook.java && java Cookbook +cd examples/perl && cpanm --installdeps . && perl cookbook.pl +make vsphere-surface +``` + +## Layout + +| Path | Stack | +|---|---| +| `python/vsphere_*.py` | Native REST + SOAP smokes / lifecycle | +| `python/requests_cookbook.py` | Raw `requests` REST cookbook (session, create/power/delete) | +| `ansible/vsphere_playbook.yml` | Ansible REST lifecycle | +| `terraform/vsphere/` | Terraform `hashicorp/vsphere` (SOAP-backed provider) | +| `pulumi/` | Pulumi REST `ComponentResource` | +| `go/`, `java/`, `perl/` | Minimal REST cookbooks in other languages (stdlib HTTP clients, Basic-auth session) | + +An independent `pulumi-vsphere` lab suite lives under +[`pulumi-tests/`](../pulumi-tests/README.md) — run `make pulumi-tests` from the +repo root (or `make test-pulumi` inside that directory). + +Guides: [docs/examples/](../docs/examples/overview.md). Coverage matrix: +[docs/api-coverage.md](../docs/api-coverage.md). diff --git a/examples/README.ru.md b/examples/README.ru.md new file mode 100644 index 0000000..4027b9c --- /dev/null +++ b/examples/README.ru.md @@ -0,0 +1,49 @@ +**Language / Язык:** [English](README.md) | [Русский](README.ru.md) + +# Исполняемые client cookbooks + +Сопровождающий код к [docs/ru/clients.md](../docs/ru/clients.md) и +[docs/ru/examples/](../docs/ru/examples/overview.md). + +## Требования + +```bash +make up +VSPHERE_PROFILE=demo-cluster make seed # or small / large +``` + +Учётные данные лаборатории по умолчанию: `administrator@vsphere.local` / `VMware1!`. + +## Нативные smoke vSphere + +```bash +python examples/python/vsphere_rest_smoke.py https://localhost +python examples/python/vsphere_soap_smoke.py https://localhost +python examples/python/vsphere_lifecycle.py # REST create/power/guest FS + SOAP CreateVM +python examples/python/requests_cookbook.py # raw requests, no SDK +ansible-playbook -i examples/ansible/inventory.ini examples/ansible/vsphere_playbook.yml +cd examples/terraform/vsphere && terraform init && terraform apply +cd examples/pulumi && pulumi up +cd examples/go && go run . +cd examples/java && javac Cookbook.java && java Cookbook +cd examples/perl && cpanm --installdeps . && perl cookbook.pl +make vsphere-surface +``` + +## Структура + +| Путь | Стек | +|---|---| +| `python/vsphere_*.py` | Нативные REST + SOAP smokes / lifecycle | +| `python/requests_cookbook.py` | Raw `requests` REST cookbook (session, create/power/delete) | +| `ansible/vsphere_playbook.yml` | Ansible REST lifecycle | +| `terraform/vsphere/` | Terraform `hashicorp/vsphere` (SOAP-backed provider) | +| `pulumi/` | Pulumi REST `ComponentResource` | +| `go/`, `java/`, `perl/` | Минимальные REST cookbook на других языках (stdlib HTTP-клиенты, сессия Basic-auth) | + +Независимый lab-набор на `pulumi-vsphere` живёт в +[`pulumi-tests/`](../pulumi-tests/README.ru.md) — из корня репозитория: +`make pulumi-tests` (или `make test-pulumi` внутри этой директории). + +Гайды: [docs/ru/examples/](../docs/ru/examples/overview.md). Матрица покрытия: +[docs/ru/api-coverage.md](../docs/ru/api-coverage.md). diff --git a/examples/ansible/inventory.ini b/examples/ansible/inventory.ini new file mode 100644 index 0000000..33623e4 --- /dev/null +++ b/examples/ansible/inventory.ini @@ -0,0 +1,2 @@ +[simulator] +localhost ansible_connection=local diff --git a/examples/ansible/vsphere_playbook.yml b/examples/ansible/vsphere_playbook.yml new file mode 100644 index 0000000..170519f --- /dev/null +++ b/examples/ansible/vsphere_playbook.yml @@ -0,0 +1,123 @@ +--- +# vSphere Automation REST cookbook against the API simulator. +# ansible-playbook -i inventory.ini vsphere_playbook.yml +# +# Requires: gateway https://localhost (or set vsphere_base). + +- name: vSphere API simulator lifecycle + hosts: simulator + gather_facts: false + vars: + vsphere_base: "https://localhost" + vsphere_user: "administrator@vsphere.local" + vsphere_password: "VMware1!" + vm_name: "ansible-lab-01" + tasks: + - name: Create CIS session + ansible.builtin.uri: + url: "{{ vsphere_base }}/api/session" + method: POST + url_username: "{{ vsphere_user }}" + url_password: "{{ vsphere_password }}" + force_basic_auth: true + validate_certs: false + status_code: [200, 201] + return_content: true + register: session + + - name: Set session header + ansible.builtin.set_fact: + vsphere_headers: + vmware-api-session-id: "{{ session.json }}" + + - name: List VMs + ansible.builtin.uri: + url: "{{ vsphere_base }}/api/vcenter/vm" + headers: "{{ vsphere_headers }}" + validate_certs: false + return_content: true + register: vms + + - name: Show inventory size + ansible.builtin.debug: + msg: "VMs in inventory: {{ vms.json | length }}" + + - name: Create VM + ansible.builtin.uri: + url: "{{ vsphere_base }}/api/vcenter/vm" + method: POST + headers: "{{ vsphere_headers }}" + body_format: json + body: + name: "{{ vm_name }}" + guest_OS: OTHER_GUEST_64 + placement: + folder: group-v23 + host: host-11 + datastore: datastore-31 + resource_pool: resgroup-22 + cpu: + count: 1 + memory: + size_MiB: 512 + validate_certs: false + status_code: [200, 201] + return_content: true + register: created + + - name: Power on + ansible.builtin.uri: + url: "{{ vsphere_base }}/api/vcenter/vm/{{ created.json }}/power?action=start" + method: POST + headers: "{{ vsphere_headers }}" + validate_certs: false + status_code: [200, 204] + return_content: true + register: power_on + + - name: Poll CIS task when returned + ansible.builtin.uri: + url: "{{ vsphere_base }}/api/cis/tasks/{{ power_on.json.task }}" + headers: "{{ vsphere_headers }}" + validate_certs: false + return_content: true + register: task + when: power_on.json is mapping and power_on.json.task is defined + until: task.json.status in ['SUCCEEDED', 'FAILED'] + retries: 30 + delay: 1 + + - name: Write guest file (lab virtual FS) + ansible.builtin.uri: + url: "{{ vsphere_base }}/api/vcenter/vm/{{ created.json }}/guest/filesystem?path=/tmp/ansible-marker" + method: PUT + headers: "{{ vsphere_headers }}" + body_format: json + body: + content: "ansible-ok" + validate_certs: false + status_code: [200, 204] + + - name: Power off + ansible.builtin.uri: + url: "{{ vsphere_base }}/api/vcenter/vm/{{ created.json }}/power?action=stop" + method: POST + headers: "{{ vsphere_headers }}" + validate_certs: false + status_code: [200, 204] + + - name: Delete VM + ansible.builtin.uri: + url: "{{ vsphere_base }}/api/vcenter/vm/{{ created.json }}" + method: DELETE + headers: "{{ vsphere_headers }}" + validate_certs: false + status_code: [200, 204] + + - name: Delete session + ansible.builtin.uri: + url: "{{ vsphere_base }}/api/session" + method: DELETE + headers: "{{ vsphere_headers }}" + validate_certs: false + status_code: [200, 204] diff --git a/examples/go/go.mod b/examples/go/go.mod new file mode 100644 index 0000000..3b501df --- /dev/null +++ b/examples/go/go.mod @@ -0,0 +1,3 @@ +module example.com/vmware-api-simulator-cookbook + +go 1.22 diff --git a/examples/go/main.go b/examples/go/main.go new file mode 100644 index 0000000..c9fc5f4 --- /dev/null +++ b/examples/go/main.go @@ -0,0 +1,121 @@ +package main + +import ( + "crypto/tls" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "net/http" + "os" + "strings" + "time" +) + +func env(k, def string) string { + if v := os.Getenv(k); v != "" { + return v + } + return def +} + +var client = &http.Client{ + Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}, // lab self-signed cert only +} + +func main() { + base := strings.TrimRight(env("VSPHERE_BASE", "https://localhost"), "/") + user := env("VSPHERE_USER", "administrator@vsphere.local") + password := env("VSPHERE_PASSWORD", "VMware1!") + vmName := env("VSPHERE_VM_NAME", "go-lab-01") + + auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(user+":"+password)) + var sessionID string + call(base+"/api/session", "POST", map[string]string{"Authorization": auth}, nil, &sessionID) + fmt.Println("session:", sessionID) + + headers := map[string]string{"vmware-api-session-id": sessionID} + + var vms []map[string]any + call(base+"/api/vcenter/vm", "GET", headers, nil, &vms) + fmt.Printf("vms before: %d\n", len(vms)) + + body, _ := json.Marshal(map[string]any{ + "name": vmName, + "guest_OS": "OTHER_GUEST_64", + "placement": map[string]string{ + "folder": "group-v23", + "host": "host-11", + "datastore": "datastore-31", + "resource_pool": "resgroup-22", + }, + "cpu": map[string]int{"count": 1}, + "memory": map[string]int{"size_MiB": 512}, + }) + var moid string + call(base+"/api/vcenter/vm", "POST", headers, body, &moid) + fmt.Println("created:", moid) + + var power map[string]string + call(base+"/api/vcenter/vm/"+moid+"/power?action=start", "POST", headers, nil, &power) + waitTask(base, headers, power["task"]) + + var detail map[string]any + call(base+"/api/vcenter/vm/"+moid, "GET", headers, nil, &detail) + fmt.Println("power_state:", detail["power_state"]) + + call(base+"/api/vcenter/vm/"+moid+"/power?action=stop", "POST", headers, nil, &power) + waitTask(base, headers, power["task"]) + + call(base+"/api/vcenter/vm/"+moid, "DELETE", headers, nil, nil) + call(base+"/api/session", "DELETE", headers, nil, nil) + fmt.Println("ok") +} + +func waitTask(base string, headers map[string]string, task string) { + if task == "" { + return + } + deadline := time.Now().Add(2 * time.Minute) + for time.Now().Before(deadline) { + var status map[string]any + call(base+"/api/cis/tasks/"+task, "GET", headers, nil, &status) + if s, _ := status["status"].(string); s == "SUCCEEDED" || s == "FAILED" { + return + } + time.Sleep(300 * time.Millisecond) + } + panic("timeout waiting for task " + task) +} + +func call(url, method string, headers map[string]string, body []byte, out any) { + var reqBody io.Reader + if body != nil { + reqBody = strings.NewReader(string(body)) + } + req, err := http.NewRequest(method, url, reqBody) + if err != nil { + panic(err) + } + for k, v := range headers { + req.Header.Set(k, v) + } + if body != nil { + req.Header.Set("Content-Type", "application/json") + } + resp, err := client.Do(req) + if err != nil { + panic(err) + } + defer resp.Body.Close() + raw, _ := io.ReadAll(resp.Body) + if resp.StatusCode >= 300 { + panic(fmt.Sprintf("%s %s: %d %s", method, url, resp.StatusCode, raw)) + } + if out == nil || len(raw) == 0 { + return + } + if err := json.Unmarshal(raw, out); err != nil { + panic(err) + } +} diff --git a/examples/java/Cookbook.java b/examples/java/Cookbook.java new file mode 100644 index 0000000..565c8fe --- /dev/null +++ b/examples/java/Cookbook.java @@ -0,0 +1,170 @@ +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.Base64; + +/** + * Minimal Java 11+ cookbook against the vSphere REST gateway using a Basic-auth + * session (vmware-api-session-id). + * + * javac Cookbook.java && java Cookbook + */ +public final class Cookbook { + private static final HttpClient CLIENT = + HttpClient.newBuilder().sslContext(insecureSslContext()).build(); + + public static void main(String[] args) throws Exception { + String base = env("VSPHERE_BASE", "https://localhost"); + String user = env("VSPHERE_USER", "administrator@vsphere.local"); + String password = env("VSPHERE_PASSWORD", "VMware1!"); + String vmName = env("VSPHERE_VM_NAME", "java-lab-01"); + + String auth = + "Basic " + Base64.getEncoder().encodeToString((user + ":" + password).getBytes(StandardCharsets.UTF_8)); + String sessionId = unquote(send(post(base + "/api/session", auth, null))); + System.out.println("session: " + sessionId); + + String vms = send(get(base + "/api/vcenter/vm", sessionId)); + System.out.println("vms before: " + vms.length() + " bytes"); + + String createBody = + "{\"name\":\"" + + vmName + + "\",\"guest_OS\":\"OTHER_GUEST_64\"," + + "\"placement\":{\"folder\":\"group-v23\",\"host\":\"host-11\"," + + "\"datastore\":\"datastore-31\",\"resource_pool\":\"resgroup-22\"}," + + "\"cpu\":{\"count\":1},\"memory\":{\"size_MiB\":512}}"; + String moid = unquote(send(postJson(base + "/api/vcenter/vm", sessionId, createBody))); + System.out.println("created: " + moid); + + String power = send(post(base + "/api/vcenter/vm/" + moid + "/power?action=start", sessionId, null)); + waitTask(base, sessionId, extractField(power, "task")); + + String detail = send(get(base + "/api/vcenter/vm/" + moid, sessionId)); + System.out.println("power_state: " + extractField(detail, "power_state")); + + power = send(post(base + "/api/vcenter/vm/" + moid + "/power?action=stop", sessionId, null)); + waitTask(base, sessionId, extractField(power, "task")); + + send(delete(base + "/api/vcenter/vm/" + moid, sessionId)); + send(delete(base + "/api/session", sessionId)); + System.out.println("ok"); + } + + private static void waitTask(String base, String sessionId, String task) throws Exception { + if (task == null || task.isBlank()) { + return; + } + long deadline = System.currentTimeMillis() + 120_000; + while (System.currentTimeMillis() < deadline) { + String body = send(get(base + "/api/cis/tasks/" + task, sessionId)); + String status = extractField(body, "status"); + if ("SUCCEEDED".equals(status) || "FAILED".equals(status)) { + return; + } + Thread.sleep(300); + } + throw new IllegalStateException("timeout waiting for task " + task); + } + + private static String env(String key, String def) { + String value = System.getenv(key); + return value == null || value.isBlank() ? def : value; + } + + private static HttpRequest get(String uri, String sessionId) { + return HttpRequest.newBuilder(URI.create(uri)) + .timeout(Duration.ofSeconds(60)) + .header("vmware-api-session-id", sessionId) + .GET() + .build(); + } + + private static HttpRequest post(String uri, String auth, String body) { + HttpRequest.Builder builder = + HttpRequest.newBuilder(URI.create(uri)).timeout(Duration.ofSeconds(60)); + if (auth.startsWith("Basic ")) { + builder.header("Authorization", auth); + } else { + builder.header("vmware-api-session-id", auth); + } + return builder.POST(body == null ? BodyPublishers.noBody() : BodyPublishers.ofString(body)).build(); + } + + private static HttpRequest postJson(String uri, String sessionId, String body) { + return HttpRequest.newBuilder(URI.create(uri)) + .timeout(Duration.ofSeconds(60)) + .header("vmware-api-session-id", sessionId) + .header("Content-Type", "application/json") + .POST(BodyPublishers.ofString(body)) + .build(); + } + + private static HttpRequest delete(String uri, String sessionId) { + return HttpRequest.newBuilder(URI.create(uri)) + .timeout(Duration.ofSeconds(60)) + .header("vmware-api-session-id", sessionId) + .DELETE() + .build(); + } + + private static String send(HttpRequest request) throws Exception { + HttpResponse response = CLIENT.send(request, HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() >= 300) { + throw new RuntimeException(response.statusCode() + ": " + response.body()); + } + return response.body(); + } + + private static String unquote(String value) { + String trimmed = value.trim(); + if (trimmed.startsWith("\"") && trimmed.endsWith("\"")) { + return trimmed.substring(1, trimmed.length() - 1); + } + return trimmed; + } + + /** Tiny string-based field extraction — good enough for a lab smoke, no JSON library required. */ + private static String extractField(String body, String field) { + String marker = "\"" + field + "\":"; + int start = body.indexOf(marker); + if (start < 0) { + return ""; + } + start += marker.length(); + while (start < body.length() && (body.charAt(start) == ' ' || body.charAt(start) == '"')) { + start++; + } + int end = start; + while (end < body.length() && body.charAt(end) != '"' && body.charAt(end) != ',' && body.charAt(end) != '}') { + end++; + } + return body.substring(start, end); + } + + private static javax.net.ssl.SSLContext insecureSslContext() { + try { + javax.net.ssl.TrustManager[] trustAll = + new javax.net.ssl.TrustManager[] { + new javax.net.ssl.X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return new java.security.cert.X509Certificate[0]; + } + + public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {} + + public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {} + } + }; + javax.net.ssl.SSLContext context = javax.net.ssl.SSLContext.getInstance("TLS"); + context.init(null, trustAll, new java.security.SecureRandom()); + return context; + } catch (Exception error) { + throw new RuntimeException(error); + } + } +} diff --git a/examples/perl/cookbook.pl b/examples/perl/cookbook.pl new file mode 100644 index 0000000..3fb276a --- /dev/null +++ b/examples/perl/cookbook.pl @@ -0,0 +1,84 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use HTTP::Tiny; +use JSON qw(decode_json encode_json); +use MIME::Base64 qw(encode_base64); +use Time::HiRes qw(sleep); + +my $base = $ENV{VSPHERE_BASE} // 'https://localhost'; +my $user = $ENV{VSPHERE_USER} // 'administrator@vsphere.local'; +my $password = $ENV{VSPHERE_PASSWORD} // 'VMware1!'; +my $vm_name = $ENV{VSPHERE_VM_NAME} // 'perl-lab-01'; + +# Lab self-signed certificate only — do not disable verification against a real vCenter. +my $http = HTTP::Tiny->new(timeout => 60, verify_SSL => 0); + +sub api { + my ($method, $path, %opts) = @_; + my $res = $http->request($method, "$base$path", \%opts); + die "$method $path failed: $res->{status} $res->{content}\n" unless $res->{success}; + return $res->{content}; +} + +sub json_field { + my ($body, $field) = @_; + my $data = decode_json($body); + return $data->{$field}; +} + +sub wait_task { + my ($task, $headers) = @_; + return unless $task; + my $deadline = time + 120; + while (time < $deadline) { + my $body = api('GET', "/api/cis/tasks/$task", headers => $headers); + my $status = json_field($body, 'status'); + return if $status eq 'SUCCEEDED' || $status eq 'FAILED'; + sleep(0.3); + } + die "timeout waiting for task $task\n"; +} + +my $auth = 'Basic ' . encode_base64("$user:$password", ''); +my $session_body = api('POST', '/api/session', headers => { Authorization => $auth }); +(my $session_id = $session_body) =~ s/^"(.*)"$/$1/; +print "session: $session_id\n"; + +my %headers = ('vmware-api-session-id' => $session_id); + +my $vms_before = api('GET', '/api/vcenter/vm', headers => \%headers); +print 'vms before: ', scalar(@{ decode_json($vms_before) }), "\n"; + +my $create_body = encode_json({ + name => $vm_name, + guest_OS => 'OTHER_GUEST_64', + placement => { + folder => 'group-v23', + host => 'host-11', + datastore => 'datastore-31', + resource_pool => 'resgroup-22', + }, + cpu => { count => 1 }, + memory => { size_MiB => 512 }, +}); +my $created = api( + 'POST', '/api/vcenter/vm', + headers => { %headers, 'Content-Type' => 'application/json' }, + content => $create_body, +); +(my $moid = $created) =~ s/^"(.*)"$/$1/; +print "created: $moid\n"; + +my $power = api('POST', "/api/vcenter/vm/$moid/power?action=start", headers => \%headers); +wait_task(json_field($power, 'task'), \%headers); + +my $detail = api('GET', "/api/vcenter/vm/$moid", headers => \%headers); +print 'power_state: ', json_field($detail, 'power_state'), "\n"; + +$power = api('POST', "/api/vcenter/vm/$moid/power?action=stop", headers => \%headers); +wait_task(json_field($power, 'task'), \%headers); + +api('DELETE', "/api/vcenter/vm/$moid", headers => \%headers); +api('DELETE', '/api/session', headers => \%headers); +print "ok\n"; diff --git a/examples/perl/cpanfile b/examples/perl/cpanfile new file mode 100644 index 0000000..f376318 --- /dev/null +++ b/examples/perl/cpanfile @@ -0,0 +1,3 @@ +requires 'HTTP::Tiny'; +requires 'JSON'; +requires 'IO::Socket::SSL'; diff --git a/examples/pulumi/Pulumi.yaml b/examples/pulumi/Pulumi.yaml new file mode 100644 index 0000000..73e4acf --- /dev/null +++ b/examples/pulumi/Pulumi.yaml @@ -0,0 +1,3 @@ +name: vmware-api-simulator +runtime: python +description: pulumi-vsphere cookbook against vmware-api-simulator diff --git a/examples/pulumi/__main__.py b/examples/pulumi/__main__.py new file mode 100644 index 0000000..bc30c29 --- /dev/null +++ b/examples/pulumi/__main__.py @@ -0,0 +1,69 @@ +"""Pulumi cookbook using official pulumi-vsphere against the simulator.""" + +from __future__ import annotations + +import os + +import pulumi +import pulumi_vsphere as vsphere + +config = pulumi.Config() +user = config.get("user") or os.environ.get("VSPHERE_USER", "administrator@vsphere.local") +password = config.get_secret("password") or os.environ.get("VSPHERE_PASSWORD", "VMware1!") +server = config.get("server") or os.environ.get("VSPHERE_SERVER", "localhost") +datacenter_name = config.get("datacenter") or "Datacenter" +datastore_name = config.get("datastore") or "datastore1" +cluster_name = config.get("cluster") or "Cluster" +network_name = config.get("network") or "VM Network" +vm_name = config.get("vm_name") or "pulumi-lab-01" + +provider = vsphere.Provider( + "vsphere", + user=user, + password=password, + vsphere_server=server, + allow_unverified_ssl=True, +) +invoke_opts = pulumi.InvokeOptions(provider=provider) +res_opts = pulumi.ResourceOptions(provider=provider) + +dc = vsphere.get_datacenter_output(name=datacenter_name, opts=invoke_opts) +ds = vsphere.get_datastore_output( + name=datastore_name, + datacenter_id=dc.id, + opts=invoke_opts, +) +cluster = vsphere.get_compute_cluster_output( + name=cluster_name, + datacenter_id=dc.id, + opts=invoke_opts, +) +network = vsphere.get_network_output( + name=network_name, + datacenter_id=dc.id, + opts=invoke_opts, +) + +vm = vsphere.VirtualMachine( + "cookbook-vm", + name=vm_name, + resource_pool_id=cluster.resource_pool_id, + datastore_id=ds.id, + num_cpus=1, + memory=1024, + guest_id="otherGuest64", + wait_for_guest_net_timeout=0, + wait_for_guest_ip_timeout=0, + network_interfaces=[ + vsphere.VirtualMachineNetworkInterfaceArgs(network_id=network.id), + ], + disks=[ + vsphere.VirtualMachineDiskArgs(label="disk0", size=16), + ], + opts=res_opts, +) + +pulumi.export("datacenter_id", dc.id) +pulumi.export("lab_vm_id", vm.id) +pulumi.export("lab_vm_name", vm.name) +pulumi.export("resource_pool_id", cluster.resource_pool_id) diff --git a/examples/pulumi/requirements.txt b/examples/pulumi/requirements.txt new file mode 100644 index 0000000..4b95798 --- /dev/null +++ b/examples/pulumi/requirements.txt @@ -0,0 +1,2 @@ +pulumi>=3.0.0,<4 +pulumi-vsphere==4.17.0 diff --git a/examples/python/requests_cookbook.py b/examples/python/requests_cookbook.py new file mode 100644 index 0000000..a805de5 --- /dev/null +++ b/examples/python/requests_cookbook.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +"""Raw `requests` cookbook against the vSphere REST gateway (no vsphere-automation-sdk).""" + +from __future__ import annotations + +import os +import sys +import time +from typing import Any + +import requests +import urllib3 + +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + +BASE = os.environ.get("VSPHERE_BASE", "https://localhost").rstrip("/") +USER = os.environ.get("VSPHERE_USER", "administrator@vsphere.local") +PASSWORD = os.environ.get("VSPHERE_PASSWORD", "VMware1!") +VM_NAME = os.environ.get("VSPHERE_VM_NAME", "req-lab-01") + + +def api( + method: str, + path: str, + *, + headers: dict[str, str] | None = None, + json_body: dict[str, Any] | None = None, +) -> Any: + response = requests.request( + method, + f"{BASE}{path}", + headers=headers, + json=json_body, + verify=False, # local self-signed development certificate only + timeout=60, + ) + response.raise_for_status() + if response.status_code == 204 or not response.content: + return None + return response.json() + + +def wait_task(headers: dict[str, str], task: str, timeout: float = 120.0) -> None: + deadline = time.time() + timeout + while time.time() < deadline: + status = api("GET", f"/api/cis/tasks/{task}", headers=headers) + if status.get("status") in {"SUCCEEDED", "FAILED"}: + return + time.sleep(0.3) + raise TimeoutError(task) + + +def session_headers() -> dict[str, str]: + response = requests.post( + f"{BASE}/api/session", + auth=(USER, PASSWORD), + verify=False, + timeout=60, + ) + response.raise_for_status() + return {"vmware-api-session-id": response.json()} + + +def main() -> int: + headers = session_headers() + print("session:", headers["vmware-api-session-id"]) + + vms = api("GET", "/api/vcenter/vm", headers=headers) + print("vms before:", len(vms)) + + moid = api( + "POST", + "/api/vcenter/vm", + headers=headers, + json_body={ + "name": VM_NAME, + "guest_OS": "OTHER_GUEST_64", + "placement": { + "folder": "group-v23", + "host": "host-11", + "datastore": "datastore-31", + "resource_pool": "resgroup-22", + }, + "cpu": {"count": 1}, + "memory": {"size_MiB": 512}, + }, + ) + print("created:", moid) + + power = api("POST", f"/api/vcenter/vm/{moid}/power?action=start", headers=headers) + wait_task(headers, power["task"]) + + detail = api("GET", f"/api/vcenter/vm/{moid}", headers=headers) + print("power_state:", detail["power_state"]) + + power = api("POST", f"/api/vcenter/vm/{moid}/power?action=stop", headers=headers) + wait_task(headers, power["task"]) + + api("DELETE", f"/api/vcenter/vm/{moid}", headers=headers) + api("DELETE", "/api/session", headers=headers) + print("ok") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/examples/python/requirements.txt b/examples/python/requirements.txt new file mode 100644 index 0000000..535409c --- /dev/null +++ b/examples/python/requirements.txt @@ -0,0 +1 @@ +requests>=2.31 diff --git a/examples/python/vsphere_lifecycle.py b/examples/python/vsphere_lifecycle.py new file mode 100644 index 0000000..0b291e1 --- /dev/null +++ b/examples/python/vsphere_lifecycle.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 +"""End-to-end Python smoke: REST create/power/guest-file + SOAP CreateVM_Task.""" + +from __future__ import annotations + +import os +import sys +import xml.etree.ElementTree as ET + +import requests +import urllib3 + +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + +BASE = os.environ.get("VSPHERE_BASE", "https://localhost").rstrip("/") +USER = os.environ.get("VSPHERE_USER", "administrator@vsphere.local") +PASSWORD = os.environ.get("VSPHERE_PASSWORD", "VMware1!") + + +def rest_session() -> dict[str, str]: + response = requests.post(f"{BASE}/api/session", auth=(USER, PASSWORD), verify=False, timeout=60) + response.raise_for_status() + return {"vmware-api-session-id": response.json()} + + +def rest_lifecycle(headers: dict[str, str]) -> str: + created = requests.post( + f"{BASE}/api/vcenter/vm", + headers=headers, + json={ + "name": "py-rest-lab-01", + "guest_OS": "OTHER_GUEST_64", + "placement": { + "folder": "group-v23", + "host": "host-11", + "datastore": "datastore-31", + "resource_pool": "resgroup-22", + }, + "cpu": {"count": 1}, + "memory": {"size_MiB": 512}, + }, + verify=False, + timeout=60, + ) + created.raise_for_status() + vm = created.json() + power = requests.post( + f"{BASE}/api/vcenter/vm/{vm}/power", + params={"action": "start"}, + headers=headers, + verify=False, + timeout=60, + ) + power.raise_for_status() + assert "task" in power.json() + put = requests.put( + f"{BASE}/api/vcenter/vm/{vm}/guest/filesystem", + params={"path": "/tmp/python-marker"}, + headers=headers, + json={"content": "ok"}, + verify=False, + timeout=60, + ) + put.raise_for_status() + requests.post( + f"{BASE}/api/vcenter/vm/{vm}/power", + params={"action": "stop"}, + headers=headers, + verify=False, + timeout=60, + ).raise_for_status() + requests.delete( + f"{BASE}/api/vcenter/vm/{vm}", headers=headers, verify=False, timeout=60 + ).raise_for_status() + return vm + + +def soap_create_vm(session_id: str) -> str: + envelope = """ + + + + <_this type="Folder">group-v23 + + py-soap-lab-01 + otherGuest64 + 1 + 512 + [datastore1] + + resgroup-22 + host-11 + + + """ + response = requests.post( + f"{BASE}/sdk", + data=envelope, + headers={ + "Content-Type": "text/xml", + "vmware-api-session-id": session_id, + "Cookie": f'vmware_soap_session="{session_id}"', + }, + verify=False, + timeout=60, + ) + response.raise_for_status() + root = ET.fromstring(response.text) + task = None + for node in root.iter(): + if node.tag.endswith("returnval") and (node.text or "").startswith("task-"): + task = node.text + break + assert task, response.text + return task + + +def main() -> int: + headers = rest_session() + rest_vm = rest_lifecycle(headers) + soap_task = soap_create_vm(headers["vmware-api-session-id"]) + print(f"REST VM lifecycle ok: {rest_vm}") + print(f"SOAP CreateVM_Task ok: {soap_task}") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/examples/python/vsphere_rest_smoke.py b/examples/python/vsphere_rest_smoke.py new file mode 100644 index 0000000..735c451 --- /dev/null +++ b/examples/python/vsphere_rest_smoke.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +"""Smoke the native vSphere REST surface against a running simulator.""" + +from __future__ import annotations + +import json +import sys +import urllib.error +import urllib.request +from base64 import b64encode + +BASE = sys.argv[1] if len(sys.argv) > 1 else "https://localhost" +USER = "administrator@vsphere.local" +PASSWORD = "VMware1!" + + +def _req( + method: str, path: str, *, headers: dict[str, str] | None = None, data: bytes | None = None +): + request = urllib.request.Request( + f"{BASE}{path}", + data=data, + method=method, + headers=headers or {}, + ) + ctx = None + if BASE.startswith("https://"): + import ssl + + ctx = ssl._create_unverified_context() # noqa: S323 - lab self-signed + with urllib.request.urlopen(request, context=ctx) as response: # noqa: S310 + body = response.read() + return response.status, dict(response.headers), body + + +def main() -> int: + basic = b64encode(f"{USER}:{PASSWORD}".encode()).decode() + status, headers, body = _req( + "POST", + "/api/session", + headers={"Authorization": f"Basic {basic}"}, + ) + print("session", status, body.decode()) + session = json.loads(body.decode()) + sess_headers = {"vmware-api-session-id": session} + status, _, vms = _req("GET", "/api/vcenter/vm", headers=sess_headers) + print("vms", status, vms.decode()) + status, _, hosts = _req("GET", "/api/vcenter/host", headers=sess_headers) + print("hosts", status, hosts.decode()) + return 0 + + +if __name__ == "__main__": + try: + raise SystemExit(main()) + except urllib.error.URLError as error: + print(f"failed: {error}", file=sys.stderr) + raise SystemExit(1) from error diff --git a/examples/python/vsphere_soap_smoke.py b/examples/python/vsphere_soap_smoke.py new file mode 100644 index 0000000..1fa53ce --- /dev/null +++ b/examples/python/vsphere_soap_smoke.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +"""Minimal SOAP /sdk smoke (RetrieveServiceContent + Login envelope).""" + +from __future__ import annotations + +import ssl +import sys +import urllib.error +import urllib.request + +BASE = sys.argv[1] if len(sys.argv) > 1 else "https://localhost" + +CONTENT = """ + + + + ServiceInstance + + + +""" + +LOGIN = """ + + + + SessionManager + administrator@vsphere.local + VMware1! + + + +""" + + +def _post(path: str, body: str) -> tuple[int, str]: + req = urllib.request.Request( + f"{BASE}{path}", + data=body.encode(), + method="POST", + headers={"Content-Type": "text/xml; charset=utf-8", "SOAPAction": '""'}, + ) + ctx = ssl._create_unverified_context() if BASE.startswith("https://") else None # noqa: S323 + with urllib.request.urlopen(req, context=ctx) as resp: # noqa: S310 + return int(resp.status), resp.read().decode() + + +def main() -> int: + status, body = _post("/sdk", CONTENT) + print("RetrieveServiceContent", status, "ServiceContent" in body) + if "ServiceContent" not in body: + return 1 + status, body = _post("/sdk", LOGIN) + login_ok = "LoginResponse" in body or "UserSession" in body or "key>" in body + print("Login", status, login_ok) + if not login_ok: + print(body[:400], file=sys.stderr) + return 1 + wsdl = urllib.request.Request(f"{BASE}/sdk/vimService.wsdl") + ctx = ssl._create_unverified_context() if BASE.startswith("https://") else None # noqa: S323 + with urllib.request.urlopen(wsdl, context=ctx) as resp: # noqa: S310 + print("wsdl", resp.status, len(resp.read())) + return 0 + + +if __name__ == "__main__": + try: + raise SystemExit(main()) + except urllib.error.URLError as error: + print(f"failed: {error}", file=sys.stderr) + raise SystemExit(1) from error diff --git a/examples/terraform/vsphere/.terraform.lock.hcl b/examples/terraform/vsphere/.terraform.lock.hcl new file mode 100644 index 0000000..6538a7a --- /dev/null +++ b/examples/terraform/vsphere/.terraform.lock.hcl @@ -0,0 +1,22 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/vsphere" { + version = "2.12.0" + constraints = "~> 2.8" + hashes = [ + "h1:WqZLjrDFhrpS0Y0IdSrKGNE/iuJf3l38K8Wz+ZRlJLE=", + "zh:02eee1071636834570106f70df904807e4d5cff2cf378c9e1dcfbebbeef4411b", + "zh:0ea4ed072d6b9bd8517a1b5c1b06ec05fac6293376c94a9b4625a41ca0626117", + "zh:0fa82a384b25a58b65523e0ea4768fa1212b1f5cfc0c9379d31162454fedcc9d", + "zh:23cede3a4cb8080662dc0416f2ea6b43e6ca0907c3af0ddae544df923b878080", + "zh:2fd2e293115fe4a3ca5f3df051ef852315d5eada304ffa8caaa11d95d15f2ab0", + "zh:532577c8897109a23eb768d23479870ccc353987b9bf28fd6532c1adc2878743", + "zh:a575a9d5e0b08866fe78da9bf50afee29a3278a0f7e0c269f0626e4a4d25bba1", + "zh:c7461658ae2d81881e84a37b6e1c69b05fcee1110fac0b57ebf7ea1a0f5406f2", + "zh:d9af3f73391a02d8c1d0e7a0f7da72afff8d49445da8c98bf6e63ad799c5dbc9", + "zh:deeed7463f1f532bb3edf70c786c8e3eca0b255cb1c74bcf69a5978d4757ed2c", + "zh:ed21ac2b742326098818876125c3a8177b76ae01ce82a88238b786c8020ef151", + "zh:f4ff28277d68956d1adc94c5d6fbc109f4a389e8ebb707d24b99ab3113235428", + ] +} diff --git a/examples/terraform/vsphere/main.tf b/examples/terraform/vsphere/main.tf new file mode 100644 index 0000000..e7ef692 --- /dev/null +++ b/examples/terraform/vsphere/main.tf @@ -0,0 +1,69 @@ +terraform { + required_providers { + vsphere = { + source = "hashicorp/vsphere" + version = "~> 2.8" + } + } +} + +provider "vsphere" { + user = var.vsphere_user + password = var.vsphere_password + vsphere_server = var.vsphere_server + allow_unverified_ssl = true +} + +data "vsphere_datacenter" "dc" { + name = var.datacenter +} + +data "vsphere_datastore" "ds" { + name = var.datastore + datacenter_id = data.vsphere_datacenter.dc.id +} + +data "vsphere_compute_cluster" "cluster" { + name = var.cluster + datacenter_id = data.vsphere_datacenter.dc.id +} + +data "vsphere_network" "network" { + name = var.network + datacenter_id = data.vsphere_datacenter.dc.id +} + +data "vsphere_virtual_machine" "web" { + name = var.vm_name + datacenter_id = data.vsphere_datacenter.dc.id +} + +# Lab VM create (SOAP CreateVM_Task). Use a unique name per apply. +resource "vsphere_virtual_machine" "lab" { + count = var.create_lab_vm ? 1 : 0 + name = var.lab_vm_name + resource_pool_id = data.vsphere_compute_cluster.cluster.resource_pool_id + datastore_id = data.vsphere_datastore.ds.id + num_cpus = 1 + memory = 1024 + guest_id = "otherGuest64" + wait_for_guest_net_timeout = 0 + wait_for_guest_ip_timeout = 0 + + network_interface { + network_id = data.vsphere_network.network.id + } + + disk { + label = "disk0" + size = 16 + } +} + +output "vm_id" { + value = data.vsphere_virtual_machine.web.id +} + +output "lab_vm_id" { + value = try(vsphere_virtual_machine.lab[0].id, null) +} diff --git a/examples/terraform/vsphere/variables.tf b/examples/terraform/vsphere/variables.tf new file mode 100644 index 0000000..bf29879 --- /dev/null +++ b/examples/terraform/vsphere/variables.tf @@ -0,0 +1,50 @@ +variable "vsphere_server" { + type = string + default = "localhost" +} + +variable "vsphere_user" { + type = string + default = "administrator@vsphere.local" +} + +variable "vsphere_password" { + type = string + default = "VMware1!" + sensitive = true +} + +variable "datacenter" { + type = string + default = "Datacenter" +} + +variable "vm_name" { + type = string + default = "web-01" +} + +variable "datastore" { + type = string + default = "datastore1" +} + +variable "cluster" { + type = string + default = "Cluster" +} + +variable "network" { + type = string + default = "VM Network" +} + +variable "create_lab_vm" { + type = bool + default = false +} + +variable "lab_vm_name" { + type = string + default = "tf-lab-01" +} diff --git a/helm/vmware-api-simulator/.helmignore b/helm/vmware-api-simulator/.helmignore new file mode 100644 index 0000000..e6b0b26 --- /dev/null +++ b/helm/vmware-api-simulator/.helmignore @@ -0,0 +1,7 @@ +.DS_Store +.git +.gitignore +*.md +*.tgz +charts/*.tgz +values-ingress-example.yaml diff --git a/helm/vmware-api-simulator/Chart.yaml b/helm/vmware-api-simulator/Chart.yaml new file mode 100644 index 0000000..ada6714 --- /dev/null +++ b/helm/vmware-api-simulator/Chart.yaml @@ -0,0 +1,16 @@ +apiVersion: v2 +name: vmware-api-simulator +description: Stateful VMware API simulator (PostgreSQL-backed) for labs and CI +type: application +version: 0.1.0 +appVersion: "0.1.0" +home: https://github.com/inecs/vmware-api-simulator +keywords: + - vmware + - cloud + - api + - simulator +maintainers: + - name: inecs +# Bundled PostgreSQL uses the official postgres image (see templates/postgresql-*.yaml). +# No external chart dependency is required — run helm install directly. diff --git a/helm/vmware-api-simulator/README.md b/helm/vmware-api-simulator/README.md new file mode 100644 index 0000000..13fa772 --- /dev/null +++ b/helm/vmware-api-simulator/README.md @@ -0,0 +1,42 @@ +**Language / Язык:** [English](README.md) | [Русский](README.ru.md) + +# Helm chart: vmware-api-simulator + +Deploys the published runtime image +[`inecs/vmware-api-simulator`](https://hub.docker.com/r/inecs/vmware-api-simulator) +with optional official PostgreSQL, migrations, seed Job, Ingress, and +cert-manager Let's Encrypt `ClusterIssuer` resources. + +Full guide: [docs/kubernetes.md](../../docs/kubernetes.md). + +## Quick install + +Prerequisites: Kubernetes, Helm 3, ingress-nginx (or compatible), cert-manager. + +```bash +helm upgrade --install vmware-sim ./helm/vmware-api-simulator \ + -n vmware-sim --create-namespace \ + -f ./helm/vmware-api-simulator/values-ingress-example.yaml \ + --set certManager.email=you@example.com \ + --set ingress.hosts[0].host=vmware-sim.example.com \ + --set ingress.tls[0].hosts[0]=vmware-sim.example.com \ + --set secret.ticketSigningKey="$(openssl rand -hex 32)" \ + --set postgresql.auth.password="$(openssl rand -hex 16)" +``` + +Point DNS for your host at the Ingress controller, wait for the Certificate to +become Ready, then open `https://vmware-sim.example.com/`. + +## Values overview + +| Key | Default | Meaning | +|---|---|---| +| `image.repository` | `inecs/vmware-api-simulator` | Hub image | +| `image.tag` | chart `appVersion` | Image tag | +| `postgresql.enabled` | `true` | Bundle official PostgreSQL StatefulSet | +| `secret.databaseUrl` / `externalDatabase.*` | | External DB when postgres disabled | +| `ingress.enabled` | `false` | Expose via Ingress | +| `certManager.enabled` | `false` | Annotate Ingress + optional ClusterIssuers | +| `seed.enabled` | `false` | Post-install seed Job | + +See [`values.yaml`](values.yaml) and [`values-ingress-example.yaml`](values-ingress-example.yaml). diff --git a/helm/vmware-api-simulator/README.ru.md b/helm/vmware-api-simulator/README.ru.md new file mode 100644 index 0000000..58e9fdc --- /dev/null +++ b/helm/vmware-api-simulator/README.ru.md @@ -0,0 +1,42 @@ +**Language / Язык:** [English](README.md) | [Русский](README.ru.md) + +# Helm-чарт: vmware-api-simulator + +Развёртывает опубликованный runtime-образ +[`inecs/vmware-api-simulator`](https://hub.docker.com/r/inecs/vmware-api-simulator) +с опциональным официальным PostgreSQL, миграциями, seed Job, Ingress и +ресурсами cert-manager Let's Encrypt `ClusterIssuer`. + +Полный гайд: [docs/ru/kubernetes.md](../../docs/ru/kubernetes.md). + +## Быстрая установка + +Требования: Kubernetes, Helm 3, ingress-nginx (или совместимый), cert-manager. + +```bash +helm upgrade --install vmware-sim ./helm/vmware-api-simulator \ + -n vmware-sim --create-namespace \ + -f ./helm/vmware-api-simulator/values-ingress-example.yaml \ + --set certManager.email=you@example.com \ + --set ingress.hosts[0].host=vmware-sim.example.com \ + --set ingress.tls[0].hosts[0]=vmware-sim.example.com \ + --set secret.ticketSigningKey="$(openssl rand -hex 32)" \ + --set postgresql.auth.password="$(openssl rand -hex 16)" +``` + +Направьте DNS хоста на Ingress controller, дождитесь Ready у Certificate, +затем откройте `https://vmware-sim.example.com/`. + +## Обзор values + +| Ключ | По умолчанию | Назначение | +|---|---|---| +| `image.repository` | `inecs/vmware-api-simulator` | Образ Hub | +| `image.tag` | chart `appVersion` | Тег образа | +| `postgresql.enabled` | `true` | Включить официальный PostgreSQL StatefulSet | +| `secret.databaseUrl` / `externalDatabase.*` | | Внешняя БД, когда postgres выключен | +| `ingress.enabled` | `false` | Открыть через Ingress | +| `certManager.enabled` | `false` | Аннотировать Ingress + опциональные ClusterIssuers | +| `seed.enabled` | `false` | Post-install seed Job | + +См. [`values.yaml`](values.yaml) и [`values-ingress-example.yaml`](values-ingress-example.yaml). diff --git a/helm/vmware-api-simulator/templates/NOTES.txt b/helm/vmware-api-simulator/templates/NOTES.txt new file mode 100644 index 0000000..6d1c51c --- /dev/null +++ b/helm/vmware-api-simulator/templates/NOTES.txt @@ -0,0 +1,35 @@ +vmware-api-simulator {{ .Chart.AppVersion }} installed as release "{{ .Release.Name }}". + +Image: {{ include "vmware-api-simulator.image" . }} + +1. Check readiness: + + kubectl -n {{ .Release.Namespace }} get pods -l "app.kubernetes.io/instance={{ .Release.Name }}" + +2. Access the API / Web UI: + +{{- if .Values.ingress.enabled }} +{{- range .Values.ingress.hosts }} + https://{{ .host }}/ +{{- end }} +{{- if .Values.certManager.enabled }} + TLS certificate is requested via cert-manager ClusterIssuer + "{{ include "vmware-api-simulator.clusterIssuer" . }}". +{{- end }} +{{- else }} + kubectl -n {{ .Release.Namespace }} port-forward svc/{{ include "vmware-api-simulator.fullname" . }} 8080:{{ .Values.service.port }} + Then open http://127.0.0.1:8080/ +{{- end }} + +3. Seed laboratory data (if seed.enabled was false): + + kubectl -n {{ .Release.Namespace }} exec deploy/{{ include "vmware-api-simulator.fullname" . }} -- \ + python -m app.simulation.seed_cli + + Or upgrade with --set seed.enabled=true,seed.profile=small + +Default lab login after seeding: + administrator@vsphere.local / VMware1! + +Change secret.ticketSigningKey (and postgresql.auth.password) before exposing +the cluster publicly. diff --git a/helm/vmware-api-simulator/templates/_helpers.tpl b/helm/vmware-api-simulator/templates/_helpers.tpl new file mode 100644 index 0000000..e5693ad --- /dev/null +++ b/helm/vmware-api-simulator/templates/_helpers.tpl @@ -0,0 +1,121 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "vmware-api-simulator.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "vmware-api-simulator.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "vmware-api-simulator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "vmware-api-simulator.labels" -}} +helm.sh/chart: {{ include "vmware-api-simulator.chart" . }} +{{ include "vmware-api-simulator.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "vmware-api-simulator.selectorLabels" -}} +app.kubernetes.io/name: {{ include "vmware-api-simulator.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Service account name +*/}} +{{- define "vmware-api-simulator.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "vmware-api-simulator.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Image reference +*/}} +{{- define "vmware-api-simulator.image" -}} +{{- $tag := .Values.image.tag | default .Chart.AppVersion }} +{{- printf "%s:%s" .Values.image.repository $tag }} +{{- end }} + +{{/* +Secret name holding DATABASE_URL and TICKET_SIGNING_KEY +*/}} +{{- define "vmware-api-simulator.secretName" -}} +{{- if .Values.secret.existingSecret }} +{{- .Values.secret.existingSecret }} +{{- else }} +{{- include "vmware-api-simulator.fullname" . }} +{{- end }} +{{- end }} + +{{/* +PostgreSQL hostname when bundled subchart is enabled +*/}} +{{- define "vmware-api-simulator.postgresqlHost" -}} +{{- printf "%s-postgresql" .Release.Name }} +{{- end }} + +{{/* +Build DATABASE_URL when not supplied explicitly (bundled or external discrete fields). +*/}} +{{- define "vmware-api-simulator.databaseUrl" -}} +{{- if .Values.secret.databaseUrl }} +{{- .Values.secret.databaseUrl }} +{{- else if .Values.postgresql.enabled }} +{{- $user := .Values.postgresql.auth.username }} +{{- $pass := .Values.postgresql.auth.password }} +{{- $db := .Values.postgresql.auth.database }} +{{- $host := include "vmware-api-simulator.postgresqlHost" . }} +{{- printf "postgresql://%s:%s@%s:5432/%s" $user $pass $host $db }} +{{- else if .Values.externalDatabase.host }} +{{- $user := .Values.externalDatabase.user }} +{{- $pass := .Values.externalDatabase.password }} +{{- $db := .Values.externalDatabase.database }} +{{- $host := .Values.externalDatabase.host }} +{{- $port := int .Values.externalDatabase.port }} +{{- printf "postgresql://%s:%s@%s:%d/%s" $user $pass $host $port $db }} +{{- else }} +{{- fail "Set postgresql.enabled=true, or secret.databaseUrl / secret.existingSecret, or externalDatabase.host" }} +{{- end }} +{{- end }} + +{{/* +cert-manager ClusterIssuer name used by Ingress +*/}} +{{- define "vmware-api-simulator.clusterIssuer" -}} +{{- if .Values.certManager.useStaging }} +{{- .Values.certManager.stagingIssuerName }} +{{- else }} +{{- .Values.certManager.issuerName }} +{{- end }} +{{- end }} diff --git a/helm/vmware-api-simulator/templates/clusterissuer.yaml b/helm/vmware-api-simulator/templates/clusterissuer.yaml new file mode 100644 index 0000000..5ea7b96 --- /dev/null +++ b/helm/vmware-api-simulator/templates/clusterissuer.yaml @@ -0,0 +1,42 @@ +{{- if and .Values.certManager.enabled .Values.certManager.createClusterIssuer }} +{{- $solverClass := .Values.certManager.solverIngressClassName | default .Values.ingress.className }} +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: {{ .Values.certManager.issuerName }} + labels: + {{- include "vmware-api-simulator.labels" . | nindent 4 }} +spec: + acme: + email: {{ required "certManager.email is required when createClusterIssuer=true" .Values.certManager.email | quote }} + server: {{ .Values.certManager.server | quote }} + privateKeySecretRef: + name: {{ printf "%s-account-key" .Values.certManager.issuerName }} + solvers: + - http01: + ingress: + {{- if $solverClass }} + ingressClassName: {{ $solverClass }} + {{- end }} +--- +{{- if .Values.certManager.createStagingIssuer }} +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: {{ .Values.certManager.stagingIssuerName }} + labels: + {{- include "vmware-api-simulator.labels" . | nindent 4 }} +spec: + acme: + email: {{ .Values.certManager.email | quote }} + server: {{ .Values.certManager.stagingServer | quote }} + privateKeySecretRef: + name: {{ printf "%s-account-key" .Values.certManager.stagingIssuerName }} + solvers: + - http01: + ingress: + {{- if $solverClass }} + ingressClassName: {{ $solverClass }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/vmware-api-simulator/templates/deployment.yaml b/helm/vmware-api-simulator/templates/deployment.yaml new file mode 100644 index 0000000..0190683 --- /dev/null +++ b/helm/vmware-api-simulator/templates/deployment.yaml @@ -0,0 +1,152 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "vmware-api-simulator.fullname" . }} + labels: + {{- include "vmware-api-simulator.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "vmware-api-simulator.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "vmware-api-simulator.labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "vmware-api-simulator.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + {{- if and .Values.migrate.enabled (not .Values.migrate.asJob) }} + initContainers: + - name: migrate + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: {{ include "vmware-api-simulator.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: {{ include "vmware-api-simulator.secretName" . }} + key: DATABASE_URL + - name: LOG_LEVEL + value: {{ .Values.config.logLevel | quote }} + command: + - python + - -c + - | + import asyncio + import os + import sys + import time + + import asyncpg + + dsn = os.environ["DATABASE_URL"] + deadline = time.time() + 300 + while True: + try: + async def ping() -> None: + conn = await asyncpg.connect(dsn=dsn, timeout=5) + await conn.close() + + asyncio.run(ping()) + break + except Exception as exc: # noqa: BLE001 - wait until Postgres accepts connections + if time.time() >= deadline: + print(f"database not ready: {exc}", file=sys.stderr) + raise + print(f"waiting for database: {exc}") + time.sleep(3) + + from app.db.migrate_cli import run + + asyncio.run(run()) + resources: + {{- toYaml .Values.migrate.resources | nindent 12 }} + volumeMounts: + - name: tmp + mountPath: /tmp + {{- end }} + containers: + - name: simulator + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: {{ include "vmware-api-simulator.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.service.port }} + protocol: TCP + env: + - name: APP_HOST + value: "0.0.0.0" + - name: APP_PORT + value: {{ .Values.service.port | quote }} + - name: LOG_LEVEL + value: {{ .Values.config.logLevel | quote }} + - name: ENABLE_PVE_STUB + value: {{ .Values.config.enablePveStub | quote }} + {{- if .Values.config.contractSnapshot }} + - name: CONTRACT_SNAPSHOT + value: {{ .Values.config.contractSnapshot | quote }} + {{- end }} + - name: COMPATIBILITY_EVIDENCE + value: {{ .Values.config.compatibilityEvidence | quote }} + - name: CONTRACT_FALLBACK + value: {{ .Values.config.contractFallback | quote }} + - name: TASK_WORKER_CONCURRENCY + value: {{ .Values.config.taskWorkerConcurrency | quote }} + - name: TASK_LEASE_SECONDS + value: {{ .Values.config.taskLeaseSeconds | quote }} + - name: SIMULATION_TIME_SCALE + value: {{ .Values.config.simulationTimeScale | quote }} + - name: REQUEST_ID_HEADER + value: {{ .Values.config.requestIdHeader | quote }} + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: {{ include "vmware-api-simulator.secretName" . }} + key: DATABASE_URL + - name: TICKET_SIGNING_KEY + valueFrom: + secretKeyRef: + name: {{ include "vmware-api-simulator.secretName" . }} + key: TICKET_SIGNING_KEY + livenessProbe: + {{- toYaml .Values.livenessProbe | nindent 12 }} + readinessProbe: + {{- toYaml .Values.readinessProbe | nindent 12 }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: tmp + mountPath: /tmp + volumes: + - name: tmp + emptyDir: {} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/helm/vmware-api-simulator/templates/ingress.yaml b/helm/vmware-api-simulator/templates/ingress.yaml new file mode 100644 index 0000000..2e10824 --- /dev/null +++ b/helm/vmware-api-simulator/templates/ingress.yaml @@ -0,0 +1,46 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "vmware-api-simulator.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "vmware-api-simulator.labels" . | nindent 4 }} + annotations: + {{- if .Values.certManager.enabled }} + cert-manager.io/cluster-issuer: {{ include "vmware-api-simulator.clusterIssuer" . | quote }} + {{- end }} + {{- with .Values.ingress.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.ingress.className }} + ingressClassName: {{ . }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/vmware-api-simulator/templates/migrate-job.yaml b/helm/vmware-api-simulator/templates/migrate-job.yaml new file mode 100644 index 0000000..02d739a --- /dev/null +++ b/helm/vmware-api-simulator/templates/migrate-job.yaml @@ -0,0 +1,50 @@ +{{- /* Kept for optional standalone migrate Job when migrate.asJob=true */ -}} +{{- if and .Values.migrate.enabled .Values.migrate.asJob }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "vmware-api-simulator.fullname" . }}-migrate + labels: + {{- include "vmware-api-simulator.labels" . | nindent 4 }} + app.kubernetes.io/component: migrate +spec: + backoffLimit: {{ .Values.migrate.backoffLimit }} + activeDeadlineSeconds: {{ .Values.migrate.activeDeadlineSeconds }} + template: + metadata: + labels: + {{- include "vmware-api-simulator.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: migrate + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "vmware-api-simulator.serviceAccountName" . }} + restartPolicy: OnFailure + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: migrate + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: {{ include "vmware-api-simulator.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: {{ include "vmware-api-simulator.secretName" . }} + key: DATABASE_URL + - name: LOG_LEVEL + value: {{ .Values.config.logLevel | quote }} + command: ["python", "-m", "app.db.migrate_cli"] + resources: + {{- toYaml .Values.migrate.resources | nindent 12 }} + volumeMounts: + - name: tmp + mountPath: /tmp + volumes: + - name: tmp + emptyDir: {} +{{- end }} diff --git a/helm/vmware-api-simulator/templates/postgresql-service.yaml b/helm/vmware-api-simulator/templates/postgresql-service.yaml new file mode 100644 index 0000000..fb068f7 --- /dev/null +++ b/helm/vmware-api-simulator/templates/postgresql-service.yaml @@ -0,0 +1,19 @@ +{{- if .Values.postgresql.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "vmware-api-simulator.postgresqlHost" . }} + labels: + {{- include "vmware-api-simulator.labels" . | nindent 4 }} + app.kubernetes.io/component: postgresql +spec: + type: ClusterIP + ports: + - port: 5432 + targetPort: postgresql + protocol: TCP + name: postgresql + selector: + app.kubernetes.io/name: {{ include "vmware-api-simulator.name" . }}-postgresql + app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/helm/vmware-api-simulator/templates/postgresql-statefulset.yaml b/helm/vmware-api-simulator/templates/postgresql-statefulset.yaml new file mode 100644 index 0000000..83066b1 --- /dev/null +++ b/helm/vmware-api-simulator/templates/postgresql-statefulset.yaml @@ -0,0 +1,71 @@ +{{- if .Values.postgresql.enabled }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "vmware-api-simulator.postgresqlHost" . }} + labels: + {{- include "vmware-api-simulator.labels" . | nindent 4 }} + app.kubernetes.io/component: postgresql +spec: + serviceName: {{ include "vmware-api-simulator.postgresqlHost" . }} + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: {{ include "vmware-api-simulator.name" . }}-postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ include "vmware-api-simulator.name" . }}-postgresql + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: postgresql + spec: + containers: + - name: postgresql + image: {{ printf "%s:%s" .Values.postgresql.image.repository .Values.postgresql.image.tag | quote }} + imagePullPolicy: {{ .Values.postgresql.image.pullPolicy }} + ports: + - name: postgresql + containerPort: 5432 + env: + - name: POSTGRES_DB + value: {{ .Values.postgresql.auth.database | quote }} + - name: POSTGRES_USER + value: {{ .Values.postgresql.auth.username | quote }} + - name: POSTGRES_PASSWORD + value: {{ .Values.postgresql.auth.password | quote }} + - name: PGDATA + value: /var/lib/postgresql/data/pgdata + livenessProbe: + exec: + command: ["pg_isready", "-U", {{ .Values.postgresql.auth.username | quote }}] + initialDelaySeconds: 20 + periodSeconds: 10 + readinessProbe: + exec: + command: ["pg_isready", "-U", {{ .Values.postgresql.auth.username | quote }}] + initialDelaySeconds: 5 + periodSeconds: 5 + resources: + {{- toYaml .Values.postgresql.resources | nindent 12 }} + volumeMounts: + - name: data + mountPath: /var/lib/postgresql/data + {{- if .Values.postgresql.persistence.enabled }} + volumeClaimTemplates: + - metadata: + name: data + spec: + accessModes: ["ReadWriteOnce"] + {{- with .Values.postgresql.persistence.storageClass }} + storageClassName: {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.postgresql.persistence.size }} + {{- else }} + volumes: + - name: data + emptyDir: {} + {{- end }} +{{- end }} diff --git a/helm/vmware-api-simulator/templates/secret.yaml b/helm/vmware-api-simulator/templates/secret.yaml new file mode 100644 index 0000000..d5dc5cb --- /dev/null +++ b/helm/vmware-api-simulator/templates/secret.yaml @@ -0,0 +1,12 @@ +{{- if and .Values.secret.create (not .Values.secret.existingSecret) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "vmware-api-simulator.fullname" . }} + labels: + {{- include "vmware-api-simulator.labels" . | nindent 4 }} +type: Opaque +stringData: + DATABASE_URL: {{ include "vmware-api-simulator.databaseUrl" . | quote }} + TICKET_SIGNING_KEY: {{ required "secret.ticketSigningKey is required when secret.create=true" .Values.secret.ticketSigningKey | quote }} +{{- end }} diff --git a/helm/vmware-api-simulator/templates/seed-job.yaml b/helm/vmware-api-simulator/templates/seed-job.yaml new file mode 100644 index 0000000..7ced167 --- /dev/null +++ b/helm/vmware-api-simulator/templates/seed-job.yaml @@ -0,0 +1,56 @@ +{{- if .Values.seed.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "vmware-api-simulator.fullname" . }}-seed + labels: + {{- include "vmware-api-simulator.labels" . | nindent 4 }} + app.kubernetes.io/component: seed + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-weight": "5" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +spec: + backoffLimit: {{ .Values.seed.backoffLimit }} + template: + metadata: + labels: + {{- include "vmware-api-simulator.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: seed + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "vmware-api-simulator.serviceAccountName" . }} + restartPolicy: OnFailure + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: seed + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: {{ include "vmware-api-simulator.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: {{ include "vmware-api-simulator.secretName" . }} + key: DATABASE_URL + - name: SEED_VSPHERE_PROFILE + value: {{ .Values.seed.profile | quote }} + - name: ENABLE_PVE_STUB + value: {{ .Values.config.enablePveStub | quote }} + - name: LOG_LEVEL + value: {{ .Values.config.logLevel | quote }} + command: ["python", "-m", "app.simulation.seed_cli"] + resources: + {{- toYaml .Values.seed.resources | nindent 12 }} + volumeMounts: + - name: tmp + mountPath: /tmp + volumes: + - name: tmp + emptyDir: {} +{{- end }} diff --git a/helm/vmware-api-simulator/templates/service.yaml b/helm/vmware-api-simulator/templates/service.yaml new file mode 100644 index 0000000..999bb2a --- /dev/null +++ b/helm/vmware-api-simulator/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "vmware-api-simulator.fullname" . }} + labels: + {{- include "vmware-api-simulator.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "vmware-api-simulator.selectorLabels" . | nindent 4 }} diff --git a/helm/vmware-api-simulator/templates/serviceaccount.yaml b/helm/vmware-api-simulator/templates/serviceaccount.yaml new file mode 100644 index 0000000..950ddc0 --- /dev/null +++ b/helm/vmware-api-simulator/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "vmware-api-simulator.serviceAccountName" . }} + labels: + {{- include "vmware-api-simulator.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: false +{{- end }} diff --git a/helm/vmware-api-simulator/values-ingress-example.yaml b/helm/vmware-api-simulator/values-ingress-example.yaml new file mode 100644 index 0000000..3812f51 --- /dev/null +++ b/helm/vmware-api-simulator/values-ingress-example.yaml @@ -0,0 +1,54 @@ +# Example: public Ingress + Let's Encrypt (cert-manager) + Hub image. +# +# helm upgrade --install vmware-sim ./helm/vmware-api-simulator \ +# -n vmware-sim --create-namespace \ +# -f ./helm/vmware-api-simulator/values-ingress-example.yaml \ +# --set certManager.email=you@example.com \ +# --set ingress.hosts[0].host=vmware-sim.example.com \ +# --set ingress.tls[0].hosts[0]=vmware-sim.example.com \ +# --set secret.ticketSigningKey="$(openssl rand -hex 32)" \ +# --set postgresql.auth.password="$(openssl rand -hex 16)" + +image: + repository: inecs/vmware-api-simulator + tag: "0.1.0" + pullPolicy: IfNotPresent + +secret: + create: true + ticketSigningKey: "replace-me" + +postgresql: + enabled: true + auth: + username: vmware + password: "replace-me-db-password" + database: vmware_simulator + +seed: + enabled: true + profile: small + +ingress: + enabled: true + className: nginx + hosts: + - host: vmware-sim.example.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: vmware-api-simulator-tls + hosts: + - vmware-sim.example.com + +certManager: + enabled: true + createClusterIssuer: true + createStagingIssuer: true + email: you@example.com + issuerName: letsencrypt-prod + stagingIssuerName: letsencrypt-staging + # Set true first to validate HTTP-01 against Let's Encrypt staging. + useStaging: false + solverIngressClassName: nginx diff --git a/helm/vmware-api-simulator/values.yaml b/helm/vmware-api-simulator/values.yaml new file mode 100644 index 0000000..d69e518 --- /dev/null +++ b/helm/vmware-api-simulator/values.yaml @@ -0,0 +1,180 @@ +## Default values for vmware-api-simulator. +## Image: https://hub.docker.com/r/inecs/vmware-api-simulator + +replicaCount: 1 + +image: + repository: inecs/vmware-api-simulator + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + create: true + annotations: {} + name: "" + +podAnnotations: {} +podLabels: {} + +podSecurityContext: + fsGroup: 10001 + +securityContext: + runAsNonRoot: true + runAsUser: 10001 + runAsGroup: 10001 + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + readOnlyRootFilesystem: true + +service: + type: ClusterIP + # Internal app port. Publish VMware service ports via Ingress/Service separately. + port: 8080 + +## Application environment (non-secret). +config: + logLevel: INFO + enablePveStub: "false" + # Optional cold-start contract path (vSphere majors use evidence + UI hot-swap). + contractSnapshot: "" + contractFallback: error + taskWorkerConcurrency: 2 + taskLeaseSeconds: "30" + simulationTimeScale: "10" + requestIdHeader: X-Request-ID + compatibilityEvidence: /app/evidence/vsphere-8.0.2.json + +## Secrets. Prefer existingSecret in production. +secret: + # Create a Secret from the values below when existingSecret is empty. + create: true + existingSecret: "" + # Keys expected in an existing secret (when existingSecret is set): + # DATABASE_URL, TICKET_SIGNING_KEY + ticketSigningKey: "change-me-to-a-long-random-secret" + # Used only when postgresql.enabled=true and databaseUrl is empty. + # The chart builds postgresql://USER:PASSWORD@HOST:5432/DB + databaseUrl: "" + +## Bundled PostgreSQL (official image — same major as docker-compose.release.yml). +postgresql: + enabled: true + image: + repository: postgres + tag: "17.5-bookworm" + pullPolicy: IfNotPresent + auth: + username: vmware + password: vmware + database: vmware_simulator + persistence: + enabled: true + size: 8Gi + storageClass: "" + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + memory: 512Mi + +## External database when postgresql.enabled=false. +## Provide either full URL (secret.databaseUrl / existingSecret) or discrete fields. +externalDatabase: + host: "" + port: 5432 + user: vmware + password: "" + database: vmware_simulator + # Optional existing secret with key database-password (or set password above). + existingSecret: "" + existingSecretPasswordKey: database-password + +## Database migrations. +## Default: idempotent initContainer on the Deployment (recommended). +## Set asJob=true to run a standalone Job instead. +migrate: + enabled: true + asJob: false + backoffLimit: 20 + activeDeadlineSeconds: 600 + resources: {} + +## Optional post-install seed Job (lab data). +seed: + enabled: false + profile: small + backoffLimit: 3 + resources: {} + +resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: "1" + memory: 1Gi + +livenessProbe: + httpGet: + path: /health/live + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 3 + failureThreshold: 3 + +readinessProbe: + httpGet: + path: /health/ready + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 3 + failureThreshold: 8 + +nodeSelector: {} +tolerations: [] +affinity: {} + +## Ingress + TLS via cert-manager (Let's Encrypt). +ingress: + enabled: false + className: nginx + annotations: {} + # Extra annotations merged after cert-manager ones when certManager.enabled. + hosts: + - host: vmware-sim.example.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: vmware-api-simulator-tls + hosts: + - vmware-sim.example.com + +## cert-manager ClusterIssuers for Let's Encrypt. +## Requires cert-manager already installed in the cluster. +certManager: + enabled: false + # Create ClusterIssuer resources from this chart. + createClusterIssuer: true + email: admin@example.com + # Production issuer (used by Ingress by default). + issuerName: letsencrypt-prod + server: https://acme-v02.api.letsencrypt.org/directory + # Staging issuer (optional; useful for dry-runs). + createStagingIssuer: true + stagingIssuerName: letsencrypt-staging + stagingServer: https://acme-staging-v02.api.letsencrypt.org/directory + # Which issuer the Ingress annotation should reference. + useStaging: false + # ACME HTTP-01 solver ingress class (usually same as ingress.className). + solverIngressClassName: "" diff --git a/pulumi-tests/Makefile b/pulumi-tests/Makefile new file mode 100644 index 0000000..b28a36c --- /dev/null +++ b/pulumi-tests/Makefile @@ -0,0 +1,48 @@ +# pulumi-vsphere lab suite (containers only). + +COMPOSE ?= docker compose +COMPOSE_FILE ?= docker-compose.yml +COMPOSE_CMD = $(COMPOSE) -f $(COMPOSE_FILE) +PROFILE = --profile test + +.PHONY: help up down build seed test-pulumi-smoke test-pulumi pulumi-tests \ + test-smoke-all test-all clean-test-resources report-open + +help: ## Show targets + @awk 'BEGIN {FS = ":.*## "}; /^[a-zA-Z0-9_-]+:.*## / {printf "%-26s %s\n", $$1, $$2}' $(MAKEFILE_LIST) + +up: ## Start simulator + gateway + seed + $(COMPOSE_CMD) up -d --build postgres + $(COMPOSE_CMD) up --build migrate + $(COMPOSE_CMD) up -d --build simulator api-gateway + $(COMPOSE_CMD) up --build seed + +down: ## Stop lab stack + $(COMPOSE_CMD) --profile test down -v + +build: ## Build pulumi-runner image (pulumi + pulumi-vsphere) + $(COMPOSE_CMD) $(PROFILE) build pulumi-runner + +seed: ## Re-run inventory seed + $(COMPOSE_CMD) up --build seed + +test-pulumi-smoke: up ## PU-INV + REST major-9 smoke (no VM/tags/CRUD/full SOAP) + $(COMPOSE_CMD) $(PROFILE) run --rm -e TEST_SMOKE=1 pulumi-runner \ + python3 /suite/run_suite.py + +test-pulumi: up ## Full hybrid: pulumi-vsphere + REST×6-9 + CRUD + SOAP WSDL + $(COMPOSE_CMD) $(PROFILE) run --rm pulumi-runner \ + python3 /suite/run_suite.py + +pulumi-tests: test-pulumi ## Alias used from repo root + +test-smoke-all: test-pulumi-smoke ## Alias + +test-all: test-pulumi ## Alias + +clean-test-resources: ## Best-effort cleanup via seed reload + $(COMPOSE_CMD) up --build seed + +report-open: ## Print how to copy the HTML report + @echo "HTML report volume: lab-reports → /reports/pulumi-report.html" + @echo "Copy: docker compose --profile test run --rm --no-deps -v \$$(pwd)/reports:/out pulumi-runner cp /reports/pulumi-report.html /out/" diff --git a/pulumi-tests/README.md b/pulumi-tests/README.md new file mode 100644 index 0000000..3e54ded --- /dev/null +++ b/pulumi-tests/README.md @@ -0,0 +1,84 @@ +# pulumi hybrid lab suite for vmware-api-simulator + +Hybrid suite under `pulumi-tests/`: + +1. Official [`pulumi-vsphere`](https://www.pulumi.com/registry/packages/vsphere/) (SOAP/VIM via govmomi) +2. Full REST `IMPLEMENTED` × majors **6–9** matrix (deep + stub response checks) +3. Deep REST CRUD (session / folder / tag / content library / VM) +4. All SOAP WSDL ops advertised on `/sdk/vimService.wsdl` + +`pulumi-vsphere` alone cannot hit ~1092 REST routes — the HTTP matrix is required for full-surface confidence. + +## Pass rules + +| Class | Pass rule | +|-------|-----------| +| REST GET (inventory-critical / deep) | 2xx, body non-empty, not `"stub": true` on major 9 critical paths | +| REST stubs (universe) | no 5xx/501; response present; reported as `stub` (not claimed durable CRUD) | +| REST deep CRUD | create → GET nonempty → update (where supported) → delete → GET missing | +| SOAP WSDL ops (~45) | POST `/sdk` without 5xx; Create/Power/Clone/Destroy checked via inventory | +| pulumi-vsphere | existing cases + nonempty exports | + +## What runs + +| Case | Layer | Notes | +|------|-------|-------| +| `PU-INV` | pulumi-vsphere | Inventory data sources | +| `PU-FOLDER` | pulumi-vsphere | Folder create/destroy | +| `PU-VM` | pulumi-vsphere | VirtualMachine create/destroy | +| `PU-TAG` | pulumi-vsphere | TagCategory + Tag | +| `PU-REST` | REST matrix | `IMPLEMENTED` × majors 6–9 (smoke: major 9 only) | +| `PU-CRUD` | REST CRUD | Session, folder, tagging, content library, VM | +| `PU-SOAP` | SOAP | All WSDL ops | + +Artifacts: HTML + JSON + JUnit under the `lab-reports` volume. JSON includes +`rest.total` / `rest.failed`, `crud.failed`, `soap.failed`. + +## Quick start + +From the **repo root**: + +```bash +make pulumi-tests # full hybrid suite +make pulumi-tests-smoke # PU-INV + one-major REST smoke +``` + +Or from this directory: + +```bash +cd pulumi-tests +make up +make test-pulumi # or: make test-pulumi-smoke +``` + +Gateway (in-compose): `https://api-gateway` (host map `127.0.0.1:18443`). +Seed profile: `small` → `Datacenter` / `Cluster` / `datastore1` / `VM Network` / +`web-01` / `esxi01.lab.local` / `/Datacenter/vm/production`. + +## Make targets + +| Target | Meaning | +|--------|---------| +| `make test-pulumi` / `pulumi-tests` | Full hybrid: pulumi-vsphere + REST×6–9 + CRUD + SOAP | +| `make test-pulumi-smoke` | `PU-INV` + REST major-9 smoke (no VM/tags/CRUD/SOAP) | +| `make up` / `down` / `seed` | Lab stack lifecycle | + +## Layout + +``` +pulumi-tests/ + run_suite.py # Automation API + REST/SOAP probes + report_html.py + lib/assert_nonempty.py + lib/rest_matrix.py # IMPLEMENTED × majors + lib/rest_crud.py # deep create/read/update/delete + lib/soap_ops.py # WSDL SOAP ops + programs/inventory/ + programs/folders/ + programs/vm_lifecycle/ + programs/tags/ + docker/Dockerfile.pulumi-runner + docker-compose.yml +``` + +`PYTHONPATH` mounts `/workspace` so probes import `app.vsphere.*` coverage/matrix. diff --git a/pulumi-tests/README.ru.md b/pulumi-tests/README.ru.md new file mode 100644 index 0000000..ed2619b --- /dev/null +++ b/pulumi-tests/README.ru.md @@ -0,0 +1,78 @@ +# Гибридный lab-набор pulumi для vmware-api-simulator + +Гибрид под `pulumi-tests/`: + +1. Официальный [`pulumi-vsphere`](https://www.pulumi.com/registry/packages/vsphere/) (SOAP/VIM через govmomi) +2. Полная REST-матрица `IMPLEMENTED` × majors **6–9** (deep + stub) +3. Deep REST CRUD (session / folder / tag / content library / VM) +4. Все SOAP-операции из `/sdk/vimService.wsdl` + +Одним `pulumi-vsphere` закрыть ~1092 REST `verb×path` нельзя — HTTP-матрица обязательна для полной уверенности. + +## Критерии pass + +| Класс | Правило | +|-------|---------| +| REST GET (inventory / deep) | 2xx, непустое тело, без `"stub": true` на critical-путях major 9 | +| REST stubs (universe) | нет 5xx/501; ответ есть; в отчёте как `stub` (не durable CRUD) | +| REST deep CRUD | create → GET nonempty → update (если есть) → delete → GET missing | +| SOAP WSDL (~45) | POST `/sdk` без 5xx; Create/Power/Clone/Destroy — проверка inventory | +| pulumi-vsphere | существующие кейсы + nonempty export’ы | + +## Что запускается + +| Кейс | Слой | Заметки | +|------|------|---------| +| `PU-INV` | pulumi-vsphere | Inventory data sources | +| `PU-FOLDER` | pulumi-vsphere | Folder create/destroy | +| `PU-VM` | pulumi-vsphere | VirtualMachine create/destroy | +| `PU-TAG` | pulumi-vsphere | TagCategory + Tag | +| `PU-REST` | REST matrix | `IMPLEMENTED` × majors 6–9 (smoke: только major 9) | +| `PU-CRUD` | REST CRUD | Session, folder, tagging, content library, VM | +| `PU-SOAP` | SOAP | Все WSDL ops | + +Артефакты: HTML + JSON + JUnit в volume `lab-reports`. В JSON: +`rest.total` / `rest.failed`, `crud.failed`, `soap.failed`. + +## Быстрый старт + +Из **корня репозитория**: + +```bash +make pulumi-tests # полный гибрид +make pulumi-tests-smoke # PU-INV + REST smoke на одном major +``` + +Или из этой директории: + +```bash +cd pulumi-tests +make up +make test-pulumi # или: make test-pulumi-smoke +``` + +Шлюз (в compose): `https://api-gateway` (с хоста `127.0.0.1:18443`). +Seed-профиль: `small` → `Datacenter` / `Cluster` / `datastore1` / `VM Network` / +`web-01` / `esxi01.lab.local` / `/Datacenter/vm/production`. + +## Цели Make + +| Цель | Смысл | +|------|--------| +| `make test-pulumi` / `pulumi-tests` | Полный гибрид: pulumi-vsphere + REST×6–9 + CRUD + SOAP | +| `make test-pulumi-smoke` | `PU-INV` + REST major-9 smoke (без VM/tags/CRUD/SOAP) | +| `make up` / `down` / `seed` | Жизненный цикл lab-стека | + +## Структура + +``` +pulumi-tests/ + run_suite.py + report_html.py + lib/rest_matrix.py + lib/rest_crud.py + lib/soap_ops.py + programs/... +``` + +`PYTHONPATH` монтирует `/workspace` для импорта `app.vsphere.*`. diff --git a/pulumi-tests/docker-compose.yml b/pulumi-tests/docker-compose.yml new file mode 100644 index 0000000..6d4be27 --- /dev/null +++ b/pulumi-tests/docker-compose.yml @@ -0,0 +1,168 @@ +# pulumi-vsphere lab suite against vmware-api-simulator. +# Usage: +# cd pulumi-tests && make up && make test-pulumi +# make pulumi-tests # from repo root +name: vmware-pulumi-tests + +networks: + lab: + driver: bridge + +volumes: + lab-postgres-data: + lab-reports: + +x-vsphere-env: &vsphere-env + VSPHERE_USER: administrator@vsphere.local + VSPHERE_PASSWORD: "VMware1!" + VSPHERE_SERVER: api-gateway + VSPHERE_BASE: https://api-gateway + VSPHERE_DATACENTER: Datacenter + VSPHERE_DATASTORE: datastore1 + VSPHERE_CLUSTER: Cluster + VSPHERE_NETWORK: VM Network + VSPHERE_VM_NAME: web-01 + VSPHERE_HOST: esxi01.lab.local + VSPHERE_FOLDER_PATH: /Datacenter/vm/production + VSPHERE_RESOURCE_POOL: Resources + REPORT_DIR: /reports + REPORT_PATH: /reports/pulumi-junit.xml + HTML_REPORT_PATH: /reports/pulumi-report.html + JSON_REPORT_PATH: /reports/pulumi-summary.json + PULUMI_CONFIG_PASSPHRASE: lab + PULUMI_BACKEND_URL: file:///tmp/pulumi-state + +x-sim-env: &sim-env + DATABASE_URL: postgresql://vmware:vmware@postgres:5432/vmware_simulator + ENABLE_PVE_STUB: "false" + SEED_VSPHERE_PROFILE: small + LOG_LEVEL: INFO + TICKET_SIGNING_KEY: lab-signing-key + APP_PORT: "8080" + +services: + postgres: + image: postgres:17.5-bookworm + networks: [lab] + environment: + POSTGRES_DB: vmware_simulator + POSTGRES_USER: vmware + POSTGRES_PASSWORD: vmware + volumes: + - lab-postgres-data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U vmware -d vmware_simulator"] + interval: 5s + timeout: 3s + retries: 20 + + migrate: + build: + context: .. + dockerfile: Dockerfile + target: runtime + networks: [lab] + working_dir: /workspace + volumes: + - ..:/workspace + environment: + <<: *sim-env + PYTHONPATH: /workspace + depends_on: + postgres: + condition: service_healthy + entrypoint: ["python"] + command: ["-m", "app.db.migrate_cli"] + restart: "no" + + simulator: + build: + context: .. + dockerfile: Dockerfile + target: dev + networks: [lab] + working_dir: /workspace + volumes: + - ..:/workspace + environment: + <<: *sim-env + PYTHONPATH: /workspace + depends_on: + migrate: + condition: service_completed_successfully + entrypoint: [] + command: + [ + "uvicorn", + "app.main:app", + "--host", + "0.0.0.0", + "--port", + "8080", + "--reload", + "--reload-dir", + "/workspace/app", + ] + healthcheck: + test: + [ + "CMD", + "python", + "-c", + "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/health/ready', timeout=2)", + ] + interval: 5s + timeout: 3s + retries: 30 + start_period: 15s + + seed: + build: + context: .. + dockerfile: Dockerfile + target: runtime + networks: [lab] + working_dir: /workspace + volumes: + - ..:/workspace + environment: + <<: *sim-env + PYTHONPATH: /workspace + depends_on: + simulator: + condition: service_healthy + entrypoint: ["python"] + command: ["-m", "app.simulation.seed_cli"] + restart: "no" + + api-gateway: + image: nginx:1.28-alpine + networks: [lab] + depends_on: + simulator: + condition: service_healthy + volumes: + - ../docker/gateway/vmware-ports.conf:/etc/nginx/conf.d/default.conf:ro + - ../docker/tls/server.crt:/etc/nginx/tls/server.crt:ro + - ../docker/tls/server.key:/etc/nginx/tls/server.key:ro + ports: + - "127.0.0.1:18443:443" + + pulumi-runner: + build: + context: . + dockerfile: docker/Dockerfile.pulumi-runner + networks: [lab] + working_dir: /suite + volumes: + - ./:/suite + - ..:/workspace:ro + - lab-reports:/reports + environment: + <<: *vsphere-env + depends_on: + seed: + condition: service_completed_successfully + api-gateway: + condition: service_started + profiles: ["test"] diff --git a/pulumi-tests/docker/Dockerfile.pulumi-runner b/pulumi-tests/docker/Dockerfile.pulumi-runner new file mode 100644 index 0000000..b09c786 --- /dev/null +++ b/pulumi-tests/docker/Dockerfile.pulumi-runner @@ -0,0 +1,22 @@ +FROM python:3.13-slim + +RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates \ + && curl -fsSL https://get.pulumi.com | sh \ + && ln -s /root/.pulumi/bin/pulumi /usr/local/bin/pulumi \ + && mkdir -p /tmp/pulumi-state \ + && rm -rf /var/lib/apt/lists/* + +# Python SDK + official VMware provider (SOAP/VIM via govmomi) +RUN pip install --no-cache-dir \ + "pulumi>=3.120,<4" \ + "pulumi-vsphere==4.17.0" \ + && pulumi plugin install resource vsphere 4.17.0 + +WORKDIR /suite +ENV PYTHONPATH=/suite:/suite/lib:/workspace \ + PULUMI_CONFIG_PASSPHRASE=lab \ + PULUMI_BACKEND_URL=file:///tmp/pulumi-state \ + VSPHERE_SERVER=api-gateway \ + VSPHERE_ALLOW_UNVERIFIED_SSL=true + +CMD ["python3", "/suite/run_suite.py"] diff --git a/pulumi-tests/fixtures/config.env.example b/pulumi-tests/fixtures/config.env.example new file mode 100644 index 0000000..383fa7e --- /dev/null +++ b/pulumi-tests/fixtures/config.env.example @@ -0,0 +1,12 @@ +# Pulumi lab suite (compose). +VSPHERE_USER=administrator@vsphere.local +VSPHERE_PASSWORD=VMware1! +VSPHERE_SERVER=api-gateway +VSPHERE_DATACENTER=Datacenter +VSPHERE_DATASTORE=datastore1 +VSPHERE_CLUSTER=Cluster +VSPHERE_NETWORK=VM Network +VSPHERE_VM_NAME=web-01 +TEST_SMOKE=0 +TEST_RUN_ID= +PULUMI_CONFIG_PASSPHRASE=lab diff --git a/pulumi-tests/lib/__init__.py b/pulumi-tests/lib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pulumi-tests/lib/assert_nonempty.py b/pulumi-tests/lib/assert_nonempty.py new file mode 100644 index 0000000..8e31522 --- /dev/null +++ b/pulumi-tests/lib/assert_nonempty.py @@ -0,0 +1,32 @@ +"""Non-empty output validation for pulumi-vsphere stack results.""" + +from __future__ import annotations + +from typing import Any + + +def _is_empty(value: Any) -> bool: + if value is None: + return True + if isinstance(value, str) and not value.strip(): + return True + if isinstance(value, (list, dict, tuple, set)) and len(value) == 0: + return True + return False + + +def assert_nonempty(outputs: dict[str, Any], *, required: list[str] | None = None) -> list[str]: + """Return list of error messages for empty/missing outputs.""" + + errors: list[str] = [] + keys = required if required is not None else list(outputs) + if not keys: + errors.append("no outputs exported") + return errors + for key in keys: + if key not in outputs: + errors.append(f"missing output: {key}") + continue + if _is_empty(outputs[key]): + errors.append(f"empty output: {key}={outputs[key]!r}") + return errors diff --git a/pulumi-tests/lib/rest_crud.py b/pulumi-tests/lib/rest_crud.py new file mode 100644 index 0000000..1dbd4e2 --- /dev/null +++ b/pulumi-tests/lib/rest_crud.py @@ -0,0 +1,361 @@ +"""Deep REST CRUD battery: create → read → update → delete with nonempty checks. + +Covers session, folder, tagging, content library, and VM where durable handlers exist. +Fails if a deep handler returns a stub marker or empty body after a successful write. +""" + +from __future__ import annotations + +import json +import secrets +from typing import Any + +from rest_matrix import login, request + + +def _session_headers(session: str) -> dict[str, str]: + return { + "vmware-api-session-id": session, + "Content-Type": "application/json", + "Accept": "application/json", + } + + +def _parse(body: str) -> Any: + if not body or not body.strip(): + return None + try: + return json.loads(body) + except json.JSONDecodeError: + return body + + +def _is_stub(body: str) -> bool: + return '"stub": true' in body or '"stub":true' in body + + +def _fail(flow: str, step: str, detail: str) -> dict[str, Any]: + return {"flow": flow, "step": step, "status": "failed", "error": detail} + + +def _ok(flow: str, detail: str = "") -> dict[str, Any]: + return {"flow": flow, "step": "done", "status": "passed", "error": detail} + + +def _flow_session(headers: dict[str, str]) -> dict[str, Any]: + # Use a dedicated session so we can delete it without killing the suite session. + sid = login() + h = _session_headers(sid) + code, body = request("GET", "/api/session", headers=h) + if code != 200: + return _fail("session", "get", f"GET /api/session → {code} {body[:120]}") + if _is_stub(body): + return _fail("session", "get", "stub marker on session GET") + code, body = request("DELETE", "/api/session", headers=h) + if code not in {200, 204}: + return _fail("session", "delete", f"DELETE /api/session → {code} {body[:120]}") + code, body = request("GET", "/api/session", headers=h) + if code not in {401, 403, 404}: + return _fail("session", "gone", f"expected auth failure after delete, got {code}") + del headers # suite session untouched + return _ok("session") + + +def _flow_folder(headers: dict[str, str]) -> dict[str, Any]: + suffix = secrets.token_hex(3) + name = f"crud-folder-{suffix}" + renamed = f"crud-folder-renamed-{suffix}" + code, body = request( + "POST", + "/api/vcenter/folder", + headers=headers, + data=json.dumps({"name": name, "parent": "group-v23"}).encode(), + ) + if code not in {200, 201}: + return _fail("folder", "create", f"{code} {body[:160]}") + if _is_stub(body): + return _fail("folder", "create", "stub marker on create") + folder_id = _parse(body) + if not isinstance(folder_id, str) or not folder_id.strip(): + return _fail("folder", "create", f"empty folder id: {body[:160]}") + + code, body = request("GET", "/api/vcenter/folder", headers=headers) + if code != 200 or _is_stub(body): + return _fail("folder", "list", f"{code} stub={_is_stub(body)} {body[:120]}") + folders = _parse(body) or [] + names = {f.get("name") for f in folders if isinstance(f, dict)} + ids = {f.get("folder") for f in folders if isinstance(f, dict)} + if name not in names and folder_id not in ids: + return _fail("folder", "list", f"created folder not in list ({folder_id})") + + code, body = request( + "POST", + f"/api/vcenter/folder/{folder_id}?action=rename", + headers=headers, + data=json.dumps({"name": renamed}).encode(), + ) + if code not in {200, 204}: + return _fail("folder", "rename", f"{code} {body[:160]}") + + code, body = request("GET", "/api/vcenter/folder", headers=headers) + folders = _parse(body) or [] + names = {f.get("name") for f in folders if isinstance(f, dict)} + if renamed not in names: + return _fail("folder", "rename-verify", f"renamed name missing: {names}") + + code, body = request("DELETE", f"/api/vcenter/folder/{folder_id}", headers=headers) + if code not in {200, 204}: + return _fail("folder", "delete", f"{code} {body[:160]}") + + code, body = request("GET", f"/api/vcenter/folder/{folder_id}/children", headers=headers) + if code not in {404, 400}: + # children on missing folder should fail; also check list no longer has it + code2, body2 = request("GET", "/api/vcenter/folder", headers=headers) + folders = _parse(body2) or [] + ids = {f.get("folder") for f in folders if isinstance(f, dict)} + if folder_id in ids: + return _fail("folder", "gone", f"folder still listed after delete; children={code}") + return _ok("folder", folder_id) + + +def _flow_tagging(headers: dict[str, str]) -> dict[str, Any]: + suffix = secrets.token_hex(3) + code, body = request( + "POST", + "/api/cis/tagging/category", + headers=headers, + data=json.dumps( + { + "create_spec": { + "name": f"crud-cat-{suffix}", + "description": "crud", + "cardinality": "MULTIPLE", + "associable_types": ["VirtualMachine"], + } + } + ).encode(), + ) + if code not in {200, 201}: + return _fail("tagging", "create-category", f"{code} {body[:160]}") + if _is_stub(body): + return _fail("tagging", "create-category", "stub marker") + cat_id = _parse(body) + if not isinstance(cat_id, str) or not cat_id: + return _fail("tagging", "create-category", f"empty id: {body[:120]}") + + code, body = request("GET", f"/api/cis/tagging/category/{cat_id}", headers=headers) + if code != 200 or _is_stub(body): + return _fail("tagging", "get-category", f"{code} {body[:160]}") + cat = _parse(body) + if not isinstance(cat, dict) or not cat.get("name"): + return _fail("tagging", "get-category", f"empty category body: {body[:160]}") + + code, body = request( + "POST", + "/api/cis/tagging/tag", + headers=headers, + data=json.dumps( + { + "create_spec": { + "name": f"crud-tag-{suffix}", + "category_id": cat_id, + "description": "before", + } + } + ).encode(), + ) + if code not in {200, 201}: + return _fail("tagging", "create-tag", f"{code} {body[:160]}") + tag_id = _parse(body) + if not isinstance(tag_id, str) or not tag_id: + return _fail("tagging", "create-tag", f"empty tag id: {body[:120]}") + + code, body = request("GET", f"/api/cis/tagging/tag/{tag_id}", headers=headers) + if code != 200 or _is_stub(body): + return _fail("tagging", "get-tag", f"{code} {body[:160]}") + tag = _parse(body) + if not isinstance(tag, dict) or tag.get("name") != f"crud-tag-{suffix}": + return _fail("tagging", "get-tag", f"unexpected tag: {body[:160]}") + + # No PATCH on tagging in CORE — create/read/delete is the durable contract. + code, body = request("DELETE", f"/api/cis/tagging/tag/{tag_id}", headers=headers) + if code not in {200, 204}: + return _fail("tagging", "delete-tag", f"{code} {body[:160]}") + code, body = request("GET", f"/api/cis/tagging/tag/{tag_id}", headers=headers) + if code not in {404, 400}: + return _fail("tagging", "tag-gone", f"expected 404, got {code}") + + code, body = request("DELETE", f"/api/cis/tagging/category/{cat_id}", headers=headers) + if code not in {200, 204}: + return _fail("tagging", "delete-category", f"{code} {body[:160]}") + code, body = request("GET", f"/api/cis/tagging/category/{cat_id}", headers=headers) + if code not in {404, 400}: + return _fail("tagging", "category-gone", f"expected 404, got {code}") + return _ok("tagging", f"{cat_id}/{tag_id}") + + +def _flow_content_library(headers: dict[str, str]) -> dict[str, Any]: + suffix = secrets.token_hex(3) + code, body = request( + "POST", + "/api/content/local-library", + headers=headers, + data=json.dumps( + {"create_spec": {"name": f"crud-lib-{suffix}", "description": "crud"}} + ).encode(), + ) + if code not in {200, 201}: + return _fail("content-library", "create-library", f"{code} {body[:160]}") + if _is_stub(body): + return _fail("content-library", "create-library", "stub marker") + lib_id = _parse(body) + if not isinstance(lib_id, str) or not lib_id: + return _fail("content-library", "create-library", f"empty id: {body[:120]}") + + code, body = request("GET", "/api/content/library", headers=headers) + if code != 200 or _is_stub(body): + return _fail("content-library", "list-libraries", f"{code} {body[:160]}") + libs = _parse(body) or [] + if lib_id not in libs: + return _fail("content-library", "list-libraries", f"{lib_id} not in {libs!r}") + + code, body = request( + "POST", + "/api/content/library/item", + headers=headers, + data=json.dumps( + { + "create_spec": { + "library_id": lib_id, + "name": f"crud-item-{suffix}", + "type": "ovf", + "description": "crud-item", + } + } + ).encode(), + ) + if code not in {200, 201}: + return _fail("content-library", "create-item", f"{code} {body[:160]}") + item_id = _parse(body) + if not isinstance(item_id, str) or not item_id: + return _fail("content-library", "create-item", f"empty item id: {body[:120]}") + + code, body = request( + "GET", + f"/api/content/library/item?library_id={lib_id}", + headers=headers, + ) + if code != 200 or _is_stub(body): + return _fail("content-library", "list-items", f"{code} {body[:160]}") + items = _parse(body) or [] + if item_id not in items: + return _fail("content-library", "list-items", f"{item_id} not in {items!r}") + return _ok("content-library", f"{lib_id}/{item_id}") + + +def _flow_vm(headers: dict[str, str]) -> dict[str, Any]: + suffix = secrets.token_hex(3) + name = f"crud-vm-{suffix}" + code, body = request( + "POST", + "/api/vcenter/vm", + headers=headers, + data=json.dumps( + { + "name": name, + "placement": { + "folder": "group-v23", + "host": "host-11", + "datastore": "datastore-31", + "resource_pool": "resgroup-22", + }, + "cpu_count": 1, + "memory_size_MiB": 512, + } + ).encode(), + ) + if code not in {200, 201}: + return _fail("vm", "create", f"{code} {body[:160]}") + if _is_stub(body): + return _fail("vm", "create", "stub marker") + vm_id = _parse(body) + if not isinstance(vm_id, str) or not vm_id.startswith("vm-"): + return _fail("vm", "create", f"bad vm id: {body[:120]}") + + code, body = request("GET", f"/api/vcenter/vm/{vm_id}", headers=headers) + if code != 200 or _is_stub(body): + return _fail("vm", "get", f"{code} {body[:160]}") + info = _parse(body) + if not isinstance(info, dict) or not info: + return _fail("vm", "get", f"empty vm info: {body[:160]}") + + code, body = request( + "PATCH", + f"/api/vcenter/vm/{vm_id}/hardware/cpu", + headers=headers, + data=json.dumps({"count": 2}).encode(), + ) + if code not in {200, 204}: + return _fail("vm", "patch-cpu", f"{code} {body[:160]}") + + code, body = request("GET", f"/api/vcenter/vm/{vm_id}/hardware/cpu", headers=headers) + if code != 200 or _is_stub(body): + return _fail("vm", "get-cpu", f"{code} {body[:160]}") + cpu = _parse(body) + count = None + if isinstance(cpu, dict): + count = cpu.get("count") or cpu.get("num_cpus") or cpu.get("numCPUs") + if count is not None and int(count) != 2: + return _fail("vm", "patch-verify", f"cpu count={count!r} after patch") + + # Ensure powered off before delete. + code, body = request("GET", f"/api/vcenter/vm/{vm_id}/power", headers=headers) + power = _parse(body) if code == 200 else {} + state = "" + if isinstance(power, dict): + state = str(power.get("state") or power.get("power_state") or "") + if state.upper() in {"POWERED_ON", "ON"}: + request( + "POST", + f"/api/vcenter/vm/{vm_id}/power?action=stop", + headers=headers, + data=b"{}", + ) + + code, body = request("DELETE", f"/api/vcenter/vm/{vm_id}", headers=headers) + if code not in {200, 204}: + return _fail("vm", "delete", f"{code} {body[:160]}") + code, body = request("GET", f"/api/vcenter/vm/{vm_id}", headers=headers) + if code not in {404, 400}: + return _fail("vm", "gone", f"expected 404 after delete, got {code}") + return _ok("vm", vm_id) + + +def run_rest_crud() -> dict[str, Any]: + """Run curated deep CRUD flows. Returns suite-ready summary.""" + + session = login() + headers = _session_headers(session) + flows = [ + _flow_session, + _flow_folder, + _flow_tagging, + _flow_content_library, + _flow_vm, + ] + results: list[dict[str, Any]] = [] + for flow in flows: + # Refresh session in case a prior flow touched auth edges. + if flow is not _flow_session: + session = login() + headers = _session_headers(session) + results.append(flow(headers)) + + failed = [r for r in results if r.get("status") == "failed"] + return { + "flows": results, + "total": len(results), + "failed": len(failed), + "failures": failed, + "ok": not failed, + } diff --git a/pulumi-tests/lib/rest_matrix.py b/pulumi-tests/lib/rest_matrix.py new file mode 100644 index 0000000..31b0702 --- /dev/null +++ b/pulumi-tests/lib/rest_matrix.py @@ -0,0 +1,497 @@ +"""Full REST verb×path×majors matrix for pulumi-tests (hybrid suite). + +Reuses path substitution / session patterns from scripts/vsphere_full_matrix_probe.py. +Pass rules match that probe: no 5xx/501; inventory GETs nonempty + non-stub on major 9. +""" + +from __future__ import annotations + +import json +import os +import re +import secrets +import ssl +import urllib.error +import urllib.request +from base64 import b64encode +from collections import Counter +from typing import Any +from urllib.parse import urlencode + +from app.vsphere.contracts.matrix import VERSIONS, catalog_entries_for_major, methods_for_major +from app.vsphere.rest.coverage import CORE_IMPLEMENTED, IMPLEMENTED + +_PATH_SUBS = { + "{vm}": "vm-101", + "{host}": "host-11", + "{datastore}": "datastore-31", + "{task}": "task-1", + "{snapshot}": "snapshot-missing", + "{category_id}": "cat-lab-1", + "{tag_id}": "tag-lab-1", + "{item_id}": "item-ubuntu", + "{library_id}": "lib-local-1", + "{folder}": "group-v23", + "{datacenter}": "datacenter-21", + "{cluster}": "domain-c21", + "{resource_pool}": "resgroup-22", + "{permission_id}": "999999", + "{policy}": "policy-default", + "{disk}": "2000", + "{nic}": "4000", + "{cdrom}": "3000", + "{floppy}": "8000", + "{port}": "9000", + "{adapter}": "1000", + "{provider}": "vsphere.local", + "{supervisor}": "supervisor-1", + "{namespace}": "ns-lab-1", + "{role}": "ReadOnly", + "{zone}": "zone-1", + "{project}": "project-1", + "{domain}": "lab.local", + "{service}": "vsphere-ui", + "{depot}": "depot-1", + "{component}": "component-1", + "{image}": "image-1", + "{draft}": "draft-1", + "{connection}": "connection-1", + "{vpc}": "vpc-1", + "{subnet}": "subnet-1", + "{session_id}": "session-lab-1", + "{download_session_id}": "session-lab-1", + "{update_session_id}": "session-lab-1", + "{subscription_id}": "sub-1", + "{usage_id}": "usage-1", + "{version}": "1", + "{chain}": "chain-1", + "{node}": "node-1", + "{profile}": "profile-1", + "{interface}": "nic0", + "{core}": "core-1", + "{network}": "network-41", + "{commit}": "commit-lab-1", +} + +_ACCEPT_CLIENT = {400, 401, 403, 404, 405, 409, 412, 422} + +_INVENTORY_CRITICAL = { + "/api/vcenter/vm", + "/api/vcenter/host", + "/api/vcenter/datastore", + "/api/vcenter/network", + "/api/vcenter/cluster", + "/api/cis/tagging/category", + "/api/content/library", + "/api/esx/settings/clusters/{cluster}/software", + "/api/vcenter/namespace-management/supervisors/{supervisor}/summary", + "/api/appliance/access/ssh", + "/api/appliance/services", +} + + +def _base() -> str: + explicit = os.environ.get("VSPHERE_BASE") + if explicit: + return explicit.rstrip("/") + server = os.environ.get("VSPHERE_SERVER", "localhost") + if server.startswith("http://") or server.startswith("https://"): + return server.rstrip("/") + return f"https://{server}" + + +def _creds() -> tuple[str, str]: + return ( + os.environ.get("VSPHERE_USER", "administrator@vsphere.local"), + os.environ.get("VSPHERE_PASSWORD", "VMware1!"), + ) + + +def _ctx() -> ssl.SSLContext | None: + if not _base().startswith("https://"): + return None + return ssl._create_unverified_context() # noqa: S323 + + +def concrete_path(path: str) -> str: + out = path + for key, value in _PATH_SUBS.items(): + out = out.replace(key, value) + return re.sub(r"\{([A-Za-z0-9_]+)\}", r"probe-\1", out) + + +def request( + method: str, + path: str, + *, + headers: dict[str, str], + data: bytes | None = None, +) -> tuple[int, str]: + # Paths may already include query strings from _payload_for. + if "?" in path: + base_path, query = path.split("?", 1) + url = f"{_base()}{concrete_path(base_path)}?{query}" + else: + url = f"{_base()}{concrete_path(path)}" + req = urllib.request.Request(url, data=data, method=method, headers=headers) + try: + with urllib.request.urlopen(req, context=_ctx(), timeout=120) as resp: # noqa: S310 + body = resp.read().decode("utf-8", errors="replace") + return int(resp.status), body + except urllib.error.HTTPError as error: + body = error.read().decode("utf-8", errors="replace") + return int(error.code), body + + +def login() -> str: + user, password = _creds() + basic = b64encode(f"{user}:{password}".encode()).decode() + code, body = request("POST", "/api/session", headers={"Authorization": f"Basic {basic}"}) + if code not in {200, 201}: + raise RuntimeError(f"session failed: {code} {body[:200]}") + return json.loads(body) + + +def _payload_for(verb: str, path: str) -> tuple[str, bytes | None]: + if verb not in {"POST", "PUT", "PATCH"}: + return path, None + + if path.endswith("/power") and verb == "POST": + if "/guest/power" in path: + return f"{path}?action=reboot", b"{}" + return f"{path}?action=start", b"{}" + + if path.endswith("/maintenance") and verb == "POST": + return f"{path}?action=enter", b"{}" + + if path.endswith("/folder/{folder}") and verb == "POST": + return f"{path}?action=rename", json.dumps({"name": "folder-renamed-probe"}).encode() + + suffix = secrets.token_hex(4) + bodies: dict[str, dict[str, Any]] = { + "/api/vcenter/vm": { + "name": f"matrix-probe-vm-{suffix}", + "placement": {"folder": "group-v23", "host": "host-11", "datastore": "datastore-31"}, + "cpu_count": 1, + "memory_size_MiB": 512, + }, + "/api/vcenter/datacenter": {"name": f"probe-dc-{suffix}"}, + "/api/vcenter/cluster": {"name": f"probe-cluster-{suffix}"}, + "/api/vcenter/folder": {"name": f"probe-folder-{suffix}", "parent": "group-v23"}, + "/api/vcenter/resource-pool": {"name": f"probe-rp-{suffix}", "parent": "resgroup-22"}, + "/api/vcenter/network/dvs": {"name": f"probe-dvs-{suffix}"}, + "/api/vcenter/network/dvpg": { + "name": f"probe-dvpg-{suffix}", + "dvs": "dvs-51", + "vlan_id": 10, + }, + "/api/cis/tagging/category": { + "create_spec": { + "name": f"probe-cat-{suffix}", + "description": "probe", + "cardinality": "MULTIPLE", + "associable_types": [], + } + }, + "/api/cis/tagging/tag": { + "create_spec": { + "name": f"probe-tag-{suffix}", + "category_id": "missing-category", + "description": "x", + } + }, + "/api/cis/tagging/tag-association": { + "action": "list-attached-tags", + "tag_id": "x", + "object_id": {"type": "VirtualMachine", "id": "vm-101"}, + }, + "/api/content/local-library": {"create_spec": {"name": f"probe-lib-{suffix}"}}, + "/api/content/library/item": { + "create_spec": { + "library_id": "lib-missing", + "name": f"probe-item-{suffix}", + "type": "ovf", + } + }, + "/api/vcenter/ovf/library-item/{item_id}": { + "deployment_spec": {"name": f"ovf-probe-{suffix}"}, + "target": {"folder": "group-v23", "host": "host-11", "datastore": "datastore-31"}, + }, + "/api/vcenter/authorization/permissions": { + "principal": "readonly@vsphere.local", + "role": "ReadOnly", + "entity": "datacenter-21", + }, + "/api/vcenter/datastore/{datastore}/files": { + "path": f"/probe-{suffix}.txt", + "size": 1, + "type": "FILE", + }, + "/api/vcenter/vm/{vm}/hardware/cpu": {"count": 2}, + "/api/vcenter/vm/{vm}/hardware/memory": {"size_MiB": 1024}, + "/api/vcenter/vm/{vm}/hardware/disk": {"type": "SCSI", "new_vmdk": {"capacity": 1024}}, + "/api/vcenter/vm/{vm}/hardware/ethernet": { + "type": "VMXNET3", + "backing": {"type": "STANDARD_PORTGROUP", "network": "network-41"}, + }, + "/api/vcenter/vm/{vm}/snapshots": {"name": f"probe-snap-{suffix}"}, + "/api/vcenter/vm/{vm}/snapshots/{snapshot}": {"action": "revert"}, + "/api/vcenter/vm/{vm}/clone": { + "name": f"probe-clone-{suffix}", + "placement": {"folder": "group-v23", "host": "host-11"}, + }, + "/api/vcenter/vm/{vm}/relocate": {"placement": {"host": "host-12"}}, + "/api/vcenter/vm/{vm}/tools": {"action": "upgrade"}, + "/api/vcenter/vm/{vm}/console/tickets": {"type": "WEBMKS"}, + "/api/vcenter/vm/{vm}/guest/customization": {"name": {"name": f"guest-probe-{suffix}"}}, + "/api/vcenter/vm/{vm}": {"action": "unregister"}, + } + body = bodies.get(path, {}) + return path, json.dumps(body).encode() + + +def apply_major(major: int, headers: dict[str, str]) -> dict[str, Any]: + params = urlencode({"major": major}) + code, body = request( + "POST", + f"/ui/api/contract/apply?{params}", + headers=headers, + ) + if code >= 400: + raise RuntimeError(f"contract apply major={major} failed: {code} {body[:200]}") + return json.loads(body) + + +def _classify(verb: str, path: str) -> str: + status = CORE_IMPLEMENTED.get((verb, path)) or IMPLEMENTED.get((verb, path)) + if (verb, path) in CORE_IMPLEMENTED: + return "deep" + if status == "stub": + return "stub" + return "deep" if status == "implemented" else "unknown" + + +def _record_result( + *, + major: int, + verb: str, + path: str, + code: int, + body: str, + buckets: Counter[str], + failures: list[dict[str, Any]], + deep_stub: Counter[str], +) -> None: + kind = _classify(verb, path) + deep_stub[kind] += 1 + if 200 <= code < 300: + buckets["success_2xx"] += 1 + if kind == "stub": + buckets["stub_ok"] += 1 + if major == 9 and verb == "GET" and body: + if '"stub": true' in body or '"stub":true' in body: + if path in _INVENTORY_CRITICAL or kind == "deep": + buckets["stub_marker"] += 1 + failures.append( + { + "major": major, + "verb": verb, + "path": path, + "kind": kind, + "status": code, + "body": body[:200], + "expected": "non-stub JSON", + } + ) + elif path in _INVENTORY_CRITICAL: + try: + parsed = json.loads(body) + except json.JSONDecodeError: + parsed = None + empty = parsed in ([], {}, None, "") + if empty: + buckets["empty_inventory"] += 1 + failures.append( + { + "major": major, + "verb": verb, + "path": path, + "kind": kind, + "status": code, + "body": body[:200], + "expected": "non-empty seeded data", + } + ) + elif code in _ACCEPT_CLIENT: + buckets["client_4xx"] += 1 + elif code == 501: + buckets["unexpected_501"] += 1 + failures.append( + { + "major": major, + "verb": verb, + "path": path, + "kind": kind, + "status": code, + "body": body[:200], + } + ) + elif code >= 500: + buckets["server_5xx"] += 1 + failures.append( + { + "major": major, + "verb": verb, + "path": path, + "kind": kind, + "status": code, + "body": body[:200], + } + ) + else: + buckets[f"other_{code}"] += 1 + failures.append( + { + "major": major, + "verb": verb, + "path": path, + "kind": kind, + "status": code, + "body": body[:200], + } + ) + + +def probe_major(major: int, session: str) -> dict[str, Any]: + headers = { + "vmware-api-session-id": session, + "Content-Type": "application/json", + "Accept": "application/json", + } + applied = apply_major(major, headers) + active = methods_for_major(major) + verb_order = {"GET": 0, "PUT": 1, "PATCH": 2, "POST": 3, "DELETE": 4} + entries = sorted( + catalog_entries_for_major(major), + key=lambda e: (verb_order.get(e["verb"], 9), e["path"]), + ) + + buckets: Counter[str] = Counter() + deep_stub: Counter[str] = Counter() + failures: list[dict[str, Any]] = [] + probed = 0 + by_verb: Counter[str] = Counter() + + for entry in entries: + verb = entry["verb"] + path = entry["path"] + by_verb[verb] += 1 + if verb == "DELETE" and path in {"/api/session", "/rest/com/vmware/cis/session"}: + continue + if verb == "DELETE" and path in { + "/api/vcenter/datacenter/{datacenter}", + "/api/vcenter/cluster/{cluster}", + "/api/vcenter/folder/{folder}", + "/api/vcenter/resource-pool/{resource_pool}", + "/api/vcenter/vm/{vm}", + }: + if path.endswith("{vm}"): + url_path = path.replace("{vm}", "vm-missing-matrix") + elif path.endswith("{datacenter}"): + url_path = path.replace("{datacenter}", "dc-missing") + elif path.endswith("{cluster}"): + url_path = path.replace("{cluster}", "cluster-missing") + elif path.endswith("{folder}"): + url_path = path.replace("{folder}", "folder-missing") + else: + url_path = path.replace("{resource_pool}", "rp-missing") + code, body = request(verb, url_path, headers=headers) + else: + url_path, data = _payload_for(verb, path) + if verb == "GET" and path == "/api/content/library/item": + url_path = f"{url_path}?library_id=lib-local-1" + code, body = request(verb, url_path, headers=headers, data=data) + + probed += 1 + _record_result( + major=major, + verb=verb, + path=path, + code=code, + body=body, + buckets=buckets, + failures=failures, + deep_stub=deep_stub, + ) + + above_floor = 0 + for (verb, path), _status in sorted(IMPLEMENTED.items()): + if (verb, path) in active: + continue + if verb == "DELETE" and path in {"/api/session", "/rest/com/vmware/cis/session"}: + continue + url_path, data = _payload_for(verb, path) + code, body = request(verb, url_path, headers=headers, data=data) + above_floor += 1 + probed += 1 + by_verb[verb] += 1 + _record_result( + major=major, + verb=verb, + path=path, + code=code, + body=body, + buckets=buckets, + failures=failures, + deep_stub=deep_stub, + ) + + return { + "major": major, + "version": applied.get("runtime_version"), + "method_count": len(entries), + "by_verb": dict(by_verb), + "probed": probed, + "above_floor_checked": above_floor, + "buckets": dict(buckets), + "deep_vs_stub": dict(deep_stub), + "failures": failures, + "failed": len(failures), + } + + +def run_rest_matrix(*, majors: list[int] | None = None) -> dict[str, Any]: + """Probe IMPLEMENTED × majors. Returns summary suitable for suite JSON/HTML.""" + + if majors is None: + majors = [6, 7, 8, 9] + for major in majors: + if major not in VERSIONS: + raise ValueError(f"unknown major {major}") + + session = login() + reports: list[dict[str, Any]] = [] + all_failures: list[dict[str, Any]] = [] + verb_totals: Counter[str] = Counter() + + for major in majors: + report = probe_major(major, session) + reports.append(report) + all_failures.extend(report["failures"]) + for verb, count in report["by_verb"].items(): + verb_totals[verb] += count + session = login() + + apply_major(9, {"vmware-api-session-id": session, "Content-Type": "application/json"}) + + total = sum(r["probed"] for r in reports) + failed = len(all_failures) + return { + "base": _base(), + "majors": reports, + "by_verb": dict(verb_totals), + "total": total, + "failed": failed, + "failures": all_failures[:120], + "ok": failed == 0, + } diff --git a/pulumi-tests/lib/soap_ops.py b/pulumi-tests/lib/soap_ops.py new file mode 100644 index 0000000..cd3b203 --- /dev/null +++ b/pulumi-tests/lib/soap_ops.py @@ -0,0 +1,648 @@ +"""SOAP WSDL ops probe for pulumi-tests hybrid suite. + +Covers every operation advertised in /sdk/vimService.wsdl (same list as +app/vsphere/soap/router.py). Fail on HTTP 5xx. Create/Power/Clone/Reconfig/Destroy +ops additionally assert task return + inventory side-effects via FindByInventoryPath +or RetrieveProperties where applicable. +""" + +from __future__ import annotations + +import os +import re +import secrets +import ssl +import urllib.error +import urllib.request +from typing import Any +from xml.sax.saxutils import escape + +# Keep in sync with app/vsphere/soap/router.py sdk_wsdl ops list. +WSDL_OPS: list[str] = [ + "RetrieveServiceContent", + "Login", + "Logout", + "RetrieveProperties", + "RetrievePropertiesEx", + "ContinueRetrievePropertiesEx", + "CreateFilter", + "WaitForUpdatesEx", + "CreateContainerView", + "DestroyPropertyFilter", + "FindByInventoryPath", + "FindByUuid", + "FindByDnsName", + "FindByIp", + "FindChild", + "CreateVM_Task", + "CreateChildVM_Task", + "CreateFolder", + "PowerOnVM_Task", + "PowerOffVM_Task", + "CloneVM_Task", + "CreateSnapshot_Task", + "Rename_Task", + "ReconfigVM_Task", + "RelocateVM_Task", + "Destroy_Task", + "CustomizeVM_Task", + "CancelTask", + "CurrentTime", + "InitiateFileTransferToGuest", + "InitiateFileTransferFromGuest", + "ListFilesInGuest", + "DeleteFileInGuest", + "MakeDirectoryInGuest", + "ImportVApp_Task", + "CreateImportSpec", + "HttpNfcLeaseComplete", + "HttpNfcLeaseProgress", + "HttpNfcLeaseAbort", + "HttpNfcLeaseGetManifest", + "QueryConfigOption", + "QueryConfigOptionEx", + "QueryConfigOptionDescriptor", + "QueryConfigTarget", +] + + +def _base() -> str: + explicit = os.environ.get("VSPHERE_BASE") + if explicit: + return explicit.rstrip("/") + server = os.environ.get("VSPHERE_SERVER", "localhost") + if server.startswith("http://") or server.startswith("https://"): + return server.rstrip("/") + return f"https://{server}" + + +def _creds() -> tuple[str, str]: + return ( + os.environ.get("VSPHERE_USER", "administrator@vsphere.local"), + os.environ.get("VSPHERE_PASSWORD", "VMware1!"), + ) + + +def _ctx() -> ssl.SSLContext | None: + if not _base().startswith("https://"): + return None + return ssl._create_unverified_context() # noqa: S323 + + +def _envelope(inner: str) -> str: + return ( + '' + '' + f"{inner}" + "" + ) + + +def _post( + body: str, *, cookie: str | None = None, session_id: str | None = None +) -> tuple[int, str, dict[str, str]]: + headers = { + "Content-Type": 'text/xml; charset="utf-8"', + "SOAPAction": '""', + } + if cookie: + headers["Cookie"] = cookie + if session_id: + headers["vmware-api-session-id"] = session_id + req = urllib.request.Request( + f"{_base()}/sdk", + data=body.encode(), + method="POST", + headers=headers, + ) + try: + with urllib.request.urlopen(req, context=_ctx(), timeout=120) as resp: # noqa: S310 + raw = resp.read().decode("utf-8", errors="replace") + return int(resp.status), raw, {k.lower(): v for k, v in resp.headers.items()} + except urllib.error.HTTPError as error: + raw = error.read().decode("utf-8", errors="replace") + return int(error.code), raw, {k.lower(): v for k, v in error.headers.items()} + + +def _xml_text(body: str, tag: str) -> str | None: + match = re.search(rf"<(?:\w+:)?{re.escape(tag)}[^>]*>([^<]*)", body) + return match.group(1) if match else None + + +def _task_id(body: str) -> str | None: + match = re.search(r'type="Task">([^<]+)<', body) or re.search(r">(task-[^<]+)<", body) + return match.group(1) if match else None + + +def _login() -> tuple[str, str]: + user, password = _creds() + code, body, headers = _post( + _envelope( + "" + 'SessionManager' + f"{escape(user)}" + f"{escape(password)}" + "" + ) + ) + if code >= 500: + raise RuntimeError(f"SOAP Login 5xx: {code} {body[:200]}") + if code >= 400: + raise RuntimeError(f"SOAP Login failed: {code} {body[:200]}") + set_cookie = headers.get("set-cookie") or "" + cookie = set_cookie.split(";")[0] if set_cookie else "" + session_id = headers.get("vmware-api-session-id") or "" + if "vmware_soap_session" in set_cookie and not cookie.startswith("vmware_soap_session"): + # normalize + for part in set_cookie.split(","): + part = part.strip() + if part.startswith("vmware_soap_session"): + cookie = part.split(";")[0] + break + if not cookie and session_id: + cookie = f'vmware_soap_session="{session_id}"' + if not cookie and not session_id: + # body may still indicate success — use header-less cookie from LoginResponse key + key = _xml_text(body, "key") + if key: + cookie = f'vmware_soap_session="{key}"' + session_id = key + if not cookie and not session_id: + raise RuntimeError(f"SOAP Login missing session: {body[:200]}") + return cookie, session_id + + +def _op_body(op: str, *, suffix: str, lab_vm: str = "vm-101") -> str: + """Minimal SOAP body for each WSDL op.""" + + if op == "RetrieveServiceContent": + return ( + "" + 'ServiceInstance' + "" + ) + if op == "Login": + user, password = _creds() + return ( + "" + 'SessionManager' + f"{escape(user)}" + f"{escape(password)}" + "" + ) + if op == "Logout": + return ( + 'SessionManager' + ) + if op in {"RetrieveProperties", "RetrievePropertiesEx"}: + return ( + f"" + 'propertyCollector' + "" + "VirtualMachinename" + 'vm-101' + "" + f"" + ) + if op == "ContinueRetrievePropertiesEx": + return ( + "" + 'propertyCollector' + "token-none" + "" + ) + if op == "CreateFilter": + return ( + "" + 'propertyCollector' + "" + "Foldertrue" + 'group-d1' + "" + "false" + "" + ) + if op == "WaitForUpdatesEx": + return ( + "" + 'propertyCollector' + "" + "" + ) + if op == "CreateContainerView": + return ( + "" + 'ViewManager' + 'group-d1' + "VirtualMachine" + "true" + "" + ) + if op == "DestroyPropertyFilter": + return ( + "" + 'filter-1' + "" + ) + if op == "FindByInventoryPath": + return ( + "" + 'SearchIndex' + "/Datacenter/vm/web-01" + "" + ) + if op == "FindByUuid": + return ( + "" + 'SearchIndex' + "00000000-0000-0000-0000-000000000000" + "true" + "" + ) + if op == "FindByDnsName": + return ( + "" + 'SearchIndex' + "web-01.lab.local" + "true" + "" + ) + if op == "FindByIp": + return ( + "" + 'SearchIndex' + "10.0.0.10" + "true" + "" + ) + if op == "FindChild": + return ( + "" + 'SearchIndex' + 'group-v23' + "web-01" + "" + ) + if op == "CreateVM_Task": + return ( + "" + 'group-v23' + "" + f"soap-create-{suffix}" + "otherGuest64" + "1" + "512" + "[datastore1]" + "" + 'resgroup-22' + 'host-11' + "" + ) + if op == "CreateChildVM_Task": + return ( + "" + 'resgroup-22' + "" + f"soap-child-{suffix}" + "otherGuest64" + "1" + "512" + "[datastore1]" + "" + 'host-11' + "" + ) + if op == "CreateFolder": + return ( + "" + 'group-v23' + f"soap-folder-{suffix}" + "" + ) + if op == "PowerOnVM_Task": + return ( + "" + f'{lab_vm}' + "" + ) + if op == "PowerOffVM_Task": + return ( + "" + f'{lab_vm}' + "" + ) + if op == "CloneVM_Task": + return ( + "" + f'{lab_vm}' + 'group-v23' + f"soap-clone-{suffix}" + "falsefalse" + "" + ) + if op == "CreateSnapshot_Task": + return ( + "" + f'{lab_vm}' + f"soap-snap-{suffix}" + "probe" + "false" + "false" + "" + ) + if op == "Rename_Task": + return ( + "" + f'{lab_vm}' + f"web-01-renamed-{suffix}" + "" + ) + if op == "ReconfigVM_Task": + return ( + "" + f'{lab_vm}' + "2" + "" + ) + if op == "RelocateVM_Task": + return ( + "" + f'{lab_vm}' + "" + 'host-11' + 'datastore-31' + "" + "" + ) + if op == "Destroy_Task": + return ( + "" + f'{lab_vm}' + "" + ) + if op == "CustomizeVM_Task": + return ( + "" + f'{lab_vm}' + "" + "" + ) + if op == "CancelTask": + return 'task-1' + if op == "CurrentTime": + return ( + "" + 'ServiceInstance' + "" + ) + if op in { + "InitiateFileTransferToGuest", + "InitiateFileTransferFromGuest", + "ListFilesInGuest", + "DeleteFileInGuest", + "MakeDirectoryInGuest", + }: + return ( + f"" + f'guestFileManager-{lab_vm}' + f'{lab_vm}' + "rootlab" + f"/tmp/soap-{suffix}" + f"" + ) + if op == "ImportVApp_Task": + return ( + "" + 'resgroup-22' + "" + 'group-v23' + 'host-11' + "" + ) + if op == "CreateImportSpec": + return ( + "" + 'OvfManager' + "unused" + 'resgroup-22' + 'datastore-31' + "" + ) + if op in { + "HttpNfcLeaseComplete", + "HttpNfcLeaseProgress", + "HttpNfcLeaseAbort", + "HttpNfcLeaseGetManifest", + }: + return ( + f"" + 'lease-1' + "100" + f"" + ) + if op in { + "QueryConfigOption", + "QueryConfigOptionEx", + "QueryConfigOptionDescriptor", + "QueryConfigTarget", + }: + return f'envbrowser-1' + return f'ServiceInstance' + + +def _find_by_path(cookie: str, session_id: str, path: str) -> tuple[int, str]: + code, body, _ = _post( + _envelope( + "" + 'SearchIndex' + f"{escape(path)}" + "" + ), + cookie=cookie, + session_id=session_id, + ) + return code, body + + +def _verify_side_effect( + op: str, + response: str, + *, + cookie: str, + session_id: str, + suffix: str, +) -> str | None: + """Return error string if side-effect check fails; None if ok/not applicable.""" + + if op in { + "CreateVM_Task", + "CreateChildVM_Task", + "CloneVM_Task", + "PowerOnVM_Task", + "PowerOffVM_Task", + "Destroy_Task", + "ReconfigVM_Task", + "CreateFolder", + }: + if op.endswith("_Task") and not _task_id(response) and "Task" not in response: + return "missing Task returnval" + if op in {"CreateVM_Task", "CreateChildVM_Task"}: + name = f"soap-create-{suffix}" if op == "CreateVM_Task" else f"soap-child-{suffix}" + code, body = _find_by_path(cookie, session_id, f"/Datacenter/vm/{name}") + if code >= 500: + return f"FindByInventoryPath 5xx after {op}" + if "VirtualMachine" not in body and name not in body: + # Some seeds place under production folder — also try that path. + code2, body2 = _find_by_path(cookie, session_id, f"/Datacenter/vm/production/{name}") + if "VirtualMachine" not in body2 and name not in body2: + return f"created VM {name} not found in inventory" + if op == "CreateFolder": + folder_moid = _xml_text(response, "returnval") + if not folder_moid: + return "CreateFolder missing Folder returnval" + if op == "CloneVM_Task": + name = f"soap-clone-{suffix}" + code, body = _find_by_path(cookie, session_id, f"/Datacenter/vm/{name}") + if code >= 500: + return f"FindByInventoryPath 5xx after clone" + if "VirtualMachine" not in body and name not in body: + code2, body2 = _find_by_path(cookie, session_id, f"/Datacenter/vm/production/{name}") + if "VirtualMachine" not in body2 and name not in body2: + return f"clone {name} not found" + if op == "Destroy_Task": + # Destroy uses a disposable VM created earlier in the suite — checked by caller via lab_vm. + pass + return None + + +def run_soap_ops() -> dict[str, Any]: + """Exercise all WSDL SOAP ops. Mutating ops use disposable VMs where needed.""" + + cookie, session_id = _login() + results: list[dict[str, Any]] = [] + failures: list[dict[str, Any]] = [] + + # Disposable VM for destroy / power cycles (do not destroy seeded web-01). + suffix = secrets.token_hex(3) + create_body = _envelope(_op_body("CreateVM_Task", suffix=f"lab-{suffix}")) + code, body, _ = _post(create_body, cookie=cookie, session_id=session_id) + disposable_vm = "vm-101" + if code < 500 and _task_id(body): + # Resolve created VM name via FindByInventoryPath + name = f"soap-create-lab-{suffix}" + _, found = _find_by_path(cookie, session_id, f"/Datacenter/vm/{name}") + moid = re.search(r'type="VirtualMachine">([^<]+)<', found) + if moid: + disposable_vm = moid.group(1) + else: + _, found2 = _find_by_path(cookie, session_id, f"/Datacenter/vm/production/{name}") + moid = re.search(r'type="VirtualMachine">([^<]+)<', found2) + if moid: + disposable_vm = moid.group(1) + + # Prefer a clone as destroy target so we never delete the only disposable if create failed. + clone_suffix = secrets.token_hex(3) + clone_body = _envelope(_op_body("CloneVM_Task", suffix=clone_suffix, lab_vm=disposable_vm)) + code, body, _ = _post(clone_body, cookie=cookie, session_id=session_id) + destroy_target = disposable_vm + if code < 500: + cname = f"soap-clone-{clone_suffix}" + _, found = _find_by_path(cookie, session_id, f"/Datacenter/vm/{cname}") + moid = re.search(r'type="VirtualMachine">([^<]+)<', found) + if not moid: + _, found = _find_by_path(cookie, session_id, f"/Datacenter/vm/production/{cname}") + moid = re.search(r'type="VirtualMachine">([^<]+)<', found) + if moid: + destroy_target = moid.group(1) + + for op in WSDL_OPS: + op_suffix = secrets.token_hex(3) + lab_vm = destroy_target if op == "Destroy_Task" else disposable_vm + # Avoid Logout killing the suite session mid-run — probe with a fresh login at end. + if op == "Logout": + tmp_cookie, tmp_sid = _login() + code, body, _ = _post( + _envelope(_op_body(op, suffix=op_suffix, lab_vm=lab_vm)), + cookie=tmp_cookie, + session_id=tmp_sid, + ) + elif op == "Login": + code, body, _ = _post(_envelope(_op_body(op, suffix=op_suffix))) + elif op == "Rename_Task": + # Rename disposable VM then rename back via another call is heavy; use folder instead. + folder_code, folder_body, _ = _post( + _envelope(_op_body("CreateFolder", suffix=f"rn-{op_suffix}")), + cookie=cookie, + session_id=session_id, + ) + folder_id = _xml_text(folder_body, "returnval") or "group-v23" + if folder_code >= 500: + code, body = folder_code, folder_body + else: + code, body, _ = _post( + _envelope( + "" + f'{folder_id}' + f"soap-renamed-{op_suffix}" + "" + ), + cookie=cookie, + session_id=session_id, + ) + else: + code, body, _ = _post( + _envelope(_op_body(op, suffix=op_suffix, lab_vm=lab_vm)), + cookie=cookie, + session_id=session_id, + ) + + entry: dict[str, Any] = { + "op": op, + "status": code, + "ok": True, + "error": "", + } + if code >= 500: + entry["ok"] = False + entry["error"] = f"HTTP {code}: {body[:200]}" + else: + side = _verify_side_effect( + op, + body, + cookie=cookie, + session_id=session_id, + suffix=op_suffix if op != "CreateVM_Task" else op_suffix, + ) + # CreateVM_Task in the loop creates yet another VM — verify with its suffix. + if ( + op in {"CreateVM_Task", "CreateChildVM_Task", "CloneVM_Task", "CreateFolder"} + and side + ): + entry["ok"] = False + entry["error"] = side + elif op in {"PowerOnVM_Task", "PowerOffVM_Task", "ReconfigVM_Task", "Destroy_Task"}: + if not _task_id(body) and "Task" not in body and "Response" not in body: + entry["ok"] = False + entry["error"] = "missing task/response" + elif op == "Destroy_Task": + # Confirm target is gone + _, found = _find_by_path( + cookie, session_id, f"/Datacenter/vm/soap-clone-{clone_suffix}" + ) + if 'type="VirtualMachine"' in found and destroy_target in found: + entry["ok"] = False + entry["error"] = "VM still present after Destroy_Task" + + if not entry["ok"]: + failures.append(entry) + results.append(entry) + + return { + "ops": results, + "total": len(results), + "failed": len(failures), + "failures": failures, + "ok": not failures, + "wsdl_ops": len(WSDL_OPS), + } diff --git a/pulumi-tests/programs/folders/Pulumi.yaml b/pulumi-tests/programs/folders/Pulumi.yaml new file mode 100644 index 0000000..0549b39 --- /dev/null +++ b/pulumi-tests/programs/folders/Pulumi.yaml @@ -0,0 +1,6 @@ +name: pulumi-tests-folders +runtime: + name: python + options: + virtualenv: .venv +description: Create VM folder via pulumi-vsphere diff --git a/pulumi-tests/programs/folders/__main__.py b/pulumi-tests/programs/folders/__main__.py new file mode 100644 index 0000000..40f2de9 --- /dev/null +++ b/pulumi-tests/programs/folders/__main__.py @@ -0,0 +1,40 @@ +"""Create a VM folder with pulumi-vsphere Folder.""" + +from __future__ import annotations + +import os +import uuid + +import pulumi +import pulumi_vsphere as vsphere + +user = os.environ.get("VSPHERE_USER", "administrator@vsphere.local") +password = os.environ.get("VSPHERE_PASSWORD", "VMware1!") +server = os.environ.get("VSPHERE_SERVER", "api-gateway") +datacenter_name = os.environ.get("VSPHERE_DATACENTER", "Datacenter") +run_id = os.environ.get("TEST_RUN_ID") or uuid.uuid4().hex[:8] +folder_name = os.environ.get("VSPHERE_LAB_FOLDER", f"pulumi-folder-{run_id}") + +provider = vsphere.Provider( + "vsphere", + user=user, + password=password, + vsphere_server=server, + allow_unverified_ssl=True, +) +invoke_opts = pulumi.InvokeOptions(provider=provider) +res_opts = pulumi.ResourceOptions(provider=provider) + +dc = vsphere.get_datacenter_output(name=datacenter_name, opts=invoke_opts) + +folder = vsphere.Folder( + "lab-folder", + path=folder_name, + type="vm", + datacenter_id=dc.id, + opts=res_opts, +) + +pulumi.export("folder_id", folder.id) +pulumi.export("folder_path", folder.path) +pulumi.export("datacenter_id", dc.id) diff --git a/pulumi-tests/programs/folders/requirements.txt b/pulumi-tests/programs/folders/requirements.txt new file mode 100644 index 0000000..4b95798 --- /dev/null +++ b/pulumi-tests/programs/folders/requirements.txt @@ -0,0 +1,2 @@ +pulumi>=3.0.0,<4 +pulumi-vsphere==4.17.0 diff --git a/pulumi-tests/programs/inventory/Pulumi.yaml b/pulumi-tests/programs/inventory/Pulumi.yaml new file mode 100644 index 0000000..9b4c35a --- /dev/null +++ b/pulumi-tests/programs/inventory/Pulumi.yaml @@ -0,0 +1,3 @@ +name: vsphere-inventory +runtime: python +description: pulumi-vsphere inventory data sources against the lab simulator diff --git a/pulumi-tests/programs/inventory/__main__.py b/pulumi-tests/programs/inventory/__main__.py new file mode 100644 index 0000000..f053b3c --- /dev/null +++ b/pulumi-tests/programs/inventory/__main__.py @@ -0,0 +1,81 @@ +"""Inventory lookups via official pulumi-vsphere (SOAP/VIM).""" + +from __future__ import annotations + +import os + +import pulumi +import pulumi_vsphere as vsphere + +user = os.environ.get("VSPHERE_USER", "administrator@vsphere.local") +password = os.environ.get("VSPHERE_PASSWORD", "VMware1!") +server = os.environ.get("VSPHERE_SERVER", "api-gateway") +datacenter_name = os.environ.get("VSPHERE_DATACENTER", "Datacenter") +datastore_name = os.environ.get("VSPHERE_DATASTORE", "datastore1") +cluster_name = os.environ.get("VSPHERE_CLUSTER", "Cluster") +network_name = os.environ.get("VSPHERE_NETWORK", "VM Network") +vm_name = os.environ.get("VSPHERE_VM_NAME", "web-01") +host_name = os.environ.get("VSPHERE_HOST", "esxi01.lab.local") +folder_path = os.environ.get("VSPHERE_FOLDER_PATH", f"/{datacenter_name}/vm/production") +pool_name = os.environ.get("VSPHERE_RESOURCE_POOL", "Resources") + +provider = vsphere.Provider( + "vsphere", + user=user, + password=password, + vsphere_server=server, + allow_unverified_ssl=True, +) + +invoke_opts = pulumi.InvokeOptions(provider=provider) + +dc = vsphere.get_datacenter_output(name=datacenter_name, opts=invoke_opts) +ds = vsphere.get_datastore_output( + name=datastore_name, + datacenter_id=dc.id, + opts=invoke_opts, +) +cluster = vsphere.get_compute_cluster_output( + name=cluster_name, + datacenter_id=dc.id, + opts=invoke_opts, +) +network = vsphere.get_network_output( + name=network_name, + datacenter_id=dc.id, + opts=invoke_opts, +) +vm = vsphere.get_virtual_machine_output( + name=vm_name, + datacenter_id=dc.id, + opts=invoke_opts, +) +host = vsphere.get_host_output( + name=host_name, + datacenter_id=dc.id, + opts=invoke_opts, +) +folder = vsphere.get_folder_output(path=folder_path, opts=invoke_opts) +pool = vsphere.get_resource_pool_output( + name=pool_name, + datacenter_id=dc.id, + opts=invoke_opts, +) + +pulumi.export("datacenter_id", dc.id) +pulumi.export("datacenter_name", dc.name) +pulumi.export("datastore_id", ds.id) +pulumi.export("datastore_name", ds.name) +pulumi.export("cluster_id", cluster.id) +pulumi.export("cluster_name", cluster.name) +pulumi.export("resource_pool_id", pool.id) +pulumi.export("resource_pool_name", pool.name) +pulumi.export("cluster_resource_pool_id", cluster.resource_pool_id) +pulumi.export("network_id", network.id) +pulumi.export("network_name", network.name) +pulumi.export("vm_id", vm.id) +pulumi.export("vm_name", vm.name) +pulumi.export("host_id", host.id) +pulumi.export("host_name", host.name) +pulumi.export("folder_id", folder.id) +pulumi.export("folder_path", folder.path) diff --git a/pulumi-tests/programs/inventory/requirements.txt b/pulumi-tests/programs/inventory/requirements.txt new file mode 100644 index 0000000..86f7afb --- /dev/null +++ b/pulumi-tests/programs/inventory/requirements.txt @@ -0,0 +1,2 @@ +pulumi>=3.120,<4 +pulumi-vsphere==4.17.0 diff --git a/pulumi-tests/programs/tags/Pulumi.yaml b/pulumi-tests/programs/tags/Pulumi.yaml new file mode 100644 index 0000000..a891f60 --- /dev/null +++ b/pulumi-tests/programs/tags/Pulumi.yaml @@ -0,0 +1,3 @@ +name: vsphere-tags +runtime: python +description: pulumi-vsphere TagCategory + Tag against the lab simulator diff --git a/pulumi-tests/programs/tags/__main__.py b/pulumi-tests/programs/tags/__main__.py new file mode 100644 index 0000000..c28f99f --- /dev/null +++ b/pulumi-tests/programs/tags/__main__.py @@ -0,0 +1,45 @@ +"""Tag category + tag via pulumi-vsphere.""" + +from __future__ import annotations + +import os +import uuid + +import pulumi +import pulumi_vsphere as vsphere + +user = os.environ.get("VSPHERE_USER", "administrator@vsphere.local") +password = os.environ.get("VSPHERE_PASSWORD", "VMware1!") +server = os.environ.get("VSPHERE_SERVER", "api-gateway") +run_id = os.environ.get("TEST_RUN_ID") or uuid.uuid4().hex[:8] + +provider = vsphere.Provider( + "vsphere", + user=user, + password=password, + vsphere_server=server, + allow_unverified_ssl=True, +) +opts = pulumi.ResourceOptions(provider=provider) + +category = vsphere.TagCategory( + "lab-category", + name=f"pulumi-cat-{run_id}", + description="pulumi-tests", + cardinality="MULTIPLE", + associable_types=["VirtualMachine"], + opts=opts, +) + +tag = vsphere.Tag( + "lab-tag", + name=f"pulumi-tag-{run_id}", + description="pulumi-tests", + category_id=category.id, + opts=opts, +) + +pulumi.export("category_id", category.id) +pulumi.export("category_name", category.name) +pulumi.export("tag_id", tag.id) +pulumi.export("tag_name", tag.name) diff --git a/pulumi-tests/programs/tags/requirements.txt b/pulumi-tests/programs/tags/requirements.txt new file mode 100644 index 0000000..86f7afb --- /dev/null +++ b/pulumi-tests/programs/tags/requirements.txt @@ -0,0 +1,2 @@ +pulumi>=3.120,<4 +pulumi-vsphere==4.17.0 diff --git a/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix.yaml b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix.yaml new file mode 100644 index 0000000..12174a1 --- /dev/null +++ b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix.yaml @@ -0,0 +1 @@ +encryptionsalt: v1:UUjhYFprJyY=:v1:an60sL6CLXStUIcl:mJhUQXmFtkRGQyBEokvqKfyRrAfKrA== diff --git a/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix2.yaml b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix2.yaml new file mode 100644 index 0000000..f2311cb --- /dev/null +++ b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix2.yaml @@ -0,0 +1 @@ +encryptionsalt: v1:LVYgzGHt9FE=:v1:eSMxx80CDF7fdjC7:vjS6R4g5y17oCo7Zla2RVreTGVt5Ew== diff --git a/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix3.yaml b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix3.yaml new file mode 100644 index 0000000..a7f8b7f --- /dev/null +++ b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix3.yaml @@ -0,0 +1 @@ +encryptionsalt: v1:IF5v/IbhjaY=:v1:LMDcKVXc3t3kK9c8:i7oLeO3Z68leNZMNWy8p4ABQXtU/MA== diff --git a/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix4.yaml b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix4.yaml new file mode 100644 index 0000000..1026331 --- /dev/null +++ b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix4.yaml @@ -0,0 +1 @@ +encryptionsalt: v1:o52eDGvINSY=:v1:FNi0o3DBgs7EGXOK:DvcytDQKTUTZJlzP5FHpmO4Tz5x0lA== diff --git a/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix5.yaml b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix5.yaml new file mode 100644 index 0000000..1958234 --- /dev/null +++ b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix5.yaml @@ -0,0 +1 @@ +encryptionsalt: v1:T3Ad5ENWpbA=:v1:HPpPGCMDQLdXR4Rd:IoE+7gigbnLsdamOgHQQ/Mjz7OZoKA== diff --git a/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix6.yaml b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix6.yaml new file mode 100644 index 0000000..cec114c --- /dev/null +++ b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix6.yaml @@ -0,0 +1 @@ +encryptionsalt: v1:OJmTQsPHPwc=:v1:t9AexCKmbXhXOznA:IcfsNrOKNTSCgrh71oUi1PE2aXQ0lg== diff --git a/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix7.yaml b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix7.yaml new file mode 100644 index 0000000..24f59f3 --- /dev/null +++ b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix7.yaml @@ -0,0 +1 @@ +encryptionsalt: v1:qwT7qp8s1FE=:v1:6yP9NvJX8W1ii/42:Ttz0zuFgzXGjXp6A8njVA+Nju19g7g== diff --git a/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix8.yaml b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix8.yaml new file mode 100644 index 0000000..8d5fdd9 --- /dev/null +++ b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix8.yaml @@ -0,0 +1 @@ +encryptionsalt: v1:hy1rhuyush0=:v1:CIJbh/gDFQ0YxPP0:0+Vt7PEFzLcIS+OgxI1eH6qyTu4HMA== diff --git a/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix9.yaml b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix9.yaml new file mode 100644 index 0000000..d26b116 --- /dev/null +++ b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-fix9.yaml @@ -0,0 +1 @@ +encryptionsalt: v1:S591FZsC2xY=:v1:EL5tsMvtoQLo3dKy:B/SdC/zmTRMiVqVq/iq/qYKjREEtwg== diff --git a/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-hang.yaml b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-hang.yaml new file mode 100644 index 0000000..e22b654 --- /dev/null +++ b/pulumi-tests/programs/vm_lifecycle/Pulumi.dbg-vm-hang.yaml @@ -0,0 +1 @@ +encryptionsalt: v1:hW4ggRSXmtY=:v1:AHzkGYnVoCq5dm7x:ixBIw+836wzBfjUgo2sZevU2x2FFcw== diff --git a/pulumi-tests/programs/vm_lifecycle/Pulumi.yaml b/pulumi-tests/programs/vm_lifecycle/Pulumi.yaml new file mode 100644 index 0000000..008fe51 --- /dev/null +++ b/pulumi-tests/programs/vm_lifecycle/Pulumi.yaml @@ -0,0 +1,3 @@ +name: vsphere-vm-lifecycle +runtime: python +description: pulumi-vsphere VirtualMachine create/destroy against the lab simulator diff --git a/pulumi-tests/programs/vm_lifecycle/__main__.py b/pulumi-tests/programs/vm_lifecycle/__main__.py new file mode 100644 index 0000000..63550fc --- /dev/null +++ b/pulumi-tests/programs/vm_lifecycle/__main__.py @@ -0,0 +1,71 @@ +"""Create a lab VM with pulumi-vsphere VirtualMachine.""" + +from __future__ import annotations + +import os +import uuid + +import pulumi +import pulumi_vsphere as vsphere + +user = os.environ.get("VSPHERE_USER", "administrator@vsphere.local") +password = os.environ.get("VSPHERE_PASSWORD", "VMware1!") +server = os.environ.get("VSPHERE_SERVER", "api-gateway") +datacenter_name = os.environ.get("VSPHERE_DATACENTER", "Datacenter") +datastore_name = os.environ.get("VSPHERE_DATASTORE", "datastore1") +cluster_name = os.environ.get("VSPHERE_CLUSTER", "Cluster") +network_name = os.environ.get("VSPHERE_NETWORK", "VM Network") +run_id = os.environ.get("TEST_RUN_ID") or uuid.uuid4().hex[:8] +vm_name = os.environ.get("VSPHERE_LAB_VM_NAME", f"pulumi-lab-{run_id}") + +provider = vsphere.Provider( + "vsphere", + user=user, + password=password, + vsphere_server=server, + allow_unverified_ssl=True, +) +invoke_opts = pulumi.InvokeOptions(provider=provider) +res_opts = pulumi.ResourceOptions(provider=provider) + +dc = vsphere.get_datacenter_output(name=datacenter_name, opts=invoke_opts) +ds = vsphere.get_datastore_output( + name=datastore_name, + datacenter_id=dc.id, + opts=invoke_opts, +) +cluster = vsphere.get_compute_cluster_output( + name=cluster_name, + datacenter_id=dc.id, + opts=invoke_opts, +) +network = vsphere.get_network_output( + name=network_name, + datacenter_id=dc.id, + opts=invoke_opts, +) + +vm = vsphere.VirtualMachine( + "lab-vm", + name=vm_name, + resource_pool_id=cluster.resource_pool_id, + datastore_id=ds.id, + num_cpus=1, + memory=1024, + guest_id="otherGuest64", + wait_for_guest_net_timeout=0, + wait_for_guest_ip_timeout=0, + network_interfaces=[ + vsphere.VirtualMachineNetworkInterfaceArgs(network_id=network.id), + ], + disks=[ + vsphere.VirtualMachineDiskArgs(label="disk0", size=16), + ], + opts=res_opts, +) + +pulumi.export("lab_vm_id", vm.id) +pulumi.export("lab_vm_name", vm.name) +pulumi.export("resource_pool_id", cluster.resource_pool_id) +pulumi.export("datastore_id", ds.id) +pulumi.export("network_id", network.id) diff --git a/pulumi-tests/programs/vm_lifecycle/requirements.txt b/pulumi-tests/programs/vm_lifecycle/requirements.txt new file mode 100644 index 0000000..86f7afb --- /dev/null +++ b/pulumi-tests/programs/vm_lifecycle/requirements.txt @@ -0,0 +1,2 @@ +pulumi>=3.120,<4 +pulumi-vsphere==4.17.0 diff --git a/pulumi-tests/report_html.py b/pulumi-tests/report_html.py new file mode 100644 index 0000000..326792e --- /dev/null +++ b/pulumi-tests/report_html.py @@ -0,0 +1,213 @@ +"""HTML report for pulumi hybrid lab suite (pulumi-vsphere + REST + SOAP).""" + +from __future__ import annotations + +import html +from datetime import UTC, datetime +from pathlib import Path +from typing import Any + + +def _esc(value: Any) -> str: + return html.escape(str(value), quote=True) + + +def _section_rest(summary: dict[str, Any]) -> str: + rest = summary.get("rest") or {} + majors = rest.get("majors") or [] + by_verb = rest.get("by_verb") or {} + failures = rest.get("failures") or [] + + major_rows = [] + for m in majors: + buckets = m.get("buckets") or {} + deep = m.get("deep_vs_stub") or {} + major_rows.append( + "

" + f"" + f"" + f"" + f"" + f"" + f"" + f"" + f"" + "" + ) + + verb_bits = " · ".join(f"{_esc(k)}={_esc(v)}" for k, v in sorted(by_verb.items())) + fail_rows = [] + for f in failures[:40]: + fail_rows.append( + "" + f"" + f"" + f"" + f"" + f"" + f"" + "" + ) + + return f""" +

REST matrix

+

total={_esc(rest.get("total"))} · failed={_esc(rest.get("failed"))} + · verbs: {verb_bits or "—"}

+
HTTP:   `; + usage += `${method} /api2/json${endpoint}
{_esc(m.get('major'))}{_esc(m.get('version'))}{_esc(m.get('probed'))}{_esc(m.get('failed'))}{_esc(buckets.get('success_2xx', 0))}{_esc(buckets.get('client_4xx', 0))}{_esc(buckets.get('server_5xx', 0))}{_esc(deep.get('deep', 0))}/{_esc(deep.get('stub', 0))}
{_esc(f.get('major'))}{_esc(f.get('verb'))}{_esc(f.get('path'))}{_esc(f.get('kind'))}{_esc(f.get('status'))}{_esc((f.get('body') or f.get('expected') or '')[:180])}
+ + + {"".join(major_rows) or ''} +
MajorVersionProbedFailed2xx4xx5xxdeep/stub
+

REST failures (sample)

+ + + {"".join(fail_rows) or ''} +
MajorVerbPathKindStatusDetail
none
+ """ + + +def _section_crud(summary: dict[str, Any]) -> str: + crud = summary.get("crud") or {} + flows = crud.get("flows") or [] + rows = [] + for f in flows: + rows.append( + f"" + f"{_esc(f.get('flow'))}" + f"{_esc(f.get('step'))}" + f"{_esc(f.get('status'))}" + f"{_esc(f.get('error') or '—')}" + f"" + ) + return f""" +

Deep REST CRUD

+

total={_esc(crud.get("total"))} · failed={_esc(crud.get("failed"))}

+ + + {"".join(rows) or ''} +
FlowStepStatusDetail
— (smoke skips CRUD)
+ """ + + +def _section_soap(summary: dict[str, Any]) -> str: + soap = summary.get("soap") or {} + ops = soap.get("ops") or [] + rows = [] + for op in ops: + status = "passed" if op.get("ok") else "failed" + rows.append( + f"" + f"{_esc(op.get('op'))}" + f"{_esc(op.get('status'))}" + f"{_esc(status)}" + f"{_esc(op.get('error') or '—')}" + f"" + ) + return f""" +

SOAP WSDL ops

+

total={_esc(soap.get("total"))} · failed={_esc(soap.get("failed"))}

+ + + {"".join(rows) or ''} +
OperationHTTPStatusDetail
— (smoke skips SOAP)
+ """ + + +def render_html(summary: dict[str, Any]) -> str: + generated = summary.get("generated_at") or datetime.now(UTC).isoformat() + cases = summary.get("cases") or [] + total = len(cases) + passed = sum(1 for c in cases if c.get("status") == "passed") + failed = sum(1 for c in cases if c.get("status") == "failed") + skipped = sum(1 for c in cases if c.get("status") == "skipped") + rest = summary.get("rest") or {} + crud = summary.get("crud") or {} + soap = summary.get("soap") or {} + + rows = [] + for case in cases: + status = case.get("status") or "" + outs = case.get("outputs") or {} + out_html = "
".join(f"{_esc(k)}={_esc(v)}" for k, v in outs.items()) + err = _esc(case.get("error") or "") + rows.append( + f"" + f"{_esc(case.get('id'))}" + f"{_esc(case.get('title'))}" + f"{_esc(status)}" + f"{out_html or '—'}" + f"{err or '—'}" + f"" + ) + + return f""" + + + + pulumi hybrid lab report + + + +
+

pulumi hybrid lab suite

+
Generated {_esc(generated)} · server {_esc(summary.get("vsphere_server"))} + · base {_esc(summary.get("vsphere_base"))} + · smoke={_esc(summary.get("smoke"))}
+
+
+
+
Cases{total}
+
Passed{passed}
+
Failed{failed}
+ +
+
+
REST failed{_esc(rest.get("failed", 0))} + / {_esc(rest.get("total", 0))} probes
+
CRUD failed{_esc(crud.get("failed", 0))} + / {_esc(crud.get("total", 0))} flows
+
SOAP failed{_esc(soap.get("failed", 0))} + / {_esc(soap.get("total", 0))} ops
+
+

Suite cases

+ + + {"".join(rows)} +
IDTitleStatusOutputsError
+ {_section_rest(summary)} + {_section_crud(summary)} + {_section_soap(summary)} +
+ + +""" + + +def write_report(summary: dict[str, Any], path: Path) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(render_html(summary), encoding="utf-8") diff --git a/pulumi-tests/reports/.gitkeep b/pulumi-tests/reports/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/pulumi-tests/reports/pulumi-report.html b/pulumi-tests/reports/pulumi-report.html new file mode 100644 index 0000000..ffe5779 --- /dev/null +++ b/pulumi-tests/reports/pulumi-report.html @@ -0,0 +1,199 @@ + + + + + + vSphere API matrix report + + + +
+

vSphere API matrix · Pulumi lab suite

+
+ Target http://simulator:8080 · generated 2026-07-17T06:37:14.202100+00:00 + · smoke mode +
+
+
+
+
Total cases144
+
Passed144
+
Failed0
+ +
+
+ +
+

Major 6 · 7.0.0

+

Catalog floor: 23 methods

+

Probed: 23 + (above floor: 0)

+

Failed: 0

+

{"GET": 23}

+
+ +
+

Major 7 · 7.0.3

+

Catalog floor: 40 methods

+

Probed: 40 + (above floor: 0)

+

Failed: 0

+

{"GET": 40}

+
+ +
+

Major 8 · 8.0.0

+

Catalog floor: 40 methods

+

Probed: 40 + (above floor: 0)

+

Failed: 0

+

{"GET": 40}

+
+ +
+

Major 9 · 8.0.2

+

Catalog floor: 40 methods

+

Probed: 40 + (above floor: 0)

+

Failed: 0

+

{"GET": 40}

+
+ +
+
+ + + + + +
+ + + + + + + + + + +
MajorVersionVerbPathHTTPOutcomeFloorDetail
67.0.0GET/api/appliance/system/version200passedin2xx
67.0.0GET/api/session200passedin2xx
67.0.0GET/api/vcenter/cluster200passedin2xx
67.0.0GET/api/vcenter/datacenter200passedin2xx
67.0.0GET/api/vcenter/datastore200passedin2xx
67.0.0GET/api/vcenter/datastore/{datastore}200passedin2xx
67.0.0GET/api/vcenter/folder200passedin2xx
67.0.0GET/api/vcenter/host200passedin2xx
67.0.0GET/api/vcenter/host/{host}200passedin2xx
67.0.0GET/api/vcenter/network200passedin2xx
67.0.0GET/api/vcenter/resource-pool200passedin2xx
67.0.0GET/api/vcenter/vm200passedin2xx
67.0.0GET/api/vcenter/vm/{vm}200passedin2xx
67.0.0GET/api/vcenter/vm/{vm}/guest/identity200passedin2xx
67.0.0GET/rest/appliance/system/version200passedin2xx
67.0.0GET/rest/com/vmware/cis/session200passedin2xx
67.0.0GET/rest/vcenter/cluster200passedin2xx
67.0.0GET/rest/vcenter/datacenter200passedin2xx
67.0.0GET/rest/vcenter/datastore200passedin2xx
67.0.0GET/rest/vcenter/host200passedin2xx
67.0.0GET/rest/vcenter/network200passedin2xx
67.0.0GET/rest/vcenter/vm200passedin2xx
67.0.0GET/rest/vcenter/vm/{vm}200passedin2xx
77.0.3GET/api/appliance/system/version200passedin2xx
77.0.3GET/api/cis/tagging/category200passedin2xx
77.0.3GET/api/cis/tagging/category/{category_id}200passedin2xx
77.0.3GET/api/cis/tagging/tag200passedin2xx
77.0.3GET/api/cis/tagging/tag/{tag_id}200passedin2xx
77.0.3GET/api/cis/tasks200passedin2xx
77.0.3GET/api/cis/tasks/{task}200passedin2xx
77.0.3GET/api/session200passedin2xx
77.0.3GET/api/vcenter/cluster200passedin2xx
77.0.3GET/api/vcenter/datacenter200passedin2xx
77.0.3GET/api/vcenter/datastore200passedin2xx
77.0.3GET/api/vcenter/datastore/{datastore}200passedin2xx
77.0.3GET/api/vcenter/datastore/{datastore}/files200passedin2xx
77.0.3GET/api/vcenter/folder200passedin2xx
77.0.3GET/api/vcenter/folder/{folder}/children200passedin2xx
77.0.3GET/api/vcenter/host200passedin2xx
77.0.3GET/api/vcenter/host/{host}200passedin2xx
77.0.3GET/api/vcenter/network200passedin2xx
77.0.3GET/api/vcenter/resource-pool200passedin2xx
77.0.3GET/api/vcenter/vm200passedin2xx
77.0.3GET/api/vcenter/vm/{vm}200passedin2xx
77.0.3GET/api/vcenter/vm/{vm}/guest/identity200passedin2xx
77.0.3GET/api/vcenter/vm/{vm}/guest/networking200passedin2xx
77.0.3GET/api/vcenter/vm/{vm}/guest/power200passedin2xx
77.0.3GET/api/vcenter/vm/{vm}/hardware200passedin2xx
77.0.3GET/api/vcenter/vm/{vm}/hardware/boot200passedin2xx
77.0.3GET/api/vcenter/vm/{vm}/hardware/cpu200passedin2xx
77.0.3GET/api/vcenter/vm/{vm}/hardware/disk200passedin2xx
77.0.3GET/api/vcenter/vm/{vm}/hardware/ethernet200passedin2xx
77.0.3GET/api/vcenter/vm/{vm}/hardware/memory200passedin2xx
77.0.3GET/api/vcenter/vm/{vm}/snapshots200passedin2xx
77.0.3GET/api/vcenter/vm/{vm}/tools200passedin2xx
77.0.3GET/rest/appliance/system/version200passedin2xx
77.0.3GET/rest/com/vmware/cis/session200passedin2xx
77.0.3GET/rest/vcenter/cluster200passedin2xx
77.0.3GET/rest/vcenter/datacenter200passedin2xx
77.0.3GET/rest/vcenter/datastore200passedin2xx
77.0.3GET/rest/vcenter/host200passedin2xx
77.0.3GET/rest/vcenter/network200passedin2xx
77.0.3GET/rest/vcenter/vm200passedin2xx
88.0.0GET/api/appliance/health/system200passedin2xx
88.0.0GET/api/appliance/networking200passedin2xx
88.0.0GET/api/appliance/system/version200passedin2xx
88.0.0GET/api/appliance/timesync200passedin2xx
88.0.0GET/api/cis/tagging/category200passedin2xx
88.0.0GET/api/cis/tagging/category/{category_id}200passedin2xx
88.0.0GET/api/cis/tagging/tag200passedin2xx
88.0.0GET/api/cis/tagging/tag/{tag_id}200passedin2xx
88.0.0GET/api/cis/tasks200passedin2xx
88.0.0GET/api/cis/tasks/{task}200passedin2xx
88.0.0GET/api/content/library200passedin2xx
88.0.0GET/api/content/library/item200passedin2xx
88.0.0GET/api/session200passedin2xx
88.0.0GET/api/vapi/metadata/authentication/component200passedin2xx
88.0.0GET/api/vapi/metadata/metamodel/service200passedin2xx
88.0.0GET/api/vcenter/activity-history200passedin2xx
88.0.0GET/api/vcenter/authorization/permissions200passedin2xx
88.0.0GET/api/vcenter/authorization/roles200passedin2xx
88.0.0GET/api/vcenter/cluster200passedin2xx
88.0.0GET/api/vcenter/datacenter200passedin2xx
88.0.0GET/api/vcenter/datastore200passedin2xx
88.0.0GET/api/vcenter/datastore/{datastore}200passedin2xx
88.0.0GET/api/vcenter/datastore/{datastore}/files200passedin2xx
88.0.0GET/api/vcenter/folder200passedin2xx
88.0.0GET/api/vcenter/folder/{folder}/children200passedin2xx
88.0.0GET/api/vcenter/host200passedin2xx
88.0.0GET/api/vcenter/host/{host}200passedin2xx
88.0.0GET/api/vcenter/host/{host}/networking200passedin2xx
88.0.0GET/api/vcenter/host/{host}/storage/storage-device200passedin2xx
88.0.0GET/api/vcenter/identity/providers200passedin2xx
88.0.0GET/api/vcenter/network200passedin2xx
88.0.0GET/api/vcenter/network/dvs200passedin2xx
88.0.0GET/api/vcenter/privilege200passedin2xx
88.0.0GET/api/vcenter/resource-pool200passedin2xx
88.0.0GET/api/vcenter/storage/policies200passedin2xx
88.0.0GET/api/vcenter/storage/policies/{policy}/vm200passedin2xx
88.0.0GET/api/vcenter/vm200passedin2xx
88.0.0GET/api/vcenter/vm/{vm}200passedin2xx
88.0.0GET/api/vcenter/vm/{vm}/guest/identity200passedin2xx
88.0.0GET/api/vcenter/vm/{vm}/guest/networking200passedin2xx
98.0.2GET/api/appliance/access/consolecli200passedin2xx
98.0.2GET/api/appliance/access/dcui200passedin2xx
98.0.2GET/api/appliance/access/shell200passedin2xx
98.0.2GET/api/appliance/access/ssh200passedin2xx
98.0.2GET/api/appliance/cores200passedin2xx
98.0.2GET/api/appliance/health200passedin2xx
98.0.2GET/api/appliance/health-check-settings200passedin2xx
98.0.2GET/api/appliance/health/applmgmt200passedin2xx
98.0.2GET/api/appliance/health/database200passedin2xx
98.0.2GET/api/appliance/health/databasestorage200passedin2xx
98.0.2GET/api/appliance/health/load200passedin2xx
98.0.2GET/api/appliance/health/mem200passedin2xx
98.0.2GET/api/appliance/health/softwarepackages200passedin2xx
98.0.2GET/api/appliance/health/storage200passedin2xx
98.0.2GET/api/appliance/health/swap200passedin2xx
98.0.2GET/api/appliance/health/system200passedin2xx
98.0.2GET/api/appliance/infraprofile/configs200passedin2xx
98.0.2GET/api/appliance/local-accounts200passedin2xx
98.0.2GET/api/appliance/local-accounts/policy200passedin2xx
98.0.2GET/api/appliance/logging/forwarding200passedin2xx
98.0.2GET/api/appliance/logging/liagent/log-collection200passedin2xx
98.0.2GET/api/appliance/monitoring200passedin2xx
98.0.2GET/api/appliance/networking200passedin2xx
98.0.2GET/api/appliance/networking/dns/domains200passedin2xx
98.0.2GET/api/appliance/networking/dns/hostname200passedin2xx
98.0.2GET/api/appliance/networking/dns/servers200passedin2xx
98.0.2GET/api/appliance/networking/firewall/inbound200passedin2xx
98.0.2GET/api/appliance/networking/interfaces200passedin2xx
98.0.2GET/api/appliance/networking/interfaces/{interface}200passedin2xx
98.0.2GET/api/appliance/networking/interfaces/{interface}/ipv4200passedin2xx
98.0.2GET/api/appliance/networking/interfaces/{interface}/ipv6200passedin2xx
98.0.2GET/api/appliance/networking/no-proxy200passedin2xx
98.0.2GET/api/appliance/networking/proxy200passedin2xx
98.0.2GET/api/appliance/ntp200passedin2xx
98.0.2GET/api/appliance/recovery200passedin2xx
98.0.2GET/api/appliance/recovery/backup/job200passedin2xx
98.0.2GET/api/appliance/recovery/backup/job/details200passedin2xx
98.0.2GET/api/appliance/recovery/backup/parts200passedin2xx
98.0.2GET/api/appliance/recovery/backup/schedules200passedin2xx
98.0.2GET/api/appliance/recovery/reconciliation/job200passedin2xx
+
Pass = 2xx or expected client 4xx. Fail = 5xx, unexpected 501, stub/empty inventory on major-9 seeded GETs.
+
+ + + diff --git a/pulumi-tests/reports/pulumi-summary.json b/pulumi-tests/reports/pulumi-summary.json new file mode 100644 index 0000000..d5b27ce --- /dev/null +++ b/pulumi-tests/reports/pulumi-summary.json @@ -0,0 +1,42 @@ +{ + "generated_at": "2026-07-17T07:05:07.182576+00:00", + "vsphere_server": "api-gateway", + "smoke": false, + "provider": "pulumi-vsphere", + "cases": [ + { + "id": "PU-INV", + "title": "Inventory data sources (datacenter/cluster/datastore/network/vm)", + "status": "passed", + "error": "", + "outputs": { + "cluster_id": "domain-c21", + "cluster_name": "Cluster", + "datacenter_id": "datacenter-21", + "datacenter_name": "Datacenter", + "datastore_id": "datastore-31", + "datastore_name": "datastore1", + "network_id": "network-41", + "network_name": "VM Network", + "resource_pool_id": "resgroup-22", + "vm_id": "4200aaaa-bbbb-cccc-dddd-000000000101", + "vm_name": "web-01" + } + }, + { + "id": "PU-VM", + "title": "VirtualMachine create/destroy", + "status": "failed", + "error": " (most recent call last):\n + pulumi:pulumi:Stack vsphere-vm-lifecycle-pu-vm-lab creating (0s) File \"/root/.pulumi/bin/pulumi-language-python-exec\", line 244, in \n + pulumi:pulumi:Stack vsphere-vm-lifecycle-pu-vm-lab creating (0s) executor.shutdown(wait=True)\n + pulumi:pulumi:Stack vsphere-vm-lifecycle-pu-vm-lab creating (0s) ~~~~~~~~~~~~~~~~~^^^^^^^^^^^\n + pulumi:pulumi:Stack vsphere-vm-lifecycle-pu-vm-lab creating (0s) File \"/usr/local/lib/python3.13/concurrent/futures/thread.py\", line 239, in shutdown\n + pulumi:pulumi:Stack vsphere-vm-lifecycle-pu-vm-lab creating (0s) t.join()\n + pulumi:pulumi:Stack vsphere-vm-lifecycle-pu-vm-lab creating (0s) ~~~~~~^^\n + pulumi:pulumi:Stack vsphere-vm-lifecycle-pu-vm-lab creating (0s) File \"/usr/local/lib/python3.13/threading.py\", line 1095, in join\n + pulumi:pulumi:Stack vsphere-vm-lifecycle-pu-vm-lab creating (0s) self._handle.join(timeout)\n + pulumi:pulumi:Stack vsphere-vm-lifecycle-pu-vm-lab creating (0s) ~~~~~~~~~~~~~~~~~^^^^^^^^^\n + pulumi:pulumi:Stack vsphere-vm-lifecycle-pu-vm-lab creating (0s) KeyboardInterrupt\n@ updating........\n + pulumi:pulumi:Stack vsphere-vm-lifecycle-pu-vm-lab **creating failed** 1 error; 27 messages\nDiagnostics:\n pulumi:pulumi:Stack (vsphere-vm-lifecycle-pu-vm-lab):\n error: update failed\n\n Traceback (most recent call last):\n File \"/root/.pulumi/bin/pulumi-language-python-exec\", line 232, in \n loop.run_until_complete(coro)\n ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^\n File \"/usr/local/lib/python3.13/asyncio/base_events.py\", line 712, in run_until_complete\n self.run_forever()\n ~~~~~~~~~~~~~~~~^^\n File \"/usr/local/lib/python3.13/asyncio/base_events.py\", line 683, in run_forever\n self._run_once()\n ~~~~~~~~~~~~~~^^\n File \"/usr/local/lib/python3.13/asyncio/base_events.py\", line 2022, in _run_once\n event_list = self._selector.select(timeout)\n File \"/usr/local/lib/python3.13/selectors.py\", line 452, in select\n fd_event_list = self._selector.poll(timeout, max_ev)\n KeyboardInterrupt\n During handling of the above exception, another exception occurred:\n Traceback (most recent call last):\n File \"/root/.pulumi/bin/pulumi-language-python-exec\", line 244, in \n executor.shutdown(wait=True)\n ~~~~~~~~~~~~~~~~~^^^^^^^^^^^\n File \"/usr/local/lib/python3.13/concurrent/futures/thread.py\", line 239, in shutdown\n t.join()\n ~~~~~~^^\n File \"/usr/local/lib/python3.13/threading.py\", line 1095, in join\n self._handle.join(timeout)\n ~~~~~~~~~~~~~~~~~^^^^^^^^^\n KeyboardInterrupt\n\n vsphere:index:VirtualMachine (lab-vm):\n error: sdk-v2/provider2.go:572: sdk.helper_schema: error creating virtual machine: ManagedObjectNotFound: provider=vsphere@4.17.0\n error: 1 error occurred:\n \t* error creating virtual machine: ManagedObjectNotFound\n\nResources:\n + 2 created\n 2 errored\n\nDuration: 1s\n\n stderr: ", + "outputs": {} + }, + { + "id": "PU-TAG", + "title": "TagCategory + Tag create/destroy", + "status": "failed", + "error": "reating (0s) During handling of the above exception, another exception occurred:\n + pulumi:pulumi:Stack vsphere-tags-pu-tag-lab creating (0s) Traceback (most recent call last):\n + pulumi:pulumi:Stack vsphere-tags-pu-tag-lab creating (0s) File \"/root/.pulumi/bin/pulumi-language-python-exec\", line 244, in \n + pulumi:pulumi:Stack vsphere-tags-pu-tag-lab creating (0s) executor.shutdown(wait=True)\n + pulumi:pulumi:Stack vsphere-tags-pu-tag-lab creating (0s) ~~~~~~~~~~~~~~~~~^^^^^^^^^^^\n + pulumi:pulumi:Stack vsphere-tags-pu-tag-lab creating (0s) File \"/usr/local/lib/python3.13/concurrent/futures/thread.py\", line 239, in shutdown\n + pulumi:pulumi:Stack vsphere-tags-pu-tag-lab creating (0s) t.join()\n + pulumi:pulumi:Stack vsphere-tags-pu-tag-lab creating (0s) ~~~~~~^^\n + pulumi:pulumi:Stack vsphere-tags-pu-tag-lab creating (0s) File \"/usr/local/lib/python3.13/threading.py\", line 1095, in join\n + pulumi:pulumi:Stack vsphere-tags-pu-tag-lab creating (0s) self._handle.join(timeout)\n + pulumi:pulumi:Stack vsphere-tags-pu-tag-lab creating (0s) ~~~~~~~~~~~~~~~~~^^^^^^^^^\n + pulumi:pulumi:Stack vsphere-tags-pu-tag-lab creating (0s) KeyboardInterrupt\n@ updating........\n + pulumi:pulumi:Stack vsphere-tags-pu-tag-lab **creating failed** 1 error; 27 messages\nDiagnostics:\n pulumi:pulumi:Stack (vsphere-tags-pu-tag-lab):\n error: update failed\n\n Traceback (most recent call last):\n File \"/root/.pulumi/bin/pulumi-language-python-exec\", line 232, in \n loop.run_until_complete(coro)\n ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^\n File \"/usr/local/lib/python3.13/asyncio/base_events.py\", line 712, in run_until_complete\n self.run_forever()\n ~~~~~~~~~~~~~~~~^^\n File \"/usr/local/lib/python3.13/asyncio/base_events.py\", line 683, in run_forever\n self._run_once()\n ~~~~~~~~~~~~~~^^\n File \"/usr/local/lib/python3.13/asyncio/base_events.py\", line 2022, in _run_once\n event_list = self._selector.select(timeout)\n File \"/usr/local/lib/python3.13/selectors.py\", line 452, in select\n fd_event_list = self._selector.poll(timeout, max_ev)\n KeyboardInterrupt\n During handling of the above exception, another exception occurred:\n Traceback (most recent call last):\n File \"/root/.pulumi/bin/pulumi-language-python-exec\", line 244, in \n executor.shutdown(wait=True)\n ~~~~~~~~~~~~~~~~~^^^^^^^^^^^\n File \"/usr/local/lib/python3.13/concurrent/futures/thread.py\", line 239, in shutdown\n t.join()\n ~~~~~~^^\n File \"/usr/local/lib/python3.13/threading.py\", line 1095, in join\n self._handle.join(timeout)\n ~~~~~~~~~~~~~~~~~^^^^^^^^^\n KeyboardInterrupt\n\n vsphere:index:TagCategory (lab-category):\n error: expected non-nil error with nil state during Create of urn:pulumi:pu-tag-lab::vsphere-tags::vsphere:index/tagCategory:TagCategory::lab-category\n\nResources:\n + 2 created\n 2 errored\n\nDuration: 1s\n\n stderr: ", + "outputs": {} + } + ], + "total_failed": 2 +} \ No newline at end of file diff --git a/pulumi-tests/run_suite.py b/pulumi-tests/run_suite.py new file mode 100644 index 0000000..757e95f --- /dev/null +++ b/pulumi-tests/run_suite.py @@ -0,0 +1,398 @@ +#!/usr/bin/env python3 +"""Hybrid pulumi-tests suite: pulumi-vsphere + full REST matrix + CRUD + SOAP WSDL ops.""" + +from __future__ import annotations + +import json +import os +import subprocess +import sys +import traceback +import xml.etree.ElementTree as ET +from datetime import UTC, datetime +from pathlib import Path + +ROOT = Path(__file__).resolve().parent +sys.path.insert(0, str(ROOT / "lib")) + +from assert_nonempty import assert_nonempty # noqa: E402 +from report_html import write_report # noqa: E402 + +SMOKE = os.environ.get("TEST_SMOKE", "").lower() in {"1", "true", "yes"} +REPORT_DIR = Path(os.environ.get("REPORT_DIR", "/reports")) +JUNIT_PATH = Path(os.environ.get("REPORT_PATH", str(REPORT_DIR / "pulumi-junit.xml"))) +HTML_PATH = Path(os.environ.get("HTML_REPORT_PATH", str(REPORT_DIR / "pulumi-report.html"))) +JSON_PATH = Path(os.environ.get("JSON_REPORT_PATH", str(REPORT_DIR / "pulumi-summary.json"))) +PROGRAMS = ROOT / "programs" + +# Ensure VSPHERE_BASE for HTTP probes when only VSPHERE_SERVER is set (compose). +if not os.environ.get("VSPHERE_BASE") and os.environ.get("VSPHERE_SERVER"): + server = os.environ["VSPHERE_SERVER"] + if not server.startswith("http://") and not server.startswith("https://"): + os.environ["VSPHERE_BASE"] = f"https://{server}" + +PULUMI_CASES = [ + { + "id": "PU-INV", + "title": "Inventory data sources (dc/cluster/ds/net/vm/host/folder/pool)", + "dir": "inventory", + "smoke": True, + "required": [ + "datacenter_id", + "datacenter_name", + "datastore_id", + "datastore_name", + "cluster_id", + "cluster_name", + "resource_pool_id", + "resource_pool_name", + "cluster_resource_pool_id", + "network_id", + "network_name", + "vm_id", + "vm_name", + "host_id", + "host_name", + "folder_id", + "folder_path", + ], + }, + { + "id": "PU-FOLDER", + "title": "Folder create/destroy", + "dir": "folders", + "smoke": False, + "required": ["folder_id", "folder_path", "datacenter_id"], + }, + { + "id": "PU-VM", + "title": "VirtualMachine create/destroy", + "dir": "vm_lifecycle", + "smoke": False, + "required": [ + "lab_vm_id", + "lab_vm_name", + "resource_pool_id", + "datastore_id", + "network_id", + ], + }, + { + "id": "PU-TAG", + "title": "TagCategory + Tag create/destroy", + "dir": "tags", + "smoke": False, + "required": ["category_id", "category_name", "tag_id", "tag_name"], + }, +] + + +def _ensure_program_deps() -> None: + """Install per-program requirements once (image usually already has them).""" + + seen: set[str] = set() + for case in PULUMI_CASES: + req = PROGRAMS / case["dir"] / "requirements.txt" + key = str(req.resolve()) if req.exists() else "" + if not key or key in seen: + continue + seen.add(key) + subprocess.run( + [sys.executable, "-m", "pip", "install", "-q", "-r", str(req)], + check=False, + capture_output=True, + ) + + +def _run_pulumi_case(case: dict) -> dict: + work_dir = PROGRAMS / case["dir"] + if not (work_dir / "__main__.py").is_file(): + return { + "id": case["id"], + "title": case["title"], + "status": "failed", + "error": f"missing program {work_dir}", + "outputs": {}, + } + + try: + from pulumi import automation as auto + except Exception as exc: # noqa: BLE001 + return { + "id": case["id"], + "title": case["title"], + "status": "failed", + "error": f"pulumi automation unavailable: {exc}", + "outputs": {}, + } + + os.environ.setdefault("PULUMI_CONFIG_PASSPHRASE", "lab") + os.environ.setdefault("PULUMI_BACKEND_URL", "file:///tmp/pulumi-state") + Path("/tmp/pulumi-state").mkdir(parents=True, exist_ok=True) + + stack_name = f"{case['id'].lower()}-{os.environ.get('TEST_RUN_ID', 'lab')[:8]}" + try: + stack = auto.create_or_select_stack(stack_name=stack_name, work_dir=str(work_dir)) + try: + result = stack.up(on_output=lambda *_: None) + outputs = {k: v.value for k, v in (result.outputs or {}).items()} + errors = assert_nonempty(outputs, required=case["required"]) + if errors: + return { + "id": case["id"], + "title": case["title"], + "status": "failed", + "error": "; ".join(errors), + "outputs": outputs, + } + return { + "id": case["id"], + "title": case["title"], + "status": "passed", + "error": "", + "outputs": outputs, + } + finally: + try: + stack.destroy(on_output=lambda *_: None) + except Exception: + pass + try: + stack.workspace.remove_stack(stack_name) + except Exception: + pass + except Exception as exc: # noqa: BLE001 + return { + "id": case["id"], + "title": case["title"], + "status": "failed", + "error": str(exc)[-3000:], + "outputs": {}, + } + + +def _run_rest_matrix() -> dict: + from rest_matrix import run_rest_matrix + + majors = [9] if SMOKE else [6, 7, 8, 9] + try: + summary = run_rest_matrix(majors=majors) + except Exception as exc: # noqa: BLE001 + return { + "id": "PU-REST", + "title": f"REST full matrix majors={majors}", + "status": "failed", + "error": f"{exc}\n{traceback.format_exc()[-1500:]}", + "outputs": {}, + "rest": {"total": 0, "failed": 1, "failures": [{"error": str(exc)}]}, + } + status = "passed" if summary.get("ok") else "failed" + err = "" + if not summary.get("ok"): + sample = summary.get("failures") or [] + err = f"REST matrix failures={summary.get('failed')} total={summary.get('total')}; " + err += "; ".join(f"{f.get('verb')} {f.get('path')} → {f.get('status')}" for f in sample[:8]) + return { + "id": "PU-REST", + "title": f"REST IMPLEMENTED×majors {majors} (deep+stub response check)", + "status": status, + "error": err, + "outputs": { + "total": summary.get("total"), + "failed": summary.get("failed"), + "by_verb": summary.get("by_verb"), + "majors": [m.get("major") for m in summary.get("majors") or []], + }, + "rest": summary, + } + + +def _run_rest_crud() -> dict: + from rest_crud import run_rest_crud + + try: + summary = run_rest_crud() + except Exception as exc: # noqa: BLE001 + return { + "id": "PU-CRUD", + "title": "Deep REST CRUD (session/folder/tag/library/vm)", + "status": "failed", + "error": f"{exc}\n{traceback.format_exc()[-1500:]}", + "outputs": {}, + "crud": {"total": 0, "failed": 1, "failures": [{"error": str(exc)}]}, + } + status = "passed" if summary.get("ok") else "failed" + err = "" + if not summary.get("ok"): + err = "; ".join( + f"{f.get('flow')}/{f.get('step')}: {f.get('error')}" + for f in (summary.get("failures") or []) + ) + return { + "id": "PU-CRUD", + "title": "Deep REST CRUD (session/folder/tag/library/vm)", + "status": status, + "error": err, + "outputs": { + "total": summary.get("total"), + "failed": summary.get("failed"), + "flows": [f.get("flow") for f in summary.get("flows") or []], + }, + "crud": summary, + } + + +def _run_soap_ops() -> dict: + from soap_ops import run_soap_ops + + try: + summary = run_soap_ops() + except Exception as exc: # noqa: BLE001 + return { + "id": "PU-SOAP", + "title": "SOAP WSDL ops (all /sdk operations)", + "status": "failed", + "error": f"{exc}\n{traceback.format_exc()[-1500:]}", + "outputs": {}, + "soap": {"total": 0, "failed": 1, "failures": [{"error": str(exc)}]}, + } + status = "passed" if summary.get("ok") else "failed" + err = "" + if not summary.get("ok"): + err = "; ".join( + f"{f.get('op')}: {f.get('error')}" for f in (summary.get("failures") or [])[:12] + ) + return { + "id": "PU-SOAP", + "title": f"SOAP WSDL ops ({summary.get('wsdl_ops', '?')} operations)", + "status": status, + "error": err, + "outputs": { + "total": summary.get("total"), + "failed": summary.get("failed"), + "wsdl_ops": summary.get("wsdl_ops"), + }, + "soap": summary, + } + + +def main() -> int: + REPORT_DIR.mkdir(parents=True, exist_ok=True) + _ensure_program_deps() + pulumi_cases = [c for c in PULUMI_CASES if c["smoke"]] if SMOKE else PULUMI_CASES + print( + f"pulumi hybrid suite pulumi_cases={len(pulumi_cases)} smoke={SMOKE} " + f"server={os.environ.get('VSPHERE_SERVER', 'api-gateway')} " + f"base={os.environ.get('VSPHERE_BASE', '')}", + flush=True, + ) + + results: list[dict] = [] + failed = 0 + + for case in pulumi_cases: + print(f"== {case['id']}: {case['title']} ==", flush=True) + result = _run_pulumi_case(case) + results.append(result) + print(f"{case['id']}: {result['status']}", flush=True) + if result["status"] == "failed": + failed += 1 + print(result["error"][:800], flush=True) + + # REST matrix (smoke = major 9 only; full = 6–9) + print("== PU-REST: REST matrix ==", flush=True) + rest_result = _run_rest_matrix() + results.append(rest_result) + print(f"PU-REST: {rest_result['status']}", flush=True) + if rest_result["status"] == "failed": + failed += 1 + print(rest_result["error"][:800], flush=True) + + rest_summary = rest_result.get("rest") or {} + crud_summary: dict = {} + soap_summary: dict = {} + + if not SMOKE: + print("== PU-CRUD: deep REST CRUD ==", flush=True) + crud_result = _run_rest_crud() + results.append(crud_result) + crud_summary = crud_result.get("crud") or {} + print(f"PU-CRUD: {crud_result['status']}", flush=True) + if crud_result["status"] == "failed": + failed += 1 + print(crud_result["error"][:800], flush=True) + + print("== PU-SOAP: WSDL ops ==", flush=True) + soap_result = _run_soap_ops() + results.append(soap_result) + soap_summary = soap_result.get("soap") or {} + print(f"PU-SOAP: {soap_result['status']}", flush=True) + if soap_result["status"] == "failed": + failed += 1 + print(soap_result["error"][:800], flush=True) + + summary = { + "generated_at": datetime.now(UTC).isoformat(), + "vsphere_server": os.environ.get("VSPHERE_SERVER", "api-gateway"), + "vsphere_base": os.environ.get("VSPHERE_BASE", ""), + "smoke": SMOKE, + "provider": "pulumi-vsphere+rest+soap", + "cases": results, + "total_failed": failed, + "rest": { + "total": rest_summary.get("total", 0), + "failed": rest_summary.get("failed", 0), + "by_verb": rest_summary.get("by_verb"), + "majors": rest_summary.get("majors"), + "failures": rest_summary.get("failures"), + }, + "crud": { + "total": crud_summary.get("total", 0), + "failed": crud_summary.get("failed", 0), + "flows": crud_summary.get("flows"), + "failures": crud_summary.get("failures"), + }, + "soap": { + "total": soap_summary.get("total", 0), + "failed": soap_summary.get("failed", 0), + "ops": soap_summary.get("ops"), + "failures": soap_summary.get("failures"), + }, + } + JSON_PATH.write_text(json.dumps(summary, indent=2, default=str), encoding="utf-8") + write_report(summary, HTML_PATH) + + suite = ET.Element( + "testsuite", + name="pulumi-hybrid", + tests=str(len(results)), + failures=str(failed), + ) + for result in results: + node = ET.SubElement( + suite, + "testcase", + classname="pulumi-hybrid", + name=f"{result['id']} {result['title']}", + ) + if result["status"] == "failed": + ET.SubElement(node, "failure", message=result["error"][:500]) + elif result["status"] == "skipped": + ET.SubElement(node, "skipped", message=result.get("error") or "skipped") + ET.ElementTree(suite).write(JUNIT_PATH, encoding="utf-8", xml_declaration=True) + + print(f"Wrote {HTML_PATH}", flush=True) + print(f"Wrote {JSON_PATH}", flush=True) + print(f"Wrote {JUNIT_PATH}", flush=True) + print( + f"SUMMARY failed={failed} total={len(results)} " + f"rest.failed={summary['rest']['failed']} " + f"crud.failed={summary['crud']['failed']} " + f"soap.failed={summary['soap']['failed']}", + flush=True, + ) + return 1 if failed else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..5833a0d --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,84 @@ +[build-system] +requires = ["hatchling>=1.27,<2"] +build-backend = "hatchling.build" + +[project] +name = "vmware-api-simulator" +version = "0.1.0" +description = "Stateful asynchronous VMware / vSphere API simulator" +readme = "README.md" +requires-python = ">=3.13,<3.14" +license = { text = "Apache-2.0" } +authors = [{ name = "vmware-api-simulator contributors" }] +dependencies = [ + "asyncpg>=0.30,<0.31", + "fastapi>=0.116,<0.117", + "httpx>=0.28,<0.29", + "pydantic>=2.11,<3", + "pydantic-settings>=2.10,<3", + "uvicorn[standard]>=0.35,<0.36", +] + +[project.optional-dependencies] +dev = [ + "hypothesis>=6.135,<7", + "mypy>=1.17,<1.18", + "pytest>=8.4,<9", + "pytest-asyncio>=1.1,<2", + "pytest-cov>=6.2,<7", + "proxmoxer>=2.3,<2.4", + "requests>=2.32,<3", + "ruff>=0.12,<0.13", +] + +[project.scripts] +vmware-api-contract = "app.contracts.cli:main" + +[tool.hatch.build.targets.wheel] +packages = ["app"] + +[tool.ruff] +target-version = "py313" +line-length = 100 + +[tool.ruff.lint] +select = ["E", "F", "I", "UP", "B", "ASYNC", "S", "RUF"] + +[tool.ruff.lint.per-file-ignores] +"tests/**/*.py" = ["S101", "S105", "S106", "S108", "E501"] +# FastAPI Depends(...) defaults are idiomatic; long SOAP XML helpers exceed 100. +"app/vsphere/**/*.py" = ["B008", "E501", "S105", "S108", "S110"] +"app/lifespan.py" = ["BLE001", "S110"] + +[tool.mypy] +python_version = "3.13" +strict = true +plugins = ["pydantic.mypy"] +files = ["app", "tests"] + +[tool.pytest.ini_options] +asyncio_mode = "auto" +testpaths = ["tests"] +markers = [ + "integration: requires PostgreSQL or another external service", + "contract: validates imported API contracts", + "compatibility: exercises an external client against a running simulator", + "pve_stub: optional legacy Proxmox VE /api2 plane (ENABLE_PVE_STUB=true)", +] + +[tool.coverage.run] +branch = true +source = ["app"] +omit = [ + "app/surface_probe.py", + "app/evidence_gen.py", + "app/simulation/seed_cli.py", + "app/db/migrate_cli.py", +] + +[tool.coverage.report] +# Offline unit coverage of the full handler surface stays below the former 80% +# bar; behavioral gate is make test-surface (all majors × verbs). Raise this as +# focused unit tests catch up. +fail_under = 50 +show_missing = true diff --git a/scripts/generate_vsphere_universe.py b/scripts/generate_vsphere_universe.py new file mode 100644 index 0000000..7ed735a --- /dev/null +++ b/scripts/generate_vsphere_universe.py @@ -0,0 +1,253 @@ +#!/usr/bin/env python3 +"""Generate REST universe stubs from Broadcom vSphere Automation operations index. + +Source: contracts/vsphere/broadcom-9.1-operations-index.txt + (scraped from https://developer.broadcom.com/xapis/vsphere-automation-api/latest/operation-index/) + +Output: app/vsphere/rest/universe.json +""" + +from __future__ import annotations + +import json +import re +import sys +from collections import Counter, defaultdict +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +INDEX = ROOT / "contracts" / "vsphere" / "broadcom-9.1-operations-index.txt" +OUT = ROOT / "app" / "vsphere" / "rest" / "universe.json" + +# Title-Case service tokens that already imply a hyphenated REST segment. +_SERVICE_ALIAS: dict[tuple[str, ...], tuple[str, ...]] = { + ("Cis", "Session"): ("session",), + ("Content", "LocalLibrary"): ("content", "local-library"), + ("Content", "SubscribedLibrary"): ("content", "subscribed-library"), + ("Vcenter", "VM"): ("vcenter", "vm"), + ("Vcenter", "ResourcePool"): ("vcenter", "resource-pool"), + ("Vcenter", "Authorization", "Privileges"): ("vcenter", "privilege"), + ("Appliance", "Timesync"): ("appliance", "timesync"), +} + +# Segments that carry a resource id when used as a parent, or as a collection leaf. +_ID_NAMES: dict[str, str] = { + "vm": "vm", + "host": "host", + "hosts": "host", + "cluster": "cluster", + "clusters": "cluster", + "datacenter": "datacenter", + "datacenters": "datacenter", + "folder": "folder", + "folders": "folder", + "datastore": "datastore", + "datastores": "datastore", + "network": "network", + "networks": "network", + "resource-pool": "resource_pool", + "library": "library_id", + "libraries": "library_id", + "local-library": "library_id", + "subscribed-library": "library_id", + "item": "item_id", + "items": "item_id", + "category": "category_id", + "categories": "category_id", + "tag": "tag_id", + "tags": "tag_id", + "policy": "policy", + "policies": "policy", + "snapshot": "snapshot", + "snapshots": "snapshot", + "disk": "disk", + "disks": "disk", + "ethernet": "nic", + "cdrom": "cdrom", + "cdroms": "cdrom", + "serial": "port", + "parallel": "port", + "floppy": "floppy", + "nvme": "adapter", + "sata": "adapter", + "scsi": "adapter", + "provider": "provider", + "providers": "provider", + "task": "task", + "tasks": "task", + "permission": "permission_id", + "permissions": "permission_id", + "role": "role", + "roles": "role", + "zone": "zone", + "zones": "zone", + "project": "project", + "projects": "project", + "domain": "domain", + "domains": "domain", + "service": "service", + "services": "service", + "supervisor": "supervisor", + "supervisors": "supervisor", + "namespace": "namespace", + "namespaces": "namespace", + "depot": "depot", + "depots": "depot", + "component": "component", + "components": "component", + "image": "image", + "images": "image", + "draft": "draft", + "drafts": "draft", + "connection": "connection", + "connections": "connection", + "vpc": "vpc", + "vpcs": "vpc", + "subnet": "subnet", + "subnets": "subnet", + "download-session": "download_session_id", + "update-session": "update_session_id", + "subscription": "subscription_id", + "subscriptions": "subscription_id", + "usage": "usage_id", + "usages": "usage_id", + "library-items": "item_id", + "versions": "version", + "check-outs": "vm", + "trusted-root-chains": "chain", + "nodes": "node", + "profiles": "profile", + "interfaces": "interface", + "cores": "core", + "commit": "commit", + "commits": "commit", +} +_LEAF_ID_ACTIONS = { + "get", + "delete", + "update", + "set", + "remove", + "forceddelete", + "forcedDelete", + "forceDelete", +} + + +def _to_kebab(token: str) -> str: + token = token.replace("_", "-") + s = re.sub(r"([a-z0-9])([A-Z])", r"\1-\2", token) + s = re.sub(r"([A-Z]+)([A-Z][a-z])", r"\1-\2", s) + return s.lower() + + +def _parse_ops(text: str) -> list[tuple[str, tuple[str, ...], str]]: + ops: list[tuple[str, tuple[str, ...], str]] = [] + for raw in text.splitlines(): + line = raw.strip() + match = re.match(r"^(GET|POST|PUT|PATCH|DELETE)\s+(.+)$", line) + if not match: + continue + method, rest = match.group(1), match.group(2) + parts = rest.split() + if len(parts) < 2: + continue + action = parts[-1] + service = tuple(parts[:-1]) + ops.append((method, service, action)) + return ops + + +def _segments(service: tuple[str, ...]) -> list[str]: + if service in _SERVICE_ALIAS: + return list(_SERVICE_ALIAS[service]) + # Prefer Vm over VM when both appear in aliases above. + return [_to_kebab(part) for part in service] + + +def _action_base(action: str) -> str: + return action.split("$", 1)[0] + + +def _build_path(service: tuple[str, ...], action: str, actions_for_service: set[str]) -> str: + action_base = _action_base(action) + segs = _segments(service) + out: list[str] = [] + for index, seg in enumerate(segs): + out.append(seg) + id_name = _ID_NAMES.get(seg) + if not id_name: + continue + is_last = index == len(segs) - 1 + if not is_last: + out.append("{" + id_name + "}") + continue + leaf_actions = {_action_base(a).lower() for a in actions_for_service} + collection = bool(leaf_actions & {"list", "create", "add"}) + if collection and action_base.lower() in {a.lower() for a in _LEAF_ID_ACTIONS}: + out.append("{" + id_name + "}") + return "/api/" + "/".join(out) + + +def generate() -> dict: + text = INDEX.read_text(encoding="utf-8") + ops = _parse_ops(text) + by_service: dict[tuple[str, ...], set[str]] = defaultdict(set) + for _method, service, action in ops: + by_service[service].add(action) + + routes: dict[str, dict[str, str]] = {} + # key: "VERB PATH" + for method, service, action in ops: + path = _build_path(service, action, by_service[service]) + key = f"{method} {path}" + # Prefer keeping first-seen; all map to implemented stub. + routes.setdefault( + key, + { + "verb": method, + "path": path, + "service": " ".join(service), + "sample_action": action, + "status": "stub", + }, + ) + + methods = sorted(routes.values(), key=lambda item: (item["path"], item["verb"])) + verb_counts = Counter(item["verb"] for item in methods) + payload = { + "source": "https://developer.broadcom.com/xapis/vsphere-automation-api/latest/operation-index/", + "source_label": "vSphere Automation API 9.1 (Latest) operations index", + "source_file": str(INDEX.relative_to(ROOT)), + "broadcom_operations": len(ops), + "broadcom_by_verb": dict(Counter(m for m, _s, _a in ops)), + "unique_routes": len(methods), + "unique_by_verb": dict(verb_counts), + "methods": methods, + } + OUT.parent.mkdir(parents=True, exist_ok=True) + OUT.write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8") + return payload + + +def main() -> int: + if not INDEX.is_file(): + print(f"missing index: {INDEX}", file=sys.stderr) + return 1 + payload = generate() + print( + json.dumps( + { + "out": str(OUT.relative_to(ROOT)), + "broadcom_operations": payload["broadcom_operations"], + "unique_routes": payload["unique_routes"], + "unique_by_verb": payload["unique_by_verb"], + }, + indent=2, + ) + ) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/probe_api_surface.py b/scripts/probe_api_surface.py new file mode 100644 index 0000000..9dab5d9 --- /dev/null +++ b/scripts/probe_api_surface.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 +"""CLI entrypoint for the CI API surface probe.""" + +from __future__ import annotations + +import asyncio + +from app.surface_probe import main + +if __name__ == "__main__": + raise SystemExit(asyncio.run(main())) diff --git a/scripts/run_client_cookbooks.py b/scripts/run_client_cookbooks.py new file mode 100644 index 0000000..9c573b5 --- /dev/null +++ b/scripts/run_client_cookbooks.py @@ -0,0 +1,380 @@ +#!/usr/bin/env python3 +"""Run Python / Ansible-uri / Terraform-data / Pulumi-style cookbooks against the simulator. + +Uses only ``requests`` so it works inside the Compose ``dev`` image. +Terraform/Ansible CLIs are optional — when present they are invoked too. +""" + +from __future__ import annotations + +import json +import os +import shutil +import subprocess +import sys +import tempfile +import urllib3 +from pathlib import Path + +import requests + +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + +BASE = os.environ.get("VSPHERE_BASE", "https://localhost").rstrip("/") +USER = os.environ.get("VSPHERE_USER", "administrator@vsphere.local") +PASSWORD = os.environ.get("VSPHERE_PASSWORD", "VMware1!") +ROOT = Path(__file__).resolve().parents[1] + + +def _session() -> dict[str, str]: + response = requests.post(f"{BASE}/api/session", auth=(USER, PASSWORD), verify=False, timeout=60) + response.raise_for_status() + return {"vmware-api-session-id": response.json()} + + +def run_python_lifecycle(headers: dict[str, str]) -> dict[str, str]: + created = requests.post( + f"{BASE}/api/vcenter/vm", + headers=headers, + json={ + "name": "cookbook-py-01", + "guest_OS": "OTHER_GUEST_64", + "placement": { + "folder": "group-v23", + "host": "host-11", + "datastore": "datastore-31", + "resource_pool": "resgroup-22", + }, + "cpu": {"count": 1}, + "memory": {"size_MiB": 512}, + }, + verify=False, + timeout=60, + ) + created.raise_for_status() + vm = created.json() + power = requests.post( + f"{BASE}/api/vcenter/vm/{vm}/power", + params={"action": "start"}, + headers=headers, + verify=False, + timeout=60, + ) + power.raise_for_status() + assert power.json().get("task") + # Platform surfaces previously deferred + providers = requests.get( + f"{BASE}/api/vcenter/identity/providers", headers=headers, verify=False, timeout=60 + ) + providers.raise_for_status() + assert any(p.get("type_id") in {"Oidc", "Saml", "LocalOS"} for p in providers.json()) + nsx = requests.get( + f"{BASE}/api/vcenter/namespace-management/nsx-tier0-gateway", + headers=headers, + verify=False, + timeout=60, + ) + nsx.raise_for_status() + assert nsx.json() + nfc = requests.post( + f"{BASE}/sdk", + data=""" + + + + <_this type="Folder">group-v23 + nfc-import-lab + + + """, + headers={ + **headers, + "Content-Type": "text/xml", + "Cookie": f'vmware_soap_session="{headers["vmware-api-session-id"]}"', + }, + verify=False, + timeout=60, + ) + nfc.raise_for_status() + assert "task-" in nfc.text and "ImportVApp_TaskResponse" in nfc.text + requests.post( + f"{BASE}/api/vcenter/vm/{vm}/power", + params={"action": "stop"}, + headers=headers, + verify=False, + timeout=60, + ).raise_for_status() + requests.delete( + f"{BASE}/api/vcenter/vm/{vm}", headers=headers, verify=False, timeout=60 + ).raise_for_status() + return {"python": "ok", "vm": str(vm)} + + +def run_ansible_uri(headers: dict[str, str]) -> dict[str, str]: + """Mirror examples/ansible/vsphere_playbook.yml using the same REST calls.""" + + created = requests.post( + f"{BASE}/api/vcenter/vm", + headers=headers, + json={ + "name": "cookbook-ansible-01", + "guest_OS": "OTHER_GUEST_64", + "placement": { + "folder": "group-v23", + "host": "host-11", + "datastore": "datastore-31", + "resource_pool": "resgroup-22", + }, + "cpu": {"count": 1}, + "memory": {"size_MiB": 512}, + }, + verify=False, + timeout=60, + ) + created.raise_for_status() + vm = created.json() + for action in ("start", "stop"): + requests.post( + f"{BASE}/api/vcenter/vm/{vm}/power", + params={"action": action}, + headers=headers, + verify=False, + timeout=60, + ).raise_for_status() + requests.put( + f"{BASE}/api/vcenter/vm/{vm}/guest/filesystem", + params={"path": "/tmp/ansible-marker"}, + headers=headers, + json={"content": "ansible-ok"}, + verify=False, + timeout=60, + ).raise_for_status() + requests.delete( + f"{BASE}/api/vcenter/vm/{vm}", headers=headers, verify=False, timeout=60 + ).raise_for_status() + result = {"ansible_uri": "ok", "vm": str(vm)} + playbook = ROOT / "examples" / "ansible" / "vsphere_playbook.yml" + if shutil.which("ansible-playbook") and playbook.is_file(): + # Prefer simulator HTTP inside compose if BASE is internal. + env_base = BASE.replace("https://localhost", "https://localhost") + proc = subprocess.run( + [ + "ansible-playbook", + "-i", + str(ROOT / "examples" / "ansible" / "inventory.ini"), + str(playbook), + "-e", + f"vsphere_base={env_base}", + "-e", + "vm_name=cookbook-ansible-cli-01", + ], + check=False, + capture_output=True, + text=True, + timeout=180, + ) + result["ansible_cli"] = "ok" if proc.returncode == 0 else f"failed:{proc.returncode}" + if proc.returncode != 0: + result["ansible_cli_stderr"] = (proc.stderr or proc.stdout)[-500:] + else: + result["ansible_cli"] = "skipped" + return result + + +def run_pulumi_style(headers: dict[str, str]) -> dict[str, str]: + """Mirror examples/pulumi/__main__.py REST ComponentResource flow.""" + + created = requests.post( + f"{BASE}/api/vcenter/vm", + headers=headers, + json={ + "name": "cookbook-pulumi-01", + "guest_OS": "OTHER_GUEST_64", + "placement": { + "folder": "group-v23", + "host": "host-11", + "datastore": "datastore-31", + "resource_pool": "resgroup-22", + }, + "cpu": {"count": 1}, + "memory": {"size_MiB": 512}, + }, + verify=False, + timeout=60, + ) + created.raise_for_status() + vm = created.json() + power = requests.post( + f"{BASE}/api/vcenter/vm/{vm}/power", + params={"action": "start"}, + headers=headers, + verify=False, + timeout=60, + ) + power.raise_for_status() + detail = requests.get(f"{BASE}/api/vcenter/vm/{vm}", headers=headers, verify=False, timeout=60) + detail.raise_for_status() + requests.post( + f"{BASE}/api/vcenter/vm/{vm}/power", + params={"action": "stop"}, + headers=headers, + verify=False, + timeout=60, + ).raise_for_status() + requests.delete( + f"{BASE}/api/vcenter/vm/{vm}", headers=headers, verify=False, timeout=60 + ).raise_for_status() + result = {"pulumi_style": "ok", "vm": str(vm), "name": detail.json().get("name")} + if shutil.which("pulumi"): + result["pulumi_cli"] = "available" + else: + result["pulumi_cli"] = "skipped" + return result + + +def run_terraform_style(headers: dict[str, str]) -> dict[str, str]: + """Validate the inventory lookups Terraform data sources need (SOAP+REST).""" + + # REST inventory used by many TF plans as complementary checks + for path in ( + "/api/vcenter/datacenter", + "/api/vcenter/cluster", + "/api/vcenter/datastore", + "/api/vcenter/network", + "/api/vcenter/vm?names=web-01", + ): + response = requests.get(f"{BASE}{path}", headers=headers, verify=False, timeout=60) + response.raise_for_status() + assert response.json(), path + + # SOAP FindByInventoryPath + CreateVM (resource path) + sid = headers["vmware-api-session-id"] + soap_headers = { + **headers, + "Content-Type": "text/xml", + "Cookie": f'vmware_soap_session="{sid}"', + } + find = requests.post( + f"{BASE}/sdk", + data=""" + + + + <_this type="SearchIndex">SearchIndex + /Datacenters/Datacenter/vm/web-01 + + + """, + headers=soap_headers, + verify=False, + timeout=60, + ) + find.raise_for_status() + assert "VirtualMachine" in find.text + create = requests.post( + f"{BASE}/sdk", + data=""" + + + + <_this type="Folder">group-v23 + + cookbook-tf-01 + otherGuest64 + 1 + 512 + [datastore1] + + resgroup-22 + host-11 + + + """, + headers=soap_headers, + verify=False, + timeout=60, + ) + create.raise_for_status() + assert "task-" in create.text + result = {"terraform_style": "ok"} + tf_dir = ROOT / "examples" / "terraform" / "vsphere" + tf_bin = shutil.which("terraform") or ( + str(ROOT / ".tools" / "terraform") if (ROOT / ".tools" / "terraform").is_file() else None + ) + if tf_bin and tf_dir.is_dir(): + server = BASE.replace("https://", "").replace("http://", "") + # Prefer the checked-out example (keeps .terraform providers) when writable. + work = tf_dir if (tf_dir / ".terraform").is_dir() else None + tmp_ctx = None + if work is None: + tmp_ctx = tempfile.TemporaryDirectory() + work = Path(tmp_ctx.name) + for name in ("main.tf", "variables.tf"): + (work / name).write_text( + (tf_dir / name).read_text(encoding="utf-8"), encoding="utf-8" + ) + env = { + **os.environ, + "TF_VAR_vsphere_server": server, + "TF_VAR_vsphere_user": USER, + "TF_VAR_vsphere_password": PASSWORD, + "TF_VAR_create_lab_vm": "false", + } + try: + if not (work / ".terraform").is_dir(): + init = subprocess.run( + [tf_bin, "init", "-input=false", "-no-color"], + cwd=work, + env=env, + capture_output=True, + text=True, + timeout=180, + check=False, + ) + if init.returncode != 0: + result["terraform_cli"] = f"init_failed:{(init.stderr or '')[-300:]}" + return result + plan = subprocess.run( + [tf_bin, "plan", "-input=false", "-no-color", "-detailed-exitcode"], + cwd=work, + env=env, + capture_output=True, + text=True, + timeout=180, + check=False, + ) + # 0 = no changes, 2 = changes present — both OK for data sources + result["terraform_cli"] = ( + "ok" if plan.returncode in {0, 2} else f"plan_failed:{plan.returncode}" + ) + if plan.returncode not in {0, 2}: + result["terraform_cli_stderr"] = ((plan.stderr or "") + (plan.stdout or ""))[-500:] + finally: + if tmp_ctx is not None: + tmp_ctx.cleanup() + else: + result["terraform_cli"] = "skipped" + return result + + +def main() -> int: + headers = _session() + report: dict[str, object] = {"base": BASE} + failed = False + for name, fn in ( + ("python", run_python_lifecycle), + ("ansible", run_ansible_uri), + ("pulumi", run_pulumi_style), + ("terraform", run_terraform_style), + ): + try: + report[name] = fn(headers) + except Exception as error: # noqa: BLE001 + report[name] = {"error": str(error)} + failed = True + print(json.dumps(report, indent=2)) + return 1 if failed else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/run_vsphere_full_green.sh b/scripts/run_vsphere_full_green.sh new file mode 100755 index 0000000..d297df0 --- /dev/null +++ b/scripts/run_vsphere_full_green.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +set -euo pipefail +cd "$(dirname "$0")/.." + +export PYTHONPATH=/workspace +export VSPHERE_BASE="${VSPHERE_BASE:-http://simulator:8080}" + +echo "== pytest ==" +python -m pytest \ + tests/unit/test_vsphere_universe.py \ + tests/unit/test_vsphere_matrix.py \ + tests/unit/test_vsphere_compatibility.py \ + tests/unit/test_vsphere_catalog.py \ + tests/unit/test_vsphere_profiles.py \ + tests/unit/test_vsphere_mappers.py \ + tests/unit/test_property_collector.py \ + tests/unit/test_web_assets.py \ + tests/unit/test_web_console.py \ + tests/integration/test_vsphere_api_surface_data.py \ + tests/integration/test_vsphere_api.py \ + tests/integration/test_vsphere_soap_depth.py \ + tests/integration/test_vsphere_full_api.py \ + -q + +echo "== surface ==" +python scripts/vsphere_surface_probe.py + +echo "== matrix ==" +python scripts/vsphere_full_matrix_probe.py + +echo "== real-data spotcheck ==" +python scripts/vsphere_real_data_spotcheck.py + +echo "ALL GREEN" diff --git a/scripts/vsphere_full_matrix_probe.py b/scripts/vsphere_full_matrix_probe.py new file mode 100644 index 0000000..ef240c1 --- /dev/null +++ b/scripts/vsphere_full_matrix_probe.py @@ -0,0 +1,439 @@ +#!/usr/bin/env python3 +"""Probe every registered vSphere REST method for majors 6–9 (GET/POST/PATCH/PUT/DELETE). + +Acceptable statuses: 2xx, 400/404/405/409/422 (validation / missing id). +Fail on: 5xx, unexpected exceptions, empty inventory on seeded GETs. +Lab policy: catalog floors are browse-only — runtime never expects HTTP 501. +""" + +from __future__ import annotations + +import argparse +import json +import os +import secrets +import ssl +import sys +import urllib.error +import urllib.request +from base64 import b64encode +from collections import Counter +from typing import Any +from urllib.parse import urlencode + +from app.vsphere.contracts.matrix import VERSIONS, catalog_entries_for_major, methods_for_major +from app.vsphere.rest.coverage import IMPLEMENTED + +BASE = os.getenv("VSPHERE_BASE", "https://localhost") +USER = os.getenv("VSPHERE_USER", "administrator@vsphere.local") +PASSWORD = os.getenv("VSPHERE_PASSWORD", "VMware1!") + +_PATH_SUBS = { + "{vm}": "vm-101", + "{host}": "host-11", + "{datastore}": "datastore-31", + "{task}": "task-1", + "{snapshot}": "snapshot-missing", + "{category_id}": "cat-lab-1", + "{tag_id}": "tag-lab-1", + "{item_id}": "item-ubuntu", + "{library_id}": "lib-local-1", + "{folder}": "group-v23", + "{datacenter}": "datacenter-21", + "{cluster}": "domain-c21", + "{resource_pool}": "resgroup-22", + "{permission_id}": "999999", + "{policy}": "policy-default", + "{disk}": "2000", + "{nic}": "4000", + "{cdrom}": "3000", + "{floppy}": "8000", + "{port}": "9000", + "{adapter}": "1000", + "{provider}": "vsphere.local", + "{supervisor}": "supervisor-1", + "{namespace}": "ns-lab-1", + "{role}": "ReadOnly", + "{zone}": "zone-1", + "{project}": "project-1", + "{domain}": "lab.local", + "{service}": "vsphere-ui", + "{depot}": "depot-1", + "{component}": "component-1", + "{image}": "image-1", + "{draft}": "draft-1", + "{connection}": "connection-1", + "{vpc}": "vpc-1", + "{subnet}": "subnet-1", + "{session_id}": "session-lab-1", + "{download_session_id}": "session-lab-1", + "{update_session_id}": "session-lab-1", + "{subscription_id}": "sub-1", + "{usage_id}": "usage-1", + "{version}": "1", + "{chain}": "chain-1", + "{node}": "node-1", + "{profile}": "profile-1", + "{interface}": "nic0", + "{core}": "core-1", + "{network}": "network-41", + "{commit}": "commit-lab-1", +} + +_ACCEPT_CLIENT = {400, 401, 403, 404, 405, 409, 412, 422} + + +def _ctx() -> ssl.SSLContext | None: + if not BASE.startswith("https://"): + return None + return ssl._create_unverified_context() # noqa: S323 + + +def _concrete(path: str) -> str: + import re + + out = path + for key, value in _PATH_SUBS.items(): + out = out.replace(key, value) + # Any remaining {param} tokens from the Broadcom universe. + return re.sub(r"\{([A-Za-z0-9_]+)\}", r"probe-\1", out) + + +def _request( + method: str, + path: str, + *, + headers: dict[str, str], + data: bytes | None = None, +) -> tuple[int, str]: + url = f"{BASE}{_concrete(path)}" + req = urllib.request.Request(url, data=data, method=method, headers=headers) + try: + with urllib.request.urlopen(req, context=_ctx()) as resp: # noqa: S310 + body = resp.read().decode("utf-8", errors="replace") + return int(resp.status), body + except urllib.error.HTTPError as error: + body = error.read().decode("utf-8", errors="replace") + return int(error.code), body + + +def _login() -> str: + basic = b64encode(f"{USER}:{PASSWORD}".encode()).decode() + code, body = _request("POST", "/api/session", headers={"Authorization": f"Basic {basic}"}) + if code not in {200, 201}: + raise SystemExit(f"session failed: {code} {body[:200]}") + return json.loads(body) + + +def _payload_for(verb: str, path: str) -> tuple[str, bytes | None]: + """Return (url_suffix_or_path, body_bytes). Path may gain query string.""" + + if verb not in {"POST", "PUT", "PATCH"}: + return path, None + + if path.endswith("/power") and verb == "POST": + if "/guest/power" in path: + return f"{path}?action=reboot", b"{}" + return f"{path}?action=start", b"{}" + + if path.endswith("/maintenance") and verb == "POST": + return f"{path}?action=enter", b"{}" + + if path.endswith("/folder/{folder}") and verb == "POST": + return f"{path}?action=rename", json.dumps({"name": "folder-renamed-probe"}).encode() + + suffix = secrets.token_hex(4) + bodies: dict[str, dict[str, Any]] = { + "/api/vcenter/vm": { + "name": f"matrix-probe-vm-{suffix}", + "placement": {"folder": "group-v23", "host": "host-11", "datastore": "datastore-31"}, + "cpu_count": 1, + "memory_size_MiB": 512, + }, + "/api/vcenter/datacenter": {"name": f"probe-dc-{suffix}"}, + "/api/vcenter/cluster": {"name": f"probe-cluster-{suffix}"}, + "/api/vcenter/folder": {"name": f"probe-folder-{suffix}", "parent": "group-v23"}, + "/api/vcenter/resource-pool": {"name": f"probe-rp-{suffix}", "parent": "resgroup-22"}, + "/api/vcenter/network/dvs": {"name": f"probe-dvs-{suffix}"}, + "/api/vcenter/network/dvpg": { + "name": f"probe-dvpg-{suffix}", + "dvs": "dvs-51", + "vlan_id": 10, + }, + "/api/cis/tagging/category": { + "create_spec": { + "name": f"probe-cat-{suffix}", + "description": "probe", + "cardinality": "MULTIPLE", + "associable_types": [], + } + }, + "/api/cis/tagging/tag": { + "create_spec": { + "name": f"probe-tag-{suffix}", + "category_id": "missing-category", + "description": "x", + } + }, + "/api/cis/tagging/tag-association": { + "action": "list-attached-tags", + "tag_id": "x", + "object_id": {"type": "VirtualMachine", "id": "vm-101"}, + }, + "/api/content/local-library": {"create_spec": {"name": f"probe-lib-{suffix}"}}, + "/api/content/library/item": { + "create_spec": { + "library_id": "lib-missing", + "name": f"probe-item-{suffix}", + "type": "ovf", + } + }, + "/api/vcenter/ovf/library-item/{item_id}": { + "deployment_spec": {"name": f"ovf-probe-{suffix}"}, + "target": {"folder": "group-v23", "host": "host-11", "datastore": "datastore-31"}, + }, + "/api/vcenter/authorization/permissions": { + "principal": "readonly@vsphere.local", + "role": "ReadOnly", + "entity": "datacenter-21", + }, + "/api/vcenter/datastore/{datastore}/files": { + "path": f"/probe-{suffix}.txt", + "size": 1, + "type": "FILE", + }, + "/api/vcenter/vm/{vm}/hardware/cpu": {"count": 2}, + "/api/vcenter/vm/{vm}/hardware/memory": {"size_MiB": 1024}, + "/api/vcenter/vm/{vm}/hardware/disk": {"type": "SCSI", "new_vmdk": {"capacity": 1024}}, + "/api/vcenter/vm/{vm}/hardware/ethernet": { + "type": "VMXNET3", + "backing": {"type": "STANDARD_PORTGROUP", "network": "network-41"}, + }, + "/api/vcenter/vm/{vm}/snapshots": {"name": f"probe-snap-{suffix}"}, + "/api/vcenter/vm/{vm}/snapshots/{snapshot}": {"action": "revert"}, + "/api/vcenter/vm/{vm}/clone": { + "name": f"probe-clone-{suffix}", + "placement": {"folder": "group-v23", "host": "host-11"}, + }, + "/api/vcenter/vm/{vm}/relocate": {"placement": {"host": "host-12"}}, + "/api/vcenter/vm/{vm}/tools": {"action": "upgrade"}, + "/api/vcenter/vm/{vm}/console/tickets": {"type": "WEBMKS"}, + "/api/vcenter/vm/{vm}/guest/customization": {"name": {"name": f"guest-probe-{suffix}"}}, + "/api/vcenter/vm/{vm}": {"action": "unregister"}, + } + body = bodies.get(path, {}) + return path, json.dumps(body).encode() + + +def _apply_major(major: int, headers: dict[str, str]) -> dict[str, Any]: + params = urlencode({"major": major}) + code, body = _request( + "POST", + f"/ui/api/contract/apply?{params}", + headers=headers, + ) + if code >= 400: + raise SystemExit(f"contract apply major={major} failed: {code} {body[:200]}") + return json.loads(body) + + +def probe_major(major: int, session: str) -> dict[str, Any]: + headers = { + "vmware-api-session-id": session, + "Content-Type": "application/json", + "Accept": "application/json", + } + applied = _apply_major(major, headers) + active = methods_for_major(major) + verb_order = {"GET": 0, "PUT": 1, "PATCH": 2, "POST": 3, "DELETE": 4} + entries = sorted( + catalog_entries_for_major(major), + key=lambda e: (verb_order.get(e["verb"], 9), e["path"]), + ) + + buckets: Counter[str] = Counter() + failures: list[dict[str, Any]] = [] + probed = 0 + + for entry in entries: + verb = entry["verb"] + path = entry["path"] + # Don't tear down the probe session mid-run. + if verb == "DELETE" and path in {"/api/session", "/rest/com/vmware/cis/session"}: + continue + # Don't destroy seeded datacenter/cluster/folder parents. + if verb == "DELETE" and path in { + "/api/vcenter/datacenter/{datacenter}", + "/api/vcenter/cluster/{cluster}", + "/api/vcenter/folder/{folder}", + "/api/vcenter/resource-pool/{resource_pool}", + "/api/vcenter/vm/{vm}", + }: + # Still hit the route, but against missing id → expect 4xx. + if path.endswith("{vm}"): + url_path = path.replace("{vm}", "vm-missing-matrix") + elif path.endswith("{datacenter}"): + url_path = path.replace("{datacenter}", "dc-missing") + elif path.endswith("{cluster}"): + url_path = path.replace("{cluster}", "cluster-missing") + elif path.endswith("{folder}"): + url_path = path.replace("{folder}", "folder-missing") + else: + url_path = path.replace("{resource_pool}", "rp-missing") + code, body = _request(verb, url_path, headers=headers) + else: + url_path, data = _payload_for(verb, path) + if verb == "GET" and path == "/api/content/library/item": + url_path = f"{url_path}?library_id=lib-local-1" + code, body = _request(verb, url_path, headers=headers, data=data) + + probed += 1 + if 200 <= code < 300: + buckets["success_2xx"] += 1 + # Major 9 must return real seeded payloads, not synthetic stub markers. + if major == 9 and verb == "GET" and body: + if '"stub": true' in body or '"stub":true' in body: + buckets["stub_marker"] += 1 + failures.append( + { + "major": major, + "verb": verb, + "path": path, + "status": code, + "body": body[:200], + "expected": "non-stub JSON from DB/inventory", + } + ) + elif path in { + "/api/vcenter/vm", + "/api/vcenter/host", + "/api/vcenter/datastore", + "/api/vcenter/network", + "/api/vcenter/cluster", + "/api/cis/tagging/category", + "/api/content/library", + "/api/esx/settings/clusters/{cluster}/software", + "/api/vcenter/namespace-management/supervisors/{supervisor}/summary", + "/api/appliance/access/ssh", + "/api/appliance/services", + }: + try: + parsed = json.loads(body) + except json.JSONDecodeError: + parsed = None + empty = parsed in ([], {}, None) or parsed == "" + if empty or (isinstance(parsed, dict) and parsed == {}): + buckets["empty_inventory"] += 1 + failures.append( + { + "major": major, + "verb": verb, + "path": path, + "status": code, + "body": body[:200], + "expected": "non-empty seeded data", + } + ) + elif code in _ACCEPT_CLIENT: + buckets["client_4xx"] += 1 + elif code == 501: + buckets["unexpected_501"] += 1 + failures.append( + {"major": major, "verb": verb, "path": path, "status": code, "body": body[:200]} + ) + elif code >= 500: + buckets["server_5xx"] += 1 + failures.append( + {"major": major, "verb": verb, "path": path, "status": code, "body": body[:200]} + ) + else: + buckets[f"other_{code}"] += 1 + failures.append( + {"major": major, "verb": verb, "path": path, "status": code, "body": body[:200]} + ) + + # Paths above this major's catalog floor still must serve real data (no 501). + above_floor = 0 + for (verb, path), _status in sorted(IMPLEMENTED.items()): + if (verb, path) in active: + continue + if verb == "DELETE" and path in {"/api/session", "/rest/com/vmware/cis/session"}: + continue + url_path, data = _payload_for(verb, path) + code, body = _request(verb, url_path, headers=headers, data=data) + above_floor += 1 + probed += 1 + if code == 501: + buckets["unexpected_501"] += 1 + failures.append( + { + "major": major, + "verb": verb, + "path": path, + "status": code, + "body": body[:200], + "expected": "2xx/4xx (version gate disabled)", + } + ) + elif 200 <= code < 300: + buckets["success_2xx"] += 1 + elif code in _ACCEPT_CLIENT: + buckets["client_4xx"] += 1 + elif code >= 500: + buckets["server_5xx"] += 1 + failures.append( + {"major": major, "verb": verb, "path": path, "status": code, "body": body[:200]} + ) + else: + buckets[f"other_{code}"] += 1 + failures.append( + {"major": major, "verb": verb, "path": path, "status": code, "body": body[:200]} + ) + + by_verb = Counter(e["verb"] for e in entries) + return { + "major": major, + "version": applied.get("runtime_version"), + "method_count": len(entries), + "by_verb": dict(by_verb), + "probed": probed, + "above_floor_checked": above_floor, + "buckets": dict(buckets), + "failures": failures, + } + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument("--majors", default="6,7,8,9", help="Comma-separated majors") + args = parser.parse_args() + majors = [int(x) for x in args.majors.split(",") if x.strip()] + for major in majors: + if major not in VERSIONS: + raise SystemExit(f"unknown major {major}") + + session = _login() + reports = [] + all_failures: list[dict[str, Any]] = [] + for major in majors: + report = probe_major(major, session) + reports.append(report) + all_failures.extend(report["failures"]) + # Refresh session between majors (logout delete skipped during probe). + session = _login() + + # Restore latest floor for the lab UI. + _apply_major(9, {"vmware-api-session-id": session, "Content-Type": "application/json"}) + + summary = { + "base": BASE, + "majors": reports, + "total_failures": len(all_failures), + "failures": all_failures[:80], + } + print(json.dumps(summary, indent=2)) + return 1 if all_failures else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/vsphere_nonempty_probe.py b/scripts/vsphere_nonempty_probe.py new file mode 100644 index 0000000..06b3478 --- /dev/null +++ b/scripts/vsphere_nonempty_probe.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 +"""Fail if any registered GET returns 501, stub marker, or empty JSON body.""" + +from __future__ import annotations + +import json +import os +import re +import ssl +import sys +import urllib.error +import urllib.request +from base64 import b64encode + +from app.vsphere.rest.coverage import IMPLEMENTED + +BASE = os.getenv("VSPHERE_BASE", "https://localhost") +USER = os.getenv("VSPHERE_USER", "administrator@vsphere.local") +PASSWORD = os.getenv("VSPHERE_PASSWORD", "VMware1!") + +_SUBS = { + "{vm}": "vm-101", + "{host}": "host-11", + "{datastore}": "datastore-31", + "{task}": "task-1", + "{snapshot}": "snapshot-missing", + "{category_id}": "cat-lab-1", + "{tag_id}": "tag-lab-1", + "{item_id}": "item-ubuntu", + "{library_id}": "lib-local-1", + "{folder}": "group-v23", + "{datacenter}": "datacenter-21", + "{cluster}": "domain-c21", + "{resource_pool}": "resgroup-22", + "{permission_id}": "1", + "{policy}": "policy-default", + "{disk}": "2000", + "{nic}": "4000", + "{cdrom}": "3000", + "{adapter}": "1000", + "{network}": "network-41", + "{supervisor}": "supervisor-1", + "{commit}": "commit-lab-1", + "{domain}": "lab.local", + "{interface}": "nic0", + "{service}": "vpxd", + "{session_id}": "session-lab-1", + "{download_session_id}": "session-lab-1", + "{update_session_id}": "session-lab-1", + "{provider}": "vsphere.local", + "{role}": "ReadOnly", + "{chain}": "chain-1", + "{floppy}": "8000", + "{port}": "9000", +} + + +def _ctx() -> ssl.SSLContext | None: + if not BASE.startswith("https://"): + return None + return ssl._create_unverified_context() # noqa: S323 + + +def _concrete(path: str) -> str: + out = path + for key, value in _SUBS.items(): + out = out.replace(key, value) + return re.sub(r"\{([A-Za-z0-9_]+)\}", r"lab-\1", out) + + +def _request(method: str, path: str, *, headers: dict[str, str]) -> tuple[int, str]: + req = urllib.request.Request(f"{BASE}{path}", method=method, headers=headers) + try: + with urllib.request.urlopen(req, context=_ctx(), timeout=60) as resp: # noqa: S310 + return int(resp.status), resp.read().decode("utf-8", errors="replace") + except urllib.error.HTTPError as error: + return int(error.code), error.read().decode("utf-8", errors="replace") + + +def main() -> int: + basic = b64encode(f"{USER}:{PASSWORD}".encode()).decode() + code, body = _request("POST", "/api/session", headers={"Authorization": f"Basic {basic}"}) + if code not in {200, 201}: + print(json.dumps({"error": f"session failed {code}", "body": body[:200]})) + return 1 + session = json.loads(body) + headers = {"vmware-api-session-id": session, "Accept": "application/json"} + failures: list[dict[str, object]] = [] + ok = 0 + checked = 0 + for (verb, path), _status in sorted(IMPLEMENTED.items()): + if verb != "GET" or path in {"/api/session", "/rest/com/vmware/cis/session"}: + continue + checked += 1 + concrete = _concrete(path) + if path == "/api/content/library/item": + concrete = f"{concrete}?library_id=lib-local-1" + status, raw = _request("GET", concrete, headers=headers) + if status == 501: + failures.append({"path": path, "status": status, "reason": "version gate 501"}) + continue + if status >= 500: + failures.append( + {"path": path, "status": status, "reason": "server error", "body": raw[:160]} + ) + continue + if status not in {200, 201}: + # Missing probe ids may 404 — still require a JSON error body. + if not raw.strip(): + failures.append({"path": path, "status": status, "reason": "empty error body"}) + continue + if not raw.strip(): + failures.append({"path": path, "status": status, "reason": "empty body"}) + continue + if '"stub": true' in raw or '"stub":true' in raw: + failures.append({"path": path, "status": status, "reason": "stub marker"}) + continue + try: + payload = json.loads(raw) + except json.JSONDecodeError: + failures.append( + {"path": path, "status": status, "reason": "non-json", "body": raw[:160]} + ) + continue + if payload in ([], {}, None, "") or ( + isinstance(payload, (list, dict)) and len(payload) == 0 + ): + failures.append( + {"path": path, "status": status, "reason": "empty json", "body": raw[:160]} + ) + continue + if isinstance(payload, dict): + for key in ("data", "value", "messages", "items", "results"): + if key in payload and payload[key] in ([], None, {}): + failures.append( + { + "path": path, + "status": status, + "reason": f"empty nested {key}", + "body": raw[:160], + } + ) + break + else: + ok += 1 + continue + ok += 1 + print( + json.dumps( + { + "checked": checked, + "ok": ok, + "failure_count": len(failures), + "failures": failures[:80], + }, + indent=2, + ) + ) + return 1 if failures else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/vsphere_real_data_spotcheck.py b/scripts/vsphere_real_data_spotcheck.py new file mode 100644 index 0000000..e6af045 --- /dev/null +++ b/scripts/vsphere_real_data_spotcheck.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +"""Spot-check that critical Automation API GETs return real seeded payloads.""" + +from __future__ import annotations + +import json +import os +import ssl +import sys +import urllib.error +import urllib.request +from base64 import b64encode + +BASE = os.getenv("VSPHERE_BASE", "https://localhost") +USER = os.getenv("VSPHERE_USER", "administrator@vsphere.local") +PASSWORD = os.getenv("VSPHERE_PASSWORD", "VMware1!") + +SPOTS = [ + ("/api/vcenter/vm", "list"), + ("/api/vcenter/host", "list"), + ("/api/vcenter/datastore", "list"), + ("/api/vcenter/network", "list"), + ("/api/vcenter/cluster", "list"), + ("/api/content/library", "list"), + ("/api/cis/tagging/category", "list"), + ("/api/appliance/access/ssh", "object"), + ("/api/appliance/services", "list"), + ("/api/esx/settings/clusters/domain-c21/software", "object"), + ("/api/vcenter/namespace-management/supervisors/supervisor-1/summary", "object"), + ("/api/vcenter/crypto-manager/kms/providers", "list"), + ("/api/vcenter/vm/vm-101/hardware/cdrom", "list"), + ("/api/vcenter/vm/vm-101/hardware/disk", "list"), + ("/api/vcenter/host/host-11/networking", "object"), + ("/api/vcenter/host/host-11/storage/storage-device", "list"), + ("/api/vcenter/storage/policies", "list"), + ("/api/vcenter/guest/customization-specs", "list"), + ("/api/vcenter/identity/providers", "list"), + ("/api/vcenter/certificate-management/vcenter/tls", "object"), +] + + +def _ctx() -> ssl.SSLContext | None: + if not BASE.startswith("https://"): + return None + return ssl._create_unverified_context() # noqa: S323 + + +def _request(method: str, path: str, *, headers: dict[str, str]) -> tuple[int, str]: + req = urllib.request.Request(f"{BASE}{path}", method=method, headers=headers) + try: + with urllib.request.urlopen(req, context=_ctx()) as resp: # noqa: S310 + return int(resp.status), resp.read().decode("utf-8", errors="replace") + except urllib.error.HTTPError as error: + return int(error.code), error.read().decode("utf-8", errors="replace") + + +def main() -> int: + basic = b64encode(f"{USER}:{PASSWORD}".encode()).decode() + code, body = _request("POST", "/api/session", headers={"Authorization": f"Basic {basic}"}) + if code not in {200, 201}: + print(json.dumps({"error": f"session failed {code}", "body": body[:200]})) + return 1 + session = json.loads(body) + headers = {"vmware-api-session-id": session, "Accept": "application/json"} + failures: list[dict[str, object]] = [] + ok = 0 + for path, kind in SPOTS: + status, raw = _request("GET", path, headers=headers) + if status != 200: + failures.append({"path": path, "status": status, "body": raw[:160]}) + continue + if '"stub": true' in raw or '"stub":true' in raw: + failures.append( + {"path": path, "status": status, "reason": "stub marker", "body": raw[:160]} + ) + continue + try: + payload = json.loads(raw) + except json.JSONDecodeError: + failures.append( + {"path": path, "status": status, "reason": "non-json", "body": raw[:160]} + ) + continue + if kind == "list": + if not isinstance(payload, list) or len(payload) < 1: + failures.append( + {"path": path, "status": status, "reason": "empty list", "body": raw[:160]} + ) + continue + else: + if not isinstance(payload, dict) or not payload: + failures.append( + {"path": path, "status": status, "reason": "empty object", "body": raw[:160]} + ) + continue + ok += 1 + print(json.dumps({"checked": len(SPOTS), "ok": ok, "failures": failures}, indent=2)) + return 1 if failures else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/vsphere_surface_probe.py b/scripts/vsphere_surface_probe.py new file mode 100644 index 0000000..fb6397f --- /dev/null +++ b/scripts/vsphere_surface_probe.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python3 +"""Probe every implemented REST path from the coverage registry.""" + +from __future__ import annotations + +import json +import os +import ssl +import sys +import urllib.error +import urllib.request +from base64 import b64encode + +from app.vsphere.rest.coverage import catalog_entries + +BASE = os.getenv("VSPHERE_BASE", "https://localhost") +USER = "administrator@vsphere.local" +PASSWORD = "VMware1!" + + +def _ctx() -> ssl.SSLContext | None: + if not BASE.startswith("https://"): + return None + return ssl._create_unverified_context() # noqa: S323 + + +def _concrete(path: str) -> str: + import re + + subs = { + "{vm}": "vm-101", + "{host}": "host-11", + "{datastore}": "datastore-31", + "{task}": "task-missing", + "{snapshot}": "snapshot-missing", + "{category_id}": "missing", + "{tag_id}": "missing", + "{item_id}": "missing", + "{library_id}": "lib-missing", + "{folder}": "group-v23", + "{datacenter}": "datacenter-21", + "{cluster}": "domain-c21", + "{resource_pool}": "resgroup-22", + "{permission_id}": "1", + "{policy}": "policy-default", + "{disk}": "2000", + "{nic}": "4000", + "{cdrom}": "3000", + "{adapter}": "1000", + "{network}": "network-41", + } + out = path + for key, value in subs.items(): + out = out.replace(key, value) + return re.sub(r"\{([A-Za-z0-9_]+)\}", r"probe-\1", out) + + +def _request(method: str, path: str, *, headers: dict[str, str], data: bytes | None = None) -> int: + concrete = _concrete(path) + req = urllib.request.Request(f"{BASE}{concrete}", data=data, method=method, headers=headers) + try: + with urllib.request.urlopen(req, context=_ctx()) as resp: # noqa: S310 + return int(resp.status) + except urllib.error.HTTPError as error: + return int(error.code) + + +def main() -> int: + basic = b64encode(f"{USER}:{PASSWORD}".encode()).decode() + status = _request("POST", "/api/session", headers={"Authorization": f"Basic {basic}"}) + if status not in {200, 201}: + print(f"session failed: {status}", file=sys.stderr) + return 1 + # Re-login to capture body + req = urllib.request.Request( + f"{BASE}/api/session", + method="POST", + headers={"Authorization": f"Basic {basic}"}, + ) + with urllib.request.urlopen(req, context=_ctx()) as resp: # noqa: S310 + session = json.loads(resp.read().decode()) + headers = {"vmware-api-session-id": session, "Content-Type": "application/json"} + failures: list[str] = [] + probed = 0 + for entry in catalog_entries(): + verb = entry["verb"] + path = entry["path"] + if verb == "DELETE" and path in {"/api/session", "/rest/com/vmware/cis/session"}: + continue + if ( + "{" in path + and verb in {"POST", "PATCH", "DELETE"} + and "missing" in (path.replace("{vm}", "vm-101")) + ): + # skip destructive ops on missing ids except GET + pass + data = b"{}" if verb in {"POST", "PUT", "PATCH"} else None + if path.endswith("/power") and verb == "POST": + code = _request(verb, path + "?action=start", headers=headers) + elif "tag-association" in path and verb == "POST": + data = json.dumps( + { + "action": "list-attached-tags", + "tag_id": "x", + "object_id": {"type": "VirtualMachine", "id": "vm-101"}, + } + ).encode() + code = _request(verb, path, headers=headers, data=data) + else: + code = _request(verb, path, headers=headers, data=data) + probed += 1 + # Accept success, not-found for missing substitutions, or validation errors. + if code >= 500: + failures.append(f"{verb} {path} -> {code}") + continue + if verb == "GET" and 200 <= code < 300: + # Surface probe reads body via a second request-sized check only for markers. + # Re-fetch is avoided: empty GET bodies for session are OK. + pass + # Re-auth in case any probe request invalidated the session cookie. + req = urllib.request.Request( + f"{BASE}/api/session", + method="POST", + headers={"Authorization": f"Basic {basic}"}, + ) + with urllib.request.urlopen(req, context=_ctx()) as resp: # noqa: S310 + session = json.loads(resp.read().decode()) + headers = {"vmware-api-session-id": session, "Content-Type": "application/json"} + + # Spot-check critical inventory payloads are non-empty / non-stub. + spot = [ + "/api/vcenter/vm", + "/api/vcenter/host", + "/api/content/library", + "/api/cis/tagging/category", + "/api/esx/settings/clusters/domain-c21/software", + "/api/vcenter/namespace-management/supervisors/supervisor-1/summary", + "/api/appliance/access/ssh", + "/api/appliance/services", + "/api/vcenter/vm/vm-101/hardware/cdrom", + ] + for path in spot: + url = f"{BASE}{_concrete(path)}" + req = urllib.request.Request(url, method="GET", headers=headers) + try: + with urllib.request.urlopen(req, context=_ctx()) as resp: # noqa: S310 + body = resp.read().decode("utf-8", errors="replace") + code = int(resp.status) + except urllib.error.HTTPError as error: + body = error.read().decode("utf-8", errors="replace") + code = int(error.code) + if code >= 400: + failures.append(f"GET {path} spot -> {code}") + continue + if '"stub": true' in body or '"stub":true' in body: + failures.append(f"GET {path} spot -> stub marker") + continue + try: + parsed = json.loads(body) + except json.JSONDecodeError: + failures.append(f"GET {path} spot -> non-json") + continue + if parsed in ([], {}, None): + failures.append(f"GET {path} spot -> empty") + print(json.dumps({"probed": probed, "failures": failures}, indent=2)) + return 1 if failures else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/write_vsphere_bundles.py b/scripts/write_vsphere_bundles.py new file mode 100644 index 0000000..68ecc26 --- /dev/null +++ b/scripts/write_vsphere_bundles.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 +"""Regenerate contracts/vsphere/*/manifest.json stub OpenAPI matrices.""" + +from __future__ import annotations + +from app.vsphere.contracts.matrix import write_bundles + + +def main() -> int: + written = write_bundles() + for path in written: + print(path) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/write_vsphere_evidence.py b/scripts/write_vsphere_evidence.py new file mode 100644 index 0000000..c4b2f41 --- /dev/null +++ b/scripts/write_vsphere_evidence.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +"""Regenerate evidence/vsphere-*.json ledgers from the live coverage matrix.""" + +from __future__ import annotations + +import json +from pathlib import Path + +from app.vsphere.contracts.compatibility import evidence_ledger +from app.vsphere.contracts.matrix import VERSIONS + +ROOT = Path(__file__).resolve().parents[1] / "evidence" + + +def main() -> int: + ROOT.mkdir(parents=True, exist_ok=True) + for major, meta in VERSIONS.items(): + payload = evidence_ledger(major) + path = ROOT / f"vsphere-{meta['version']}.json" + path.write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8") + summary = payload["summary"] + print( + f"{path} implemented={summary['implemented_methods']}/" + f"{summary['universe_methods']} coverage={summary['coverage']}" + ) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..38bb211 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +"""Test package.""" diff --git a/tests/compatibility/__init__.py b/tests/compatibility/__init__.py new file mode 100644 index 0000000..c1212c3 --- /dev/null +++ b/tests/compatibility/__init__.py @@ -0,0 +1 @@ +"""External client compatibility tests.""" diff --git a/tests/compatibility/test_api_surface_probe.py b/tests/compatibility/test_api_surface_probe.py new file mode 100644 index 0000000..f644a56 --- /dev/null +++ b/tests/compatibility/test_api_surface_probe.py @@ -0,0 +1,38 @@ +"""CI gate: every declared method on majors 6-9 is callable without critical failures. + +Critical = HTTP 501, server 5xx, unhandled exceptions, or emulator-limitation +strings. Synthetic 4xx (missing object / incomplete payload) are allowed. +Requires PostgreSQL via ``TEST_DATABASE_URL``. +""" + +from __future__ import annotations + +import os + +import pytest + +from app.surface_probe import run_probe + +pytestmark = [ + pytest.mark.integration, + pytest.mark.skipif(not os.getenv("TEST_DATABASE_URL"), reason="TEST_DATABASE_URL is required"), +] + + +@pytest.mark.asyncio +async def test_all_majors_surface_has_zero_critical_failures() -> None: + results = await run_probe() + assert len(results) == 4 + for item in results: + version = item["version"] + declared = item["declared"] + assert item["implemented"] == declared, version + assert item["verified"] == declared, version + assert item["dimensions_min"] == declared, version + assert item["failure_count"] == 0, f"{version} critical failures: {item.get('failures')}" + by_verb = item["by_verb"] + for verb, buckets in by_verb.items(): + assert buckets.get("unimplemented_501", 0) == 0, (version, verb, buckets) + assert buckets.get("unsupported_message", 0) == 0, (version, verb, buckets) + assert buckets.get("server_5xx", 0) == 0, (version, verb, buckets) + assert buckets.get("exception", 0) == 0, (version, verb, buckets) diff --git a/tests/compatibility/test_group_smoke.py b/tests/compatibility/test_group_smoke.py new file mode 100644 index 0000000..5289926 --- /dev/null +++ b/tests/compatibility/test_group_smoke.py @@ -0,0 +1,283 @@ +"""Group-level API smoke with real PostgreSQL persistence. + +Exercises representative create/update/read paths per major API group so the +surface verified ledger is backed by working handlers, not only route presence. +Requires ``TEST_DATABASE_URL`` (same as other integration tests). +""" + +from __future__ import annotations + +import asyncio +import os +from collections.abc import AsyncIterator +from pathlib import Path +from typing import Any, cast + +import asyncpg # type: ignore[import-untyped] +import pytest +from httpx import ASGITransport, AsyncClient +from pydantic import SecretStr + +from app.config import Settings +from app.db.migrations import migrate +from app.db.pool import AsyncpgDatabase +from app.main import create_app +from app.simulation.seed import apply_seed, small_profile + +pytestmark = pytest.mark.pve_stub + +pytestmark = [ + pytest.mark.integration, + pytest.mark.skipif(not os.getenv("TEST_DATABASE_URL"), reason="TEST_DATABASE_URL is required"), +] + +_BUNDLED_9 = Path( + "contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/snapshot.json" +) +_EVIDENCE_9 = Path("evidence/pve-9.2.3.json") +_NODE = "pve01" + + +async def _prepare_database(url: str) -> None: + connection = await asyncpg.connect(url) + try: + await migrate(connection) + await apply_seed(connection, small_profile()) + finally: + await connection.close() + + +async def _login(client: AsyncClient) -> str: + response = await client.post( + "/api2/json/access/ticket", + content="username=root%40pam&password=secret", + headers={"content-type": "application/x-www-form-urlencoded"}, + ) + assert response.status_code == 200, response.text + data = response.json()["data"] + assert data["username"] == "root@pam" + ticket = data["ticket"] + client.cookies.set("PVEAuthCookie", ticket) + return str(data["CSRFPreventionToken"]) + + +async def _wait_task(client: AsyncClient, upid: str, *, node: str = _NODE) -> dict[str, Any]: + for _ in range(100): + response = await client.get(f"/api2/json/nodes/{node}/tasks/{upid}/status") + assert response.status_code == 200, response.text + task = cast(dict[str, Any], response.json()["data"]) + if task.get("status") == "stopped": + return task + await asyncio.sleep(0.05) + raise AssertionError(f"task did not finish: {upid}") + + +@pytest.fixture +async def api_client() -> AsyncIterator[tuple[AsyncClient, str]]: + url = os.environ["TEST_DATABASE_URL"] + await _prepare_database(url) + settings = Settings( + database_url=SecretStr(url), + contract_snapshot=_BUNDLED_9, + compatibility_evidence=_EVIDENCE_9, + ticket_signing_key=SecretStr("development-only-signing-key-change-me"), + ) + + def database_factory(resolved: Settings) -> AsyncpgDatabase: + return AsyncpgDatabase(resolved) + + app = create_app(settings=settings, database_factory=database_factory) + async with app.router.lifespan_context(app): + async with AsyncClient( + transport=ASGITransport(app=app), + base_url="http://test", + ) as client: + csrf = await _login(client) + yield client, csrf + + +async def test_access_group_realm_and_user_persist(api_client: tuple[AsyncClient, str]) -> None: + client, csrf = api_client + realm = "smoke-ldap" + create_realm = await client.post( + "/api2/json/access/domains", + data={ + "realm": realm, + "type": "ldap", + "server1": "ldap.smoke.local", + "base_dn": "dc=smoke,dc=local", + "comment": "group smoke realm", + }, + headers={"CSRFPreventionToken": csrf}, + ) + assert create_realm.status_code == 200, create_realm.text + + listed = await client.get("/api2/json/access/domains") + assert listed.status_code == 200 + names = {item["realm"] for item in listed.json()["data"]} + assert realm in names + + detail = await client.get(f"/api2/json/access/domains/{realm}") + assert detail.status_code == 200 + assert detail.json()["data"]["type"] == "ldap" + + user = "smoke-user@pam" + create_user = await client.post( + "/api2/json/access/users", + data={"userid": user, "comment": "group smoke user", "enable": 1}, + headers={"CSRFPreventionToken": csrf}, + ) + assert create_user.status_code == 200, create_user.text + got_user = await client.get(f"/api2/json/access/users/{user}") + assert got_user.status_code == 200 + assert got_user.json()["data"]["userid"] == user + + delete_realm = await client.delete( + f"/api2/json/access/domains/{realm}", + headers={"CSRFPreventionToken": csrf}, + ) + assert delete_realm.status_code == 200, delete_realm.text + + +async def test_qemu_group_create_config_and_power(api_client: tuple[AsyncClient, str]) -> None: + client, csrf = api_client + vmid = 9101 + create = await client.post( + f"/api2/json/nodes/{_NODE}/qemu", + data={ + "vmid": str(vmid), + "name": "smoke-qemu", + "cores": "1", + "memory": "512", + }, + headers={"CSRFPreventionToken": csrf}, + ) + assert create.status_code == 200, create.text + upid = create.json()["data"] + assert isinstance(upid, str) and upid.startswith("UPID:") + task = await _wait_task(client, upid) + assert task.get("exitstatus") == "OK" + + config = await client.get(f"/api2/json/nodes/{_NODE}/qemu/{vmid}/config") + assert config.status_code == 200 + assert config.json()["data"]["name"] == "smoke-qemu" + + update = await client.put( + f"/api2/json/nodes/{_NODE}/qemu/{vmid}/config", + data={"name": "smoke-qemu-renamed", "cores": "2"}, + headers={"CSRFPreventionToken": csrf}, + ) + assert update.status_code == 200, update.text + config2 = await client.get(f"/api2/json/nodes/{_NODE}/qemu/{vmid}/config") + assert config2.json()["data"]["name"] == "smoke-qemu-renamed" + assert int(config2.json()["data"]["cores"]) == 2 + + start = await client.post( + f"/api2/json/nodes/{_NODE}/qemu/{vmid}/status/start", + headers={"CSRFPreventionToken": csrf}, + ) + assert start.status_code == 200, start.text + start_task = await _wait_task(client, start.json()["data"]) + assert start_task.get("exitstatus") == "OK" + status = await client.get(f"/api2/json/nodes/{_NODE}/qemu/{vmid}/status/current") + assert status.status_code == 200 + assert status.json()["data"]["status"] in {"running", "started"} + + +async def test_lxc_group_create_and_status(api_client: tuple[AsyncClient, str]) -> None: + client, csrf = api_client + vmid = 9201 + create = await client.post( + f"/api2/json/nodes/{_NODE}/lxc", + data={ + "vmid": str(vmid), + "hostname": "smoke-lxc", + "ostemplate": "local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst", + "memory": "256", + "rootfs": "local-lvm:4", + }, + headers={"CSRFPreventionToken": csrf}, + ) + assert create.status_code == 200, create.text + upid = create.json()["data"] + task = await _wait_task(client, upid) + assert task.get("exitstatus") == "OK" + + config = await client.get(f"/api2/json/nodes/{_NODE}/lxc/{vmid}/config") + assert config.status_code == 200 + cfg = config.json()["data"] + assert "hostname" in cfg or cfg.get("hostname") == "smoke-lxc" + + status = await client.get(f"/api2/json/nodes/{_NODE}/lxc/{vmid}/status/current") + assert status.status_code == 200 + assert "status" in status.json()["data"] + + +async def test_storage_and_cluster_groups_mutate(api_client: tuple[AsyncClient, str]) -> None: + client, csrf = api_client + + storages = await client.get("/api2/json/storage") + if storages.status_code == 404: + storages = await client.get(f"/api2/json/nodes/{_NODE}/storage") + assert storages.status_code == 200, storages.text + assert storages.json()["data"] + + content = await client.get(f"/api2/json/nodes/{_NODE}/storage/local/content") + assert content.status_code == 200, content.text + assert isinstance(content.json()["data"], list) + + resources = await client.get("/api2/json/cluster/resources") + assert resources.status_code == 200 + assert resources.json()["data"] + + notify = await client.post( + "/api2/json/cluster/notifications/endpoints/gotify", + data={ + "name": "smoke-gotify", + "server": "https://gotify.smoke.local", + "token": "smoke-token", + }, + headers={"CSRFPreventionToken": csrf}, + ) + assert notify.status_code == 200, notify.text + got = await client.get("/api2/json/cluster/notifications/endpoints/gotify/smoke-gotify") + assert got.status_code == 200 + assert got.json()["data"]["name"] == "smoke-gotify" + # secret must not be echoed + assert "token" not in got.json()["data"] or got.json()["data"].get("token") in {None, ""} + + +async def test_sdn_and_node_ops_groups_persist(api_client: tuple[AsyncClient, str]) -> None: + client, csrf = api_client + + zone = await client.post( + "/api2/json/cluster/sdn/zones", + data={"zone": "smokecn", "type": "simple", "mtu": "1500"}, + headers={"CSRFPreventionToken": csrf}, + ) + assert zone.status_code == 200, zone.text + zones = await client.get("/api2/json/cluster/sdn/zones") + assert zones.status_code == 200 + names = {item.get("zone") or item.get("id") for item in zones.json()["data"]} + assert "smokecn" in names + + network_put = await client.put( + f"/api2/json/nodes/{_NODE}/network", + data={}, + headers={"CSRFPreventionToken": csrf}, + ) + # Apply/reload may return null/UPID; must not be 501. + assert network_put.status_code == 200, network_put.text + + dns = await client.get(f"/api2/json/nodes/{_NODE}/dns") + assert dns.status_code == 200 + assert isinstance(dns.json()["data"], dict) + + dns_put = await client.put( + f"/api2/json/nodes/{_NODE}/dns", + data={"search": "smoke.local", "dns1": "1.1.1.1"}, + headers={"CSRFPreventionToken": csrf}, + ) + assert dns_put.status_code == 200, dns_put.text + dns2 = await client.get(f"/api2/json/nodes/{_NODE}/dns") + assert dns2.json()["data"].get("search") == "smoke.local" or "dns1" in dns2.json()["data"] diff --git a/tests/compatibility/test_proxmoxer.py b/tests/compatibility/test_proxmoxer.py new file mode 100644 index 0000000..8d1fac8 --- /dev/null +++ b/tests/compatibility/test_proxmoxer.py @@ -0,0 +1,195 @@ +"""Unmodified proxmoxer HTTPS smoke flow.""" + +import os +from threading import Event +from typing import Any, cast + +import pytest +from proxmoxer import ProxmoxAPI, ResourceException # type: ignore[import-untyped] + +pytestmark = pytest.mark.pve_stub + +pytestmark = [ + pytest.mark.compatibility, + pytest.mark.skipif(not os.getenv("PROXMOXER_HOST"), reason="running TLS simulator required"), +] + + +def wait_task(proxmox: Any, upid: str) -> dict[str, object]: + for _attempt in range(100): + task = proxmox.nodes("pve1").tasks(upid).status.get() + if task["status"] == "stopped": + return cast(dict[str, object], task) + Event().wait(0.05) + raise AssertionError("task did not finish") + + +def test_proxmoxer_read_and_qemu_task_flow() -> None: + proxmox = ProxmoxAPI( + os.environ["PROXMOXER_HOST"], + port=int(os.getenv("PROXMOXER_PORT", "8007")), + user="root@pam", + password=os.getenv("PROXMOXER_PASSWORD", "secret"), + verify_ssl=False, + ) + + assert proxmox.version.get()["version"] == "9.2.3" + assert any(node["node"] == "pve1" for node in proxmox.nodes.get()) + assert any(vm["vmid"] == 101 for vm in proxmox.nodes("pve1").qemu.get()) + + token_api = ProxmoxAPI( + os.environ["PROXMOXER_HOST"], + port=int(os.getenv("PROXMOXER_PORT", "8007")), + user="root@pam", + token_name=os.getenv("PROXMOXER_TOKEN_NAME", "automation"), + token_value=os.getenv("PROXMOXER_TOKEN_SECRET", "automation-secret"), + verify_ssl=False, + ) + assert any(node["node"] == "pve1" for node in token_api.nodes.get()) + + readonly_api = ProxmoxAPI( + os.environ["PROXMOXER_HOST"], + port=int(os.getenv("PROXMOXER_PORT", "8007")), + user="auditor@pve", + token_name=os.getenv("PROXMOXER_READONLY_TOKEN_NAME", "readonly"), + token_value=os.getenv("PROXMOXER_READONLY_TOKEN_SECRET", "readonly-secret"), + verify_ssl=False, + ) + assert readonly_api.nodes.get() + assert readonly_api.nodes("pve1").status.get()["status"] == "online" + assert readonly_api.nodes("pve1").qemu("101").config.get()["vmid"] == 101 + with pytest.raises(ResourceException) as denied: + readonly_api.nodes("pve1").qemu("101").status.start.post() + assert denied.value.status_code == 403 + + token_endpoint = proxmox.access.users("root@pam").token("ephemeral") + created = token_endpoint.post(comment="compatibility lifecycle", privsep=0) + assert created["full-tokenid"] == "root@pam!ephemeral" + ephemeral = ProxmoxAPI( + os.environ["PROXMOXER_HOST"], + port=int(os.getenv("PROXMOXER_PORT", "8007")), + user="root@pam", + token_name=os.getenv("PROXMOXER_EPHEMERAL_TOKEN_NAME", "ephemeral"), + token_value=created["value"], + verify_ssl=False, + ) + assert ephemeral.nodes.get() + updated = token_endpoint.put(comment="updated", privsep=0) + assert updated["comment"] == "updated" + assert token_endpoint.get()["comment"] == "updated" + token_endpoint.delete() + with pytest.raises(ResourceException) as removed: + ephemeral.nodes.get() + assert removed.value.status_code == 401 + + storage_api = ProxmoxAPI( + os.environ["PROXMOXER_HOST"], + port=int(os.getenv("PROXMOXER_PORT", "8007")), + user="storage@pve", + token_name=os.getenv("PROXMOXER_STORAGE_TOKEN_NAME", "storage"), + token_value=os.getenv("PROXMOXER_STORAGE_TOKEN_SECRET", "storage-secret"), + verify_ssl=False, + ) + for vmid in ("101", "999999"): + with pytest.raises(ResourceException) as hidden: + storage_api.nodes("pve1").qemu(vmid).config.get() + assert hidden.value.status_code == 403 + + create_upid = proxmox.nodes("pve1").qemu.post( + vmid=150, + name="created-by-proxmoxer", + cores=2, + memory=1024, + agent=1, + scsi0="local-lvm:vm-150-disk-0,size=8G", + ) + with pytest.raises(ResourceException) as duplicate_create: + proxmox.nodes("pve1").qemu.post(vmid=150, name="duplicate") + assert duplicate_create.value.status_code == 409 + assert wait_task(proxmox, create_upid)["exitstatus"] == "OK" + created_config = proxmox.nodes("pve1").qemu("150").config.get() + assert created_config["name"] == "created-by-proxmoxer" + assert created_config["cores"] == 2 + + assert proxmox.nodes("pve1").qemu("150").config.put(name="sync-update", cores=3) is None + assert proxmox.nodes("pve1").qemu("150").config.get()["name"] == "sync-update" + update_upid = proxmox.nodes("pve1").qemu("150").config.post(name="async-update", memory=2048) + assert wait_task(proxmox, update_upid)["exitstatus"] == "OK" + assert proxmox.nodes("pve1").qemu("150").config.get()["name"] == "async-update" + + disk_api = proxmox.nodes("pve1").qemu("150") + assert disk_api.resize.put(disk="scsi0", size="+2G") is None + assert "size=10G" in disk_api.config.get()["scsi0"] + move_upid = disk_api.move_disk.post(disk="scsi0", storage="local") + assert wait_task(proxmox, move_upid)["exitstatus"] == "OK" + assert disk_api.config.get()["scsi0"].startswith("local:") + assert disk_api.pending.get() == [] + assert wait_task(proxmox, disk_api.status.start.post())["exitstatus"] == "OK" + assert disk_api.agent.ping.post()["result"] == {} + assert disk_api.agent.info.get()["result"]["version"] == "9.2.0-simulator" + assert disk_api.agent("get-osinfo").get()["result"]["machine"] == "x86_64" + assert disk_api.agent("get-host-name").get()["result"]["host-name"] == "async-update" + assert disk_api.agent("network-get-interfaces").get()["result"][0]["name"] == "eth0" + assert disk_api.agent("get-time").get()["result"]["seconds"] > 0 + assert wait_task(proxmox, disk_api.status.stop.post())["exitstatus"] == "OK" + + snapshots = proxmox.nodes("pve1").qemu("150").snapshot + snapshot_upid = snapshots.post(snapname="baseline", description="before change") + assert wait_task(proxmox, snapshot_upid)["exitstatus"] == "OK" + assert any(item["name"] == "baseline" for item in snapshots.get()) + baseline = snapshots("baseline") + assert baseline.get()["description"] == "before change" + assert baseline.config.put(description="stable baseline") is None + assert baseline.config.get()["description"] == "stable baseline" + assert proxmox.nodes("pve1").qemu("150").config.put(name="after-snapshot") is None + rollback_upid = baseline.rollback.post() + assert wait_task(proxmox, rollback_upid)["exitstatus"] == "OK" + assert proxmox.nodes("pve1").qemu("150").config.get()["name"] == "async-update" + snapshot_delete_upid = baseline.delete() + assert wait_task(proxmox, snapshot_delete_upid)["exitstatus"] == "OK" + assert not snapshots.get() + + clone_upid = ( + proxmox.nodes("pve1").qemu("150").clone.post(newid=151, name="clone-by-proxmoxer", full=1) + ) + assert wait_task(proxmox, clone_upid)["exitstatus"] == "OK" + assert proxmox.nodes("pve1").qemu("151").config.get()["name"] == "clone-by-proxmoxer" + migration = proxmox.nodes("pve1").qemu("151").migrate + assert migration.get(target="pve2")["local_disks"] == [] + migrate_upid = migration.post(target="pve2", online=0) + assert wait_task(proxmox, migrate_upid)["exitstatus"] == "OK" + assert proxmox.nodes("pve2").qemu("151").config.get()["name"] == "clone-by-proxmoxer" + clone_delete_upid = proxmox.nodes("pve2").qemu("151").delete() + assert wait_task(proxmox, clone_delete_upid)["exitstatus"] == "OK" + + delete_upid = proxmox.nodes("pve1").qemu("150").delete() + assert wait_task(proxmox, delete_upid)["exitstatus"] == "OK" + with pytest.raises(ResourceException) as deleted_vm: + proxmox.nodes("pve1").qemu("150").config.get() + assert deleted_vm.value.status_code == 404 + + if os.getenv("PROXMOXER_MUTATION_TEST") == "1": + operator_api = ProxmoxAPI( + os.environ["PROXMOXER_HOST"], + port=int(os.getenv("PROXMOXER_PORT", "8007")), + user="operator@pve", + token_name=os.getenv("PROXMOXER_OPERATOR_TOKEN_NAME", "operator"), + token_value=os.getenv("PROXMOXER_OPERATOR_TOKEN_SECRET", "operator-secret"), + verify_ssl=False, + ) + status_resource = operator_api.nodes("pve1").qemu("101").status + + def run(operation: str, expected: str) -> None: + upid = status_resource(operation).post() + assert wait_task(operator_api, upid)["exitstatus"] == "OK" + assert status_resource.current.get()["status"] == expected + + if status_resource.current.get()["status"] == "stopped": + run("start", "running") + run("reboot", "running") + run("reset", "running") + run("suspend", "paused") + run("resume", "running") + run("shutdown", "stopped") + run("start", "running") + run("stop", "stopped") diff --git a/tests/compatibility/test_verified_surface.py b/tests/compatibility/test_verified_surface.py new file mode 100644 index 0000000..78dc924 --- /dev/null +++ b/tests/compatibility/test_verified_surface.py @@ -0,0 +1,73 @@ +"""Durable full-surface verified ledger for bundled Proxmox majors 6-9. + +These tests stay offline (no TLS gateway). When a new contract snapshot is +imported, regenerate ledgers with ``make evidence`` and commit the updated +``evidence/pve-*.json`` files so this suite stays green. +""" + +from __future__ import annotations + +from pathlib import Path + +import pytest +from fastapi import FastAPI +from httpx import ASGITransport, AsyncClient + +from app.config import Settings +from app.evidence_gen import generate_all +from app.main import create_app +from tests.unit.test_health import FakeDatabase + +pytestmark = pytest.mark.pve_stub + +_BUNDLED_9 = Path( + "contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/snapshot.json" +) +_EVIDENCE_9 = Path("evidence/pve-9.2.3.json") +_MAJORS = (6, 7, 8, 9) + + +def _app() -> FastAPI: + settings = Settings( + contract_snapshot=_BUNDLED_9, + compatibility_evidence=_EVIDENCE_9, + ) + return create_app( + settings=settings, + database_factory=lambda _settings: FakeDatabase(True), + worker_factories=(), + ) + + +@pytest.mark.parametrize("major", _MAJORS) +async def test_hot_swap_reports_full_verified_surface(major: int) -> None: + app = _app() + async with app.router.lifespan_context(app): + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + applied = await client.post("/ui/api/contract/apply", params={"major": major}) + assert applied.status_code == 200 + assert applied.json()["ok"] is True + + report = await client.get("/admin/compatibility") + assert report.status_code == 200 + body = report.json() + declared = body["total_declared"] + levels = body["levels"] + assert declared > 0 + assert levels["implemented"]["count"] == declared + assert levels["observed"]["count"] == declared + assert levels["verified"]["count"] == declared + assert levels["verified"]["score"] == pytest.approx(1.0) + for name, dimension in (body.get("dimensions") or {}).items(): + assert dimension["count"] == declared, name + assert dimension["score"] == pytest.approx(1.0), name + assert len(body.get("classifications", {}).get("fully_compatible") or []) == declared + + +def test_committed_evidence_matches_generator(tmp_path: Path) -> None: + written = generate_all(out_dir=tmp_path) + assert set(written) == {"6.4-15", "7.4-16", "8.4.5", "9.2.3"} + for version, generated in written.items(): + committed = Path("evidence") / f"pve-{version}.json" + assert committed.is_file(), f"missing committed ledger for {version}" + assert generated.read_text(encoding="utf-8") == committed.read_text(encoding="utf-8") diff --git a/tests/compatibility/test_vsphere_pyvmomi.py b/tests/compatibility/test_vsphere_pyvmomi.py new file mode 100644 index 0000000..4ab035d --- /dev/null +++ b/tests/compatibility/test_vsphere_pyvmomi.py @@ -0,0 +1,44 @@ +"""Optional pyvmomi SmartConnect smoke (skipped when package uninstalled).""" + +from __future__ import annotations + +import os + +import pytest + +pytest.importorskip("pyVim") +pytest.importorskip("pyVmomi") + +from pyVim.connect import Disconnect, SmartConnect # type: ignore[import-untyped] +from pyVmomi import vim # type: ignore[import-untyped] + +pytestmark = pytest.mark.compatibility + + +def test_pyvmomi_inventory_and_power() -> None: + host = os.getenv("VSPHERE_HOST", "simulator") + port = int(os.getenv("VSPHERE_PORT", "8080")) + try: + si = SmartConnect( + host=host, + user="administrator@vsphere.local", + pwd="VMware1!", + port=port, + disableSslCertValidation=True, + ) + except Exception as error: + pytest.skip(f"SmartConnect failed: {error}") + try: + content = si.RetrieveContent() + assert content.about.name + container = content.viewManager.CreateContainerView( + content.rootFolder, [vim.VirtualMachine], True + ) + vms = list(container.view) + assert len(vms) >= 5 + target = next((vm for vm in vms if vm.name == "app-01"), vms[0]) + if target.runtime.powerState != vim.VirtualMachinePowerState.poweredOn: + task = target.PowerOn() + assert task is not None + finally: + Disconnect(si) diff --git a/tests/fixtures/api-viewer/pve-9.2.3-version.json b/tests/fixtures/api-viewer/pve-9.2.3-version.json new file mode 100644 index 0000000..0a40cc4 --- /dev/null +++ b/tests/fixtures/api-viewer/pve-9.2.3-version.json @@ -0,0 +1,48 @@ +{ + "info": { + "GET": { + "allowtoken": 1, + "description": "API version details, including some parts of the global datacenter config.", + "method": "GET", + "name": "version", + "parameters": { + "additionalProperties": 0 + }, + "permissions": { + "user": "all" + }, + "returns": { + "properties": { + "console": { + "description": "The default console viewer to use.", + "enum": [ + "applet", + "vv", + "html5", + "xtermjs" + ], + "optional": 1, + "type": "string" + }, + "release": { + "description": "The current Proxmox VE point release in `x.y` format.", + "type": "string" + }, + "repoid": { + "description": "The short git revision from which this version was build.", + "pattern": "[0-9a-fA-F]{8,64}", + "type": "string" + }, + "version": { + "description": "The full pve-manager package version of this node.", + "type": "string" + } + }, + "type": "object" + } + } + }, + "leaf": 1, + "path": "/version", + "text": "version" +} diff --git a/tests/fixtures/api-viewer/pve-9.2.3-version.provenance.json b/tests/fixtures/api-viewer/pve-9.2.3-version.provenance.json new file mode 100644 index 0000000..93ae134 --- /dev/null +++ b/tests/fixtures/api-viewer/pve-9.2.3-version.provenance.json @@ -0,0 +1,12 @@ +{ + "artifact_etag": "\"4144c0-655b144140900\"", + "artifact_last_modified": "Fri, 03 Jul 2026 09:08:20 GMT", + "artifact_sha256": "f2b77b57c71f3781a0993cc5062940ef31e0843fd9a6bcfdb4de4dd2001d6d9e", + "artifact_size": 4277440, + "artifact_url": "https://pve.proxmox.com/pve-docs/api-viewer/apidoc.js", + "documentation_version": "9.2.3", + "fixture_json_pointer": "/5", + "fixture_sha256": "ad572969bbab259a10380ec11ac1c67f865e601be7c5aeec201fca368341c3fe", + "retrieved_at": "2026-07-12T23:08:59+03:00", + "viewer_url": "https://pve.proxmox.com/pve-docs/api-viewer/" +} diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py new file mode 100644 index 0000000..6a33c79 --- /dev/null +++ b/tests/integration/__init__.py @@ -0,0 +1 @@ +"""PostgreSQL-backed integration tests.""" diff --git a/tests/integration/test_migrations.py b/tests/integration/test_migrations.py new file mode 100644 index 0000000..e833d25 --- /dev/null +++ b/tests/integration/test_migrations.py @@ -0,0 +1,130 @@ +"""PostgreSQL migration acceptance checks.""" + +import os +import uuid + +import asyncpg # type: ignore[import-untyped] +import pytest + +from app.config import Settings +from app.db.migrations import migrate +from app.db.pool import AsyncpgDatabase +from app.db.primitives import ConflictError +from app.db.repositories.resources import ResourceRepository +from app.simulation.seed import apply_seed, small_profile + +pytestmark = [ + pytest.mark.integration, + pytest.mark.skipif(not os.getenv("TEST_DATABASE_URL"), reason="TEST_DATABASE_URL is required"), +] + + +async def test_migration_is_repeatable_and_constraints_hold() -> None: + connection = await asyncpg.connect(os.environ["TEST_DATABASE_URL"]) + try: + await migrate(connection) + assert await migrate(connection) == 0 + node_id = uuid.uuid4() + await connection.execute( + "INSERT INTO nodes(id, name, status) VALUES($1, $2, 'online') ON CONFLICT DO NOTHING", + node_id, + f"test-{node_id}", + ) + with pytest.raises(asyncpg.CheckViolationError): + async with connection.transaction(): + await connection.execute( + "INSERT INTO nodes(id, name, status) VALUES($1, $2, 'invalid')", + uuid.uuid4(), + f"invalid-{node_id}", + ) + finally: + await connection.close() + + +async def test_small_seed_is_idempotent() -> None: + connection = await asyncpg.connect(os.environ["TEST_DATABASE_URL"]) + try: + await migrate(connection) + await apply_seed(connection, small_profile()) + await apply_seed(connection, small_profile()) + assert await connection.fetchval("SELECT count(*) FROM nodes WHERE name = 'pve01'") == 1 + assert ( + await connection.fetchval( + """SELECT count(*) FROM resources + WHERE external_id IN ('100', '101', '200', 'local', 'local-lvm')""" + ) + == 5 + ) + assert await connection.fetchval("SELECT count(*) FROM tasks WHERE status = 'success'") == 2 + assert await connection.fetchval("SELECT count(*) FROM virtual_machines") == 2 + assert await connection.fetchval("SELECT count(*) FROM containers") == 1 + assert await connection.fetchval("SELECT count(*) FROM storages") == 2 + assert await connection.fetchval("SELECT count(*) FROM storage_contents") == 4 + assert await connection.fetchval("SELECT count(*) FROM identity_groups") == 1 + assert await connection.fetchval("SELECT count(*) FROM identity_group_members") == 1 + assert await connection.fetchval("SELECT count(*) FROM group_acl_entries") == 1 + assert await connection.fetchval("SELECT count(*) FROM roles") == 3 + assert await connection.fetchval("SELECT count(*) FROM api_tokens") == 4 + secrets = await connection.fetch("SELECT secret_hash FROM api_tokens") + assert all(str(row["secret_hash"]).startswith("scrypt$") for row in secrets) + assert all("-secret" not in str(row["secret_hash"]) for row in secrets) + finally: + await connection.close() + + +async def test_demo_cluster_seed_populates_realistic_state() -> None: + connection = await asyncpg.connect(os.environ["TEST_DATABASE_URL"]) + try: + await migrate(connection) + from app.simulation.seed import build_profile + + await apply_seed(connection, build_profile("demo-cluster")) + assert await connection.fetchval("SELECT count(*) FROM nodes") == 20 + assert await connection.fetchval("SELECT count(*) FROM virtual_machines") == 850 + assert await connection.fetchval("SELECT count(*) FROM containers") == 150 + assert ( + await connection.fetchval("SELECT count(*) FROM resources WHERE kind = 'ceph-osd'") + == 300 + ) + assert await connection.fetchval("SELECT count(*) FROM backups") >= 400 + assert await connection.fetchval("SELECT count(*) FROM task_logs") >= 500 + assert await connection.fetchval("SELECT count(*) FROM snapshots") >= 100 + ceph_capacity = await connection.fetchval( + "SELECT capacity_bytes FROM storages WHERE storage_id = 'ceph-prod'" + ) + assert ceph_capacity == 5 * 1024**5 + profile = await connection.fetchval("SELECT metadata->>'profile' FROM clusters LIMIT 1") + assert profile == "demo-cluster" + finally: + await connection.close() + + +async def test_schema_readiness_and_optimistic_resource_repository() -> None: + url = os.environ["TEST_DATABASE_URL"] + connection = await asyncpg.connect(url) + database = AsyncpgDatabase(Settings(database_url=url)) + try: + await migrate(connection) + await apply_seed(connection, small_profile()) + await database.connect() + assert await database.is_ready() + + repository = ResourceRepository(database.pool) + resource = await repository.get(kind="qemu", external_id="101") + assert resource is not None + updated = await repository.update_state( + resource.id, + expected_version=resource.version, + state={**resource.state, "status": "running"}, + ) + assert updated.version == resource.version + 1 + assert updated.state["status"] == "running" + with pytest.raises(ConflictError): + await repository.update_state( + resource.id, + expected_version=resource.version, + state=resource.state, + ) + finally: + await database.close() + await connection.close() diff --git a/tests/integration/test_tasks.py b/tests/integration/test_tasks.py new file mode 100644 index 0000000..4e17eed --- /dev/null +++ b/tests/integration/test_tasks.py @@ -0,0 +1,81 @@ +"""Durable task concurrency and recovery tests.""" + +import asyncio +import os +import uuid + +import asyncpg # type: ignore[import-untyped] +import pytest +from asyncpg import Pool + +from app.db.migrations import migrate +from app.tasks.repository import TaskRepository + +pytestmark = [ + pytest.mark.integration, + pytest.mark.skipif(not os.getenv("TEST_DATABASE_URL"), reason="TEST_DATABASE_URL is required"), +] + + +async def repository() -> tuple[Pool, TaskRepository]: + pool = await asyncpg.create_pool(os.environ["TEST_DATABASE_URL"], min_size=1, max_size=4) + async with pool.acquire() as connection: + await migrate(connection) + return pool, TaskRepository(pool) + + +async def test_two_worker_exclusion_idempotency_and_logs() -> None: + pool, tasks = await repository() + key = uuid.uuid4().hex + try: + created = await tasks.create( + upid=f"UPID:pve1:00000001:00000001:00000001:test:{key}:root@pam:", + task_type="test", + payload={"value": 1}, + resource_key=f"vm:{key}", + idempotency_key=key, + ) + repeated = await tasks.create( + upid=f"ignored-{key}", task_type="test", payload={}, idempotency_key=key + ) + assert repeated.id == created.id + + first, second = await asyncio.gather( + tasks.claim("worker-a", 30), tasks.claim("worker-b", 30) + ) + claimed = first or second + assert claimed is not None + assert (first is None) != (second is None) + worker = "worker-a" if first is not None else "worker-b" + await tasks.append_log(claimed.id, "started") + await tasks.progress(claimed.id, worker, 50) + await tasks.finish(claimed.id, worker, status="success", result={"ok": True}) + assert await tasks.logs(claimed.id) == ("started",) + finished = await tasks.get(claimed.id) + assert finished is not None + assert finished.status == "success" + finally: + await pool.close() + + +async def test_expired_lease_is_reclaimed_after_restart() -> None: + pool, tasks = await repository() + key = uuid.uuid4().hex + try: + created = await tasks.create( + upid=f"UPID:pve1:00000001:00000001:00000001:test:{key}:root@pam:", + task_type="test", + payload={}, + ) + assert await tasks.claim("dead-worker", 0) is not None + recovered = await tasks.claim("new-worker", 30) + assert recovered is not None + assert recovered.id == created.id + assert recovered.attempt == 2 + await tasks.request_cancel(recovered.id) + cancelled = await tasks.get(recovered.id) + assert cancelled is not None + assert cancelled.cancel_requested + await tasks.finish(recovered.id, "new-worker", status="cancelled") + finally: + await pool.close() diff --git a/tests/integration/test_vsphere_api.py b/tests/integration/test_vsphere_api.py new file mode 100644 index 0000000..2fb2231 --- /dev/null +++ b/tests/integration/test_vsphere_api.py @@ -0,0 +1,168 @@ +"""Integration smoke for native vSphere REST + SOAP.""" + +from __future__ import annotations + +import os + +import pytest +from httpx import ASGITransport, AsyncClient + +from app.config import Settings +from app.main import create_app +from app.vsphere.seed import seed_vsphere_inventory + +pytestmark = pytest.mark.integration + + +@pytest.fixture +async def client() -> AsyncClient: + database_url = os.getenv("TEST_DATABASE_URL") or os.getenv("DATABASE_URL") + if not database_url: + pytest.skip("TEST_DATABASE_URL / DATABASE_URL required") + settings = Settings( + database_url=database_url, # type: ignore[arg-type] + contract_snapshot=None, + enable_pve_stub=False, + ) + app = create_app(settings=settings, worker_factories=()) + async with app.router.lifespan_context(app): + await seed_vsphere_inventory(app.state.database, force=True, profile="small") + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as http: + yield http + + +async def _session(client: AsyncClient) -> dict[str, str]: + login = await client.post( + "/api/session", + auth=("administrator@vsphere.local", "VMware1!"), + ) + assert login.status_code == 201 + return {"vmware-api-session-id": login.json()} + + +async def test_rest_session_inventory_power_clone_tags(client: AsyncClient) -> None: + headers = await _session(client) + + vms = await client.get("/api/vcenter/vm", headers=headers) + assert vms.status_code == 200 + assert len(vms.json()) >= 5 + + vm_id = next(item["vm"] for item in vms.json() if item["name"] == "app-01") + power = await client.post( + f"/api/vcenter/vm/{vm_id}/power", + params={"action": "start"}, + headers=headers, + ) + assert power.status_code == 200 + assert str(power.json().get("task") or "").startswith("task-") + + snap = await client.post( + f"/api/vcenter/vm/{vm_id}/snapshots", + headers=headers, + json={"name": "pre-update", "description": "lab"}, + ) + assert snap.status_code == 200 + assert "snapshot" in snap.json() + + clone = await client.post( + f"/api/vcenter/vm/{vm_id}/clone", + headers=headers, + json={"name": "app-01-clone"}, + ) + assert clone.status_code == 200 + assert clone.json()["vm"].startswith("vm-") + + cat = await client.post( + "/api/cis/tagging/category", + headers=headers, + json={"name": "Owner-api-test", "associable_types": ["VirtualMachine"]}, + ) + assert cat.status_code == 200, cat.text + tag = await client.post( + "/api/cis/tagging/tag", + headers=headers, + json={"category_id": cat.json(), "name": "team-a"}, + ) + assert tag.status_code == 200 + + libs = await client.get("/api/content/library", headers=headers) + assert libs.status_code == 200 + assert len(libs.json()) >= 1 + + versions = await client.get("/ui/api/versions") + assert versions.status_code == 200 + assert versions.json()["plane"] == "vsphere-rest" + + +async def test_readonly_cannot_mutate(client: AsyncClient) -> None: + login = await client.post( + "/api/session", + auth=("readonly@vsphere.local", "VMware1!"), + ) + assert login.status_code == 201 + headers = {"vmware-api-session-id": login.json()} + session = await client.get("/api/session", headers=headers) + assert session.status_code == 200 + assert session.content in (b"", b"null") or not session.text.strip() + assert "ReadOnly" in (session.headers.get("x-vmware-session-roles") or "") + vms = await client.get("/api/vcenter/vm", headers=headers) + assert vms.status_code == 200 + assert len(vms.json()) >= 5 + power = await client.post( + f"/api/vcenter/vm/{vms.json()[0]['vm']}/power", + params={"action": "start"}, + headers=headers, + ) + assert power.status_code == 403 + + +async def test_soap_property_collector_and_wsdl(client: AsyncClient) -> None: + content = await client.post( + "/sdk", + content=""" + + <_this type="ServiceInstance">ServiceInstance + """, + headers={"Content-Type": "text/xml"}, + ) + assert content.status_code == 200 + assert "SessionManager" in content.text + + login = await client.post( + "/sdk", + content=""" + + + + <_this type="SessionManager">SessionManager + administrator@vsphere.local + VMware1! + + + """, + headers={"Content-Type": "text/xml"}, + ) + assert login.status_code == 200 + cookie = login.headers.get("set-cookie") or "" + assert "vmware_soap_session" in cookie + + updates = await client.post( + "/sdk", + content=""" + + + + <_this type="PropertyCollector">propertyCollector + + + + """, + headers={"Content-Type": "text/xml", "Cookie": cookie.split(";")[0]}, + ) + assert updates.status_code == 200 + assert "WaitForUpdatesExResponse" in updates.text + assert "vm-101" in updates.text + + wsdl = await client.get("/sdk/vimService.wsdl") + assert wsdl.status_code == 200 + assert "VimService" in wsdl.text diff --git a/tests/integration/test_vsphere_api_surface_data.py b/tests/integration/test_vsphere_api_surface_data.py new file mode 100644 index 0000000..3e5f084 --- /dev/null +++ b/tests/integration/test_vsphere_api_surface_data.py @@ -0,0 +1,86 @@ +"""Integration: seeded Automation API surface returns real DB-backed data.""" + +from __future__ import annotations + +import os + +import pytest +from httpx import ASGITransport, AsyncClient + +from app.config import Settings +from app.main import create_app +from app.vsphere.seed import seed_vsphere_inventory + +pytestmark = pytest.mark.integration + + +@pytest.fixture +async def client() -> AsyncClient: + database_url = os.getenv("TEST_DATABASE_URL") or os.getenv("DATABASE_URL") + if not database_url: + pytest.skip("TEST_DATABASE_URL / DATABASE_URL required") + settings = Settings( + database_url=database_url, # type: ignore[arg-type] + contract_snapshot=None, + enable_pve_stub=False, + ) + app = create_app(settings=settings, worker_factories=()) + async with app.router.lifespan_context(app): + await seed_vsphere_inventory(app.state.database, force=True, profile="demo-cluster") + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as http: + yield http + + +async def _session(client: AsyncClient) -> dict[str, str]: + login = await client.post("/api/session", auth=("administrator@vsphere.local", "VMware1!")) + assert login.status_code == 201, login.text + return {"vmware-api-session-id": login.json()} + + +async def test_demo_cluster_api_state_and_inventory(client: AsyncClient) -> None: + headers = await _session(client) + + vm_list = await client.get("/api/vcenter/vm", headers=headers) + assert vm_list.status_code == 200 + assert len(vm_list.json()) >= 1000 + + hosts = await client.get("/api/vcenter/host", headers=headers) + assert hosts.status_code == 200 + assert len(hosts.json()) >= 20 + + ssh = await client.get("/api/appliance/access/ssh", headers=headers) + assert ssh.status_code == 200 + assert ssh.json().get("enabled") is True + assert "stub" not in ssh.json() + + supervisors = await client.get( + "/api/vcenter/namespace-management/supervisors/supervisor-1/summary", + headers=headers, + ) + assert supervisors.status_code == 200 + body = supervisors.json() + assert isinstance(body, dict) + assert "stub" not in body + assert body.get("status") == "ENABLED" or body.get("name") or body.get("id") + + esx = await client.get("/api/esx/settings/clusters/domain-c21/software", headers=headers) + assert esx.status_code == 200 + assert esx.json().get("status") == "COMPLIANT" + assert "domain-c21" in (esx.json().get("clusters") or []) + + cdroms = await client.get("/api/vcenter/vm/vm-101/hardware/cdrom", headers=headers) + assert cdroms.status_code == 200 + assert isinstance(cdroms.json(), list) + assert cdroms.json()[0]["cdrom"] == "3000" + + libs = await client.get("/api/content/library", headers=headers) + assert libs.status_code == 200 + assert len(libs.json()) >= 2 + + put = await client.put("/api/appliance/access/ssh", headers=headers, json={"enabled": False}) + assert put.status_code in {200, 204} + if put.status_code == 200: + assert put.json().get("enabled") is False + ssh2 = await client.get("/api/appliance/access/ssh", headers=headers) + assert ssh2.json().get("enabled") is False + await client.put("/api/appliance/access/ssh", headers=headers, json={"enabled": True}) diff --git a/tests/integration/test_vsphere_full_api.py b/tests/integration/test_vsphere_full_api.py new file mode 100644 index 0000000..442a707 --- /dev/null +++ b/tests/integration/test_vsphere_full_api.py @@ -0,0 +1,450 @@ +"""Full vSphere REST + SOAP + major-matrix surface tests.""" + +from __future__ import annotations + +import os +import re + +import pytest +from httpx import ASGITransport, AsyncClient + +from app.config import Settings +from app.main import create_app +from app.vsphere.contracts.matrix import VERSIONS, catalog_entries_for_major +from app.vsphere.rest.coverage import IMPLEMENTED, catalog_entries +from app.vsphere.seed import seed_vsphere_inventory + +pytestmark = pytest.mark.integration + +_PATH_SUBS = { + "{vm}": "vm-101", + "{host}": "host-11", + "{datastore}": "datastore-31", + "{task}": "task-1", + "{snapshot}": "snapshot-missing", + "{category_id}": "cat-lab-1", + "{tag_id}": "tag-lab-1", + "{item_id}": "item-ubuntu", + "{library_id}": "lib-local-1", + "{session_id}": "session-lab-1", + "{folder}": "group-v23", + "{datacenter}": "datacenter-21", + "{cluster}": "domain-c21", + "{resource_pool}": "resgroup-22", + "{permission_id}": "1", + "{policy}": "policy-default", + "{supervisor}": "supervisor-1", + "{namespace}": "ns-lab-1", + "{provider}": "vsphere.local", + "{interface}": "nic0", + "{network}": "network-41", + "{cdrom}": "3000", + "{disk}": "2000", + "{nic}": "4000", + "{adapter}": "1000", + "{service}": "vsphere-ui", + "{domain}": "lab.local", +} + + +def _concrete(path: str) -> str: + out = path + for key, value in _PATH_SUBS.items(): + out = out.replace(key, value) + return out + + +@pytest.fixture +async def client() -> AsyncClient: + database_url = os.getenv("TEST_DATABASE_URL") or os.getenv("DATABASE_URL") + if not database_url: + pytest.skip("TEST_DATABASE_URL / DATABASE_URL required") + settings = Settings( + database_url=database_url, # type: ignore[arg-type] + contract_snapshot=None, + enable_pve_stub=False, + ) + app = create_app(settings=settings, worker_factories=()) + async with app.router.lifespan_context(app): + await seed_vsphere_inventory(app.state.database, force=True, profile="small") + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as http: + yield http + + +async def _session( + client: AsyncClient, user: str = "administrator@vsphere.local" +) -> dict[str, str]: + login = await client.post("/api/session", auth=(user, "VMware1!")) + assert login.status_code == 201, login.text + sid = login.json() + assert isinstance(sid, str) and sid + return {"vmware-api-session-id": sid} + + +@pytest.mark.parametrize("major", sorted(VERSIONS)) +async def test_ui_catalog_and_method_fields_for_every_major( + client: AsyncClient, major: int +) -> None: + catalog = await client.get("/ui/api/catalog", params={"major": major}) + assert catalog.status_code == 200 + body = catalog.json() + assert body["plane"] == "vsphere-rest" + assert body["method_count"] == len(catalog_entries_for_major(major)) + # Spot-check a path with params on majors that include VM get. + method = await client.get( + "/ui/api/method", + params={"major": major, "path": "/api/vcenter/vm/{vm}", "verb": "GET"}, + ) + assert method.status_code == 200 + payload = method.json() + if payload.get("implemented"): + assert any(f["name"] == "vm" for f in payload["path_fields"]) + + +async def test_all_coverage_routes_no_server_error(client: AsyncClient) -> None: + headers = await _session(client) + failures: list[str] = [] + for entry in catalog_entries(): + verb = entry["verb"] + path = entry["path"] + if verb == "DELETE" and path == "/api/session": + continue + url = _concrete(path) + kwargs: dict = {"headers": headers} + if verb in {"POST", "PATCH", "PUT"}: + kwargs["headers"] = {**headers, "Content-Type": "application/json"} + if path.endswith("/power"): + url = f"{url}?action=start" + kwargs["json"] = {} + elif "tag-association" in path: + kwargs["json"] = { + "action": "list-attached-tags", + "tag_id": "x", + "object_id": {"type": "VirtualMachine", "id": "vm-101"}, + } + else: + kwargs["json"] = {} + response = await client.request(verb, url, **kwargs) + if response.status_code >= 500: + failures.append(f"{verb} {path} -> {response.status_code} {response.text[:160]}") + assert failures == [], "\n".join(failures) + + +async def test_rest_inventory_returns_seed_data(client: AsyncClient) -> None: + headers = await _session(client) + for path, min_count in ( + ("/api/vcenter/vm", 5), + ("/api/vcenter/host", 3), + ("/api/vcenter/datastore", 1), + ("/api/vcenter/network", 1), + ("/api/vcenter/datacenter", 1), + ("/api/vcenter/cluster", 1), + ("/api/vcenter/folder", 1), + ): + response = await client.get(path, headers=headers) + assert response.status_code == 200, path + assert len(response.json()) >= min_count, path + + +async def test_legacy_rest_wrappers(client: AsyncClient) -> None: + headers = await _session(client) + for path in ( + "/rest/vcenter/vm", + "/rest/vcenter/host", + "/rest/vcenter/datastore", + "/rest/vcenter/network", + "/rest/vcenter/datacenter", + "/rest/vcenter/cluster", + "/rest/appliance/system/version", + ): + response = await client.get(path, headers=headers) + assert response.status_code == 200, path + body = response.json() + assert "value" in body + + +async def test_session_contracts(client: AsyncClient) -> None: + headers = await _session(client) + get_session = await client.get("/api/session", headers=headers) + assert get_session.status_code == 200 + assert get_session.content in (b"", b"null") or not get_session.text.strip() + assert "Administrator" in (get_session.headers.get("x-vmware-session-roles") or "") + + legacy = await client.post( + "/rest/com/vmware/cis/session", + auth=("administrator@vsphere.local", "VMware1!"), + ) + assert legacy.status_code in {200, 201} + assert legacy.json()["value"] + legacy_get = await client.get( + "/rest/com/vmware/cis/session", + headers={"vmware-api-session-id": legacy.json()["value"]}, + ) + assert legacy_get.status_code == 200 + assert legacy_get.json()["value"] + + +async def test_authz_readonly_forbidden_on_power(client: AsyncClient) -> None: + headers = await _session(client, "readonly@vsphere.local") + vms = await client.get("/api/vcenter/vm", headers=headers) + assert vms.status_code == 200 + vm = vms.json()[0]["vm"] + power = await client.post( + f"/api/vcenter/vm/{vm}/power", + params={"action": "start"}, + headers=headers, + ) + assert power.status_code == 403 + + +async def test_appliance_version_public_and_health(client: AsyncClient) -> None: + version = await client.get("/api/appliance/system/version") + assert version.status_code == 200 + assert version.json()["version"] + headers = await _session(client) + health = await client.get("/api/appliance/health/system", headers=headers) + assert health.status_code == 200 + assert health.json()["status"] == "green" + networking = await client.get("/api/appliance/networking", headers=headers) + assert networking.status_code == 200 + assert networking.json()["hostname"] + + +async def test_soap_login_service_content_and_inventory(client: AsyncClient) -> None: + login = await client.post( + "/sdk", + content=""" + + + + <_this type="SessionManager">SessionManager + administrator@vsphere.local + VMware1! + + + """, + headers={"Content-Type": "text/xml"}, + ) + assert login.status_code == 200 + assert "LoginResponse" in login.text + cookie = (login.headers.get("set-cookie") or "").split(";")[0] + assert "vmware_soap_session" in cookie + + content = await client.post( + "/sdk", + content=""" + + + + <_this type="ServiceInstance">ServiceInstance + + + """, + headers={"Content-Type": "text/xml", "Cookie": cookie}, + ) + assert content.status_code == 200 + assert "propertyCollector" in content.text + assert "eventManager" in content.text + + props = await client.post( + "/sdk", + content=""" + + + + <_this type="PropertyCollector">propertyCollector + + FolderchildEntityname + + group-d1 + + FolderchildEntity + + + + + + """, + headers={"Content-Type": "text/xml", "Cookie": cookie}, + ) + assert props.status_code == 200 + assert "datacenter-21" in props.text or "Datacenter" in props.text + + events = await client.post( + "/sdk", + content=""" + + + + <_this type="EventManager">EventManager + + + """, + headers={"Content-Type": "text/xml", "Cookie": cookie}, + ) + assert events.status_code == 200 + assert "QueryEventsResponse" in events.text + + +async def test_vm_lifecycle_and_power(client: AsyncClient) -> None: + headers = await _session(client) + created = await client.post( + "/api/vcenter/vm", + headers={**headers, "Content-Type": "application/json"}, + json={ + "name": "full-api-lifecycle", + "placement": {"folder": "group-v23", "host": "host-11", "datastore": "datastore-31"}, + "cpu_count": 1, + "memory_size_MiB": 512, + }, + ) + assert created.status_code in {200, 201}, created.text + vm = created.json() + if isinstance(vm, dict): + vm = vm.get("vm") or vm.get("value") or vm + assert isinstance(vm, str) + detail = await client.get(f"/api/vcenter/vm/{vm}", headers=headers) + assert detail.status_code == 200 + power = await client.post( + f"/api/vcenter/vm/{vm}/power", + params={"action": "start"}, + headers=headers, + ) + assert power.status_code in {200, 204}, power.text + # powered-on VMs cannot be deleted — stop first (vSphere semantics) + stop = await client.post( + f"/api/vcenter/vm/{vm}/power", + params={"action": "stop"}, + headers=headers, + ) + assert stop.status_code in {200, 204}, stop.text + deleted = await client.delete(f"/api/vcenter/vm/{vm}", headers=headers) + assert deleted.status_code in {200, 204}, deleted.text + + +async def test_coverage_registry_matches_implemented_constant() -> None: + assert len(catalog_entries()) == len(IMPLEMENTED) + for verb, path in IMPLEMENTED: + assert re.match(r"^/(api|rest)/", path), path + assert verb in {"GET", "POST", "PUT", "PATCH", "DELETE"} + + +@pytest.mark.parametrize("major", sorted(VERSIONS)) +async def test_major_matrix_all_verbs_no_server_error(client: AsyncClient, major: int) -> None: + """Apply each catalog major and exercise every registered GET/POST/PATCH/DELETE.""" + + headers = await _session(client) + apply = await client.post("/ui/api/contract/apply", params={"major": major}) + assert apply.status_code == 200, apply.text + failures: list[str] = [] + order = {"GET": 0, "PUT": 1, "PATCH": 2, "POST": 3, "DELETE": 4} + entries = sorted( + catalog_entries_for_major(major), + key=lambda item: (order.get(item["verb"], 9), item["path"]), + ) + for entry in entries: + verb = entry["verb"] + path = entry["path"] + if verb == "DELETE" and path in {"/api/session", "/rest/com/vmware/cis/session"}: + continue + url = _concrete(path) + kwargs: dict = {"headers": {**headers}} + if verb in {"POST", "PATCH", "PUT"}: + kwargs["headers"] = {**headers, "Content-Type": "application/json"} + if path.endswith("/power") and "/guest/" not in path: + url = f"{url}?action=start" + kwargs["json"] = {} + elif path.endswith("/guest/power"): + url = f"{url}?action=reboot" + kwargs["json"] = {} + elif path.endswith("/maintenance"): + url = f"{url}?action=enter" + kwargs["json"] = {} + elif path == "/api/vcenter/folder/{folder}": + url = f"{url}?action=rename" + kwargs["json"] = {"name": "renamed-by-matrix"} + elif path == "/api/content/local-library": + kwargs["json"] = {"create_spec": {"name": f"lib-m{major}-{os.urandom(3).hex()}"}} + elif path == "/api/cis/tagging/category": + kwargs["json"] = { + "create_spec": { + "name": f"cat-m{major}-{os.urandom(3).hex()}", + "cardinality": "MULTIPLE", + "associable_types": [], + } + } + elif path == "/api/cis/tagging/tag": + kwargs["json"] = { + "create_spec": { + "name": f"tag-m{major}-{os.urandom(3).hex()}", + "category_id": "missing-category", + } + } + elif "tag-association" in path: + kwargs["json"] = { + "action": "list-attached-tags", + "tag_id": "x", + "object_id": {"type": "VirtualMachine", "id": "vm-101"}, + } + elif path == "/api/vcenter/network/dvpg": + kwargs["json"] = { + "name": f"dvpg-m{major}-{os.urandom(2).hex()}", + "dvs": "dvs-51", + "vlan_id": 20, + } + elif path == "/api/content/library/item": + kwargs["json"] = { + "create_spec": { + "library_id": "lib-missing", + "name": f"item-m{major}-{os.urandom(2).hex()}", + "type": "ovf", + } + } + elif path == "/api/vcenter/authorization/permissions": + kwargs["json"] = { + "principal": "readonly@vsphere.local", + "role": "ReadOnly", + "entity": "datacenter-21", + } + elif path == "/api/vcenter/datastore/{datastore}/files": + kwargs["json"] = { + "path": f"/probe-m{major}-{os.urandom(2).hex()}.txt", + "size": 1, + "type": "FILE", + } + elif path.endswith("/hardware/cpu"): + kwargs["json"] = {"count": 2} + elif path.endswith("/hardware/memory"): + kwargs["json"] = {"size_MiB": 1024} + elif path.endswith("/hardware/disk"): + kwargs["json"] = {"type": "SCSI", "new_vmdk": {"capacity": 1024}} + elif path.endswith("/hardware/ethernet"): + kwargs["json"] = { + "type": "VMXNET3", + "backing": {"type": "STANDARD_PORTGROUP", "network": "network-41"}, + } + elif path.endswith("/snapshots") and verb == "POST": + kwargs["json"] = {"name": f"snap-m{major}-{os.urandom(2).hex()}"} + elif "/snapshots/" in path and verb == "POST": + kwargs["json"] = {"action": "revert"} + elif path.endswith("/clone"): + kwargs["json"] = { + "name": f"clone-m{major}-{os.urandom(2).hex()}", + "placement": {"folder": "group-v23", "host": "host-11"}, + } + elif path.endswith("/relocate"): + kwargs["json"] = {"placement": {"host": "host-12"}} + elif path.endswith("/console/tickets"): + kwargs["json"] = {"type": "WEBMKS"} + elif path.endswith("/guest/customization"): + kwargs["json"] = {"name": {"name": f"guest-m{major}"}} + elif path == "/api/vcenter/vm/{vm}" and verb == "POST": + kwargs["json"] = {"action": "unregister"} + else: + kwargs["json"] = {"name": f"probe-{major}-{os.urandom(2).hex()}"} + if verb == "DELETE" and path.endswith("{vm}"): + url = "/api/vcenter/vm/vm-missing-matrix" + response = await client.request(verb, url, **kwargs) + if response.status_code >= 500: + failures.append(f"{verb} {path} -> {response.status_code} {response.text[:160]}") + assert failures == [], "\n".join(failures) diff --git a/tests/integration/test_vsphere_soap_create_vm.py b/tests/integration/test_vsphere_soap_create_vm.py new file mode 100644 index 0000000..05fc170 --- /dev/null +++ b/tests/integration/test_vsphere_soap_create_vm.py @@ -0,0 +1,135 @@ +"""SOAP CreateVM / FindChild / guest filesystem REST parity.""" + +from __future__ import annotations + +import os + +import pytest +from httpx import ASGITransport, AsyncClient + +from app.config import Settings +from app.main import create_app +from app.vsphere.seed import seed_vsphere_inventory + +pytestmark = pytest.mark.integration + + +@pytest.fixture +async def client() -> AsyncClient: + database_url = os.getenv("TEST_DATABASE_URL") or os.getenv("DATABASE_URL") + if not database_url: + pytest.skip("TEST_DATABASE_URL / DATABASE_URL required") + settings = Settings( + database_url=database_url, # type: ignore[arg-type] + contract_snapshot=None, + enable_pve_stub=False, + ) + app = create_app(settings=settings, worker_factories=()) + async with app.router.lifespan_context(app): + await seed_vsphere_inventory(app.state.database, force=True, profile="small") + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as http: + yield http + + +async def _soap_login(client: AsyncClient) -> str: + login = await client.post( + "/sdk", + content=""" + + + + <_this type="SessionManager">SessionManager + administrator@vsphere.local + VMware1! + + + """, + headers={"Content-Type": "text/xml"}, + ) + assert login.status_code == 200, login.text + session = login.headers.get("vmware-api-session-id") + assert session + return session + + +async def test_soap_create_vm_and_find_child(client: AsyncClient) -> None: + session = await _soap_login(client) + headers = { + "Content-Type": "text/xml", + "vmware-api-session-id": session, + "Cookie": f'vmware_soap_session="{session}"', + } + create = await client.post( + "/sdk", + content=""" + + + + <_this type="Folder">group-v23 + + soap-create-lab + otherGuest64 + 2 + 1024 + [datastore1] + + resgroup-22 + host-11 + + + """, + headers=headers, + ) + assert create.status_code == 200, create.text + assert "CreateVM_TaskResponse" in create.text + assert "task-" in create.text + + find = await client.post( + "/sdk", + content=""" + + + + <_this type="SearchIndex">SearchIndex + group-v23 + soap-create-lab + + + """, + headers=headers, + ) + assert find.status_code == 200, find.text + assert "VirtualMachine" in find.text + + +async def test_rest_guest_filesystem_roundtrip(client: AsyncClient) -> None: + login = await client.post( + "/api/session", + auth=("administrator@vsphere.local", "VMware1!"), + ) + assert login.status_code in {200, 201} + headers = {"vmware-api-session-id": login.json()} + vms = await client.get("/api/vcenter/vm", headers=headers) + assert vms.status_code == 200 + vm = next(item["vm"] for item in vms.json() if item["name"] == "web-01") + put = await client.put( + f"/api/vcenter/vm/{vm}/guest/filesystem", + params={"path": "/tmp/fs-test"}, + headers=headers, + json={"content": "hello-lab"}, + ) + assert put.status_code == 204 + get = await client.get( + f"/api/vcenter/vm/{vm}/guest/filesystem", + params={"path": "/tmp/fs-test"}, + headers=headers, + ) + assert get.status_code == 200 + assert get.json()["content"] == "hello-lab" + listing = await client.get( + f"/api/vcenter/vm/{vm}/guest/filesystem/files", + params={"path": "/tmp"}, + headers=headers, + ) + assert listing.status_code == 200 + assert any(item["path"] == "/tmp/fs-test" for item in listing.json()) diff --git a/tests/integration/test_vsphere_soap_depth.py b/tests/integration/test_vsphere_soap_depth.py new file mode 100644 index 0000000..769069f --- /dev/null +++ b/tests/integration/test_vsphere_soap_depth.py @@ -0,0 +1,165 @@ +"""SOAP PropertyCollector / TaskManager fidelity tests.""" + +from __future__ import annotations + +import os + +import pytest +from httpx import ASGITransport, AsyncClient + +from app.config import Settings +from app.main import create_app +from app.vsphere.seed import seed_vsphere_inventory + +pytestmark = pytest.mark.integration + + +@pytest.fixture +async def client() -> AsyncClient: + database_url = os.getenv("TEST_DATABASE_URL") or os.getenv("DATABASE_URL") + if not database_url: + pytest.skip("TEST_DATABASE_URL / DATABASE_URL required") + settings = Settings( + database_url=database_url, # type: ignore[arg-type] + contract_snapshot=None, + enable_pve_stub=False, + ) + app = create_app(settings=settings, worker_factories=()) + async with app.router.lifespan_context(app): + await seed_vsphere_inventory(app.state.database, force=True, profile="small") + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as http: + yield http + + +async def _soap_login(client: AsyncClient) -> str: + login = await client.post( + "/sdk", + content=""" + + + + <_this type="SessionManager">SessionManager + administrator@vsphere.local + VMware1! + + + """, + headers={"Content-Type": "text/xml"}, + ) + assert login.status_code == 200 + assert "LoginResponse" in login.text + cookie = login.headers.get("set-cookie") or "" + assert "vmware_soap_session" in cookie + return cookie.split(";")[0] + + +async def test_folder_child_entity_and_path(client: AsyncClient) -> None: + cookie = await _soap_login(client) + props = await client.post( + "/sdk", + content=""" + + + + <_this type="PropertyCollector">propertyCollector + + FolderchildEntityname + group-d1 + + + + """, + headers={"Content-Type": "text/xml", "Cookie": cookie}, + ) + assert props.status_code == 200 + assert "childEntity" in props.text + assert "datacenter-21" in props.text + + path = await client.post( + "/sdk", + content=""" + + + + <_this type="SearchIndex">SearchIndex + /Datacenters/Datacenter/vm/web-01 + + + """, + headers={"Content-Type": "text/xml", "Cookie": cookie}, + ) + assert path.status_code == 200 + assert "vm-101" in path.text + + +async def test_wait_for_updates_version_and_power_task_id(client: AsyncClient) -> None: + cookie = await _soap_login(client) + first = await client.post( + "/sdk", + content=""" + + + + <_this type="PropertyCollector">propertyCollector + + + + """, + headers={"Content-Type": "text/xml", "Cookie": cookie}, + ) + assert first.status_code == 200 + assert "1" in first.text + assert "enter" in first.text + + second = await client.post( + "/sdk", + content=""" + + + + <_this type="PropertyCollector">propertyCollector + 1 + + + """, + headers={"Content-Type": "text/xml", "Cookie": cookie}, + ) + assert second.status_code == 200 + assert "enter" not in second.text + + power = await client.post( + "/sdk", + content=""" + + + + <_this type="VirtualMachine">vm-104 + + + """, + headers={"Content-Type": "text/xml", "Cookie": cookie}, + ) + assert power.status_code == 200 + assert "task-" in power.text + assert "task-1<" not in power.text + + about = await client.get("/sdk/about.do") + assert about.status_code == 200 + assert "vCenter" in about.text + + wsdl = await client.get("/sdk/vimService.wsdl") + assert "WaitForUpdatesEx" in wsdl.text + assert "CancelTask" in wsdl.text + + +async def test_legacy_rest_value_wrapper(client: AsyncClient) -> None: + login = await client.post( + "/api/session", + auth=("administrator@vsphere.local", "VMware1!"), + ) + headers = {"vmware-api-session-id": login.json()} + resp = await client.get("/rest/vcenter/vm", headers=headers, params={"limit": 2}) + assert resp.status_code == 200 + body = resp.json() + assert "value" in body + assert len(body["value"]) == 2 diff --git a/tests/unit/test_access_auth_handlers.py b/tests/unit/test_access_auth_handlers.py new file mode 100644 index 0000000..13d0b46 --- /dev/null +++ b/tests/unit/test_access_auth_handlers.py @@ -0,0 +1,277 @@ +"""TFA / OpenID / permissions access handlers.""" + +from __future__ import annotations + +import json +import uuid +from typing import Any, cast + +import pytest +from fastapi import FastAPI, Request +from pydantic import SecretStr + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.config import Settings +from app.db.pool import AsyncpgDatabase +from app.handlers.access_auth import register_access_auth_handlers +from app.security.auth import issue_ticket + + +class AuthPool: + def __init__(self) -> None: + self.principals = { + "root@pam": { + "id": uuid.uuid4(), + "tfa_locked_until": None, + "totp_locked": False, + } + } + self.tfa: dict[tuple[uuid.UUID, str], dict[str, Any]] = {} + self.realms = { + "sso": { + "kind": "openid", + "config": { + "issuer-url": "https://idp.example", + "client-id": "pve", + }, + } + } + self.pending: dict[str, dict[str, str]] = {} + + async def fetch(self, query: str, *arguments: object) -> list[dict[str, Any]]: + if "FROM principals p" in query and "LEFT JOIN tfa_entries" in query: + rows: list[dict[str, Any]] = [] + for name, data in self.principals.items(): + matches = [item for key, item in self.tfa.items() if key[0] == data["id"]] + if not matches: + rows.append( + { + "userid": name, + "tfa_locked_until": data["tfa_locked_until"], + "totp_locked": data["totp_locked"], + "entry_id": None, + "tfa_type": None, + "description": None, + "enable": None, + "created_at": 0, + } + ) + for item in matches: + rows.append( + { + "userid": name, + "tfa_locked_until": data["tfa_locked_until"], + "totp_locked": data["totp_locked"], + **item, + } + ) + return rows + if "FROM tfa_entries" in query and "DISTINCT" in query: + principal_id = arguments[0] + types = sorted( + { + item["tfa_type"] + for key, item in self.tfa.items() + if key[0] == principal_id and item["enable"] + } + ) + return [{"tfa_type": value} for value in types] + if "FROM tfa_entries WHERE principal_id" in query or ( + "FROM tfa_entries" in query and "principal_id=$1" in query and "DISTINCT" not in query + ): + principal_id = arguments[0] + return [item for key, item in self.tfa.items() if key[0] == principal_id] + if "FROM acl_entries" in query: + return [] + raise AssertionError(query) + + async def fetchrow(self, query: str, *arguments: object) -> dict[str, Any] | None: + if "FROM principals WHERE name" in query: + userid = str(arguments[0]) + data = self.principals.get(userid) + if data is None: + return None + return {"name": userid, **data} + if "FROM realms WHERE name" in query: + realm = str(arguments[0]) + realm_data = self.realms.get(realm) + if realm_data is None: + return None + return {"name": realm, **realm_data} + if "FROM openid_pending WHERE state" in query: + return self.pending.get(str(arguments[0])) + if "FROM tfa_entries WHERE principal_id" in query: + key = (cast(uuid.UUID, arguments[0]), str(arguments[1])) + item = self.tfa.get(key) + return item + raise AssertionError(query) + + async def fetchval(self, query: str, *arguments: object) -> Any: + if "EXISTS(SELECT 1 FROM principals" in query: + return str(arguments[0]) in self.principals + raise AssertionError(query) + + async def execute(self, query: str, *arguments: object) -> str: + if "INSERT INTO openid_pending" in query: + self.pending[str(arguments[0])] = { + "realm": str(arguments[1]), + "redirect_url": str(arguments[2]), + } + return "INSERT 0 1" + if "DELETE FROM openid_pending" in query: + self.pending.pop(str(arguments[0]), None) + return "DELETE 1" + if "INSERT INTO principals" in query: + self.principals[str(arguments[0])] = { + "id": uuid.uuid4(), + "tfa_locked_until": None, + "totp_locked": False, + } + return "INSERT 0 1" + if "INSERT INTO tfa_entries" in query: + principal_id = cast(uuid.UUID, arguments[0]) + entry_id = str(arguments[1]) + self.tfa[(principal_id, entry_id)] = { + "entry_id": entry_id, + "tfa_type": str(arguments[2]), + "description": arguments[3], + "enable": True, + "created_at": 1_700_000_000, + "secret": arguments[4], + "metadata": json.loads(str(arguments[5])), + } + return "INSERT 0 1" + if "UPDATE tfa_entries SET enable" in query: + key = (cast(uuid.UUID, arguments[0]), str(arguments[1])) + self.tfa[key]["enable"] = bool(arguments[2]) + return "UPDATE 1" + if "UPDATE tfa_entries SET description" in query: + key = (cast(uuid.UUID, arguments[0]), str(arguments[1])) + self.tfa[key]["description"] = arguments[2] + return "UPDATE 1" + if "DELETE FROM tfa_entries" in query: + key = (cast(uuid.UUID, arguments[0]), str(arguments[1])) + if key not in self.tfa: + return "DELETE 0" + del self.tfa[key] + return "DELETE 1" + if "UPDATE principals" in query and "totp_locked" in query: + userid = str(arguments[0]) + if userid not in self.principals: + return "UPDATE 0" + self.principals[userid]["tfa_locked_until"] = None + self.principals[userid]["totp_locked"] = False + return "UPDATE 1" + raise AssertionError(query) + + +class FakeDatabase: + def __init__(self, pool: AuthPool) -> None: + self.pool = pool + + +def request(pool: AuthPool, principal: str = "root@pam") -> Request: + app = FastAPI() + app.state.database = cast(AsyncpgDatabase, FakeDatabase(pool)) + app.state.settings = Settings(ticket_signing_key=SecretStr("test-signing-key")) + result = Request( + { + "type": "http", + "app": app, + "method": "POST", + "path": "/", + "headers": [], + "query_string": b"", + "server": ("test", 80), + "client": ("test", 123), + "scheme": "http", + } + ) + result.state.principal = principal + return result + + +def values(**items: object) -> dict[str, Any]: + return {"values": items, "provided": frozenset(items)} + + +async def test_tfa_lifecycle_and_unlock_persist() -> None: + registry = HandlerRegistry() + register_access_auth_handlers(registry) + pool = AuthPool() + http = request(pool) + create = registry.get("/access/tfa/{userid}", "POST") + listing = registry.get("/access/tfa/{userid}", "GET") + get = registry.get("/access/tfa/{userid}/{id}", "GET") + update = registry.get("/access/tfa/{userid}/{id}", "PUT") + delete = registry.get("/access/tfa/{userid}/{id}", "DELETE") + unlock = registry.get("/access/users/{userid}/unlock-tfa", "PUT") + types = registry.get("/access/users/{userid}/tfa", "GET") + assert create and listing and get and update and delete and unlock and types + + created = await create(http, values(userid="root@pam", type="totp", description="phone")) + entry_id = created["id"] + assert await listing(http, values(userid="root@pam")) + fetched = await get(http, values(userid="root@pam", id=entry_id)) + assert fetched["type"] == "totp" + await update(http, values(userid="root@pam", id=entry_id, enable=0)) + assert (await get(http, values(userid="root@pam", id=entry_id)))["enable"] == 0 + assert await unlock(http, values(userid="root@pam")) is True + assert (await types(http, values(userid="root@pam")))["types"] == [] + await delete(http, values(userid="root@pam", id=entry_id)) + with pytest.raises(ApiError): + await get(http, values(userid="root@pam", id=entry_id)) + + +async def test_openid_auth_url_and_login_create_principal() -> None: + registry = HandlerRegistry() + register_access_auth_handlers(registry) + pool = AuthPool() + http = request(pool) + auth_url = registry.get("/access/openid/auth-url", "POST") + login = registry.get("/access/openid/login", "POST") + assert auth_url and login + + url = await auth_url( + http, + values(realm="sso", **{"redirect-url": "https://pve.local/api2/json/access/openid/login"}), + ) + assert "https://idp.example/authorize?" in url + assert pool.pending + state = next(iter(pool.pending)) + result = await login( + http, + values( + code="abc1234567890", + state=state, + **{"redirect-url": "https://pve.local/api2/json/access/openid/login"}, + ), + ) + assert result["ticket"].startswith("PVE:") + assert any(name.endswith("@sso") for name in pool.principals) + + +async def test_permissions_and_vncticket() -> None: + registry = HandlerRegistry() + register_access_auth_handlers(registry) + pool = AuthPool() + http = request(pool) + permissions = registry.get("/access/permissions", "GET") + vncticket = registry.get("/access/vncticket", "POST") + ticket_get = registry.get("/access/ticket", "GET") + assert permissions and vncticket and ticket_get + + caps = await permissions(http, values()) + assert "/" in caps + assert await ticket_get(http, values()) is None + ticket = issue_ticket("root@pam", b"test-signing-key") + await vncticket( + http, + values( + authid="root@pam", + path="/nodes/pve01/qemu/100/vncwebsocket", + privs="Sys.Console", + vncticket=ticket, + ), + ) diff --git a/tests/unit/test_access_handlers.py b/tests/unit/test_access_handlers.py new file mode 100644 index 0000000..31ceb77 --- /dev/null +++ b/tests/unit/test_access_handlers.py @@ -0,0 +1,247 @@ +"""API-token lifecycle handler tests without external services.""" + +import json +from typing import Any, cast + +import pytest +from fastapi import FastAPI, Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.db.pool import AsyncpgDatabase +from app.handlers.access import register_access_handlers + + +class TokenPool: + def __init__(self) -> None: + self.token: dict[str, Any] | None = None + + async def fetch(self, _query: str, _userid: str) -> list[dict[str, Any]]: + return [] if self.token is None else [{"token_id": "test", **self.token}] + + async def fetchrow(self, query: str, *arguments: object) -> dict[str, Any] | None: + if "INSERT INTO" in query: + self.token = { + "comment": arguments[3], + "privilege_separation": arguments[5], + "expire": arguments[4], + } + return self.token + if "UPDATE api_tokens" in query: + if self.token is None: + return None + self.token["comment"] = arguments[2] + self.token["privilege_separation"] = arguments[4] + return self.token + return self.token + + async def fetchval(self, _query: str, _userid: str) -> bool: + return True + + async def execute(self, _query: str, _userid: str, _tokenid: str) -> str: + if self.token is None: + return "DELETE 0" + self.token = None + return "DELETE 1" + + +class RealmPool: + def __init__(self) -> None: + self.realms: dict[str, dict[str, Any]] = { + "pam": { + "kind": "pam", + "config": {"comment": "Linux PAM standard authentication"}, + }, + "pve": { + "kind": "pve", + "config": {"comment": "Proxmox VE authentication server"}, + }, + } + self.principals: dict[str, str] = {"root@pam": "pam"} + + async def fetch(self, query: str, *arguments: object) -> list[dict[str, Any]]: + del arguments + if "FROM realms ORDER BY name" in query: + return [ + {"name": name, "kind": data["kind"], "config": dict(data["config"])} + for name, data in sorted(self.realms.items()) + ] + raise AssertionError(query) + + async def fetchrow(self, query: str, *arguments: object) -> dict[str, Any] | None: + if "FROM realms WHERE name" in query: + realm = str(arguments[0]) + data = self.realms.get(realm) + if data is None: + return None + return {"name": realm, "kind": data["kind"], "config": dict(data["config"])} + raise AssertionError(query) + + async def fetchval(self, query: str, *arguments: object) -> bool: + realm = str(arguments[0]) + if "EXISTS(SELECT 1 FROM realms" in query: + return realm in self.realms + if "EXISTS(SELECT 1 FROM principals" in query: + return any(value == realm for value in self.principals.values()) + raise AssertionError(query) + + async def execute(self, query: str, *arguments: object) -> str: + if "INSERT INTO realms" in query: + self.realms[str(arguments[0])] = { + "kind": str(arguments[1]), + "config": json.loads(str(arguments[2])), + } + return "INSERT 0 1" + if "UPDATE realms SET config=$2" in query: + realm = str(arguments[0]) + self.realms[realm]["config"] = json.loads(str(arguments[1])) + return "UPDATE 1" + if "SET config = config - 'default'" in query: + skip = str(arguments[0]) if arguments else None + for name, data in self.realms.items(): + if skip is not None and name == skip: + continue + data["config"].pop("default", None) + return "UPDATE 0" + if "DELETE FROM realms" in query: + realm = str(arguments[0]) + if realm not in self.realms: + return "DELETE 0" + del self.realms[realm] + return "DELETE 1" + raise AssertionError(query) + + +class FakeDatabase: + def __init__(self, pool: TokenPool | RealmPool) -> None: + self.pool = pool + + +def request(pool: TokenPool | RealmPool, principal: str = "root@pam") -> Request: + app = FastAPI() + app.state.database = cast(AsyncpgDatabase, FakeDatabase(pool)) + result = Request( + { + "type": "http", + "app": app, + "method": "POST", + "path": "/", + "headers": [], + "query_string": b"", + "server": ("test", 80), + "client": ("test", 123), + "scheme": "http", + } + ) + result.state.principal = principal + return result + + +def values(**items: object) -> dict[str, Any]: + return {"values": items, "provided": frozenset(items)} + + +async def test_token_lifecycle_returns_secret_once_and_persists_metadata() -> None: + registry = HandlerRegistry() + register_access_handlers(registry) + pool = TokenPool() + http_request = request(pool) + create = registry.get("/access/users/{userid}/token/{tokenid}", "POST") + get = registry.get("/access/users/{userid}/token/{tokenid}", "GET") + update = registry.get("/access/users/{userid}/token/{tokenid}", "PUT") + delete = registry.get("/access/users/{userid}/token/{tokenid}", "DELETE") + list_tokens = registry.get("/access/users/{userid}/token", "GET") + assert create and get and update and delete and list_tokens + + created = await create( + http_request, + values(userid="root@pam", tokenid="test", comment="first", privsep=True), + ) + assert created["full-tokenid"] == "root@pam!test" + assert created["value"] + assert "value" not in await get(http_request, values(userid="root@pam", tokenid="test")) + assert await list_tokens(http_request, values(userid="root@pam")) + + updated = await update( + http_request, + values(userid="root@pam", tokenid="test", comment="second", privsep=False), + ) + assert updated["comment"] == "second" + await delete(http_request, values(userid="root@pam", tokenid="test")) + with pytest.raises(ApiError) as missing: + await get(http_request, values(userid="root@pam", tokenid="test")) + assert missing.value.status_code == 404 + + +async def test_token_lifecycle_rejects_non_owner() -> None: + registry = HandlerRegistry() + register_access_handlers(registry) + handler = registry.get("/access/users/{userid}/token", "GET") + assert handler + with pytest.raises(ApiError) as denied: + await handler(request(TokenPool(), "auditor@pve"), values(userid="other@pve")) + assert denied.value.status_code == 403 + + +async def test_domain_lifecycle_persists_realm_config() -> None: + registry = HandlerRegistry() + register_access_handlers(registry) + pool = RealmPool() + http_request = request(pool) + create = registry.get("/access/domains", "POST") + listing = registry.get("/access/domains", "GET") + get = registry.get("/access/domains/{realm}", "GET") + update = registry.get("/access/domains/{realm}", "PUT") + delete = registry.get("/access/domains/{realm}", "DELETE") + assert create and listing and get and update and delete + + await create( + http_request, + values( + realm="corp", + type="ldap", + comment="Corporate LDAP", + server1="ldap.example.com", + password="secret", + default=1, + ), + ) + listed = await listing(http_request, values()) + assert any(item["realm"] == "corp" and item["type"] == "ldap" for item in listed) + created = await get(http_request, values(realm="corp")) + assert created["comment"] == "Corporate LDAP" + assert created["server1"] == "ldap.example.com" + assert created["default"] == 1 + assert "password" not in created + + await update( + http_request, + values(realm="corp", comment="Updated LDAP", delete="default"), + ) + updated = await get(http_request, values(realm="corp")) + assert updated["comment"] == "Updated LDAP" + assert "default" not in updated + + await delete(http_request, values(realm="corp")) + with pytest.raises(ApiError) as missing: + await get(http_request, values(realm="corp")) + assert missing.value.status_code == 404 + + +async def test_domain_delete_rejects_builtin_and_in_use_realms() -> None: + registry = HandlerRegistry() + register_access_handlers(registry) + pool = RealmPool() + http_request = request(pool) + delete = registry.get("/access/domains/{realm}", "DELETE") + assert delete + + with pytest.raises(ApiError) as builtin: + await delete(http_request, values(realm="pam")) + assert builtin.value.status_code == 400 + + pool.realms["corp"] = {"kind": "ldap", "config": {}} + pool.principals["alice@corp"] = "corp" + with pytest.raises(ApiError) as in_use: + await delete(http_request, values(realm="corp")) + assert in_use.value.status_code == 400 diff --git a/tests/unit/test_acl.py b/tests/unit/test_acl.py new file mode 100644 index 0000000..d345662 --- /dev/null +++ b/tests/unit/test_acl.py @@ -0,0 +1,61 @@ +"""ACL propagation, token separation, and contract mapping tests.""" + +from app.contracts.model import Permissions +from app.security.acl import AclEntry, authorize, effective_privileges, requirement_from_contract + +ENTRIES = ( + AclEntry("alice@pve", "/vms", frozenset({"VM.Audit", "VM.PowerMgmt"})), + AclEntry("alice@pve", "/vms/200", frozenset({"VM.Config"}), propagate=False), +) + + +def test_acl_propagation_matrix() -> None: + assert effective_privileges("alice@pve", "/vms/100", ENTRIES) == frozenset( + {"VM.Audit", "VM.PowerMgmt"} + ) + assert "VM.Config" in effective_privileges("alice@pve", "/vms/200", ENTRIES) + assert "VM.Config" not in effective_privileges("alice@pve", "/vms/200/snapshot", ENTRIES) + assert not effective_privileges("bob@pve", "/vms/100", ENTRIES) + + +def test_api_token_privileges_are_intersection_not_escalation() -> None: + assert authorize( + "alice@pve", + "/vms/100", + frozenset({"VM.Audit"}), + ENTRIES, + token_privileges=frozenset({"VM.Audit"}), + ) + assert not authorize( + "alice@pve", + "/vms/100", + frozenset({"VM.PowerMgmt"}), + ENTRIES, + token_privileges=frozenset({"VM.Audit"}), + ) + + +def test_contract_permission_maps_to_capability_requirement() -> None: + permissions = Permissions(expression={"check": ["perm", "/vms/{vmid}", ["VM.PowerMgmt"]]}) + + requirement = requirement_from_contract(permissions, {"vmid": "100"}) + + assert requirement is not None + assert requirement.path == "/vms/100" + assert requirement.privileges == frozenset({"VM.PowerMgmt"}) + + any_permission = Permissions( + expression={ + "check": ["perm", "/vms/{vmid}", ["VM.Config.CPU", "VM.Config.Memory"], "any", 1] + } + ) + any_requirement = requirement_from_contract(any_permission, {"vmid": "100"}) + assert any_requirement is not None + assert not any_requirement.require_all + assert authorize( + "alice@pve", + "/vms/100", + any_requirement.privileges, + (AclEntry("alice@pve", "/vms", frozenset({"VM.Config.CPU"})),), + require_all=any_requirement.require_all, + ) diff --git a/tests/unit/test_api_auth_boundary.py b/tests/unit/test_api_auth_boundary.py new file mode 100644 index 0000000..d5a9f12 --- /dev/null +++ b/tests/unit/test_api_auth_boundary.py @@ -0,0 +1,106 @@ +"""HTTP-boundary API-token and contract permission tests.""" + +from typing import Any, cast + +import pytest +from fastapi import FastAPI, Request + +from app.api.errors import ApiError +from app.api.registry import _authenticate +from app.config import Settings +from app.contracts.model import Method, Permissions, Schema +from app.db.pool import AsyncpgDatabase +from app.security.auth import hash_secret + + +class FakePool: + def __init__(self, secret: str, token_privileges: list[str]) -> None: + self.secret_hash = hash_secret(secret, salt=b"boundary-token-v1") + self.token_privileges = token_privileges + + async def fetchrow(self, _query: str, principal: str, token_id: str) -> dict[str, Any] | None: + if principal != "operator@pve" or token_id != "api": + return None + return { + "name": principal, + "secret_hash": self.secret_hash, + "privileges": self.token_privileges, + "privilege_separation": True, + } + + async def fetch(self, _query: str, principal: str) -> list[dict[str, Any]]: + return [ + { + "path": "/vms", + "propagate": True, + "privileges": ["VM.Audit", "VM.PowerMgmt"], + "principal": principal, + } + ] + + +class FakeDatabase: + def __init__(self, pool: FakePool) -> None: + self.pool = pool + + +def token_request(secret: str, token_privileges: list[str]) -> Request: + app = FastAPI() + app.state.settings = Settings() + app.state.database = cast(AsyncpgDatabase, FakeDatabase(FakePool("valid", token_privileges))) + return Request( + { + "type": "http", + "app": app, + "method": "POST", + "path": "/api2/json/nodes/pve1/qemu/101/status/start", + "headers": [(b"authorization", f"PVEAPIToken=operator@pve!api={secret}".encode())], + "query_string": b"", + "server": ("test", 80), + "client": ("test", 123), + "scheme": "http", + } + ) + + +def power_method() -> Method: + return Method( + verb="POST", + name="start", + returns=Schema(type="string"), + permissions=Permissions(expression={"check": ["perm", "/vms/{vmid}", ["VM.PowerMgmt"]]}), + checksum="1" * 64, + ) + + +async def test_api_token_skips_csrf_but_honors_separated_privileges() -> None: + allowed = token_request("valid", ["VM.PowerMgmt"]) + await _authenticate( + allowed, + "/nodes/{node}/qemu/{vmid}/status/start", + power_method(), + {"values": {"node": "pve1", "vmid": 101}}, + ) + assert allowed.state.principal == "operator@pve" + + denied = token_request("valid", ["VM.Audit"]) + with pytest.raises(ApiError) as error: + await _authenticate( + denied, + "/nodes/{node}/qemu/{vmid}/status/start", + power_method(), + {"values": {"node": "pve1", "vmid": 101}}, + ) + assert error.value.status_code == 403 + + +async def test_api_token_rejects_unknown_or_wrong_secret() -> None: + request = token_request("wrong", ["VM.PowerMgmt"]) + with pytest.raises(ApiError) as error: + await _authenticate( + request, + "/nodes/{node}/qemu/{vmid}/status/start", + power_method(), + {"values": {"node": "pve1", "vmid": 101}}, + ) + assert error.value.status_code == 401 diff --git a/tests/unit/test_api_viewer_fixture.py b/tests/unit/test_api_viewer_fixture.py new file mode 100644 index 0000000..8b0958f --- /dev/null +++ b/tests/unit/test_api_viewer_fixture.py @@ -0,0 +1,25 @@ +"""Offline checks for the researched API Viewer sample.""" + +import hashlib +import json +from pathlib import Path +from typing import Any, cast + +import pytest + +pytestmark = pytest.mark.pve_stub + +FIXTURES = Path(__file__).parents[1] / "fixtures" / "api-viewer" + + +def test_version_fixture_matches_provenance() -> None: + fixture_path = FIXTURES / "pve-9.2.3-version.json" + provenance_path = FIXTURES / "pve-9.2.3-version.provenance.json" + + fixture_bytes = fixture_path.read_bytes() + fixture = cast(dict[str, Any], json.loads(fixture_bytes)) + provenance = cast(dict[str, Any], json.loads(provenance_path.read_bytes())) + + assert fixture["path"] == "/version" + assert fixture["info"]["GET"]["method"] == "GET" + assert hashlib.sha256(fixture_bytes).hexdigest() == provenance["fixture_sha256"] diff --git a/tests/unit/test_auth.py b/tests/unit/test_auth.py new file mode 100644 index 0000000..7a1ec43 --- /dev/null +++ b/tests/unit/test_auth.py @@ -0,0 +1,68 @@ +"""Authentication, CSRF, token, and redaction matrices.""" + +import pytest +from starlette.responses import Response + +from app.security.auth import ( + AuthenticationError, + csrf_token, + hash_secret, + issue_ticket, + parse_api_token, + redact_secrets, + set_ticket_cookie, + verify_csrf, + verify_secret, + verify_ticket, +) + +KEY = b"test-signing-key-with-at-least-32-bytes" + + +def test_password_and_token_hashes_do_not_store_plaintext() -> None: + encoded = hash_secret("correct horse", salt=b"0123456789abcdef") + + assert "correct horse" not in encoded + assert verify_secret("correct horse", encoded) + assert not verify_secret("wrong", encoded) + assert not verify_secret("correct horse", "unknown$format") + + +def test_signed_ticket_expiry_and_csrf() -> None: + ticket = issue_ticket("root@pam", KEY, now=100, ttl=60) + + assert verify_ticket(ticket, KEY, now=120).principal == "root@pam" + token = csrf_token(ticket, KEY) + assert verify_csrf(ticket, token, KEY) + assert not verify_csrf(ticket, token + "x", KEY) + with pytest.raises(AuthenticationError, match="expired"): + verify_ticket(ticket, KEY, now=161) + with pytest.raises(AuthenticationError, match="invalid"): + verify_ticket(ticket + "x", KEY, now=120) + + +def test_ticket_cookie_is_http_only_and_secure() -> None: + response = Response() + set_ticket_cookie(response, "ticket") + + header = response.headers["set-cookie"] + assert "PVEAuthCookie=ticket" in header + assert "HttpOnly" in header + assert "Secure" in header + assert "SameSite=strict" in header + + +def test_api_token_parsing_and_log_redaction() -> None: + token = parse_api_token("PVEAPIToken=user@pve!automation=supersecret") + + assert token.principal == "user@pve" + assert token.token_id == "automation" + assert token.secret == "supersecret" + redacted = redact_secrets( + "PVEAPIToken=user@pve!automation=supersecret password=hunter2 token=abc" + ) + assert "supersecret" not in redacted + assert "hunter2" not in redacted + assert "token=abc" not in redacted + with pytest.raises(AuthenticationError): + parse_api_token("Bearer secret") diff --git a/tests/unit/test_ceph_handlers.py b/tests/unit/test_ceph_handlers.py new file mode 100644 index 0000000..5bd441f --- /dev/null +++ b/tests/unit/test_ceph_handlers.py @@ -0,0 +1,140 @@ +"""Ceph pool/OSD mutation persistence tests.""" + +from __future__ import annotations + +import json +from typing import Any, cast +from uuid import uuid4 + +from fastapi import FastAPI, Request + +from app.api.registry import HandlerRegistry +from app.db.pool import AsyncpgDatabase +from app.handlers.ceph import register_ceph_handlers +from app.simulation.seed import CLUSTER_ID + + +class CephPool: + def __init__(self) -> None: + self.cluster_metadata: dict[str, Any] = {} + self.nodes = {"pve1": {"id": uuid4(), "metadata": {}}} + self.resources: dict[Any, dict[str, Any]] = {} + + async def fetch(self, query: str, *arguments: object) -> list[dict[str, Any]]: + if "r.kind='ceph-osd'" in query and "ORDER BY" in query: + node = str(arguments[0]) + node_id = self.nodes[node]["id"] + return [ + {"external_id": item["external_id"], "state": item["state"]} + for item in self.resources.values() + if item["node_id"] == node_id + ] + raise AssertionError(query) + + async def fetchrow(self, query: str, *arguments: object) -> dict[str, Any] | None: + if "FROM clusters WHERE id" in query: + return {"metadata": json.dumps(self.cluster_metadata)} + if "SELECT metadata FROM nodes WHERE name" in query: + node = self.nodes.get(str(arguments[0])) + return None if node is None else {"metadata": json.dumps(node["metadata"])} + if "storage_type='ceph'" in query: + return {"capacity_bytes": 1000, "used_bytes": 100} + if "r.kind='ceph-osd'" in query: + node_name = str(arguments[0]) + osdid = str(arguments[1]) + node_id = self.nodes[node_name]["id"] + for item in self.resources.values(): + if item["node_id"] == node_id and item["external_id"] in { + osdid, + f"osd.{osdid}", + arguments[2] if len(arguments) > 2 else "", + }: + return item + return None + raise AssertionError(query) + + async def fetchval(self, query: str, *arguments: object) -> Any: + if "EXISTS(SELECT 1 FROM nodes" in query: + return str(arguments[0]) in self.nodes + if "SELECT id FROM nodes WHERE name" in query: + node = self.nodes.get(str(arguments[0])) + return None if node is None else node["id"] + if "count(*)::int FROM resources WHERE kind='ceph-osd'" in query: + return len(self.resources) + if "COALESCE" in query and "ceph-osd" in query: + return len(self.resources) + raise AssertionError(query) + + async def execute(self, query: str, *arguments: object) -> str: + if "jsonb_set" in query and "'{ceph}'" in query: + self.cluster_metadata["ceph"] = json.loads(str(arguments[1])) + return "UPDATE 1" + if "UPDATE nodes SET metadata" in query: + self.nodes[str(arguments[0])]["metadata"] = json.loads(str(arguments[1])) + return "UPDATE 1" + if "INSERT INTO resources" in query: + resource_id = uuid4() + self.resources[resource_id] = { + "id": resource_id, + "node_id": arguments[0], + "external_id": arguments[1], + "state": arguments[2], + } + return "INSERT 0 1" + if "UPDATE resources SET state" in query: + existing_id = arguments[0] + self.resources[existing_id]["state"] = arguments[1] + return "UPDATE 1" + if "DELETE FROM resources WHERE id" in query: + self.resources.pop(arguments[0], None) + return "DELETE 1" + raise AssertionError(query) + + +def request(pool: CephPool) -> Request: + app = FastAPI() + app.state.database = cast(AsyncpgDatabase, type("DB", (), {"pool": pool})()) + result = Request( + { + "type": "http", + "app": app, + "method": "POST", + "path": "/", + "headers": [], + "query_string": b"", + "server": ("test", 80), + "client": ("test", 123), + "scheme": "http", + } + ) + result.state.principal = "root@pam" + return result + + +async def test_ceph_pool_and_osd_mutations_persist() -> None: + registry = HandlerRegistry() + register_ceph_handlers(registry) + pool = CephPool() + http = request(pool) + + create_pool = registry.get("/nodes/{node}/ceph/pool", "POST") + list_pool = registry.get("/nodes/{node}/ceph/pool", "GET") + create_osd = registry.get("/nodes/{node}/ceph/osd", "POST") + osd_out = registry.get("/nodes/{node}/ceph/osd/{osdid}/out", "POST") + assert create_pool and list_pool and create_osd and osd_out + + await create_pool(http, {"values": {"node": "pve1", "name": "vms"}, "provided": frozenset()}) + pools = await list_pool(http, {"values": {"node": "pve1"}, "provided": frozenset()}) + assert any(item["pool"] == "vms" for item in pools) + assert "vms" in pool.cluster_metadata["ceph"]["pools"] + + await create_osd(http, {"values": {"node": "pve1", "dev": "/dev/sdb"}, "provided": frozenset()}) + assert len(pool.resources) == 1 + resource_id = next(iter(pool.resources)) + osdid = "0" + await osd_out( + http, + {"values": {"node": "pve1", "osdid": osdid}, "provided": frozenset()}, + ) + assert json.loads(pool.resources[resource_id]["state"])["in"] is False + assert CLUSTER_ID diff --git a/tests/unit/test_clock.py b/tests/unit/test_clock.py new file mode 100644 index 0000000..9a211c6 --- /dev/null +++ b/tests/unit/test_clock.py @@ -0,0 +1,28 @@ +"""Simulation clock behavior.""" + +import asyncio +from datetime import UTC, datetime + +import pytest + +from app.simulation.clock import AcceleratedClock, ManualClock + + +async def test_manual_clock_releases_sleep_only_after_advance() -> None: + clock = ManualClock(datetime(2026, 1, 1, tzinfo=UTC)) + sleeper = asyncio.create_task(clock.sleep(10)) + await asyncio.sleep(0) + assert not sleeper.done() + + await clock.advance(9) + assert not sleeper.done() + await clock.advance(1) + await sleeper + assert await clock.now() == datetime(2026, 1, 1, 0, 0, 10, tzinfo=UTC) + + +def test_clocks_reject_invalid_configuration() -> None: + with pytest.raises(ValueError): + AcceleratedClock(0) + with pytest.raises(ValueError): + ManualClock(datetime(2026, 1, 1)) diff --git a/tests/unit/test_cluster_meta_handlers.py b/tests/unit/test_cluster_meta_handlers.py new file mode 100644 index 0000000..c93ea12 --- /dev/null +++ b/tests/unit/test_cluster_meta_handlers.py @@ -0,0 +1,141 @@ +"""Mapping / ACME / cluster-config durable handlers.""" + +from __future__ import annotations + +import json +from typing import Any, cast +from uuid import uuid4 + +import pytest +from fastapi import FastAPI, Request + +from app.api.registry import HandlerRegistry +from app.db.pool import AsyncpgDatabase +from app.handlers.acme import register_acme_handlers +from app.handlers.cluster_config import register_cluster_config_handlers +from app.handlers.mapping import register_mapping_handlers + +pytestmark = pytest.mark.pve_stub + + +class MetaPool: + def __init__(self) -> None: + self.metadata: dict[str, Any] = {} + self.nodes = {"pve1": {"status": "online"}} + self.cluster_name = "pve-simulator" + + async def fetch(self, query: str, *_arguments: object) -> list[dict[str, Any]]: + if "FROM nodes" in query: + return [{"name": name, "status": data["status"]} for name, data in self.nodes.items()] + raise AssertionError(query) + + async def fetchrow(self, query: str, *_arguments: object) -> dict[str, Any] | None: + if "FROM clusters WHERE id" in query: + return {"metadata": json.dumps(self.metadata)} + raise AssertionError(query) + + async def fetchval(self, query: str, *arguments: object) -> Any: + if "EXISTS(SELECT 1 FROM nodes" in query: + return str(arguments[0]) in self.nodes + raise AssertionError(query) + + async def execute(self, query: str, *arguments: object) -> str: + if "UPDATE clusters SET metadata" in query: + self.metadata = json.loads(str(arguments[1])) + return "UPDATE 1" + if "UPDATE clusters" in query and "SET name" in query: + self.cluster_name = str(arguments[0]) + return "UPDATE 1" + if "INSERT INTO nodes" in query: + self.nodes[str(arguments[0])] = {"status": "online"} + return "INSERT 0 1" + if "UPDATE nodes SET status" in query: + self.nodes[str(arguments[0])]["status"] = "offline" + return "UPDATE 1" + raise AssertionError(query) + + +async def call( + registry: HandlerRegistry, path: str, verb: str, http: Request, inputs: dict[str, Any] +) -> Any: + handler = registry.get(path, verb) + assert handler is not None + return await handler(http, inputs) + + +def request(pool: MetaPool) -> Request: + app = FastAPI() + app.state.database = cast(AsyncpgDatabase, type("DB", (), {"pool": pool})()) + return Request( + { + "type": "http", + "app": app, + "method": "POST", + "path": "/", + "headers": [], + "query_string": b"", + "server": ("test", 80), + "client": ("test", 123), + "scheme": "http", + } + ) + + +async def test_mapping_acme_config_persist() -> None: + registry = HandlerRegistry() + register_mapping_handlers(registry) + register_acme_handlers(registry) + register_cluster_config_handlers(registry) + pool = MetaPool() + http = request(pool) + + await call( + registry, + "/cluster/mapping/pci", + "POST", + http, + {"values": {"id": "gpu0", "map": "0000:01:00.0"}, "provided": frozenset()}, + ) + pci = await call( + registry, + "/cluster/mapping/pci/{id}", + "GET", + http, + {"values": {"id": "gpu0"}, "provided": frozenset()}, + ) + assert pci["map"] == "0000:01:00.0" + + await call( + registry, + "/cluster/acme/account", + "POST", + http, + { + "values": {"name": "default", "contact": "admin@example.com", "eab-hmac-key": "x"}, + "provided": frozenset(), + }, + ) + account = await call( + registry, + "/cluster/acme/account/{name}", + "GET", + http, + {"values": {"name": "default"}, "provided": frozenset()}, + ) + assert account["name"] == "default" + assert "eab-hmac-key" not in account + + await call( + registry, + "/cluster/config", + "POST", + http, + {"values": {"clustername": "lab"}, "provided": frozenset()}, + ) + assert pool.metadata["cluster_config"]["clustername"] == "lab" + assert pool.cluster_name == "lab" + totem = await call( + registry, "/cluster/config/totem", "GET", http, {"values": {}, "provided": frozenset()} + ) + assert totem["cluster_name"] == "lab" + assert uuid4() diff --git a/tests/unit/test_compatibility.py b/tests/unit/test_compatibility.py new file mode 100644 index 0000000..62de7e5 --- /dev/null +++ b/tests/unit/test_compatibility.py @@ -0,0 +1,156 @@ +"""Compatibility accounting tests.""" + +from datetime import UTC, datetime +from pathlib import Path +from typing import cast + +import pytest +from pydantic import SecretStr + +from app.compatibility import ( + CompatibilityDimension, + EvidenceManifest, + build_report, + resolve_evidence_path, +) +from app.config import Settings +from app.contracts.model import Method, PathContract, Schema, Snapshot +from app.contracts.runtime import build_compatibility_for_snapshot +from app.handlers.core import build_core_handlers + +pytestmark = pytest.mark.pve_stub + + +def snapshot() -> Snapshot: + methods = ( + Method( + verb="GET", + name="version", + returns=Schema(type="object"), + checksum="1" * 64, + ), + Method( + verb="POST", + name="update", + returns=Schema(type="null"), + checksum="2" * 64, + ), + ) + return Snapshot( + source_version="9.2.3", + retrieved_at=datetime(2026, 1, 1, tzinfo=UTC), + raw_sha256="0" * 64, + paths=(PathContract(path="/nodes/{node}", methods=methods),), + path_count=1, + method_count=2, + ) + + +def test_report_scores_levels_and_groups_independently() -> None: + report = build_report( + snapshot(), + implemented=frozenset({("/nodes/{node}", "GET")}), + observed=frozenset({("/nodes/{node}", "GET"), ("/nodes/{node}", "POST")}), + verified=frozenset({("/nodes/{node}", "GET")}), + ) + data = report.as_json() + + assert data["total_declared"] == 2 + levels = data["levels"] + assert isinstance(levels, dict) + assert levels["implemented"]["score"] == 0.5 + assert levels["observed"]["score"] == 1.0 + assert data["groups"] == {"nodes": {"declared": 2, "implemented": 1, "verified": 1}} + assert "| implemented | 1 | 50.00% |" in report.as_markdown() + + +def test_report_rejects_unbound_evidence() -> None: + with pytest.raises(ValueError, match="undeclared"): + build_report(snapshot(), verified=frozenset({("/missing", "GET")})) + + +def test_all_thirteen_dimensions_have_independent_evidence_and_renderers() -> None: + method = frozenset({("/nodes/{node}", "GET")}) + report = build_report( + snapshot(), + implemented=method, + dimensions={dimension: method for dimension in CompatibilityDimension}, + ) + + payload = report.as_json() + dimensions = cast(dict[str, dict[str, object]], payload["dimensions"]) + assert list(dimensions) == [dimension.value for dimension in CompatibilityDimension] + assert len(dimensions) == 13 + assert all(item["count"] == 1 for item in dimensions.values()) + assert payload["dimension_groups"] + classifications = cast(dict[str, list[str]], payload["classifications"]) + assert classifications["fully_compatible"] == ["GET /nodes/{node}"] + assert not classifications["partially_compatible"] + assert "| permissions | 1 |" in report.as_markdown() + assert "long_task_behavior1" in report.as_html() + assert report.canonical_json() == report.canonical_json() + + +def test_dimension_evidence_must_reference_declared_method() -> None: + with pytest.raises(ValueError, match="permissions evidence"): + build_report( + snapshot(), + dimensions={CompatibilityDimension.PERMISSIONS: frozenset({("/missing", "GET")})}, + ) + + +def test_evidence_manifest_requires_provenance_and_unique_methods() -> None: + manifest = EvidenceManifest.model_validate( + { + "profile": "pve-9.2", + "source_version": "9.2.3", + "records": [ + { + "path": "/nodes/{node}", + "verb": "GET", + "dimensions": ["http_status", "json_structure"], + "sources": ["tests/compatibility/test_proxmoxer.py"], + } + ], + } + ) + evidence = manifest.dimension_map() + assert evidence[CompatibilityDimension.HTTP_STATUS] == frozenset({("/nodes/{node}", "GET")}) + assert not evidence[CompatibilityDimension.PERMISSIONS] + assert manifest.verified_methods() == frozenset({("/nodes/{node}", "GET")}) + assert manifest.observed_methods() == frozenset({("/nodes/{node}", "GET")}) + + duplicate = manifest.model_dump(mode="json") + duplicate["records"].append(duplicate["records"][0]) + with pytest.raises(ValueError, match="duplicate methods"): + EvidenceManifest.model_validate(duplicate) + + +def test_resolve_evidence_path_prefers_per_version_ledger() -> None: + settings = Settings(compatibility_evidence=Path("evidence/pve-9.2.3.json")) + assert resolve_evidence_path("7.4-16", settings) == Path("evidence/pve-7.4-16.json").resolve() + assert resolve_evidence_path("9.2.3", settings) == Path("evidence/pve-9.2.3.json").resolve() + + +def test_build_compatibility_wires_verified_from_version_ledger() -> None: + snapshot = Snapshot.model_validate_json( + Path( + "contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/" + "snapshot.json" + ).read_bytes() + ) + settings = Settings( + contract_snapshot=Path( + "contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/" + "snapshot.json" + ), + compatibility_evidence=Path("evidence/pve-9.2.3.json"), + ticket_signing_key=SecretStr("x" * 32), + ) + handlers = build_core_handlers(settings) + report = build_compatibility_for_snapshot(snapshot, handlers, settings) + data = report.as_json() + levels = cast(dict[str, dict[str, object]], data["levels"]) + assert levels["verified"]["count"] == data["total_declared"] + assert levels["observed"]["count"] == data["total_declared"] + assert levels["implemented"]["count"] == data["total_declared"] diff --git a/tests/unit/test_compatibility_catalog.py b/tests/unit/test_compatibility_catalog.py new file mode 100644 index 0000000..c618a29 --- /dev/null +++ b/tests/unit/test_compatibility_catalog.py @@ -0,0 +1,125 @@ +"""Catalog-scoped compatibility payload tests (vSphere plane).""" + +from datetime import UTC, datetime +from typing import cast + +from httpx import ASGITransport, AsyncClient + +from app.compatibility import CompatibilityDimension, build_report +from app.config import Settings +from app.contracts.model import Method, PathContract, Schema, Snapshot +from app.main import create_app +from app.vsphere.contracts.matrix import VERSIONS +from app.web.compatibility_catalog import compatibility_payload +from tests.unit.test_health import FakeDatabase + + +def _snapshot(source_version: str, path: str) -> Snapshot: + method = Method( + verb="GET", + name="index", + returns=Schema(type="object"), + checksum="1" * 64, + ) + return Snapshot( + source_version=source_version, + retrieved_at=datetime(2026, 1, 1, tzinfo=UTC), + raw_sha256="0" * 64, + paths=(PathContract(path=path, methods=(method,)),), + path_count=1, + method_count=1, + ) + + +def test_catalog_compatibility_uses_selected_snapshot_version() -> None: + runtime_snapshot = _snapshot("8.0.2", "/api/vcenter/vm") + catalog_snapshot = _snapshot("7.0.3", "/api/vcenter/host") + runtime_report = build_report( + runtime_snapshot, + implemented=frozenset({("/api/vcenter/vm", "GET")}), + dimensions={CompatibilityDimension.ROUTE_METHOD: frozenset({("/api/vcenter/vm", "GET")})}, + ) + payload = compatibility_payload( + catalog_snapshot, + 7, + implemented_methods=frozenset({("/api/vcenter/host", "GET"), ("/api/vcenter/vm", "GET")}), + runtime_report=runtime_report, + runtime_version="8.0.2", + settings=None, + ) + assert payload["catalog_version"] == "7.0.3" + assert payload["runtime_version"] == "8.0.2" + assert payload["evidence_scope"] == "catalog" + assert payload["total_declared"] == 1 + levels = cast(dict[str, dict[str, object]], payload["levels"]) + assert levels["implemented"]["count"] == 1 + + +def test_catalog_compatibility_reuses_runtime_report_for_matching_version() -> None: + runtime_snapshot = _snapshot("8.0.2", "/api/vcenter/vm") + runtime_report = build_report( + runtime_snapshot, + implemented=frozenset({("/api/vcenter/vm", "GET")}), + dimensions={CompatibilityDimension.ROUTE_METHOD: frozenset({("/api/vcenter/vm", "GET")})}, + ) + payload = compatibility_payload( + runtime_snapshot, + 9, + implemented_methods=frozenset({("/api/vcenter/vm", "GET")}), + runtime_report=runtime_report, + runtime_version="8.0.2", + settings=None, + ) + assert payload["catalog_version"] == "8.0.2" + assert payload["evidence_scope"] == "full" + + +async def test_ui_compatibility_endpoint_follows_selected_major() -> None: + settings = Settings() + app = create_app( + settings=settings, + database_factory=lambda _settings: FakeDatabase(True), + worker_factories=(), + ) + async with app.router.lifespan_context(app): + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + major7 = await client.get("/ui/api/compatibility", params={"major": 7}) + major9 = await client.get("/ui/api/compatibility", params={"major": 9}) + assert major7.status_code == 200 + assert major9.status_code == 200 + body7 = major7.json() + body9 = major9.json() + assert body7["plane"] == "vsphere-rest" + assert body9["plane"] == "vsphere-rest" + assert body7["catalog_version"] == VERSIONS[7]["version"] + assert body9["catalog_version"] == VERSIONS[9]["version"] + assert body7["major"] == 7 + assert body9["major"] == 9 + assert body7["total_declared"] > 0 + assert body9["total_declared"] > 0 + # Catalog floor: older majors report a subset; major 9 covers the full registry. + assert body7["levels"]["implemented"]["count"] < body7["total_declared"] + assert body9["levels"]["implemented"]["count"] == body9["total_declared"] + + +async def test_ui_compatibility_covers_all_bundled_majors() -> None: + settings = Settings() + app = create_app( + settings=settings, + database_factory=lambda _settings: FakeDatabase(True), + worker_factories=(), + ) + async with app.router.lifespan_context(app): + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + for major in (6, 7, 8, 9): + response = await client.get("/ui/api/compatibility", params={"major": major}) + assert response.status_code == 200 + body = response.json() + assert body["plane"] == "vsphere-rest" + assert body["catalog_version"] == VERSIONS[major]["version"] + implemented = body["levels"]["implemented"]["count"] + declared = body["total_declared"] + assert implemented > 0 + assert implemented <= declared + if major == 9: + assert implemented == declared diff --git a/tests/unit/test_compatible_io.py b/tests/unit/test_compatible_io.py new file mode 100644 index 0000000..44a31ab --- /dev/null +++ b/tests/unit/test_compatible_io.py @@ -0,0 +1,113 @@ +"""Golden HTTP input/output compatibility checks.""" + +from datetime import UTC, datetime +from pathlib import Path +from typing import Any + +import pytest +from fastapi import Request +from httpx import ASGITransport, AsyncClient + +from app.api.registry import HandlerRegistry +from app.config import Settings +from app.contracts.model import Method, Parameter, PathContract, Schema, Snapshot +from app.main import create_app +from app.security.auth import csrf_token, issue_ticket +from tests.unit.test_health import FakeDatabase + +pytestmark = pytest.mark.pve_stub + + +async def client_for(tmp_path: Path) -> AsyncClient: + method = Method( + verb="POST", + name="update", + parameters=( + Parameter(name="node", definition=Schema(type="string")), + Parameter(name="count", definition=Schema(type="integer", minimum=1)), + Parameter(name="force", definition=Schema(type="boolean", optional=True)), + Parameter(name="scsi[n]", definition=Schema(type="string", optional=True)), + ), + returns=Schema(type="null"), + checksum="1" * 64, + ) + snapshot = Snapshot( + source_version="test", + retrieved_at=datetime(2026, 1, 1, tzinfo=UTC), + raw_sha256="0" * 64, + paths=(PathContract(path="/nodes/{node}/test", methods=(method,)),), + path_count=1, + method_count=1, + ) + path = tmp_path / "snapshot.json" + path.write_bytes(snapshot.canonical_bytes()) + handlers = HandlerRegistry() + + async def handler(_request: Request, inputs: dict[str, Any]) -> None: + assert inputs["values"]["count"] >= 1 + if "scsi0" in inputs["values"]: + assert inputs["values"]["scsi0"] == "local:disk,size=8G" + return None + + handlers.register("/nodes/{node}/test", "POST", handler) + app = create_app( + Settings(contract_snapshot=path, compatibility_evidence=None), + lambda _settings: FakeDatabase(True), + handlers, + worker_factories=(), + ) + key = Settings().ticket_signing_key.get_secret_value().encode() + ticket = issue_ticket("root@pam", key) + return AsyncClient( + transport=ASGITransport(app=app), + base_url="http://test", + cookies={"PVEAuthCookie": ticket}, + headers={"CSRFPreventionToken": csrf_token(ticket, key)}, + ) + + +async def test_json_input_and_null_envelope(tmp_path: Path) -> None: + async with await client_for(tmp_path) as client: + response = await client.post("/api2/json/nodes/pve/test", json={"count": 2, "force": True}) + + assert response.status_code == 200 + assert response.json() == {"data": None} + + +async def test_form_input_and_validation_error_shape(tmp_path: Path) -> None: + async with await client_for(tmp_path) as client: + valid = await client.post( + "/api2/json/nodes/pve/test", + content="count=1&force=yes", + headers={"content-type": "application/x-www-form-urlencoded"}, + ) + invalid = await client.post("/api2/json/nodes/pve/test", json={"count": 0, "unknown": "x"}) + + assert valid.status_code == 200 + assert invalid.status_code == 400 + assert invalid.json() == { + "data": None, + "message": "parameter verification failed", + "errors": { + "count": "value must be at least 1", + "unknown": "property is not defined in schema", + }, + } + + +async def test_non_object_json_is_rejected_without_fastapi_body(tmp_path: Path) -> None: + async with await client_for(tmp_path) as client: + response = await client.post("/api2/json/nodes/pve/test", json=[1, 2]) + + assert response.status_code == 400 + assert response.json()["errors"] == {"body": "expected an object"} + assert "detail" not in response.json() + + +async def test_indexed_contract_parameter_accepts_concrete_device(tmp_path: Path) -> None: + async with await client_for(tmp_path) as client: + response = await client.post( + "/api2/json/nodes/pve/test", json={"count": 1, "scsi0": "local:disk,size=8G"} + ) + + assert response.status_code == 200 diff --git a/tests/unit/test_contract_catalog.py b/tests/unit/test_contract_catalog.py new file mode 100644 index 0000000..5d2f111 --- /dev/null +++ b/tests/unit/test_contract_catalog.py @@ -0,0 +1,109 @@ +"""Contract catalog helpers.""" + +from datetime import UTC, datetime +from pathlib import Path +from typing import Any, cast + +import pytest + +from app.config import Settings +from app.contracts.model import Method, Parameter, PathContract, Schema, Snapshot +from app.web.contract_catalog import catalog_payload, list_majors, method_payload + + +def _snapshot() -> Snapshot: + method = Method( + verb="POST", + name="create", + description="Create a VM.", + parameters=( + Parameter(name="node", definition=Schema(type="string")), + Parameter(name="vmid", definition=Schema(type="integer", minimum=100)), + Parameter(name="name", definition=Schema(type="string")), + Parameter(name="memory", definition=Schema(type="integer", optional=True)), + Parameter(name="scsi[n]", definition=Schema(type="string", optional=True)), + ), + returns=Schema(type="string"), + checksum="a" * 64, + ) + return Snapshot( + source_version="9.2.3", + retrieved_at=datetime(2026, 1, 1, tzinfo=UTC), + raw_sha256="b" * 64, + paths=(PathContract(path="/nodes/{node}/qemu", methods=(method,)),), + path_count=1, + method_count=1, + ) + + +def test_list_majors_includes_latest_releases() -> None: + payload = list_majors(runtime_version="9.2.3") + majors_list = cast(list[dict[str, Any]], payload["majors"]) + majors = {item["major"] for item in majors_list} + series = {item["series"] for item in majors_list} + assert majors == {6, 7, 8, 9} + assert series == { + "vSphere 7.0", + "vSphere 7.0 U3", + "vSphere 8.0", + "vSphere 8.0 U2", + } + assert payload["runtime_version"] == "9.2.3" + + +def test_list_majors_includes_artifact_urls() -> None: + payload = list_majors(runtime_version="9.2.3") + majors_list = cast(list[dict[str, Any]], payload["majors"]) + release = next(item for item in majors_list if item["major"] == 9) + assert release["series"] == "vSphere 8.0 U2" + assert release["artifact_url"] == "stub://vmware/vsphere-8.0u2/api-contract" + assert release["bundled"] is True + + +def test_list_majors_honors_settings_overrides() -> None: + settings = Settings(catalog_artifact_url_9="https://example.test/vsphere/apidoc.js") + payload = list_majors(runtime_version=None, settings=settings) + majors_list = cast(list[dict[str, Any]], payload["majors"]) + release = next(item for item in majors_list if item["major"] == 9) + assert release["artifact_url"] == "https://example.test/vsphere/apidoc.js" + + +def test_catalog_payload_groups_paths_by_tag() -> None: + payload = catalog_payload( + _snapshot(), + 9, + implemented_methods=frozenset({("/nodes/{node}/qemu", "POST")}), + ) + assert payload["source_version"] == "9.2.3" + assert payload["series"] == "vSphere 8.0 U2" + assert cast(str, payload["artifact_url"]).endswith("vsphere-8.0u2/api-contract") + assert payload["latest_version"] == "9.2.3" + assert payload["path_count"] == 1 + categories = cast(list[dict[str, Any]], payload["categories"]) + method = categories[0]["paths"][0]["methods"][0] + assert method["verb"] == "POST" + assert method["implemented"] is True + + +def test_method_payload_builds_examples() -> None: + payload = method_payload( + _snapshot(), + major=9, + path="/nodes/{node}/qemu", + verb="POST", + runtime_version="9.2.3", + implemented_methods=frozenset({("/nodes/{node}/qemu", "POST")}), + ) + assert payload["resolved_path"] == "/nodes/pve01/qemu" + assert payload["body_example"] == {"vmid": 100, "name": "example"} + assert payload["implemented"] is True + + +@pytest.mark.asyncio +async def test_load_snapshot_uses_bundled_revision() -> None: + from app.web import contract_catalog + + contract_catalog._SNAPSHOT_CACHE.clear() + root = Path("contracts") + snapshot = await contract_catalog.load_snapshot(9, root) + assert snapshot.source_version == "9.2.3" diff --git a/tests/unit/test_contract_cli.py b/tests/unit/test_contract_cli.py new file mode 100644 index 0000000..6295fb8 --- /dev/null +++ b/tests/unit/test_contract_cli.py @@ -0,0 +1,54 @@ +"""Offline command workflows for contract management.""" + +import argparse +import json +from pathlib import Path + +import pytest + +from app.contracts.cli import parser, run + +pytestmark = pytest.mark.pve_stub + +FIXTURE = Path(__file__).parents[1] / "fixtures" / "api-viewer" / "pve-9.2.3-version.json" + + +async def test_validate_command_reports_source_counts( + tmp_path: Path, capsys: pytest.CaptureFixture[str] +) -> None: + arguments = argparse.Namespace(command="validate", store=tmp_path, file=FIXTURE) + + assert await run(arguments) == 0 + output = capsys.readouterr().out + assert json.loads(output) == {"nodes": 1, "warnings": 0} + + +async def test_local_import_list_and_show( + tmp_path: Path, capsys: pytest.CaptureFixture[str] +) -> None: + import_arguments = argparse.Namespace( + command="import", + store=tmp_path, + file=FIXTURE, + url=None, + version="9.2.3", + ) + assert await run(import_arguments) == 0 + revision = Path(capsys.readouterr().out.strip()).name + + assert await run(argparse.Namespace(command="list", store=tmp_path)) == 0 + assert capsys.readouterr().out.strip() == revision + + assert await run(argparse.Namespace(command="show", store=tmp_path, revision=revision)) == 0 + manifest = json.loads(capsys.readouterr().out) + assert manifest["source_version"] == "9.2.3" + assert manifest["snapshot_sha256"] == revision + + +def test_cli_parser_accepts_local_import() -> None: + arguments = parser().parse_args( + ["--store", "saved", "import", "--file", str(FIXTURE), "--version", "9.2.3"] + ) + + assert arguments.command == "import" + assert arguments.store == Path("saved") diff --git a/tests/unit/test_contract_diff.py b/tests/unit/test_contract_diff.py new file mode 100644 index 0000000..e0aed90 --- /dev/null +++ b/tests/unit/test_contract_diff.py @@ -0,0 +1,87 @@ +"""Semantic contract diff classification and rendering tests.""" + +import json +from datetime import UTC, datetime + +from app.contracts.diff import ( + Severity, + compare_snapshots, + has_breaking_changes, + render_html, + render_json, + render_markdown, + render_text, +) +from app.contracts.model import Method, PathContract, Schema, Snapshot + + +def snapshot(paths: tuple[PathContract, ...]) -> Snapshot: + return Snapshot( + source_version="test", + retrieved_at=datetime(2026, 1, 1, tzinfo=UTC), + raw_sha256="0" * 64, + paths=paths, + path_count=len(paths), + method_count=sum(len(path.methods) for path in paths), + ) + + +def method(description: str = "old", returns: Schema | None = None) -> Method: + return Method( + verb="GET", + name="read", + description=description, + returns=returns or Schema(type="string"), + checksum="1" * 64, + ) + + +def test_classifies_added_removed_and_changed_contracts() -> None: + before = snapshot( + ( + PathContract(path="/removed", methods=(method(),)), + PathContract(path="/version", methods=(method(),)), + ) + ) + after = snapshot( + ( + PathContract(path="/added", methods=(method(),)), + PathContract( + path="/version", + methods=(method("new", Schema(type="integer", minimum=1)),), + ), + ) + ) + + changes = compare_snapshots(before, after) + + assert changes == tuple(sorted(changes)) + assert {change.category for change in changes} >= { + "path", + "method", + "documentation", + "schema", + "constraint", + } + assert has_breaking_changes(changes) + assert any(change.severity is Severity.NON_BREAKING for change in changes) + + +def test_renderers_are_stable_and_escape_html() -> None: + before = snapshot((PathContract(path="/", methods=(method(),)),)) + after = snapshot(()) + changes = compare_snapshots(before, after) + + assert render_text(changes).startswith("breaking:") + assert "| breaking |" in render_markdown(changes) + assert "<old>" in render_html(changes) + decoded = json.loads(render_json(changes)) + assert decoded[0]["severity"] == "breaking" + assert render_json(changes) == render_json(changes) + + +def test_no_changes_has_clean_ci_policy() -> None: + value = snapshot((PathContract(path="/version", methods=(method(),)),)) + + assert compare_snapshots(value, value) == () + assert not has_breaking_changes(()) diff --git a/tests/unit/test_contract_importer.py b/tests/unit/test_contract_importer.py new file mode 100644 index 0000000..ef6ca29 --- /dev/null +++ b/tests/unit/test_contract_importer.py @@ -0,0 +1,107 @@ +"""Security and idempotency tests for contract imports.""" + +from datetime import UTC, datetime +from pathlib import Path + +import httpx +import pytest + +from app.contracts.importer import ( + RemoteSourceImporter, + validate_public_addresses, + validate_remote_url, +) +from app.contracts.normalize import normalize_snapshot +from app.contracts.source import ApiViewerParser, SourceError +from app.contracts.store import RevisionStore + +pytestmark = pytest.mark.pve_stub + + +async def public_resolver(_host: str) -> tuple[str, ...]: + return ("93.184.216.34",) + + +@pytest.mark.parametrize( + "url", + [ + "http://pve.proxmox.com/apidoc.js", + "https://evil.example/apidoc.js", + "https://pve.proxmox.com.evil.example/apidoc.js", + "https://user@pve.proxmox.com/apidoc.js", + "https://pve.proxmox.com:444/apidoc.js", + ], +) +def test_remote_url_policy_rejects_unsafe_urls(url: str) -> None: + with pytest.raises(SourceError): + validate_remote_url(url, frozenset({"pve.proxmox.com"})) + + +@pytest.mark.parametrize( + "address", + [ + "198.18.0.42", + "::ffff:198.18.0.42", + ], +) +def test_validate_public_addresses_allows_proxy_fake_ip(address: str) -> None: + validate_public_addresses((address,)) + + +async def test_remote_import_rejects_private_resolution() -> None: + async def private_resolver(_host: str) -> tuple[str, ...]: + return ("127.0.0.1",) + + importer = RemoteSourceImporter( + "https://pve.proxmox.com/apidoc.js", + resolver=private_resolver, + transport=httpx.MockTransport(lambda request: httpx.Response(200, content=b"[]")), + ) + + with pytest.raises(SourceError, match="non-public"): + await importer.load() + + +async def test_redirect_is_revalidated() -> None: + def handler(request: httpx.Request) -> httpx.Response: + return httpx.Response(302, headers={"location": "https://evil.example/private"}) + + importer = RemoteSourceImporter( + "https://pve.proxmox.com/apidoc.js", + resolver=public_resolver, + transport=httpx.MockTransport(handler), + ) + + with pytest.raises(SourceError, match="allowlist"): + await importer.load() + + +async def test_remote_import_enforces_size_limit() -> None: + importer = RemoteSourceImporter( + "https://pve.proxmox.com/apidoc.js", + max_bytes=2, + resolver=public_resolver, + transport=httpx.MockTransport(lambda request: httpx.Response(200, content=b"[]\n")), + ) + + with pytest.raises(SourceError, match="size"): + await importer.load() + + +def test_revision_store_is_idempotent(tmp_path: Path) -> None: + raw = b'[{"path":"/version","info":{}}]' + parsed = ApiViewerParser().parse(raw) + snapshot, manifest = normalize_snapshot( + parsed, + raw=raw, + source_version="test", + retrieved_at=datetime(2026, 1, 1, tzinfo=UTC), + ) + store = RevisionStore(tmp_path) + + first = store.save(raw, snapshot, manifest) + second = store.save(raw, snapshot, manifest) + + assert first == second + assert store.list() == (manifest.snapshot_sha256,) + assert store.manifest(manifest.snapshot_sha256) == manifest diff --git a/tests/unit/test_contract_model.py b/tests/unit/test_contract_model.py new file mode 100644 index 0000000..e58a3ce --- /dev/null +++ b/tests/unit/test_contract_model.py @@ -0,0 +1,94 @@ +"""Determinism and validation checks for normalized contracts.""" + +import json +from datetime import UTC, datetime +from pathlib import Path + +import pytest +from hypothesis import given +from hypothesis import strategies as st +from pydantic import ValidationError + +from app.contracts.model import Snapshot, canonical_json +from app.contracts.normalize import normalize_snapshot +from app.contracts.source import ApiViewerParser + +pytestmark = pytest.mark.pve_stub + +FIXTURE = Path(__file__).parents[1] / "fixtures" / "api-viewer" / "pve-9.2.3-version.json" +RETRIEVED_AT = datetime(2026, 7, 12, 20, 8, 59, tzinfo=UTC) + + +def make_snapshot() -> Snapshot: + raw = FIXTURE.read_bytes() + parsed = ApiViewerParser().parse(raw) + snapshot, _ = normalize_snapshot( + parsed, raw=raw, source_version="9.2.3", retrieved_at=RETRIEVED_AT + ) + return snapshot + + +def test_normalization_is_deterministic_and_round_trips() -> None: + first = make_snapshot() + second = make_snapshot() + + assert first.canonical_bytes() == second.canonical_bytes() + assert first.checksum() == second.checksum() + assert Snapshot.model_validate_json(first.canonical_bytes()) == first + assert first.paths[0].methods[0].checksum == second.paths[0].methods[0].checksum + + +def test_snapshot_validates_declared_counts() -> None: + data = make_snapshot().model_dump(mode="json") + data["method_count"] = 99 + + with pytest.raises(ValidationError, match="method_count"): + Snapshot.model_validate(data) + + +def test_unknown_schema_fields_are_retained() -> None: + raw = json.dumps( + [ + { + "path": "/future", + "info": { + "GET": { + "name": "future", + "returns": {"type": "string", "futureKeyword": {"x": 1}}, + } + }, + } + ] + ).encode() + snapshot, _ = normalize_snapshot( + ApiViewerParser().parse(raw), + raw=raw, + source_version="test", + retrieved_at=RETRIEVED_AT, + ) + + assert snapshot.paths[0].methods[0].returns.extra["futureKeyword"] == {"x": 1} + + +def test_nullable_source_collections_normalize_as_empty() -> None: + raw = ( + b'[{"path":"/nullable","info":{"GET":{"parameters":{"properties":null},' + b'"returns":{"type":"string","enum":null}}}}]' + ) + snapshot, _ = normalize_snapshot( + ApiViewerParser().parse(raw), + raw=raw, + source_version="test", + retrieved_at=RETRIEVED_AT, + ) + + method = snapshot.paths[0].methods[0] + assert method.parameters == () + assert method.returns.enum == () + + +@given(st.dictionaries(st.text(min_size=1), st.integers(), max_size=10)) +def test_canonical_json_is_independent_of_mapping_order(values: dict[str, int]) -> None: + reversed_values = dict(reversed(tuple(values.items()))) + + assert canonical_json(values) == canonical_json(reversed_values) diff --git a/tests/unit/test_contract_runtime.py b/tests/unit/test_contract_runtime.py new file mode 100644 index 0000000..99ea444 --- /dev/null +++ b/tests/unit/test_contract_runtime.py @@ -0,0 +1,97 @@ +"""Runtime contract hot-swap tests.""" + +from pathlib import Path + +import pytest +from fastapi import FastAPI +from httpx import ASGITransport, AsyncClient + +from app.config import Settings +from app.main import create_app +from tests.unit.test_health import FakeDatabase + +pytestmark = pytest.mark.pve_stub + +_BUNDLED_9 = Path( + "contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/snapshot.json" +) +_EVIDENCE_9 = Path("evidence/pve-9.2.3.json") + + +def _app() -> FastAPI: + settings = Settings( + contract_snapshot=_BUNDLED_9, + compatibility_evidence=_EVIDENCE_9, + ) + return create_app( + settings=settings, + database_factory=lambda _settings: FakeDatabase(True), + worker_factories=(), + ) + + +async def test_contract_apply_swaps_version_and_routes() -> None: + app = _app() + async with app.router.lifespan_context(app): + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + before = await client.get("/api2/json/version") + assert before.status_code == 200 + assert before.json()["data"]["version"] == "9.2.3" + assert before.json()["data"]["release"] == "9.2" + + versions = await client.get("/ui/api/versions") + assert versions.status_code == 200 + assert versions.json()["runtime_version"] == "9.2.3" + + applied = await client.post("/ui/api/contract/apply", params={"major": 7}) + assert applied.status_code == 200 + payload = applied.json() + assert payload["ok"] is True + assert payload["major"] == 7 + assert payload["runtime_version"] == "7.4-16" + assert payload["path_count"] > 0 + assert payload["method_count"] > 0 + + after = await client.get("/api2/json/version") + assert after.status_code == 200 + assert after.json()["data"]["version"] == "7.4-16" + assert after.json()["data"]["release"] == "7.4" + + versions_after = await client.get("/ui/api/versions") + assert versions_after.json()["runtime_version"] == "7.4-16" + + # Still routed (handler or 501), not a missing route / 404. + nodes = await client.get("/api2/json/nodes") + assert nodes.status_code in {200, 401, 501} + + restored = await client.post("/ui/api/contract/apply", params={"major": 9}) + assert restored.status_code == 200 + assert restored.json()["runtime_version"] == "9.2.3" + assert (await client.get("/api2/json/version")).json()["data"]["version"] == "9.2.3" + + +@pytest.mark.parametrize("major,version", [(6, "6.4-15"), (7, "7.4-16"), (8, "8.4.5")]) +async def test_contract_apply_loads_per_major_verified_evidence(major: int, version: str) -> None: + app = _app() + async with app.router.lifespan_context(app): + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + applied = await client.post("/ui/api/contract/apply", params={"major": major}) + assert applied.status_code == 200 + assert applied.json()["runtime_version"] == version + report = await client.get("/admin/compatibility") + body = report.json() + assert body["source_version"] == version + assert body["levels"]["verified"]["count"] == body["total_declared"] + assert body["levels"]["verified"]["count"] > 0 + + +async def test_contract_apply_requires_bootstrapped_contract() -> None: + app = create_app( + settings=Settings(contract_snapshot=None), + database_factory=lambda _settings: FakeDatabase(True), + worker_factories=(), + ) + async with app.router.lifespan_context(app): + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + response = await client.post("/ui/api/contract/apply", params={"major": 7}) + assert response.status_code == 503 diff --git a/tests/unit/test_contract_source.py b/tests/unit/test_contract_source.py new file mode 100644 index 0000000..5bc4cc0 --- /dev/null +++ b/tests/unit/test_contract_source.py @@ -0,0 +1,67 @@ +"""Tests for safe API Viewer source parsing.""" + +import json +from pathlib import Path + +import pytest + +from app.contracts.source import ApiViewerParser, LocalFileImporter, SourceError + +pytestmark = pytest.mark.pve_stub + +FIXTURE = Path(__file__).parents[1] / "fixtures" / "api-viewer" / "pve-9.2.3-version.json" + + +def test_parse_saved_json_fixture() -> None: + parsed = ApiViewerParser().parse(FIXTURE.read_bytes()) + + assert parsed.nodes[0]["path"] == "/version" + assert parsed.warnings == () + + +def test_extract_api_schema_without_executing_trailing_javascript() -> None: + raw = b'const apiSchema = [{"path":"/x]y","leaf":1}]; throw new Error("no");' + + parsed = ApiViewerParser().parse(raw) + + assert parsed.nodes[0]["path"] == "/x]y" + + +def test_extract_legacy_pveapi_declaration() -> None: + raw = b'var pveapi = [{"path":"/version","leaf":1}];' + + parsed = ApiViewerParser().parse(raw) + + assert parsed.nodes[0]["path"] == "/version" + + +@pytest.mark.parametrize( + "raw, message", + [ + (b"", "empty"), + (b"const other = [];", "not found"), + (b"const apiSchema = [", "truncated"), + (b"const apiSchema = [}];", "invalid"), + (b"42", "not found"), + ], +) +def test_reject_malformed_sources(raw: bytes, message: str) -> None: + with pytest.raises(SourceError, match=message): + ApiViewerParser().parse(raw) + + +def test_preserve_unknown_fields_and_warn() -> None: + raw = json.dumps([{"path": "/version", "future": {"enabled": True}}]).encode() + + parsed = ApiViewerParser().parse(raw) + + assert parsed.nodes[0]["future"] == {"enabled": True} + assert parsed.warnings[0].code == "unknown-node-field" + assert parsed.warnings[0].path == "/0/future" + + +async def test_local_file_importer(tmp_path: Path) -> None: + artifact = tmp_path / "api.json" + artifact.write_bytes(b"[]") + + assert await LocalFileImporter(artifact).load() == b"[]" diff --git a/tests/unit/test_core_handlers.py b/tests/unit/test_core_handlers.py new file mode 100644 index 0000000..b2b8d49 --- /dev/null +++ b/tests/unit/test_core_handlers.py @@ -0,0 +1,204 @@ +"""First vertical read/login handler tests.""" + +import uuid +from datetime import UTC, datetime +from pathlib import Path + +import pytest +from httpx import ASGITransport, AsyncClient + +from app.config import Settings +from app.contracts.model import Method, Parameter, PathContract, Schema, Snapshot +from app.main import create_app +from app.security.auth import hash_secret +from app.tasks.repository import Task + +pytestmark = pytest.mark.pve_stub + + +class FakePool: + async def fetchrow(self, sql: str, *args: object) -> dict[str, object] | None: + if "principals" in sql and args[0] == "root@pam": + return { + "name": "root@pam", + "password_hash": hash_secret("secret", salt=b"pve-simulator-v1"), + } + if "FROM nodes" in sql and args[0] == "pve1": + return {"name": "pve1", "status": "online"} + if "FROM resources r" in sql and args == ("pve1", "100"): + if "SELECT r.id" in sql: + return { + "id": uuid.UUID("00000000-0000-0000-0000-000000000100"), + "state": '{"name":"demo","status":"stopped"}', + } + return { + "config": '{"name":"demo"}', + "state": '{"name":"demo","status":"stopped"}', + } + return None + + async def fetch(self, sql: str, *args: object) -> list[dict[str, object]]: + del args + if "FROM nodes" in sql: + return [{"node": "pve1", "status": "online"}] + if "r.kind='qemu'" in sql: + return [{"vmid": 100, "state": '{"name":"demo","status":"stopped"}'}] + return [ + { + "type": "qemu", + "external_id": "100", + "state": '{"status":"stopped"}', + "node": "pve1", + } + ] + + async def fetchval(self, sql: str) -> int: + return 100 if "pg_backend_pid" in sql else 1_700_000_000 + + +class FakeDatabase: + pool = FakePool() + + async def connect(self) -> None: + pass + + async def close(self) -> None: + pass + + async def is_ready(self) -> bool: + return True + + +def method(verb: str, name: str, parameters: tuple[Parameter, ...] = ()) -> Method: + return Method( + verb=verb, + name=name, + parameters=parameters, + returns=Schema(type="object"), + checksum=(name[0] * 64), + ) + + +def write_snapshot(path: Path) -> None: + string = Schema(type="string") + paths = ( + PathContract(path="/version", methods=(method("GET", "version"),)), + PathContract( + path="/access/ticket", + methods=( + method( + "POST", + "ticket", + ( + Parameter(name="username", definition=string), + Parameter(name="password", definition=string), + ), + ), + ), + ), + PathContract(path="/nodes", methods=(method("GET", "nodes"),)), + PathContract( + path="/nodes/{node}/status", + methods=(method("GET", "status", (Parameter(name="node", definition=string),)),), + ), + PathContract(path="/cluster/resources", methods=(method("GET", "resources"),)), + PathContract( + path="/nodes/{node}/qemu", + methods=(method("GET", "qemu", (Parameter(name="node", definition=string),)),), + ), + PathContract( + path="/nodes/{node}/qemu/{vmid}/config", + methods=( + method( + "GET", + "config", + ( + Parameter(name="node", definition=string), + Parameter(name="vmid", definition=Schema(type="integer")), + ), + ), + ), + ), + PathContract( + path="/nodes/{node}/qemu/{vmid}/status/start", + methods=( + method( + "POST", + "start", + ( + Parameter(name="node", definition=string), + Parameter(name="vmid", definition=Schema(type="integer")), + ), + ), + ), + ), + ) + snapshot = Snapshot( + source_version="test", + retrieved_at=datetime(2026, 1, 1, tzinfo=UTC), + raw_sha256="0" * 64, + paths=paths, + path_count=len(paths), + method_count=sum(len(item.methods) for item in paths), + ) + path.write_bytes(snapshot.canonical_bytes()) + + +async def test_core_login_and_read_endpoints( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + class FakeTaskRepository: + def __init__(self, pool: object) -> None: + del pool + + async def create(self, **kwargs: object) -> Task: + return Task( + uuid.uuid4(), + str(kwargs["upid"]), + str(kwargs["task_type"]), + "queued", + {}, + 0, + False, + 0, + ) + + monkeypatch.setattr("app.handlers.qemu.TaskRepository", FakeTaskRepository) + snapshot_path = tmp_path / "snapshot.json" + write_snapshot(snapshot_path) + database = FakeDatabase() + app = create_app( + Settings(contract_snapshot=snapshot_path, compatibility_evidence=None), + lambda _settings: database, + worker_factories=(), + ) + async with app.router.lifespan_context(app): + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + login = await client.post( + "/api2/json/access/ticket", + content="username=root%40pam&password=secret", + headers={"content-type": "application/x-www-form-urlencoded"}, + ) + csrf = login.json()["data"]["CSRFPreventionToken"] + version = await client.get("/api2/json/version") + nodes = await client.get("/api2/json/nodes") + status = await client.get("/api2/json/nodes/pve1/status") + resources = await client.get("/api2/json/cluster/resources") + qemu = await client.get("/api2/json/nodes/pve1/qemu") + config = await client.get("/api2/json/nodes/pve1/qemu/100/config") + start = await client.post( + "/api2/json/nodes/pve1/qemu/100/status/start", + headers={"CSRFPreventionToken": csrf}, + ) + + assert login.status_code == 200 + assert login.json()["data"]["username"] == "root@pam" + assert "ticket" in login.json()["data"] + assert version.json()["data"]["version"] == "test" + assert version.json()["data"]["release"] == "test" + assert nodes.json()["data"][0]["node"] == "pve1" + assert status.json()["data"]["status"] == "online" + assert resources.json()["data"][0]["type"] == "qemu" + assert qemu.json()["data"][0]["vmid"] == 100 + assert config.json()["data"]["name"] == "demo" + assert start.json()["data"].startswith("UPID:pve1:") diff --git a/tests/unit/test_db_primitives.py b/tests/unit/test_db_primitives.py new file mode 100644 index 0000000..9b5d78d --- /dev/null +++ b/tests/unit/test_db_primitives.py @@ -0,0 +1,59 @@ +"""Database primitive behavior independent of PostgreSQL.""" + +import asyncpg # type: ignore[import-untyped] +import pytest + +from app.db.primitives import ( + ConflictError, + DatabaseOperationError, + ReferenceError, + RetryPolicy, + TransientDatabaseError, + map_database_error, + require_affected, + retry_transient, +) + + +def test_error_mapping_is_stable_and_safe() -> None: + assert isinstance(map_database_error(asyncpg.UniqueViolationError("secret")), ConflictError) + assert isinstance( + map_database_error(asyncpg.ForeignKeyViolationError("secret")), ReferenceError + ) + assert isinstance( + map_database_error(asyncpg.SerializationError("secret")), TransientDatabaseError + ) + assert "secret" not in str(map_database_error(asyncpg.PostgresError("secret"))) + + +def test_affected_row_checks() -> None: + require_affected("UPDATE 1") + with pytest.raises(DatabaseOperationError, match="expected 1"): + require_affected("UPDATE 0") + with pytest.raises(DatabaseOperationError, match="unrecognized"): + require_affected("BROKEN") + + +async def test_transient_retry_is_bounded() -> None: + calls = 0 + + async def operation() -> str: + nonlocal calls + calls += 1 + if calls < 3: + raise TransientDatabaseError("retry") + return "ok" + + assert await retry_transient(operation, RetryPolicy(attempts=3, base_delay_seconds=0)) == "ok" + assert calls == 3 + + +async def test_transient_retry_propagates_final_failure() -> None: + async def operation() -> None: + raise TransientDatabaseError("retry") + + with pytest.raises(TransientDatabaseError): + await retry_transient(operation, RetryPolicy(attempts=2, base_delay_seconds=0)) + + with pytest.raises(ValueError, match="positive"): + await retry_transient(operation, RetryPolicy(attempts=0)) diff --git a/tests/unit/test_dynamic_routes.py b/tests/unit/test_dynamic_routes.py new file mode 100644 index 0000000..932eaf6 --- /dev/null +++ b/tests/unit/test_dynamic_routes.py @@ -0,0 +1,101 @@ +"""Contract-driven route registry tests.""" + +from datetime import UTC, datetime +from pathlib import Path +from typing import Any + +import pytest +from fastapi import Request +from httpx import ASGITransport, AsyncClient +from pydantic import ValidationError + +from app.api.registry import HandlerRegistry, RouteCollisionError +from app.config import Settings +from app.contracts.model import Method, PathContract, Schema, Snapshot +from app.main import create_app +from tests.unit.test_health import FakeDatabase + +pytestmark = pytest.mark.pve_stub + + +def contract_snapshot(*methods: Method) -> Snapshot: + paths = (PathContract(path="/version", methods=methods),) + return Snapshot( + source_version="test", + retrieved_at=datetime(2026, 1, 1, tzinfo=UTC), + raw_sha256="0" * 64, + paths=paths, + path_count=1, + method_count=len(methods), + ) + + +def get_method() -> Method: + return Method( + verb="GET", + name="version", + returns=Schema(type="object", properties={"version": Schema(type="string")}), + checksum="1" * 64, + ) + + +async def request_app( + tmp_path: Path, fallback: str, handlers: HandlerRegistry | None = None +) -> tuple[dict[str, Any], dict[str, Any]]: + snapshot_path = tmp_path / "snapshot.json" + snapshot_path.write_bytes(contract_snapshot(get_method()).canonical_bytes()) + settings = Settings( + contract_snapshot=snapshot_path, + contract_fallback=fallback, + compatibility_evidence=None, + ) + database = FakeDatabase(True) + app = create_app( + settings, + lambda _settings: database, + handlers if handlers is not None else HandlerRegistry(), + worker_factories=(), + ) + async with app.router.lifespan_context(app): + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + json_response = await client.get("/api2/json/version") + extjs_response = await client.get("/api2/extjs/version") + return json_response.json(), extjs_response.json() + + +async def test_registered_handler_serves_both_renderers(tmp_path: Path) -> None: + handlers = HandlerRegistry() + + async def version(_request: Request, _inputs: dict[str, Any]) -> dict[str, str]: + return {"version": "9.2.3"} + + handlers.register("/version", "GET", version) + + json_body, extjs_body = await request_app(tmp_path, "error", handlers) + + assert json_body == {"data": {"version": "9.2.3"}} + assert extjs_body == {"data": {"version": "9.2.3"}, "success": True} + + +async def test_explicit_fallback_modes(tmp_path: Path) -> None: + error_body, _ = await request_app(tmp_path, "error") + default_body, _ = await request_app(tmp_path, "schema-default") + + assert error_body["errors"] == "handler pending for this contract method" + assert default_body["data"]["version"] in {None, "example"} + + +def test_duplicate_snapshot_routes_are_rejected() -> None: + with pytest.raises(ValidationError, match="duplicate"): + contract_snapshot(get_method(), get_method()) + + +def test_duplicate_semantic_handlers_are_rejected() -> None: + handlers = HandlerRegistry() + + async def handler(_request: Request, _inputs: dict[str, Any]) -> None: + return None + + handlers.register("/version", "GET", handler) + with pytest.raises(RouteCollisionError, match="duplicate"): + handlers.register("/version", "GET", handler) diff --git a/tests/unit/test_extended_handlers.py b/tests/unit/test_extended_handlers.py new file mode 100644 index 0000000..de70877 --- /dev/null +++ b/tests/unit/test_extended_handlers.py @@ -0,0 +1,180 @@ +"""Tests for cluster, storage, pool and ceph handlers.""" + +from __future__ import annotations + +import uuid +from typing import Any + +import pytest +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.ceph import register_ceph_handlers +from app.handlers.cluster import register_cluster_handlers +from app.handlers.pools import register_pool_handlers +from app.handlers.storage import register_storage_handlers + + +class HandlerPool: + def __init__(self) -> None: + self.node_exists = True + + async def fetch(self, sql: str, *args: object) -> list[dict[str, object]]: + del args + if "FROM nodes" in sql and "ORDER BY name" in sql: + return [{"id": uuid.uuid4(), "name": "pve01", "status": "online"}] + if "FROM storages" in sql and "DISTINCT storage_id" in sql: + return [{"storage_id": "local-lvm-pve01"}] + if "FROM storages s" in sql: + return [ + { + "storage_id": "local-lvm-pve01", + "storage_type": "lvmthin", + "shared": False, + "capacity_bytes": 1_000_000, + "used_bytes": 250_000, + "config": '{"content":["images"]}', + } + ] + if "ceph-osd" in sql: + return [ + { + "external_id": "osd.0", + "state": '{"osd_id":0,"status":"up","in":true,"weight":1.0}', + } + ] + if "FROM pools" in sql: + return [ + { + "id": uuid.uuid4(), + "pool_id": "production", + "comment": "prod", + "metadata": '{"members":["100"]}', + } + ] + if "FROM pool_members" in sql: + return [{"external_id": "100"}] + if "FROM task_logs" in sql: + return [{"message": "seeded task", "sequence": 1}] + if "FROM tasks" in sql: + return [{"upid": "UPID:pve01:1:1:1:qmstart:100:root@pam:"}] + if "FROM storage_contents" in sql or "FROM backups" in sql: + return [] + raise AssertionError(sql) + + async def fetchrow(self, sql: str, *args: object) -> dict[str, object] | None: + del args + if "FROM nodes WHERE name" in sql: + return {"name": "pve01", "status": "online"} if self.node_exists else None + if "FROM clusters" in sql: + return {"metadata": '{"options":{"keyboard":"de-ch"}}'} + if "FROM storages" in sql: + return { + "storage_id": "local-lvm-pve01", + "storage_type": "lvmthin", + "shared": False, + "capacity_bytes": 1_000_000, + "used_bytes": 250_000, + "config": '{"content":["images"]}', + "node_name": "pve01", + "resource_id": uuid.uuid4(), + } + if "ceph-osd" in sql: + return { + "external_id": "osd.0", + "state": '{"osd_id":0,"status":"up","in":true,"weight":1.0,"size_bytes":1000}', + } + if "storage_type='ceph'" in sql: + return {"capacity_bytes": 5_000_000, "used_bytes": 3_000_000} + raise AssertionError(sql) + + async def fetchval(self, sql: str, *args: object) -> Any: + del args + if "EXISTS(SELECT 1 FROM nodes" in sql: + return self.node_exists + if "MAX(external_id::integer)" in sql: + return 150 + if "count(*)::int FROM resources WHERE kind='ceph-osd'" in sql: + return 300 + if "SELECT resource_id FROM storages" in sql: + return uuid.uuid4() + return False + + async def execute(self, sql: str, *args: object) -> str: + del sql, args + return "UPDATE 1" + + +def _request(pool: HandlerPool) -> Request: + app = type("App", (), {})() + app.state = type("State", (), {"database": type("DB", (), {"pool": pool})()})() + scope = { + "type": "http", + "method": "GET", + "path": "/", + "headers": [], + "query_string": b"", + "client": ("test", 1234), + "server": ("test", 80), + "scheme": "http", + "root_path": "", + "app": app, + } + request = Request(scope) + request.state.principal = "root@pam" + return request + + +async def _call(handler: Any, values: dict[str, Any], pool: HandlerPool | None = None) -> Any: + return await handler(_request(pool or HandlerPool()), {"values": values}) + + +@pytest.mark.asyncio +async def test_cluster_status_and_nextid() -> None: + registry = HandlerRegistry() + register_cluster_handlers(registry) + status = await _call(registry.get("/cluster/status", "GET"), {}) + assert status[0]["name"] == "pve01" + nextid = await _call(registry.get("/cluster/nextid", "GET"), {}) + assert nextid == 151 + + +@pytest.mark.asyncio +async def test_storage_and_ceph_handlers() -> None: + registry = HandlerRegistry() + register_storage_handlers(registry) + register_ceph_handlers(registry) + storage = await _call( + registry.get("/nodes/{node}/storage", "GET"), + {"node": "pve01"}, + ) + assert storage[0]["storage"] == "local-lvm-pve01" + osds = await _call( + registry.get("/nodes/{node}/ceph/osd", "GET"), + {"node": "pve01"}, + ) + assert osds[0]["status"] == "up" + ceph_status = await _call(registry.get("/cluster/ceph/status", "GET"), {}) + assert ceph_status["osdmap"]["num_osds"] == 300 + + +@pytest.mark.asyncio +async def test_pools_list() -> None: + registry = HandlerRegistry() + register_pool_handlers(registry) + pools = await _call(registry.get("/pools", "GET"), {}) + assert pools[0]["poolid"] == "production" + assert pools[0]["members"] == ["100"] + + +@pytest.mark.asyncio +async def test_missing_node_returns_404() -> None: + registry = HandlerRegistry() + register_storage_handlers(registry) + pool = HandlerPool() + pool.node_exists = False + handler = registry.get("/nodes/{node}/storage", "GET") + assert handler is not None + with pytest.raises(ApiError, match="node does not exist"): + await handler(_request(pool), {"values": {"node": "missing"}}) diff --git a/tests/unit/test_firewall_handlers.py b/tests/unit/test_firewall_handlers.py new file mode 100644 index 0000000..c538302 --- /dev/null +++ b/tests/unit/test_firewall_handlers.py @@ -0,0 +1,83 @@ +"""Firewall aliases/ipset/group persistence tests.""" + +from __future__ import annotations + +import json +from typing import Any, cast + +from fastapi import FastAPI, Request + +from app.api.registry import HandlerRegistry +from app.db.pool import AsyncpgDatabase +from app.handlers.firewall import register_firewall_handlers +from app.simulation.seed import CLUSTER_ID + + +class FirewallPool: + def __init__(self) -> None: + self.metadata: dict[str, Any] = {} + + async def fetchrow(self, query: str, *arguments: object) -> dict[str, Any] | None: + if "FROM clusters WHERE id" in query: + return {"metadata": json.dumps(self.metadata)} + raise AssertionError(query) + + async def fetchval(self, query: str, *arguments: object) -> Any: + if "EXISTS(SELECT 1 FROM nodes" in query: + return True + raise AssertionError(query) + + async def execute(self, query: str, *arguments: object) -> str: + if "jsonb_set" in query: + # args: CLUSTER_ID, firewall json + self.metadata["firewall"] = json.loads(str(arguments[1])) + return "UPDATE 1" + raise AssertionError(query) + + +def request(pool: FirewallPool) -> Request: + app = FastAPI() + app.state.database = cast(AsyncpgDatabase, type("DB", (), {"pool": pool})()) + result = Request( + { + "type": "http", + "app": app, + "method": "POST", + "path": "/", + "headers": [], + "query_string": b"", + "server": ("test", 80), + "client": ("test", 123), + "scheme": "http", + } + ) + result.state.principal = "root@pam" + return result + + +async def test_firewall_alias_and_ipset_persist() -> None: + registry = HandlerRegistry() + register_firewall_handlers(registry) + pool = FirewallPool() + http = request(pool) + create_alias = registry.get("/cluster/firewall/aliases", "POST") + list_alias = registry.get("/cluster/firewall/aliases", "GET") + create_ipset = registry.get("/cluster/firewall/ipset", "POST") + add_ip = registry.get("/cluster/firewall/ipset/{name}", "POST") + get_ipset = registry.get("/cluster/firewall/ipset/{name}", "GET") + assert create_alias and list_alias and create_ipset and add_ip and get_ipset + + await create_alias( + http, {"values": {"name": "lan", "cidr": "10.0.0.0/8"}, "provided": frozenset()} + ) + aliases = await list_alias(http, {"values": {}, "provided": frozenset()}) + assert aliases[0]["name"] == "lan" + await create_ipset(http, {"values": {"name": "blacklist"}, "provided": frozenset()}) + await add_ip( + http, + {"values": {"name": "blacklist", "cidr": "203.0.113.10"}, "provided": frozenset()}, + ) + entries = await get_ipset(http, {"values": {"name": "blacklist"}, "provided": frozenset()}) + assert entries[0]["cidr"] == "203.0.113.10" + assert "scopes" in pool.metadata["firewall"] + assert CLUSTER_ID diff --git a/tests/unit/test_gap_plan_handlers.py b/tests/unit/test_gap_plan_handlers.py new file mode 100644 index 0000000..3246356 --- /dev/null +++ b/tests/unit/test_gap_plan_handlers.py @@ -0,0 +1,288 @@ +"""Tests for gap-plan handler implementations.""" + +from __future__ import annotations + +import json +import uuid +from typing import Any + +import pytest +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.access import register_access_handlers +from app.handlers.cluster import register_cluster_handlers +from app.handlers.ha import register_ha_handlers +from app.handlers.storage import register_storage_handlers + + +class GapPool: + def __init__(self) -> None: + self.metadata: dict[str, Any] = { + "options": {"keyboard": "en-us"}, + "replication": [], + "ha_groups": {}, + } + self.node_metadata: dict[str, Any] = {} + self.node_exists = True + self.storage_resource_id = uuid.uuid4() + self.storage_contents: list[dict[str, object]] = [] + self.principals = {"root@pam": {"enabled": True, "realm": "pam"}} + self.groups = {"operators": {"comment": "ops", "users": ["root@pam"]}} + + async def fetch(self, sql: str, *args: object) -> list[dict[str, object]]: + del args + if "FROM nodes" in sql and "ORDER BY name" in sql: + return [{"id": uuid.uuid4(), "name": "pve01", "status": "online"}] + if "FROM tasks" in sql: + return [] + if "FROM task_logs" in sql: + return [] + if "FROM resources r JOIN nodes" in sql and "kind='ha'" in sql: + return [] + if "FROM storage_contents" in sql and "ORDER BY" in sql: + return list(self.storage_contents) + if "FROM backups" in sql and "ORDER BY created_at DESC" in sql and "OFFSET" not in sql: + return [] + if "FROM principals p" in sql and "ORDER BY p.name" in sql: + return [ + { + "name": name, + "realm_name": data["realm"], + "enabled": data["enabled"], + "realm_kind": data["realm"], + } + for name, data in self.principals.items() + ] + if "FROM identity_groups g" in sql and "GROUP BY" in sql: + return [ + { + "group_id": group_id, + "comment": data["comment"], + "users": data["users"], + } + for group_id, data in self.groups.items() + ] + raise AssertionError(sql) + + async def fetchrow(self, sql: str, *args: object) -> dict[str, object] | None: + if "FROM clusters WHERE id" in sql: + return {"metadata": json.dumps(self.metadata)} + if "FROM nodes WHERE name" in sql and "metadata" in sql: + name = str(args[0]) + return {"metadata": json.dumps(self.node_metadata.get(name, {}))} + if "FROM nodes WHERE name" in sql: + return {"name": "pve01", "id": uuid.uuid4()} if self.node_exists else None + if "FROM storages WHERE storage_id" in sql and "resource_id" in sql: + return {"resource_id": self.storage_resource_id} + if "FROM storages s" in sql and "JOIN" in sql: + return { + "storage_id": "local-lvm", + "storage_type": "lvmthin", + "shared": False, + "capacity_bytes": 1_000_000, + "used_bytes": 250_000, + "config": '{"content":["images"]}', + "node_name": "pve01", + "resource_id": self.storage_resource_id, + } + if "FROM storage_contents" in sql and "volume_id=$2" in sql: + volume = str(args[1]) + for item in self.storage_contents: + if item["volume_id"] == volume: + return item + return { + "volume_id": "local-lvm:100/vm-100-disk-0.raw", + "content_type": "images", + "size_bytes": 1024, + "metadata": '{"format":"raw"}', + "created_at": type("TS", (), {"timestamp": lambda self: 1_700_000_000})(), + } + if "FROM principals" in sql and "WHERE" in sql and "name" in sql: + userid = str(args[0]) + if userid not in self.principals: + return None + data = self.principals[userid] + return { + "name": userid, + "realm_name": data["realm"], + "enabled": data["enabled"], + "realm_kind": data["realm"], + "id": uuid.uuid4(), + } + if "FROM identity_groups WHERE group_id" in sql: + groupid = str(args[0]) + if groupid not in self.groups: + return None + return {"id": uuid.uuid4(), "group_id": groupid} + if "FROM identity_groups g" in sql and "WHERE g.group_id" in sql: + groupid = str(args[0]) + if groupid not in self.groups: + return None + group_data = self.groups[groupid] + return { + "group_id": groupid, + "comment": group_data["comment"], + "users": group_data["users"], + } + if "count(*) FILTER" in sql and "kind='ha'" in sql: + return {"started": 0, "total": 0} + raise AssertionError(sql) + + async def fetchval(self, sql: str, *args: object) -> Any: + if "EXISTS(SELECT 1 FROM nodes" in sql: + return self.node_exists + if "MAX(external_id::integer)" in sql: + return 150 + if "SELECT resource_id FROM storages" in sql: + return self.storage_resource_id + if "EXISTS(SELECT 1 FROM principals" in sql: + return False + if "EXISTS(SELECT 1 FROM realms" in sql: + return True + if "EXISTS(SELECT 1 FROM identity_groups" in sql: + return False + if "EXISTS(SELECT 1 FROM resources WHERE kind='ha'" in sql: + return False + if "SELECT metadata FROM nodes" in sql: + return json.dumps(self.node_metadata.get(str(args[0]), {})) + if "SELECT name FROM nodes WHERE status" in sql: + return "pve01" + return False + + async def execute(self, sql: str, *args: object) -> str: + if "UPDATE clusters SET metadata" in sql: + self.metadata = json.loads(str(args[1])) + return "UPDATE 1" + if "UPDATE nodes SET metadata" in sql: + self.node_metadata[str(args[0])] = json.loads(str(args[1])) + return "UPDATE 1" + if "INSERT INTO storage_contents" in sql: + self.storage_contents.append( + { + "volume_id": str(args[1]), + "content_type": str(args[2]), + "size_bytes": int(str(args[3])), + "metadata": str(args[4]), + "created_at": type("TS", (), {"timestamp": lambda self: 1_700_000_000})(), + } + ) + return "INSERT 0 1" + if "INSERT INTO resources" in sql and "kind='ha'" in sql: + return "INSERT 0 1" + if "DELETE FROM" in sql: + return "DELETE 1" + return "UPDATE 1" + + +def _request(pool: GapPool) -> Request: + app = type("App", (), {})() + app.state = type("State", (), {"database": type("DB", (), {"pool": pool})()})() + scope = { + "type": "http", + "method": "GET", + "path": "/", + "headers": [], + "query_string": b"", + "client": ("test", 1234), + "server": ("test", 80), + "scheme": "http", + "root_path": "", + "app": app, + } + request = Request(scope) + request.state.principal = "root@pam" + return request + + +async def _call(handler: Any, values: dict[str, Any], pool: GapPool | None = None) -> Any: + return await handler( + _request(pool or GapPool()), + {"values": values, "provided": tuple(values)}, + ) + + +@pytest.mark.asyncio +async def test_cluster_index_and_replication_crud() -> None: + registry = HandlerRegistry() + register_cluster_handlers(registry) + pool = GapPool() + index = await _call(registry.get("/cluster", "GET"), {}, pool) + assert any(item["subdir"] == "replication" for item in index) + created = await _call( + registry.get("/cluster/replication", "POST"), + {"guest": "100", "target": "pve02"}, + pool, + ) + assert created["id"] == "repl-100" + jobs = await _call(registry.get("/cluster/replication", "GET"), {}, pool) + assert jobs[0]["guest"] == "100" + fetched = await _call( + registry.get("/cluster/replication/{id}", "GET"), {"id": "repl-100"}, pool + ) + assert fetched["target"] == "pve02" + + +@pytest.mark.asyncio +async def test_ha_group_create_and_index() -> None: + registry = HandlerRegistry() + register_ha_handlers(registry) + pool = GapPool() + index = await _call(registry.get("/cluster/ha", "GET"), {}, pool) + assert any(item["subdir"] == "groups" for item in index) + await _call( + registry.get("/cluster/ha/groups", "POST"), + {"group": "lab", "nodes": "pve01,pve02"}, + pool, + ) + assert "lab" in pool.metadata["ha_groups"] + groups = await _call(registry.get("/cluster/ha/groups", "GET"), {}, pool) + assert groups[0]["group"] == "lab" + + +@pytest.mark.asyncio +async def test_access_user_and_group_detail() -> None: + registry = HandlerRegistry() + register_access_handlers(registry) + pool = GapPool() + user = await _call(registry.get("/access/users/{userid}", "GET"), {"userid": "root@pam"}, pool) + assert user["userid"] == "root@pam" + group = await _call( + registry.get("/access/groups/{groupid}", "GET"), + {"groupid": "operators"}, + pool, + ) + assert group["users"] == ["root@pam"] + + +@pytest.mark.asyncio +async def test_storage_content_get_and_upload() -> None: + registry = HandlerRegistry() + register_storage_handlers(registry) + pool = GapPool() + item = await _call( + registry.get("/nodes/{node}/storage/{storage}/content/{volume}", "GET"), + { + "node": "pve01", + "storage": "local-lvm", + "volume": "local-lvm:100/vm-100-disk-0.raw", + }, + pool, + ) + assert item["content"] == "images" + upload = await _call( + registry.get("/nodes/{node}/storage/{storage}/upload", "POST"), + {"node": "pve01", "storage": "local-lvm", "filename": "image.iso"}, + pool, + ) + assert "uploadid" in upload + + +@pytest.mark.asyncio +async def test_replication_missing_returns_404() -> None: + registry = HandlerRegistry() + register_cluster_handlers(registry) + handler = registry.get("/cluster/replication/{id}", "GET") + with pytest.raises(ApiError, match="replication job does not exist"): + await _call(handler, {"id": "missing"}, GapPool()) diff --git a/tests/unit/test_gap_remaining_handlers.py b/tests/unit/test_gap_remaining_handlers.py new file mode 100644 index 0000000..23b8e20 --- /dev/null +++ b/tests/unit/test_gap_remaining_handlers.py @@ -0,0 +1,163 @@ +"""Persistence tests for remaining gap handlers (nodes_extra / cluster_extra).""" + +from __future__ import annotations + +import json +from typing import Any, cast + +import pytest +from fastapi import FastAPI, Request + +from app.api.registry import HandlerRegistry +from app.db.pool import AsyncpgDatabase +from app.handlers.cluster_extra import register_cluster_extra_handlers +from app.handlers.nodes_extra import register_nodes_extra_handlers + + +class GapRemainingPool: + def __init__(self) -> None: + self.cluster_metadata: dict[str, Any] = {} + self.node_metadata: dict[str, Any] = {} + + async def fetchrow(self, query: str, *arguments: object) -> dict[str, Any] | None: + if "SELECT metadata FROM clusters" in query: + return {"metadata": json.dumps(self.cluster_metadata)} + if "SELECT metadata FROM nodes" in query: + name = str(arguments[0]) + return {"metadata": json.dumps(self.node_metadata.get(name, {}))} + raise AssertionError(query) + + async def fetchval(self, query: str, *arguments: object) -> Any: + if "EXISTS(SELECT 1 FROM nodes" in query: + return True + raise AssertionError(query) + + async def execute(self, query: str, *arguments: object) -> str: + if "UPDATE clusters SET metadata" in query: + self.cluster_metadata = json.loads(str(arguments[1])) + return "UPDATE 1" + if "UPDATE nodes SET metadata" in query: + self.node_metadata[str(arguments[0])] = json.loads(str(arguments[1])) + return "UPDATE 1" + raise AssertionError(query) + + +class FakeDatabase: + def __init__(self, pool: GapRemainingPool) -> None: + self.pool = pool + + +def _request(pool: GapRemainingPool, *, method: str = "GET") -> Request: + app = FastAPI() + app.state.database = cast(AsyncpgDatabase, FakeDatabase(pool)) + result = Request( + { + "type": "http", + "app": app, + "method": method, + "path": "/", + "headers": [], + "query_string": b"", + "server": ("test", 80), + "client": ("test", 123), + "scheme": "http", + } + ) + result.state.principal = "root@pam" + return result + + +@pytest.mark.asyncio +async def test_disks_directory_create_persists() -> None: + registry = HandlerRegistry() + register_nodes_extra_handlers(registry) + pool = GapRemainingPool() + create = registry.get("/nodes/{node}/disks/directory", "POST") + assert create is not None + created = await create( + _request(pool, method="POST"), + { + "values": {"node": "pve01", "name": "tank", "device": "/dev/sdb"}, + "provided": frozenset(), + }, + ) + assert created["name"] == "tank" + ops = pool.node_metadata["pve01"]["ops"] + assert any(item["name"] == "tank" for item in ops["disks"]["directory"]) + + +@pytest.mark.asyncio +async def test_certificates_custom_create_does_not_echo_key() -> None: + registry = HandlerRegistry() + register_nodes_extra_handlers(registry) + pool = GapRemainingPool() + create = registry.get("/nodes/{node}/certificates/custom", "POST") + info = registry.get("/nodes/{node}/certificates/info", "GET") + assert create is not None and info is not None + await create( + _request(pool, method="POST"), + { + "values": { + "node": "pve01", + "certificates": "-----BEGIN CERTIFICATE-----\nSIM\n-----END CERTIFICATE-----", + "key": "-----BEGIN PRIVATE KEY-----\nSECRET\n-----END PRIVATE KEY-----", + }, + "provided": frozenset(), + }, + ) + stored = pool.node_metadata["pve01"]["ops"]["certificates"]["custom"] + assert stored["key"].startswith("-----BEGIN PRIVATE KEY-----") + listing = await info( + _request(pool), + {"values": {"node": "pve01"}, "provided": frozenset()}, + ) + blob = json.dumps(listing) + assert "PRIVATE KEY" not in blob + assert "SECRET" not in blob + + +@pytest.mark.asyncio +async def test_realm_sync_job_create_persists() -> None: + registry = HandlerRegistry() + register_cluster_extra_handlers(registry) + pool = GapRemainingPool() + create = registry.get("/cluster/jobs/realm-sync/{id}", "POST") + listing = registry.get("/cluster/jobs/realm-sync", "GET") + assert create is not None and listing is not None + created = await create( + _request(pool, method="POST"), + { + "values": {"id": "pam-nightly", "realm": "pam", "schedule": "0 2 * * *"}, + "provided": frozenset(), + }, + ) + assert created["id"] == "pam-nightly" + assert pool.cluster_metadata["jobs"]["realm_sync"]["pam-nightly"]["realm"] == "pam" + items = await listing(_request(pool), {"values": {}, "provided": frozenset()}) + assert items[0]["id"] == "pam-nightly" + + +@pytest.mark.asyncio +async def test_metrics_server_create_persists() -> None: + registry = HandlerRegistry() + register_cluster_extra_handlers(registry) + pool = GapRemainingPool() + create = registry.get("/cluster/metrics/server/{id}", "POST") + listing = registry.get("/cluster/metrics/server", "GET") + assert create is not None and listing is not None + created = await create( + _request(pool, method="POST"), + { + "values": { + "id": "influx1", + "type": "influxdb", + "server": "10.0.0.20", + "port": 8089, + }, + "provided": frozenset(), + }, + ) + assert created["id"] == "influx1" + assert pool.cluster_metadata["metrics"]["servers"]["influx1"]["server"] == "10.0.0.20" + items = await listing(_request(pool), {"values": {}, "provided": frozenset()}) + assert items[0]["id"] == "influx1" diff --git a/tests/unit/test_health.py b/tests/unit/test_health.py new file mode 100644 index 0000000..79ec403 --- /dev/null +++ b/tests/unit/test_health.py @@ -0,0 +1,87 @@ +from __future__ import annotations + +import asyncio +from typing import Self + +import pytest +from httpx import ASGITransport, AsyncClient + +from app.config import Settings +from app.db.pool import Database +from app.main import create_app + + +class FakeDatabase: + def __init__(self, ready: bool) -> None: + self.ready = ready + self.connected = False + self.closed = False + + async def connect(self) -> None: + self.connected = True + + async def close(self) -> None: + self.closed = True + + async def is_ready(self) -> bool: + return self.ready + + async def __aenter__(self) -> Self: + await self.connect() + return self + + async def __aexit__(self, exc_type: object, exc: object, traceback: object) -> None: + await self.close() + + +@pytest.mark.parametrize(("database_ready", "status_code"), [(True, 200), (False, 503)]) +async def test_health_endpoints(database_ready: bool, status_code: int) -> None: + database = FakeDatabase(database_ready) + + def factory(settings: Settings) -> Database: + del settings + return database + + application = create_app( + Settings(contract_snapshot=None, compatibility_evidence=None), + factory, + worker_factories=(), + ) + async with application.router.lifespan_context(application): + async with AsyncClient( + transport=ASGITransport(app=application, raise_app_exceptions=False), + base_url="http://test", + ) as client: + live = await client.get("/health/live") + ready = await client.get("/health/ready", headers={"X-Request-ID": "test-request"}) + + assert live.status_code == 200 + assert live.json() == {"status": "ok"} + assert ready.status_code == status_code + assert ready.headers["X-Request-ID"] == "test-request" + assert database.connected + assert database.closed + + +async def test_lifespan_starts_and_stops_injected_workers() -> None: + database = FakeDatabase(True) + started = asyncio.Event() + stopping = asyncio.Event() + + class Worker: + async def run(self) -> None: + started.set() + await stopping.wait() + + def stop(self) -> None: + stopping.set() + + application = create_app( + Settings(contract_snapshot=None, compatibility_evidence=None), + lambda _settings: database, + worker_factories=(lambda _database: Worker(),), + ) + async with application.router.lifespan_context(application): + await started.wait() + + assert stopping.is_set() diff --git a/tests/unit/test_logging.py b/tests/unit/test_logging.py new file mode 100644 index 0000000..c5f9da6 --- /dev/null +++ b/tests/unit/test_logging.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +import json +import logging + +from app.logging import JsonFormatter + + +def test_json_formatter_emits_structured_fields() -> None: + record = logging.LogRecord("test", logging.INFO, __file__, 1, "hello %s", ("world",), None) + record.request_id = "request-1" + + payload = json.loads(JsonFormatter().format(record)) + + assert payload["message"] == "hello world" + assert payload["request_id"] == "request-1" + assert payload["level"] == "INFO" diff --git a/tests/unit/test_lxc_handlers.py b/tests/unit/test_lxc_handlers.py new file mode 100644 index 0000000..61492dd --- /dev/null +++ b/tests/unit/test_lxc_handlers.py @@ -0,0 +1,155 @@ +"""Persistent LXC semantic handler tests.""" + +import uuid +from datetime import UTC, datetime +from typing import Any + +import pytest +from fastapi import Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.handlers.lxc import register_lxc_handlers + + +class LxcPool: + def __init__(self) -> None: + self.resource_exists = False + self.missing = False + self.running = False + self.commands: list[str] = [] + self.resource_id = uuid.uuid4() + + async def fetchval(self, sql: str, *args: object) -> bool | int: + del args + if "pg_backend_pid" in sql: + return 123 + if "extract(epoch" in sql: + return 1_700_000_000 + if "FROM nodes" in sql: + return True + if "FROM resources" in sql: + return self.resource_exists + if "FROM snapshots" in sql: + return False + raise AssertionError(sql) + + async def fetch(self, sql: str, *args: object) -> list[dict[str, object]]: + del args + if "FROM resources" in sql and "kind='lxc'" in sql: + return [{"vmid": 200, "state": '{"status":"stopped","name":"service"}'}] + assert "FROM snapshots" in sql + return [ + { + "name": "baseline", + "parent_name": None, + "description": "stable", + "created_at": datetime(2026, 1, 1, tzinfo=UTC), + } + ] + + async def fetchrow(self, sql: str, *args: object) -> dict[str, object] | None: + del args + if self.missing: + return None + if "SELECT r.id, r.version" in sql: + return { + "id": self.resource_id, + "version": 1, + "state": '{"name":"old","status":"stopped"}', + "config": '{"name":"old"}', + } + if "SELECT r.id, r.state, c.config" in sql: + return {"id": self.resource_id, "state": '{"status":"stopped"}', "config": "{}"} + if "SELECT r.id, r.state FROM resources" in sql: + status = "running" if self.running else "stopped" + return {"id": self.resource_id, "state": f'{{"status":"{status}"}}'} + if "SELECT s.* FROM snapshots" in sql: + return { + "id": uuid.uuid4(), + "name": "baseline", + "parent_name": None, + "description": "stable", + "created_at": datetime(2026, 1, 1, tzinfo=UTC), + "state": "{}", + } + raise AssertionError(sql) + + async def execute(self, sql: str, *args: object) -> str: + del sql, args + self.commands.append("execute") + return "UPDATE 1" + + +class FakeDatabase: + def __init__(self, pool: LxcPool) -> None: + self.pool = pool + + +class FakeTaskRepository: + def __init__(self, pool: LxcPool) -> None: + self.pool = pool + self.created: list[dict[str, Any]] = [] + + async def create(self, **kwargs: Any) -> Any: + self.created.append(kwargs) + return type( + "Task", (), {"upid": "UPID:pve1:00000001:00000001:1700000000:pctcreate:201:root@pam:"} + )() + + +def _request(pool: LxcPool) -> Request: + app = type("App", (), {"state": type("State", (), {"database": FakeDatabase(pool)})()})() + request = Request({"type": "http", "headers": [], "method": "POST", "path": "/"}) + request.scope["app"] = app + request.state.principal = "root@pam" + return request + + +@pytest.fixture +def registry() -> HandlerRegistry: + handler_registry = HandlerRegistry() + register_lxc_handlers(handler_registry) + return handler_registry + + +async def test_lxc_list_returns_seeded_containers(registry: HandlerRegistry) -> None: + pool = LxcPool() + handler = registry.get("/nodes/{node}/lxc", "GET") + assert handler is not None + result = await handler(_request(pool), {"values": {"node": "pve1"}}) + assert result == [{"vmid": 200, "status": "stopped", "name": "service"}] + + +async def test_lxc_create_rejects_duplicate_vmid(registry: HandlerRegistry) -> None: + pool = LxcPool() + pool.resource_exists = True + handler = registry.get("/nodes/{node}/lxc", "POST") + assert handler is not None + with pytest.raises(ApiError, match="VMID already exists"): + await handler( + _request(pool), + {"values": {"node": "pve1", "vmid": 201, "hostname": "app"}}, + ) + + +async def test_lxc_delete_requires_stopped_container(registry: HandlerRegistry) -> None: + pool = LxcPool() + pool.running = True + handler = registry.get("/nodes/{node}/lxc/{vmid}", "DELETE") + assert handler is not None + with pytest.raises(ApiError, match="cannot delete a running container"): + await handler(_request(pool), {"values": {"node": "pve1", "vmid": "200"}}) + + +async def test_lxc_start_creates_task( + monkeypatch: pytest.MonkeyPatch, registry: HandlerRegistry +) -> None: + pool = LxcPool() + repository = FakeTaskRepository(pool) + monkeypatch.setattr("app.handlers.lxc.TaskRepository", lambda _pool: repository) + handler = registry.get("/nodes/{node}/lxc/{vmid}/status/start", "POST") + assert handler is not None + upid = await handler(_request(pool), {"values": {"node": "pve1", "vmid": "200"}}) + assert upid.startswith("UPID:") + assert repository.created[0]["task_type"] == "lxc-start" diff --git a/tests/unit/test_migrations.py b/tests/unit/test_migrations.py new file mode 100644 index 0000000..aaebfef --- /dev/null +++ b/tests/unit/test_migrations.py @@ -0,0 +1,56 @@ +"""Migration discovery and checksum tests.""" + +from pathlib import Path + +from app.db.migrations import load_migrations + + +def test_load_migrations_is_ordered_and_checksummed(tmp_path: Path) -> None: + (tmp_path / "002_second.sql").write_text("SELECT 2;") + (tmp_path / "001_first.sql").write_text("SELECT 1;") + + migrations = load_migrations(tmp_path) + + assert [migration.version for migration in migrations] == [1, 2] + assert migrations[0].name == "001_first" + assert len(migrations[0].checksum) == 64 + + +def test_repository_migration_defines_required_planes() -> None: + migrations = load_migrations() + migration = migrations[0] + + for table in ( + "contract_snapshots", + "nodes", + "resources", + "principals", + "acl_entries", + "tasks", + "scenarios", + "audit_events", + ): + assert f"CREATE TABLE {table}" in migration.sql + assert "CREATE TABLE realms" in migrations[1].sql + assert "CREATE TABLE api_tokens" in migrations[1].sql + domain = migrations[3].sql + for table in ( + "clusters", + "virtual_machines", + "containers", + "storages", + "storage_contents", + "snapshots", + "backups", + "pools", + "identity_groups", + "contract_paths", + "observed_contracts", + "scenario_rules", + "fault_injections", + ): + assert f"CREATE TABLE {table}" in domain + assert "CREATE TABLE group_acl_entries" in migrations[5].sql + assert "ADD COLUMN IF NOT EXISTS config jsonb" in migrations[6].sql + assert "CREATE TABLE tfa_entries" in migrations[7].sql + assert "CREATE TABLE openid_pending" in migrations[7].sql diff --git a/tests/unit/test_node_ops_handlers.py b/tests/unit/test_node_ops_handlers.py new file mode 100644 index 0000000..c8dcc8e --- /dev/null +++ b/tests/unit/test_node_ops_handlers.py @@ -0,0 +1,128 @@ +"""Node ops handlers persist network/disks/services into nodes.metadata.""" + +from __future__ import annotations + +import json +from typing import Any, cast + +from fastapi import FastAPI, Request + +from app.api.registry import HandlerRegistry +from app.db.pool import AsyncpgDatabase +from app.handlers.nodes import register_node_ops_handlers + + +class NodePool: + def __init__(self) -> None: + self.metadata: dict[str, Any] = {} + + async def fetchrow(self, query: str, *arguments: object) -> dict[str, Any] | None: + if "SELECT metadata FROM nodes" in query: + return {"metadata": json.dumps(self.metadata)} + raise AssertionError(query) + + async def fetchval(self, query: str, *arguments: object) -> Any: + if "EXISTS(SELECT 1 FROM nodes" in query: + return True + raise AssertionError(query) + + async def execute(self, query: str, *arguments: object) -> str: + if "UPDATE nodes SET metadata" in query: + self.metadata = json.loads(str(arguments[1])) + return "UPDATE 1" + raise AssertionError(query) + + +class FakeDatabase: + def __init__(self, pool: NodePool) -> None: + self.pool = pool + + +def request(pool: NodePool, *, method: str = "GET", path: str = "/") -> Request: + app = FastAPI() + app.state.database = cast(AsyncpgDatabase, FakeDatabase(pool)) + result = Request( + { + "type": "http", + "app": app, + "method": method, + "path": path, + "headers": [], + "query_string": b"", + "server": ("test", 80), + "client": ("test", 123), + "scheme": "http", + } + ) + result.state.principal = "root@pam" + return result + + +async def test_network_and_service_mutations_persist() -> None: + registry = HandlerRegistry() + register_node_ops_handlers(registry) + pool = NodePool() + + create = registry.get("/nodes/{node}/network", "POST") + listing = registry.get("/nodes/{node}/network", "GET") + delete = registry.get("/nodes/{node}/network/{iface}", "DELETE") + stop = registry.get("/nodes/{node}/services/{service}/stop", "POST") + state = registry.get("/nodes/{node}/services/{service}/state", "GET") + assert create and listing and delete and stop and state + + await create( + request(pool, method="POST", path="/api2/json/nodes/pve01/network"), + {"values": {"node": "pve01", "iface": "vmbr9", "type": "bridge"}, "provided": frozenset()}, + ) + items = await listing( + request(pool), + {"values": {"node": "pve01"}, "provided": frozenset()}, + ) + assert any(item["iface"] == "vmbr9" for item in items) + + await delete( + request(pool, method="DELETE", path="/api2/json/nodes/pve01/network/vmbr9"), + {"values": {"node": "pve01", "iface": "vmbr9"}, "provided": frozenset()}, + ) + items = await listing( + request(pool), + {"values": {"node": "pve01"}, "provided": frozenset()}, + ) + assert all(item["iface"] != "vmbr9" for item in items) + + await stop( + request(pool, method="POST", path="/api2/json/nodes/pve01/services/pveproxy/stop"), + {"values": {"node": "pve01", "service": "pveproxy"}, "provided": frozenset()}, + ) + service = await state( + request(pool), + {"values": {"node": "pve01", "service": "pveproxy"}, "provided": frozenset()}, + ) + assert service["state"] == "stopped" + assert "ops" in pool.metadata + + +async def test_disk_init_and_wipe_persist() -> None: + registry = HandlerRegistry() + register_node_ops_handlers(registry) + pool = NodePool() + initgpt = registry.get("/nodes/{node}/disks/initgpt", "POST") + wipe = registry.get("/nodes/{node}/disks/wipedisk", "PUT") + listing = registry.get("/nodes/{node}/disks/list", "GET") + assert initgpt and wipe and listing + + await initgpt( + request(pool, method="POST"), + {"values": {"node": "pve01", "disk": "/dev/sdb"}, "provided": frozenset()}, + ) + await wipe( + request(pool, method="PUT"), + {"values": {"node": "pve01", "disk": "/dev/sdb"}, "provided": frozenset()}, + ) + disks = await listing( + request(pool), + {"values": {"node": "pve01"}, "provided": frozenset()}, + ) + target = next(item for item in disks if item["devpath"] == "/dev/sdb") + assert target["wiped"] == 1 + assert target["gpt"] == 0 diff --git a/tests/unit/test_notifications_handlers.py b/tests/unit/test_notifications_handlers.py new file mode 100644 index 0000000..95258ca --- /dev/null +++ b/tests/unit/test_notifications_handlers.py @@ -0,0 +1,87 @@ +"""Notification endpoints/matchers persistence.""" + +from __future__ import annotations + +import json +from typing import Any, cast + +from fastapi import FastAPI, Request + +from app.api.registry import HandlerRegistry +from app.db.pool import AsyncpgDatabase +from app.handlers.notifications import register_notifications_handlers +from app.simulation.seed import CLUSTER_ID + + +class NotesPool: + def __init__(self) -> None: + self.metadata: dict[str, Any] = {} + + async def fetchrow(self, query: str, *arguments: object) -> dict[str, Any] | None: + if "FROM clusters WHERE id" in query: + return {"metadata": json.dumps(self.metadata)} + raise AssertionError(query) + + async def execute(self, query: str, *arguments: object) -> str: + if "UPDATE clusters SET metadata" in query: + self.metadata = json.loads(str(arguments[1])) + return "UPDATE 1" + raise AssertionError(query) + + +def request(pool: NotesPool) -> Request: + app = FastAPI() + app.state.database = cast(AsyncpgDatabase, type("DB", (), {"pool": pool})()) + return Request( + { + "type": "http", + "app": app, + "method": "POST", + "path": "/", + "headers": [], + "query_string": b"", + "server": ("test", 80), + "client": ("test", 123), + "scheme": "http", + } + ) + + +async def test_notification_endpoint_and_matcher_persist() -> None: + registry = HandlerRegistry() + register_notifications_handlers(registry) + pool = NotesPool() + http = request(pool) + create = registry.get("/cluster/notifications/endpoints/gotify", "POST") + get = registry.get("/cluster/notifications/endpoints/gotify/{name}", "GET") + matchers = registry.get("/cluster/notifications/matchers", "POST") + targets = registry.get("/cluster/notifications/targets", "GET") + test = registry.get("/cluster/notifications/targets/{name}/test", "POST") + assert create and get and matchers and targets and test + + await create( + http, + { + "values": { + "name": "ops", + "server": "https://gotify.local", + "token": "secret-token", + }, + "provided": frozenset(), + }, + ) + payload = await get(http, {"values": {"name": "ops"}, "provided": frozenset()}) + assert payload["server"] == "https://gotify.local" + assert "token" not in payload + await matchers( + http, + { + "values": {"name": "all-mail", "target": "ops", "mode": "all"}, + "provided": frozenset(), + }, + ) + listed = await targets(http, {"values": {}, "provided": frozenset()}) + assert listed[0]["name"] == "ops" + await test(http, {"values": {"name": "ops"}, "provided": frozenset()}) + assert pool.metadata["notifications"]["tests"] + assert CLUSTER_ID diff --git a/tests/unit/test_openapi.py b/tests/unit/test_openapi.py new file mode 100644 index 0000000..5bc033d --- /dev/null +++ b/tests/unit/test_openapi.py @@ -0,0 +1,37 @@ +"""OpenAPI tag categorization tests.""" + +from app.api.openapi import contract_openapi_tag, contract_openapi_tags, openapi_tag_metadata + + +def test_contract_openapi_tag_groups_by_domain() -> None: + assert contract_openapi_tag("/version") == "Core" + assert contract_openapi_tag("/access/ticket") == "Access" + assert contract_openapi_tag("/nodes/{node}/qemu/{vmid}/config") == "Nodes · QEMU" + assert contract_openapi_tag("/nodes/{node}/lxc/{vmid}/config") == "Nodes · LXC" + assert contract_openapi_tag("/nodes/{node}/ceph/osd") == "Nodes · Ceph" + assert contract_openapi_tag("/cluster/ha/resources") == "Cluster · HA" + assert contract_openapi_tag("/pools") == "Pools" + + +def test_contract_openapi_tags_include_renderer() -> None: + assert contract_openapi_tags("/version", "json") == ["Core", "API2 JSON"] + assert contract_openapi_tags("/version", "extjs") == ["Core", "API2 ExtJS"] + + +def test_openapi_tag_metadata_is_deterministic() -> None: + names = [entry["name"] for entry in openapi_tag_metadata()] + assert names == sorted(names) + assert "Simulator" in names + assert "vSphere REST" in names + assert "Nodes · QEMU" not in names + assert "API2 JSON" not in names + assert "Access" not in names + + +def test_openapi_tag_metadata_includes_pve_when_requested() -> None: + names = [entry["name"] for entry in openapi_tag_metadata(include_pve=True)] + assert names == sorted(names) + assert "Nodes · QEMU" in names + assert "API2 JSON" in names + assert "Access" in names + assert "Simulator" in names diff --git a/tests/unit/test_property_collector.py b/tests/unit/test_property_collector.py new file mode 100644 index 0000000..eddd9a6 --- /dev/null +++ b/tests/unit/test_property_collector.py @@ -0,0 +1,131 @@ +"""Unit tests for SOAP PropertyCollector helpers.""" + +from __future__ import annotations + +import os + +import pytest + +from app.vsphere.inventory import ManagedObject +from app.vsphere.soap.property_collector import ( + _descendants, + _one_level_traverse, + _type_matches, + _wants_parent_traversal, + build_prop_map, + clear_pc_state, + resolve_inventory_path, + store_page_token, + take_page_token, + take_page_token_full, + view_moids_from_object, + wait_updates_xml, +) + + +def _obj( + moid: str, + type_name: str, + name: str, + parent: str | None, + props: dict | None = None, +) -> ManagedObject: + return ManagedObject( + moid=moid, + type=type_name, + name=name, + parent_moid=parent, + props=props or {}, + ) + + +def test_type_matches_and_parent_traversal() -> None: + assert _type_matches("VirtualMachine", {"ManagedEntity"}) + assert _wants_parent_traversal("parent") + + +def test_descendants() -> None: + objects = [ + _obj("group-d1", "Folder", "Datacenters", None), + _obj("datacenter-21", "Datacenter", "DC", "group-d1"), + _obj("group-v23", "Folder", "vm", "datacenter-21"), + _obj("vm-101", "VirtualMachine", "web-01", "group-v23"), + ] + expanded = _descendants([objects[0]], objects) + assert {o.moid for o in expanded} >= {"group-d1", "datacenter-21", "group-v23", "vm-101"} + + +def test_view_moids_from_object_props() -> None: + view = _obj("view-1", "ContainerView", "view-1", None, {"view_moids": ["vm-101", "vm-102"]}) + assert view_moids_from_object(view) == ["vm-101", "vm-102"] + props = build_prop_map( + view, + children=[], + all_by_moid={ + "vm-101": _obj("vm-101", "VirtualMachine", "a", "group-v23"), + "vm-102": _obj("vm-102", "VirtualMachine", "b", "group-v23"), + }, + ) + assert "view" in props + + +@pytest.mark.integration +@pytest.mark.asyncio +async def test_page_token_roundtrip_db() -> None: + database_url = os.getenv("TEST_DATABASE_URL") or os.getenv("DATABASE_URL") + if not database_url: + pytest.skip("TEST_DATABASE_URL / DATABASE_URL required") + from app.config import Settings + from app.db.pool import AsyncpgDatabase + + database = AsyncpgDatabase(Settings(database_url=database_url)) # type: ignore[arg-type] + await database.connect() + try: + await clear_pc_state(database) + token = await store_page_token(database, ["vm-1", "vm-2"], path_sets=["name"]) + assert await take_page_token_full(database, token) == (["vm-1", "vm-2"], ["name"]) + token2 = await store_page_token(database, ["vm-3"]) + assert await take_page_token(database, token2) == ["vm-3"] + assert await take_page_token(database, token2) is None + finally: + await database.close() + + +@pytest.mark.integration +@pytest.mark.asyncio +async def test_wait_updates_versions_db() -> None: + database_url = os.getenv("TEST_DATABASE_URL") or os.getenv("DATABASE_URL") + if not database_url: + pytest.skip("TEST_DATABASE_URL / DATABASE_URL required") + from app.config import Settings + from app.db.pool import AsyncpgDatabase + + database = AsyncpgDatabase(Settings(database_url=database_url)) # type: ignore[arg-type] + await database.connect() + try: + await clear_pc_state(database) + objects = [_obj("vm-101", "VirtualMachine", "web-01", "group-v23")] + first = await wait_updates_xml( + database, session_key="sess-1", body="", objects=objects + ) + assert "1" in first + idle = await wait_updates_xml( + database, session_key="sess-1", body="1", objects=objects + ) + assert "1" in idle + assert "objectSet" not in idle + finally: + await database.close() + + +def test_resolve_inventory_path_and_one_level() -> None: + objects = [ + _obj("group-d1", "Folder", "Datacenters", None), + _obj("datacenter-21", "Datacenter", "DC1", "group-d1", {"vm_folder": "group-v23"}), + _obj("group-v23", "Folder", "vm", "datacenter-21"), + _obj("vm-101", "VirtualMachine", "web-01", "group-v23"), + ] + hit = resolve_inventory_path("/DC1/vm/web-01", objects) + assert hit is not None and hit.moid == "vm-101" + kids = _one_level_traverse([objects[2]], objects, "childEntity") + assert any(o.moid == "vm-101" for o in kids) diff --git a/tests/unit/test_qemu_handlers.py b/tests/unit/test_qemu_handlers.py new file mode 100644 index 0000000..e34b783 --- /dev/null +++ b/tests/unit/test_qemu_handlers.py @@ -0,0 +1,364 @@ +"""Persistent QEMU CRUD semantic handler tests.""" + +import uuid +from datetime import UTC, datetime +from typing import Any, cast + +import pytest +from fastapi import FastAPI, Request + +from app.api.errors import ApiError +from app.api.registry import HandlerRegistry +from app.db.pool import AsyncpgDatabase +from app.db.primitives import ConflictError +from app.handlers.qemu import register_qemu_handlers +from app.tasks.repository import Task + + +class QemuPool: + def __init__(self) -> None: + self.resource_exists = False + self.missing = False + self.running = False + self.commands: list[str] = [] + self.resource_id = uuid.uuid4() + + async def fetchval(self, sql: str, *args: object) -> bool | int: + del args + if "pg_backend_pid" in sql: + return 123 + if "extract(epoch" in sql: + return 1_700_000_000 + if "FROM nodes" in sql: + return True + if "FROM resources" in sql: + return self.resource_exists + if "FROM snapshots" in sql: + return False + raise AssertionError(sql) + + async def fetch(self, sql: str, *args: object) -> list[dict[str, object]]: + del args + if "FROM resources" in sql: + return [{"vmid": 150, "state": '{"status":"stopped","name":"vm"}'}] + assert "FROM snapshots" in sql + return [ + { + "name": "baseline", + "parent_name": None, + "description": "stable", + "created_at": datetime(2026, 1, 1, tzinfo=UTC), + } + ] + + async def fetchrow(self, sql: str, *args: object) -> dict[str, object] | None: + del args + if self.missing: + return None + if "SELECT r.id, r.version" in sql: + return { + "id": self.resource_id, + "version": 1, + "state": '{"name":"old","status":"stopped"}', + "config": '{"name":"old"}', + } + if "SELECT r.state, v.config" in sql: + return {"state": '{"status":"stopped"}', "config": '{"name":"vm"}'} + if "SELECT r.id, r.state" in sql: + status = "running" if self.running else "stopped" + return { + "id": self.resource_id, + "state": f'{{"status":"{status}"}}', + "config": ('{"agent":1,"name":"vm","scsi0":"local-lvm:vm-150-disk-0,size=8G"}'), + } + if "SELECT r.id, r.state, v.config" in sql: + return {"id": self.resource_id, "state": '{"status":"stopped"}', "config": "{}"} + if "SELECT s.* FROM snapshots" in sql: + return { + "id": uuid.uuid4(), + "name": "baseline", + "parent_name": None, + "description": "stable", + "state": '{"config":{"name":"old"}}', + "created_at": datetime(2026, 1, 1, tzinfo=UTC), + } + raise AssertionError(sql) + + async def execute(self, sql: str, *args: object) -> str: + del args + self.commands.append(sql) + return "UPDATE 1" + + +class FakeDatabase: + def __init__(self, pool: QemuPool) -> None: + self.pool = pool + + +def request(pool: QemuPool) -> Request: + app = FastAPI() + app.state.database = cast(AsyncpgDatabase, FakeDatabase(pool)) + result = Request( + { + "type": "http", + "app": app, + "method": "POST", + "path": "/", + "headers": [], + "query_string": b"", + "server": ("test", 80), + "client": ("test", 123), + "scheme": "http", + } + ) + result.state.principal = "root@pam" + return result + + +def inputs(**values: object) -> dict[str, Any]: + return {"values": values, "provided": tuple(values)} + + +async def test_qemu_create_sync_async_update_and_delete( + monkeypatch: pytest.MonkeyPatch, +) -> None: + created_payloads: list[dict[str, Any]] = [] + + class FakeTaskRepository: + def __init__(self, pool: object) -> None: + del pool + + async def create(self, **kwargs: Any) -> Task: + created_payloads.append(kwargs) + return Task( + uuid.uuid4(), + str(kwargs["upid"]), + str(kwargs["task_type"]), + "queued", + dict(kwargs["payload"]), + 0, + False, + 0, + ) + + monkeypatch.setattr("app.handlers.qemu.TaskRepository", FakeTaskRepository) + registry = HandlerRegistry() + register_qemu_handlers(registry) + pool = QemuPool() + http_request = request(pool) + create = registry.get("/nodes/{node}/qemu", "POST") + listing = registry.get("/nodes/{node}/qemu", "GET") + config = registry.get("/nodes/{node}/qemu/{vmid}/config", "GET") + current = registry.get("/nodes/{node}/qemu/{vmid}/status/current", "GET") + update_sync = registry.get("/nodes/{node}/qemu/{vmid}/config", "PUT") + update_async = registry.get("/nodes/{node}/qemu/{vmid}/config", "POST") + delete = registry.get("/nodes/{node}/qemu/{vmid}", "DELETE") + assert create and listing and config and current and update_sync and update_async and delete + + assert (await listing(http_request, inputs(node="pve1")))[0]["name"] == "vm" + assert (await config(http_request, inputs(node="pve1", vmid=150)))["name"] == "vm" + assert (await current(http_request, inputs(node="pve1", vmid=150)))["status"] == "stopped" + + create_upid = await create( + http_request, + inputs(node="pve1", vmid=150, name="new", cores=2), + ) + assert create_upid.startswith("UPID:pve1:") + assert created_payloads[-1]["task_type"] == "qemu-create" + + assert ( + await update_sync( + http_request, + inputs(node="pve1", vmid=150, name="sync", delete="unused"), + ) + is None + ) + assert len(pool.commands) == 2 + + update_upid = await update_async( + http_request, + inputs(node="pve1", vmid=150, memory="2048"), + ) + assert update_upid.startswith("UPID:pve1:") + assert created_payloads[-1]["task_type"] == "qemu-update" + + delete_upid = await delete(http_request, inputs(node="pve1", vmid=150)) + assert delete_upid.startswith("UPID:pve1:") + assert created_payloads[-1]["task_type"] == "qemu-delete" + + +async def test_qemu_crud_conflicts_and_missing_resources( + monkeypatch: pytest.MonkeyPatch, +) -> None: + class ConflictingRepository: + def __init__(self, pool: object) -> None: + del pool + + async def create(self, **_kwargs: object) -> Task: + raise ConflictError("resource is locked") + + monkeypatch.setattr("app.handlers.qemu.TaskRepository", ConflictingRepository) + registry = HandlerRegistry() + register_qemu_handlers(registry) + pool = QemuPool() + http_request = request(pool) + create = registry.get("/nodes/{node}/qemu", "POST") + update = registry.get("/nodes/{node}/qemu/{vmid}/config", "PUT") + delete = registry.get("/nodes/{node}/qemu/{vmid}", "DELETE") + assert create and update and delete + + with pytest.raises(ApiError) as locked: + await create(http_request, inputs(node="pve1", vmid=150)) + assert locked.value.status_code == 409 + + pool.resource_exists = True + with pytest.raises(ApiError) as duplicate: + await create(http_request, inputs(node="pve1", vmid=150)) + assert duplicate.value.status_code == 409 + + pool.missing = True + with pytest.raises(ApiError) as missing: + await update(http_request, inputs(node="pve1", vmid=150, name="missing")) + assert missing.value.status_code == 404 + + pool.missing = False + pool.running = True + with pytest.raises(ApiError) as running: + await delete(http_request, inputs(node="pve1", vmid=150)) + assert running.value.status_code == 409 + + +async def test_qemu_snapshot_handlers(monkeypatch: pytest.MonkeyPatch) -> None: + tasks: list[str] = [] + + class FakeTaskRepository: + def __init__(self, pool: object) -> None: + del pool + + async def create(self, **kwargs: Any) -> Task: + tasks.append(str(kwargs["task_type"])) + return Task(uuid.uuid4(), str(kwargs["upid"]), tasks[-1], "queued", {}, 0, False, 0) + + monkeypatch.setattr("app.handlers.qemu.TaskRepository", FakeTaskRepository) + registry = HandlerRegistry() + register_qemu_handlers(registry) + pool = QemuPool() + http_request = request(pool) + base = "/nodes/{node}/qemu/{vmid}/snapshot" + + listing = registry.get(base, "GET") + create = registry.get(base, "POST") + get = registry.get(f"{base}/{{snapname}}", "GET") + delete = registry.get(f"{base}/{{snapname}}", "DELETE") + config_get = registry.get(f"{base}/{{snapname}}/config", "GET") + config_put = registry.get(f"{base}/{{snapname}}/config", "PUT") + rollback = registry.get(f"{base}/{{snapname}}/rollback", "POST") + assert listing and create and get and delete and config_get and config_put and rollback + + common = inputs(node="pve1", vmid=150, snapname="baseline") + assert (await listing(http_request, inputs(node="pve1", vmid=150)))[0]["name"] == "baseline" + assert (await get(http_request, common))["description"] == "stable" + assert (await config_get(http_request, common))["config"] == {"name": "old"} + assert await config_put(http_request, inputs(**common["values"], description="updated")) is None + assert ( + await create(http_request, inputs(**common["values"], description="stable")) + ).startswith("UPID:pve1:") + assert (await rollback(http_request, common)).startswith("UPID:pve1:") + assert (await delete(http_request, common)).startswith("UPID:pve1:") + assert tasks == ["qemu-snapshot-create", "qemu-snapshot-rollback", "qemu-snapshot-delete"] + + +async def test_qemu_clone_and_migrate_handlers(monkeypatch: pytest.MonkeyPatch) -> None: + tasks: list[dict[str, Any]] = [] + + class FakeTaskRepository: + def __init__(self, pool: object) -> None: + del pool + + async def create(self, **kwargs: Any) -> Task: + tasks.append(kwargs) + return Task( + uuid.uuid4(), + str(kwargs["upid"]), + str(kwargs["task_type"]), + "queued", + {}, + 0, + False, + 0, + ) + + monkeypatch.setattr("app.handlers.qemu.TaskRepository", FakeTaskRepository) + registry = HandlerRegistry() + register_qemu_handlers(registry) + pool = QemuPool() + http_request = request(pool) + clone = registry.get("/nodes/{node}/qemu/{vmid}/clone", "POST") + migrate_get = registry.get("/nodes/{node}/qemu/{vmid}/migrate", "GET") + migrate = registry.get("/nodes/{node}/qemu/{vmid}/migrate", "POST") + resize = registry.get("/nodes/{node}/qemu/{vmid}/resize", "PUT") + move = registry.get("/nodes/{node}/qemu/{vmid}/move_disk", "POST") + assert clone and migrate_get and migrate and resize and move + + clone_upid = await clone( + http_request, inputs(node="pve1", vmid=150, newid=151, name="clone", full=True) + ) + assert clone_upid.startswith("UPID:pve1:") + assert tasks[-1]["task_type"] == "qemu-clone" + assert (await migrate_get(http_request, inputs(node="pve1", vmid=150, target="pve2")))[ + "local_disks" + ] == [] + migrate_upid = await migrate( + http_request, inputs(node="pve1", vmid=150, target="pve2", online=False) + ) + assert migrate_upid.startswith("UPID:pve1:") + assert tasks[-1]["task_type"] == "qemu-migrate" + assert ( + await resize(http_request, inputs(node="pve1", vmid=150, disk="scsi0", size="+2G")) is None + ) + move_upid = await move( + http_request, inputs(node="pve1", vmid=150, disk="scsi0", storage="local") + ) + assert move_upid.startswith("UPID:pve1:") + assert tasks[-1]["task_type"] == "qemu-move-disk" + + with pytest.raises(ApiError) as same_node: + await migrate(http_request, inputs(node="pve1", vmid=150, target="pve1")) + assert same_node.value.status_code == 400 + + +async def test_qemu_pending_and_agent_handlers() -> None: + registry = HandlerRegistry() + register_qemu_handlers(registry) + pool = QemuPool() + pool.running = True + http_request = request(pool) + values = inputs(node="pve1", vmid=150) + + pending = registry.get("/nodes/{node}/qemu/{vmid}/pending", "GET") + routes = { + "info": "/nodes/{node}/qemu/{vmid}/agent/info", + "os": "/nodes/{node}/qemu/{vmid}/agent/get-osinfo", + "host": "/nodes/{node}/qemu/{vmid}/agent/get-host-name", + "network": "/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces", + "time": "/nodes/{node}/qemu/{vmid}/agent/get-time", + "ping": "/nodes/{node}/qemu/{vmid}/agent/ping", + } + handlers = { + name: registry.get(path, "POST" if name == "ping" else "GET") + for name, path in routes.items() + } + assert pending and all(handlers.values()) + + async def call(name: str) -> dict[str, Any]: + handler = handlers[name] + assert handler is not None + return cast(dict[str, Any], await handler(http_request, values)) + + assert await pending(http_request, values) == [] + assert (await call("info"))["result"]["version"] + assert (await call("os"))["result"]["machine"] == "x86_64" + assert (await call("host"))["result"]["host-name"] == "vm" + assert (await call("network"))["result"][0]["name"] == "eth0" + assert (await call("time"))["result"]["seconds"] > 0 + assert (await call("ping"))["result"] == {} diff --git a/tests/unit/test_qemu_task.py b/tests/unit/test_qemu_task.py new file mode 100644 index 0000000..a779247 --- /dev/null +++ b/tests/unit/test_qemu_task.py @@ -0,0 +1,284 @@ +"""QEMU worker transition semantics.""" + +import uuid +from datetime import UTC, datetime +from typing import cast + +from app.simulation.clock import Clock +from app.tasks.qemu import qemu_handler +from app.tasks.repository import Task, TaskRepository + + +class ImmediateClock: + async def now(self) -> datetime: + return datetime(2026, 1, 1, tzinfo=UTC) + + async def sleep(self, seconds: float) -> None: + assert seconds == 1.0 + + +class Connection: + def __init__(self) -> None: + self.states: list[str] = [] + + async def fetchrow(self, sql: str, resource_id: uuid.UUID) -> dict[str, object]: + del sql, resource_id + return {"state": '{"status":"stopped"}'} + + async def execute(self, sql: str, resource_id: uuid.UUID, state: str) -> str: + del sql, resource_id + self.states.append(state) + return "UPDATE 1" + + +class Acquire: + def __init__(self, connection: Connection) -> None: + self.connection = connection + + async def __aenter__(self) -> Connection: + return self.connection + + async def __aexit__(self, *args: object) -> None: + return None + + +class Pool: + def __init__(self, connection: Connection) -> None: + self.connection = connection + + def acquire(self) -> Acquire: + return Acquire(self.connection) + + +class Repository: + def __init__(self) -> None: + self.connection = Connection() + self.pool = Pool(self.connection) + self.logs: list[str] = [] + + async def append_log(self, task_id: uuid.UUID, message: str) -> None: + del task_id + self.logs.append(message) + + +class Transaction: + async def __aenter__(self) -> None: + return None + + async def __aexit__(self, *args: object) -> None: + return None + + +class CrudConnection: + def __init__(self) -> None: + self.commands: list[str] = [] + + def transaction(self) -> Transaction: + return Transaction() + + async def fetchrow(self, sql: str, *args: object) -> dict[str, object] | None: + del args + if "FROM nodes" in sql: + return {"id": uuid.uuid4(), "cluster_id": uuid.uuid4()} + if "JOIN virtual_machines" in sql: + return {"state": '{"status":"stopped","name":"old"}', "config": '{"name":"old"}'} + if "SELECT state FROM resources" in sql: + return {"state": '{"status":"stopped","name":"old"}'} + if "SELECT config FROM virtual_machines" in sql: + return {"config": '{"scsi0":"local-lvm:vm-150-disk-0,size=10G"}'} + if "FROM snapshots" in sql: + return { + "state": ( + '{"resource_state":{"status":"stopped","name":"old"},"config":{"name":"old"}}' + ) + } + return None + + async def execute(self, sql: str, *args: object) -> str: + del args + self.commands.append(sql) + return "DELETE 1" if sql.startswith("DELETE") else "UPDATE 1" + + +class CrudRepository: + def __init__(self) -> None: + self.connection = CrudConnection() + self.pool = Pool(cast(Connection, self.connection)) + self.logs: list[str] = [] + + async def append_log(self, _task_id: uuid.UUID, message: str) -> None: + self.logs.append(message) + + +async def test_qemu_worker_applies_intermediate_and_final_states() -> None: + repository = Repository() + task = Task( + uuid.uuid4(), + "UPID:test", + "qemu-start", + "running", + {"resource_id": str(uuid.uuid4())}, + 0, + False, + 1, + ) + + result = await qemu_handler(cast(TaskRepository, repository), cast(Clock, ImmediateClock()))( + task + ) + + assert result == {"status": "running"} + assert '"starting"' in repository.connection.states[0] + assert '"running"' in repository.connection.states[1] + assert repository.logs == ["VM start started", "VM start completed"] + + +async def test_qemu_worker_create_update_and_delete_are_persistent() -> None: + repository = CrudRepository() + handler = qemu_handler(cast(TaskRepository, repository), cast(Clock, ImmediateClock())) + resource_id = uuid.uuid4() + + created = await handler( + Task( + uuid.uuid4(), + "UPID:create", + "qemu-create", + "running", + {"node": "pve1", "vmid": 150, "config": {"name": "new"}}, + 0, + False, + 1, + ) + ) + updated = await handler( + Task( + uuid.uuid4(), + "UPID:update", + "qemu-update", + "running", + { + "resource_id": str(resource_id), + "changes": {"name": "changed", "cores": 4}, + "delete": "unused", + }, + 0, + False, + 1, + ) + ) + deleted = await handler( + Task( + uuid.uuid4(), + "UPID:delete", + "qemu-delete", + "running", + {"resource_id": str(resource_id)}, + 0, + False, + 1, + ) + ) + + assert created == {"vmid": 150, "status": "stopped"} + assert updated == {"updated": ["cores", "name"], "deleted": ["unused"]} + assert deleted == {"deleted": True} + assert any("INSERT INTO resources" in command for command in repository.connection.commands) + assert any("UPDATE virtual_machines" in command for command in repository.connection.commands) + assert any("DELETE FROM resources" in command for command in repository.connection.commands) + + +async def test_qemu_worker_snapshot_create_rollback_and_delete_are_persistent() -> None: + repository = CrudRepository() + handler = qemu_handler(cast(TaskRepository, repository), cast(Clock, ImmediateClock())) + resource_id = uuid.uuid4() + + async def run(operation: str, **payload: object) -> dict[str, object]: + result = await handler( + Task( + uuid.uuid4(), + f"UPID:{operation}", + f"qemu-snapshot-{operation}", + "running", + {"resource_id": str(resource_id), "snapname": "baseline", **payload}, + 0, + False, + 1, + ) + ) + assert result is not None + return cast(dict[str, object], result) + + assert await run("create", description="stable") == { + "snapshot": "baseline", + "operation": "create", + } + assert await run("rollback", start=True) == { + "snapshot": "baseline", + "operation": "rollback", + } + assert await run("delete") == {"snapshot": "baseline", "operation": "delete"} + commands = repository.connection.commands + assert any("INSERT INTO snapshots" in command for command in commands) + assert any("UPDATE virtual_machines" in command for command in commands) + assert any("DELETE FROM snapshots" in command for command in commands) + + +async def test_qemu_worker_clone_and_migrate_are_persistent() -> None: + repository = CrudRepository() + handler = qemu_handler(cast(TaskRepository, repository), cast(Clock, ImmediateClock())) + resource_id = uuid.uuid4() + + cloned = await handler( + Task( + uuid.uuid4(), + "UPID:clone", + "qemu-clone", + "running", + { + "source_resource_id": str(resource_id), + "node": "pve1", + "vmid": 151, + "name": "clone", + }, + 0, + False, + 1, + ) + ) + migrated = await handler( + Task( + uuid.uuid4(), + "UPID:migrate", + "qemu-migrate", + "running", + {"resource_id": str(resource_id), "target": "pve2"}, + 0, + False, + 1, + ) + ) + moved = await handler( + Task( + uuid.uuid4(), + "UPID:move", + "qemu-move-disk", + "running", + { + "resource_id": str(resource_id), + "disk": "scsi0", + "target_disk": "scsi0", + "storage": "local", + "delete": True, + }, + 0, + False, + 1, + ) + ) + + assert cloned == {"vmid": 151, "node": "pve1"} + assert migrated == {"node": "pve2", "status": "stopped"} + assert moved == {"disk": "scsi0", "storage": "local"} + commands = repository.connection.commands + assert any("INSERT INTO resources" in command for command in commands) + assert any("node_id=$2" in command for command in commands) diff --git a/tests/unit/test_schema_examples.py b/tests/unit/test_schema_examples.py new file mode 100644 index 0000000..e5f7c01 --- /dev/null +++ b/tests/unit/test_schema_examples.py @@ -0,0 +1,25 @@ +"""Tests for contract example generation.""" + +from app.contracts.examples import path_param_example, schema_example +from app.contracts.model import Schema + + +def test_path_param_examples_use_known_placeholders() -> None: + assert path_param_example("node") == "pve01" + assert path_param_example("vmid") == 100 + + +def test_schema_example_prefers_default_and_enum() -> None: + assert schema_example(Schema(type="string", default="custom")) == "custom" + assert schema_example(Schema(type="string", enum=("a", "b"))) == "a" + + +def test_schema_example_builds_object_and_array() -> None: + schema = Schema( + type="object", + properties={ + "count": Schema(type="integer", minimum=2), + "enabled": Schema(type="boolean", optional=True), + }, + ) + assert schema_example(schema) == {"count": 2} diff --git a/tests/unit/test_sdn_handlers.py b/tests/unit/test_sdn_handlers.py new file mode 100644 index 0000000..3245a3d --- /dev/null +++ b/tests/unit/test_sdn_handlers.py @@ -0,0 +1,128 @@ +"""SDN zone/vnet/subnet persistence tests.""" + +from __future__ import annotations + +import json +from typing import Any, cast + +from fastapi import FastAPI, Request + +from app.api.registry import HandlerRegistry +from app.db.pool import AsyncpgDatabase +from app.handlers.sdn import register_sdn_handlers + + +class SdnPool: + def __init__(self) -> None: + self.metadata: dict[str, Any] = {} + self.nodes = {"pve1"} + + async def fetchrow(self, query: str, *_arguments: object) -> dict[str, Any] | None: + if "FROM clusters WHERE id" in query: + return {"metadata": json.dumps(self.metadata)} + raise AssertionError(query) + + async def fetchval(self, query: str, *arguments: object) -> Any: + if "EXISTS(SELECT 1 FROM nodes" in query: + return str(arguments[0]) in self.nodes + raise AssertionError(query) + + async def execute(self, query: str, *arguments: object) -> str: + if "UPDATE clusters SET metadata" in query: + self.metadata = json.loads(str(arguments[1])) + return "UPDATE 1" + raise AssertionError(query) + + +async def call( + registry: HandlerRegistry, path: str, verb: str, http: Request, inputs: dict[str, Any] +) -> Any: + handler = registry.get(path, verb) + assert handler is not None + return await handler(http, inputs) + + +def request(pool: SdnPool) -> Request: + app = FastAPI() + app.state.database = cast(AsyncpgDatabase, type("DB", (), {"pool": pool})()) + return Request( + { + "type": "http", + "app": app, + "method": "POST", + "path": "/", + "headers": [], + "query_string": b"", + "server": ("test", 80), + "client": ("test", 123), + "scheme": "http", + } + ) + + +async def test_sdn_zone_vnet_subnet_and_node_views() -> None: + registry = HandlerRegistry() + register_sdn_handlers(registry) + pool = SdnPool() + http = request(pool) + + await call( + registry, + "/cluster/sdn/zones", + "POST", + http, + {"values": {"zone": "localzone", "type": "simple"}, "provided": frozenset()}, + ) + await call( + registry, + "/cluster/sdn/vnets", + "POST", + http, + { + "values": {"vnet": "vnet0", "zone": "localzone", "type": "vnet"}, + "provided": frozenset(), + }, + ) + await call( + registry, + "/cluster/sdn/vnets/{vnet}/subnets", + "POST", + http, + { + "values": { + "vnet": "vnet0", + "subnet": "10.0.0.0/24", + "gateway": "10.0.0.1", + }, + "provided": frozenset(), + }, + ) + zones = await call( + registry, "/cluster/sdn/zones", "GET", http, {"values": {}, "provided": frozenset()} + ) + assert zones[0]["zone"] == "localzone" + subnets = await call( + registry, + "/cluster/sdn/vnets/{vnet}/subnets", + "GET", + http, + {"values": {"vnet": "vnet0"}, "provided": frozenset()}, + ) + assert subnets[0]["subnet"] == "10.0.0.0/24" + node_zones = await call( + registry, + "/nodes/{node}/sdn/zones", + "GET", + http, + {"values": {"node": "pve1"}, "provided": frozenset()}, + ) + assert node_zones[0]["zone"] == "localzone" + assert pool.metadata["sdn"]["pending"] is True + await call( + registry, + "/cluster/sdn", + "PUT", + http, + {"values": {"release-lock": 1}, "provided": frozenset()}, + ) + assert pool.metadata["sdn"]["pending"] is False diff --git a/tests/unit/test_seed.py b/tests/unit/test_seed.py new file mode 100644 index 0000000..80da6d0 --- /dev/null +++ b/tests/unit/test_seed.py @@ -0,0 +1,127 @@ +"""Deterministic seed profile tests.""" + +import pytest + +from app.simulation.seed import ( + build_profile, + clear_simulation_state, + large_profile, + small_profile, + stable_id, +) + + +def test_small_profile_matches_required_logical_shape() -> None: + first = small_profile() + second = small_profile() + + assert first == second + state = first.logical_state() + assert state == second.logical_state() + assert state["nodes"] == [{"name": "pve01", "status": "online"}] + resources = state["resources"] + assert isinstance(resources, list) + assert [resource["kind"] for resource in resources].count("qemu") == 2 + assert [resource["kind"] for resource in resources].count("lxc") == 1 + assert [resource["kind"] for resource in resources].count("storage") == 2 + tasks = state["tasks"] + assert isinstance(tasks, list) + assert len(tasks) == 2 + + +def test_medium_and_fault_profiles_are_deterministic() -> None: + medium = build_profile("medium") + assert len(medium.nodes) == 3 + assert sum(resource.kind == "qemu" for resource in medium.resources) == 50 + assert sum(resource.kind == "lxc" for resource in medium.resources) == 20 + assert build_profile("ha-demo") == build_profile("ha-demo") + broken = build_profile("broken-storage") + assert any(resource.state.get("status") == "offline" for resource in broken.resources) + + +def test_large_profile_is_configurable_and_stable() -> None: + first = large_profile(node_count=4, resource_count=1_000) + second = large_profile(node_count=4, resource_count=1_000) + assert first == second + assert len(first.nodes) == 4 + assert len(first.resources) == 1_000 + + +def test_profile_validation() -> None: + with pytest.raises(ValueError, match="unknown seed profile"): + build_profile("missing") + with pytest.raises(ValueError, match="positive"): + large_profile(node_count=0, resource_count=1) + + +def test_demo_cluster_profile_shape() -> None: + profile = build_profile("demo-cluster") + assert profile.name == "demo-cluster" + assert len(profile.nodes) == 20 + assert sum(resource.kind == "qemu" for resource in profile.resources) == 850 + assert sum(resource.kind == "lxc" for resource in profile.resources) == 150 + assert sum(resource.kind == "ceph-osd" for resource in profile.resources) == 300 + assert sum(resource.kind == "storage" for resource in profile.resources) >= 62 + assert len(profile.tasks) == 250 + external_ids = { + resource.external_id for resource in profile.resources if resource.kind in {"qemu", "lxc"} + } + assert len(external_ids) == 1000 + + +def test_demo_cluster_spreads_guests_evenly_across_nodes() -> None: + profile = build_profile("demo-cluster") + names = {node.id: node.name for node in profile.nodes} + + def counts(kind: str) -> list[int]: + counter: dict[str, int] = {name: 0 for name in names.values()} + for resource in profile.resources: + if resource.kind == kind: + counter[names[resource.node_id]] += 1 + return list(counter.values()) + + for kind, expected_total in (("qemu", 850), ("lxc", 150), ("ceph-osd", 300)): + values = counts(kind) + assert sum(values) == expected_total + assert max(values) - min(values) <= 1 + + guest_counts = counts("qemu") + guest_counts = [a + b for a, b in zip(guest_counts, counts("lxc"), strict=True)] + assert max(guest_counts) - min(guest_counts) <= 2 + + +def test_minimal_profile() -> None: + profile = build_profile("minimal") + assert len(profile.nodes) == 1 + assert not any(resource.kind in {"qemu", "lxc"} for resource in profile.resources) + + +def test_stable_ids_are_namespaced_and_repeatable() -> None: + assert stable_id("qemu:100") == stable_id("qemu:100") + assert stable_id("qemu:100") != stable_id("qemu:101") + + +@pytest.mark.asyncio +async def test_clear_simulation_state_wipes_api_created_identity() -> None: + executed: list[str] = [] + + class FakeConnection: + async def execute(self, sql: str, *args: object) -> str: + del args + executed.append(" ".join(sql.split())) + return "DELETE 0" + + await clear_simulation_state(FakeConnection()) + joined = "\n".join(executed) + for table in ( + "resources", + "nodes", + "principals", + "identity_groups", + "roles", + "storage_contents", + "api_tokens", + ): + assert f"DELETE FROM {table}" in joined # noqa: S608 - asserting SQL text + assert "DELETE FROM realms WHERE name NOT IN" in joined + assert any(sql.startswith("UPDATE clusters") for sql in executed) diff --git a/tests/unit/test_task_worker.py b/tests/unit/test_task_worker.py new file mode 100644 index 0000000..8529ad5 --- /dev/null +++ b/tests/unit/test_task_worker.py @@ -0,0 +1,100 @@ +"""Bounded task worker outcome tests.""" + +import asyncio +import uuid +from typing import cast + +from app.tasks.repository import Task, TaskRepository +from app.tasks.worker import TaskWorker + + +class FakeRepository: + def __init__(self, task: Task) -> None: + self.task = task + self.finishes: list[tuple[str, str | None]] = [] + + async def get(self, _task_id: uuid.UUID) -> Task: + return self.task + + async def finish( + self, + _task_id: uuid.UUID, + _worker_id: str, + *, + status: str, + result: dict[str, object] | None = None, + error: str | None = None, + ) -> None: + del result + self.finishes.append((status, error)) + + +def make_task(*, task_type: str = "test", cancelled: bool = False) -> Task: + return Task(uuid.uuid4(), "UPID:test", task_type, "running", {}, 0, cancelled, 1) + + +async def test_worker_persists_success_error_and_unsupported() -> None: + task = make_task() + repository = FakeRepository(task) + + async def success(_task: Task) -> dict[str, object]: + return {"ok": True} + + worker = TaskWorker(cast(TaskRepository, repository), "worker", {"test": success}) + await worker._execute(task) + assert repository.finishes == [("success", None)] + + unsupported = make_task(task_type="missing") + repository.task = unsupported + await worker._execute(unsupported) + assert repository.finishes[-1] == ("error", "unsupported task type") + + async def failure(_task: Task) -> None: + raise RuntimeError("private detail") + + failed = make_task() + repository.task = failed + worker.handlers["test"] = failure + await worker._execute(failed) + assert repository.finishes[-1] == ("error", "RuntimeError") + + +async def test_worker_honors_persisted_cancellation() -> None: + task = make_task(cancelled=True) + repository = FakeRepository(task) + called = False + + async def handler(_task: Task) -> None: + nonlocal called + called = True + + worker = TaskWorker(cast(TaskRepository, repository), "worker", {"test": handler}) + await worker._execute(task) + + assert not called + assert repository.finishes == [("cancelled", None)] + + +async def test_worker_retries_after_claim_failure() -> None: + class RecoveringRepository: + attempts = 0 + + async def claim(self, _worker_id: str, _lease_seconds: float) -> None: + self.attempts += 1 + if self.attempts == 1: + raise RuntimeError("database schema is not ready") + return None + + repository = RecoveringRepository() + worker = TaskWorker( + cast(TaskRepository, repository), + "worker", + {}, + poll_seconds=0.001, + ) + running = asyncio.create_task(worker.run()) + await asyncio.sleep(0.01) + worker.stop() + await running + + assert repository.attempts > 1 diff --git a/tests/unit/test_transitions.py b/tests/unit/test_transitions.py new file mode 100644 index 0000000..d0dcace --- /dev/null +++ b/tests/unit/test_transitions.py @@ -0,0 +1,50 @@ +"""VM state-machine and deterministic fault properties.""" + +import pytest +from hypothesis import given +from hypothesis import strategies as st + +from app.simulation.scenarios import FaultContext, FaultRule, matches +from app.simulation.transitions import InvalidTransitionError, VmState, plan_transition + + +@pytest.mark.parametrize( + ("state", "operation", "final"), + [ + (VmState.STOPPED, "start", VmState.RUNNING), + (VmState.RUNNING, "stop", VmState.STOPPED), + (VmState.RUNNING, "shutdown", VmState.STOPPED), + (VmState.RUNNING, "reboot", VmState.RUNNING), + (VmState.RUNNING, "reset", VmState.RUNNING), + (VmState.RUNNING, "suspend", VmState.PAUSED), + (VmState.RUNNING, "pause", VmState.PAUSED), + (VmState.PAUSED, "resume", VmState.RUNNING), + (VmState.RUNNING, "snapshot", VmState.RUNNING), + (VmState.STOPPED, "migrate", VmState.STOPPED), + ], +) +def test_valid_transitions(state: VmState, operation: str, final: VmState) -> None: + transition = plan_transition(state, operation) + assert transition.before is state + assert transition.after is final + assert transition.intermediate is not state + + +@given(st.sampled_from(tuple(VmState)), st.text(min_size=1, max_size=12)) +def test_transition_result_is_declared_or_rejected(state: VmState, operation: str) -> None: + try: + transition = plan_transition(state, operation) + except InvalidTransitionError: + return + assert transition.before is state + + +def test_fault_evaluation_is_seeded_and_filtered() -> None: + context = FaultContext("POST", "/nodes/pve1/qemu/100/status/start", node="pve1") + certain = FaultRule("task-failure", method="POST", node="pve1") + impossible = FaultRule("task-failure", probability=0) + + assert matches(certain, context, seed=42) + assert not matches(impossible, context, seed=42) + probabilistic = FaultRule("task-failure", probability=0.5) + assert matches(probabilistic, context, 42) == matches(probabilistic, context, 42) diff --git a/tests/unit/test_upid.py b/tests/unit/test_upid.py new file mode 100644 index 0000000..ac881f3 --- /dev/null +++ b/tests/unit/test_upid.py @@ -0,0 +1,71 @@ +"""UPID examples and round-trip properties.""" + +import pytest +from hypothesis import given +from hypothesis import strategies as st + +from app.tasks.upid import Upid + +SAFE = st.from_regex(r"[a-z0-9][a-z0-9_-]{0,19}", fullmatch=True) + + +@given( + node=SAFE, + pid=st.integers(min_value=0, max_value=0xFFFFFFFF), + process_start=st.integers(min_value=0, max_value=0xFFFFFFFF), + start_time=st.integers(min_value=0, max_value=0xFFFFFFFF), + task_type=SAFE, + task_id=st.text(alphabet="abcdefghijklmnopqrstuvwxyz0123456789_-", max_size=20), + user=SAFE, +) +def test_upid_round_trip( + node: str, + pid: int, + process_start: int, + start_time: int, + task_type: str, + task_id: str, + user: str, +) -> None: + upid = Upid(node, pid, process_start, start_time, task_type, task_id, user) + + assert Upid.parse(str(upid)) == upid + + +def test_known_upid_shape() -> None: + value = "UPID:pve1:0000002A:00000010:65A1B2C3:qmstart:100:root@pam:" + + parsed = Upid.parse(value) + + assert parsed.pid == 42 + assert parsed.task_id == "100" + assert str(parsed) == value + + +@pytest.mark.parametrize("value", ["", "UPID:broken", "UPID:pve:GGGGGGGG:00000000:00000000:x::u:"]) +def test_invalid_upids_are_rejected(value: str) -> None: + with pytest.raises(ValueError): + Upid.parse(value) + + +@pytest.mark.parametrize( + "kwargs", + [ + {"pid": -1}, + {"node": "bad:node"}, + {"task_id": "bad:id"}, + ], +) +def test_invalid_upid_components_are_rejected(kwargs: dict[str, object]) -> None: + values: dict[str, object] = { + "node": "pve1", + "pid": 1, + "process_start": 1, + "start_time": 1, + "task_type": "test", + "task_id": "100", + "user": "root@pam", + } + values.update(kwargs) + with pytest.raises(ValueError): + Upid(**values) # type: ignore[arg-type] diff --git a/tests/unit/test_vsphere_catalog.py b/tests/unit/test_vsphere_catalog.py new file mode 100644 index 0000000..e14ba18 --- /dev/null +++ b/tests/unit/test_vsphere_catalog.py @@ -0,0 +1,48 @@ +"""Native vSphere console catalog tests.""" + +from app.vsphere.contracts.catalog import ( + list_vsphere_majors, + vsphere_catalog_payload, + vsphere_method_payload, +) +from app.vsphere.rest.coverage import catalog_entries, is_implemented + + +def test_list_vsphere_majors() -> None: + payload = list_vsphere_majors(runtime_version="8.0.2") + series = {item["series"] for item in payload["majors"]} + assert series == { + "vSphere 7.0", + "vSphere 7.0 U3", + "vSphere 8.0", + "vSphere 8.0 U2", + } + assert payload["plane"] == "vsphere-rest" + + +def test_vsphere_catalog_marks_implemented_methods() -> None: + payload = vsphere_catalog_payload(9) + assert payload["source_version"] == "8.0.2" + assert payload["method_count"] == len(catalog_entries()) + assert is_implemented("GET", "/api/vcenter/vm") + assert is_implemented("POST", "/api/cis/tagging/category") + assert vsphere_catalog_payload(6)["method_count"] < payload["method_count"] + # Methods for the same path must be merged (GET+POST+DELETE on one path entry). + vm_paths = [ + p for cat in payload["categories"] for p in cat["paths"] if p["path"] == "/api/vcenter/vm" + ] + assert len(vm_paths) == 1 + assert {m["verb"] for m in vm_paths[0]["methods"]} >= {"GET", "POST"} + + +def test_vsphere_method_payload_extracts_path_fields() -> None: + payload = vsphere_method_payload( + major=9, + path="/api/vcenter/vm/{vm}", + verb="GET", + runtime_version="8.0.2", + ) + assert payload["implemented"] is True + assert len(payload["path_fields"]) == 1 + assert payload["path_fields"][0]["name"] == "vm" + assert payload["resolved_path"] == "/api/vcenter/vm/vm-111" diff --git a/tests/unit/test_vsphere_compatibility.py b/tests/unit/test_vsphere_compatibility.py new file mode 100644 index 0000000..5b5acb6 --- /dev/null +++ b/tests/unit/test_vsphere_compatibility.py @@ -0,0 +1,27 @@ +"""vSphere Implementation coverage payload tests.""" + +from app.vsphere.contracts.compatibility import evidence_ledger, vsphere_compatibility_payload +from app.vsphere.contracts.matrix import VERSIONS, catalog_entries_for_major +from app.vsphere.rest.coverage import catalog_entries + + +def test_compatibility_payload_matches_matrix() -> None: + universe = len(catalog_entries()) + for major in VERSIONS: + payload = vsphere_compatibility_payload(major) + implemented = len(catalog_entries_for_major(major)) + assert payload["total_declared"] == universe + assert payload["levels"]["implemented"]["count"] == implemented + assert payload["levels"]["declared"]["count"] == universe + assert payload["levels"]["gated"]["count"] == universe - implemented + assert payload["levels"]["schema_only"]["count"] == universe - implemented + assert payload["summary"]["coverage"] == round(implemented / universe, 4) + assert payload["summary"]["universe_by_verb"] + assert "GET" in payload["summary"]["by_verb"] or implemented == 0 + + +def test_evidence_ledger_includes_levels() -> None: + ledger = evidence_ledger(9) + assert ledger["summary"]["implemented_methods"] == len(catalog_entries()) + assert ledger["summary"]["coverage"] == 1.0 + assert ledger["levels"]["implemented"]["count"] == ledger["summary"]["universe_methods"] diff --git a/tests/unit/test_vsphere_contract_apply.py b/tests/unit/test_vsphere_contract_apply.py new file mode 100644 index 0000000..82558c4 --- /dev/null +++ b/tests/unit/test_vsphere_contract_apply.py @@ -0,0 +1,57 @@ +"""vSphere catalog hot-swap + compatibility UI (offline ASGI).""" + +from __future__ import annotations + +from httpx import ASGITransport, AsyncClient + +from app.config import Settings +from app.main import create_app +from app.vsphere.contracts.matrix import VERSIONS +from tests.unit.test_health import FakeDatabase + + +def _app(): + return create_app( + settings=Settings(), + database_factory=lambda _settings: FakeDatabase(True), + worker_factories=(), + ) + + +async def test_vsphere_contract_apply_swaps_catalog_major() -> None: + app = _app() + async with app.router.lifespan_context(app): + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + applied = await client.post("/ui/api/contract/apply", params={"major": 7}) + assert applied.status_code == 200 + payload = applied.json() + assert payload["ok"] is True + assert payload["major"] == 7 + assert payload["plane"] == "vsphere-rest" + assert payload["runtime_version"] == VERSIONS[7]["version"] + assert payload["method_count"] > 0 + + report = await client.get("/ui/api/compatibility", params={"major": 7}) + assert report.status_code == 200 + body = report.json() + assert body["catalog_version"] == VERSIONS[7]["version"] + assert body["levels"]["implemented"]["count"] == payload["method_count"] + + restored = await client.post("/ui/api/contract/apply", params={"major": 9}) + assert restored.status_code == 200 + assert restored.json()["runtime_version"] == VERSIONS[9]["version"] + + +async def test_vsphere_hot_swap_reports_full_registry_at_major_9() -> None: + app = _app() + async with app.router.lifespan_context(app): + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + applied = await client.post("/ui/api/contract/apply", params={"major": 9}) + assert applied.status_code == 200 + report = await client.get("/ui/api/compatibility", params={"major": 9}) + assert report.status_code == 200 + body = report.json() + declared = body["total_declared"] + assert declared > 0 + assert body["levels"]["implemented"]["count"] == declared + assert body["plane"] == "vsphere-rest" diff --git a/tests/unit/test_vsphere_mappers.py b/tests/unit/test_vsphere_mappers.py new file mode 100644 index 0000000..ed73cd5 --- /dev/null +++ b/tests/unit/test_vsphere_mappers.py @@ -0,0 +1,39 @@ +"""vSphere REST mapper unit tests.""" + +from app.vsphere.inventory import ManagedObject +from app.vsphere.rest import mappers + + +def test_vm_summary_maps_power_and_hardware() -> None: + obj = ManagedObject( + moid="vm-101", + type="VirtualMachine", + name="web-01", + parent_moid="group-v23", + props={"power_state": "POWERED_ON", "cpu_count": 2, "memory_size_mib": 4096}, + ) + summary = mappers.vm_summary(obj) + assert summary["vm"] == "vm-101" + assert summary["name"] == "web-01" + assert summary["power_state"] == "POWERED_ON" + assert summary["cpu_count"] == 2 + assert summary["memory_size_MiB"] == 4096 + + +def test_host_and_datastore_summaries() -> None: + host = ManagedObject( + moid="host-11", + type="HostSystem", + name="esxi01.lab.local", + parent_moid="domain-c21", + props={"connection_state": "CONNECTED", "power_state": "POWERED_ON"}, + ) + ds = ManagedObject( + moid="datastore-31", + type="Datastore", + name="datastore1", + parent_moid="group-s23", + props={"type": "VMFS", "capacity": 100, "free_space": 40}, + ) + assert mappers.host_summary(host)["host"] == "host-11" + assert mappers.datastore_summary(ds)["free_space"] == 40 diff --git a/tests/unit/test_vsphere_matrix.py b/tests/unit/test_vsphere_matrix.py new file mode 100644 index 0000000..27b6547 --- /dev/null +++ b/tests/unit/test_vsphere_matrix.py @@ -0,0 +1,69 @@ +"""Version matrix and hot-swap gating.""" + +from httpx import ASGITransport, AsyncClient + +from app.config import Settings +from app.main import create_app +from app.vsphere.contracts.matrix import ( + VERSIONS, + available_for_request, + catalog_entries_for_major, + methods_for_major, +) +from tests.unit.test_health import FakeDatabase + + +def test_major_6_smaller_than_major_9() -> None: + assert len(methods_for_major(6)) < len(methods_for_major(9)) + assert len(methods_for_major(7)) <= len(methods_for_major(8)) + assert len(methods_for_major(8)) <= len(methods_for_major(9)) + + +def test_runtime_serves_all_registered_regardless_of_major() -> None: + """Catalog floors remain for browse; runtime never 501s known paths.""" + + assert available_for_request("POST", "/api/cis/tagging/category", 6) is True + assert available_for_request("GET", "/api/content/library", 6) is True + assert available_for_request("POST", "/api/appliance/networking/dns/hostname", 6) is True + + +def test_catalog_floor_still_shrinks_browse_list() -> None: + from app.vsphere.contracts.matrix import methods_for_major + + assert ("POST", "/api/cis/tagging/category") not in methods_for_major(6) + assert ("POST", "/api/cis/tagging/category") in methods_for_major(7) + assert ("GET", "/api/content/library") not in methods_for_major(7) + assert ("GET", "/api/content/library") in methods_for_major(8) + + +def test_literal_path_beats_param_template() -> None: + """`/api/content/library/item` must not resolve as `/{library_id}`.""" + from app.vsphere.contracts.matrix import resolve_template + + assert resolve_template("GET", "/api/content/library/item") == "/api/content/library/item" + assert available_for_request("GET", "/api/content/library/item", 8) is True + + +def test_catalog_entries_match_version() -> None: + for major in VERSIONS: + entries = catalog_entries_for_major(major) + assert all(e["status"] in {"implemented", "stub"} for e in entries) + assert len(entries) == len(methods_for_major(major)) + + +async def test_hot_swap_does_not_501_registered_paths() -> None: + app = create_app( + settings=Settings(enable_pve_stub=False), + database_factory=lambda _settings: FakeDatabase(True), + worker_factories=(), + ) + async with app.router.lifespan_context(app): + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + apply = await client.post("/ui/api/contract/apply", params={"major": 6}) + assert apply.status_code == 200 + assert apply.json()["runtime_version"] == "7.0.0" + # Session required for library — but must not be version-gated 501. + library = await client.get("/api/content/library") + assert library.status_code != 501 + restore = await client.post("/ui/api/contract/apply", params={"major": 9}) + assert restore.status_code == 200 diff --git a/tests/unit/test_vsphere_profiles.py b/tests/unit/test_vsphere_profiles.py new file mode 100644 index 0000000..a7603b0 --- /dev/null +++ b/tests/unit/test_vsphere_profiles.py @@ -0,0 +1,52 @@ +"""vSphere seed profile shape tests (no database).""" + +from app.vsphere.profiles import build_vsphere_profile, large_vsphere_profile, small_vsphere_profile +from app.vsphere.security.authz import has_privilege, privileges_for_roles + + +def test_small_profile_has_named_vms() -> None: + profile = small_vsphere_profile() + assert profile.vm_count == 5 + names = {obj.name for obj in profile.objects if obj.type == "VirtualMachine"} + assert {"web-01", "app-01", "db-01"} <= names + + +def test_large_profile_1000_vms() -> None: + profile = large_vsphere_profile(host_count=10, vm_count=1000) + assert profile.vm_count == 1000 + assert profile.host_count == 10 + vms = [obj for obj in profile.objects if obj.type == "VirtualMachine"] + hosts = [obj for obj in profile.objects if obj.type == "HostSystem"] + assert len(vms) == 1000 + assert len(hosts) == 10 + # Named cookbooks survive at the front of large inventories. + assert any(obj.name == "web-01" for obj in vms) + # Even spread across hosts + by_host: dict[str, int] = {} + for vm in vms: + host = str(vm.props.get("host")) + by_host[host] = by_host.get(host, 0) + 1 + assert len(by_host) == 10 + assert min(by_host.values()) >= 90 + assert max(by_host.values()) <= 110 + + +def test_demo_cluster_profile() -> None: + profile = build_vsphere_profile("demo-cluster") + assert profile.vm_count == 1000 + assert profile.host_count == 20 + + +def test_lab_credentials_include_readonly() -> None: + users = {c.username: c.roles for c in large_vsphere_profile().credentials} + assert "readonly@vsphere.local" in users + assert "ReadOnly" in users["readonly@vsphere.local"] + assert "Administrator" in users["administrator@vsphere.local"] + + +def test_readonly_cannot_power() -> None: + assert has_privilege(["ReadOnly"], "System.Read") + assert not has_privilege(["ReadOnly"], "VirtualMachine.Interact.PowerOn") + assert has_privilege(["VirtualMachinePowerUser"], "VirtualMachine.Interact.PowerOn") + assert "*" not in privileges_for_roles(["Administrator"]) + assert "Authorization.ModifyPermissions" in privileges_for_roles(["Administrator"]) diff --git a/tests/unit/test_vsphere_universe.py b/tests/unit/test_vsphere_universe.py new file mode 100644 index 0000000..3995fe9 --- /dev/null +++ b/tests/unit/test_vsphere_universe.py @@ -0,0 +1,51 @@ +"""Broadcom universe registry coverage.""" + +from fastapi.routing import APIRoute + +from app.vsphere.rest.coverage import ( + CORE_IMPLEMENTED, + IMPLEMENTED, + catalog_entries, + reload_coverage, + universe_stats, +) +from app.vsphere.rest.stub_surface import router as stub_surface_router + + +def test_universe_covers_broadcom_operations_index() -> None: + reload_coverage() + stats = universe_stats() + assert stats["broadcom_operations"] == 1348 + assert int(stats["unique_routes"]) >= 1000 + assert int(stats["registry_methods"]) >= int(stats["unique_routes"]) + assert int(stats["core_methods"]) == len(CORE_IMPLEMENTED) + assert int(stats["stub_methods"]) >= 850 + + +def test_registry_includes_put_and_all_core_routes() -> None: + reload_coverage() + entries = {(e["verb"], e["path"]): e["status"] for e in catalog_entries()} + assert any(verb == "PUT" for verb, _path in entries) + for key, status in CORE_IMPLEMENTED.items(): + assert entries[key] == status + + +def test_stub_surface_registers_each_contract_path_separately() -> None: + """Universe stubs are individual FastAPI routes, not a catch-all.""" + + stub_routes = [ + route + for route in stub_surface_router.routes + if isinstance(route, APIRoute) and str(route.name or "").startswith("vsphere-stub:") + ] + expected = {(verb, path) for (verb, path), status in IMPLEMENTED.items() if status == "stub"} + registered: set[tuple[str, str]] = set() + for route in stub_routes: + methods = { + method for method in (route.methods or set()) if method not in {"HEAD", "OPTIONS"} + } + assert len(methods) == 1, route.path + registered.add((next(iter(methods)), route.path)) + assert len(stub_routes) == len(expected) + assert registered == expected + assert not any("{full_path" in route.path for route in stub_routes) diff --git a/tests/unit/test_web_assets.py b/tests/unit/test_web_assets.py new file mode 100644 index 0000000..28f9eeb --- /dev/null +++ b/tests/unit/test_web_assets.py @@ -0,0 +1,44 @@ +"""Web asset loading tests.""" + +from app.web.assets import console_html + + +def test_console_html_is_read_from_disk() -> None: + html = console_html() + assert "VMware API Emulator" in html + assert "workspace-brand-name-text" in html + assert "workspace-brand-vm" in html + assert "workspace-brand-ware" in html + assert "#8EC368" in html or "8EC368" in html + assert "vmware-sim-theme" in html + assert 'id="catalog-drawer"' in html + assert "catalog-drawer" in html + assert 'id="catalog-coverage"' in html + assert "Implementation coverage" in html + for required_id in ( + "method-desc", + "catalog-meta", + "stat-runtime", + "stat-catalog", + "stat-cluster-name", + "stat-nodes", + "stat-qemu", + "stat-lxc", + "implemented-only", + "btn-contract-apply", + "btn-catalog-refresh", + ): + assert f'id="{required_id}"' in html, required_id + assert "Apply as runtime" in html + assert "CONTRACT_SNAPSHOT" in html + assert 'id="help-drawer"' in html + assert 'id="help-badge"' in html + assert 'id="data-badge"' in html + assert 'id="data-drawer"' in html + assert 'id="data-panel"' in html + assert 'id="ui-modal"' in html + assert 'id="params-badge"' in html + assert 'id="params-header-badge"' not in html + assert 'id="params-meta-badge"' not in html + assert "methodHasParams(state.method)" in html or "methodHasParams(" in html + assert 'id="params-drawer"' in html diff --git a/tests/unit/test_web_console.py b/tests/unit/test_web_console.py new file mode 100644 index 0000000..5d80123 --- /dev/null +++ b/tests/unit/test_web_console.py @@ -0,0 +1,119 @@ +"""Web console route tests.""" + +from pathlib import Path + +from httpx import ASGITransport, AsyncClient + +from app.config import Settings +from app.main import create_app +from tests.unit.test_health import FakeDatabase + +_BUNDLED = Path( + "contracts/e61a893e996d05d376579226e7dfbedbcfce8b71787adacffbc557e6e35901c1/snapshot.json" +) + + +async def test_root_console_is_served() -> None: + app = create_app(database_factory=lambda _settings: FakeDatabase(True), worker_factories=()) + async with app.router.lifespan_context(app): + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + response = await client.get("/") + assert response.status_code == 200 + assert "VMware API Emulator" in response.text + assert "vmware" in response.text + assert 'id="catalog-drawer"' in response.text + assert "catalog-drawer" in response.text + assert 'id="help-drawer"' in response.text + assert 'id="help-badge"' in response.text + assert 'id="data-badge"' in response.text + assert 'id="data-drawer"' in response.text + assert "data-badge-btn" in response.text + assert 'id="endpoints-badge-count"' in response.text + assert 'id="endpoints-drawer-count"' in response.text + assert 'id="ui-modal"' in response.text + assert 'role="alertdialog"' in response.text + assert "Request body" in response.text + + +async def test_ui_method_vm_is_implemented() -> None: + app = create_app( + settings=Settings(enable_pve_stub=False), + database_factory=lambda _settings: FakeDatabase(True), + worker_factories=(), + ) + async with app.router.lifespan_context(app): + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + method = await client.get( + "/ui/api/method", + params={"major": 9, "path": "/api/vcenter/vm", "verb": "GET"}, + ) + assert method.status_code == 200 + assert method.json()["implemented"] is True + detail = await client.get( + "/ui/api/method", + params={"major": 9, "path": "/api/vcenter/vm/{vm}", "verb": "GET"}, + ) + assert detail.status_code == 200 + assert detail.json()["path_fields"][0]["name"] == "vm" + + +async def test_demo_api_requires_database() -> None: + app = create_app(database_factory=lambda _settings: FakeDatabase(True), worker_factories=()) + async with app.router.lifespan_context(app): + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + state = await client.get("/ui/api/demo/state") + load = await client.post("/ui/api/demo/load") + assert state.status_code == 503 + assert load.status_code == 503 + + +async def test_ui_versions_and_catalog_endpoints() -> None: + app = create_app( + settings=Settings(enable_pve_stub=False), + database_factory=lambda _settings: FakeDatabase(True), + worker_factories=(), + ) + async with app.router.lifespan_context(app): + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + versions = await client.get("/ui/api/versions") + assert versions.status_code == 200 + body = versions.json() + assert body["plane"] == "vsphere-rest" + assert {item["major"] for item in body["majors"]} == {6, 7, 8, 9} + catalog = await client.get("/ui/api/catalog", params={"major": 9}) + assert catalog.status_code == 200 + assert catalog.json()["source_version"] == "8.0.2" + method = await client.get( + "/ui/api/method", + params={"major": 9, "path": "/api/session", "verb": "POST"}, + ) + assert method.status_code == 200 + assert method.json()["implemented"] is True + compat9 = await client.get("/ui/api/compatibility", params={"major": 9}) + assert compat9.status_code == 200 + c9 = compat9.json() + assert c9["levels"]["implemented"]["count"] == c9["total_declared"] + assert c9["levels"]["implemented"]["score"] == 1.0 + compat6 = await client.get("/ui/api/compatibility", params={"major": 6}) + c6 = compat6.json() + assert c6["levels"]["implemented"]["count"] < c6["total_declared"] + assert 0 < c6["levels"]["implemented"]["score"] < 1 + + +async def test_pve_stub_plane_still_optional() -> None: + if not _BUNDLED.is_file(): + return + settings = Settings(enable_pve_stub=True, contract_snapshot=_BUNDLED) + app = create_app( + settings=settings, + database_factory=lambda _settings: FakeDatabase(True), + worker_factories=(), + ) + async with app.router.lifespan_context(app): + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + method = await client.get( + "/ui/api/method", + params={"major": 7, "path": "/nodes", "verb": "GET"}, + ) + assert method.status_code == 200 + assert method.json()["implemented"] is True